>> How will the application of SmPL conjunctions evolve further? > > I really have no idea what you are talking about.
I suggest to take another look at affected implementation details. > Make one single mail that contains all of the semantic patch variants > that you want to have considered and explain what the problem is. Would you find the following data processing approach easier to clarify? I extracted a bit of source code from a known file for your convenience as an attachment. https://elixir.bootlin.com/linux/v5.6.3/source/drivers/gpu/drm/mcde/mcde_drv.c#L307 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/mcde/mcde_drv.c?id=8f3d9f354286745c751374f5f1fcafee6b3f3136#n308 > These semantic patches should involve no use of databases. A Python dictionary can also be used as a data storage technique for the discussed system test. @initialize:python@ @@ import sys records = {} class integrity_error: pass def store_positions(places, check_in, action_in): """Add source code positions to an internal table.""" for place in places: key = (place.file, place.line, int(place.column) + 1) if key in records: sys.stderr.write("\n".join(["-> duplicate data", "file:", key[0], "function:", place.current_element, "line:", str(place.line)])) sys.stderr.write("\n") raise integrity_error else: records[key] = (action_in, check_in, place.current_element) @find@ expression action, check, result; position p; statement is, es; @@ result = action(...); if@p ( ( <+... result ...+> & check ) ) is else es @script:python collection@ c << find.check; action << find.action; places << find.p; @@ store_positions(places, c, action) @finalize:python@ @@ if len(records) > 0: delimiter = "|" sys.stdout.write(delimiter.join(['action', 'check', '"source file"', 'line', 'column' ])) sys.stdout.write("\r\n") for key, value in records.items(): sys.stdout.write(delimiter.join([value[0], value[1], key[0], key[1], str(key[2]) ])) sys.stdout.write("\r\n") else: sys.stderr.write("No result for this analysis!\n") elfring@Sonne:~/Projekte/Coccinelle/janitor> spatch list_condition_checks_after_function_calls7.cocci ../Probe/mcde_drv-excerpt1.c … -> duplicate data file: ../Probe/mcde_drv-excerpt1.c function: mcde_probe line: 16 Traceback …: …, line 30, in store_positions __main__.integrity_error: <__main__.integrity_error instance at 0x7fd3bff4d730> … Would you like compare the software behaviour any further with the following rule variant for the semantic patch language? @find@ expression action, check, result; position p; statement is, es; @@ result = action(...); if ( ( <+... result ...+> & check@p ) ) is else es Regards, Markus
// SPDX-License-Identifier: GPL-2.0 static int mcde_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct drm_device *drm; struct mcde *mcde; struct component_match *match = NULL; struct resource *res; u32 pid; u32 val; int irq; int ret; int i; mcde = kzalloc(sizeof(*mcde), GFP_KERNEL); if (!mcde) return -ENOMEM; mcde->dev = dev; ret = drm_dev_init(&mcde->drm, &mcde_drm_driver, dev); if (ret) { kfree(mcde); return ret; } drm = &mcde->drm; drm->dev_private = mcde; platform_set_drvdata(pdev, drm); /* Enable continuous updates: this is what Linux' framebuffer expects */ mcde->oneshot_mode = false; drm->dev_private = mcde; /* First obtain and turn on the main power */ mcde->epod = devm_regulator_get(dev, "epod"); if (IS_ERR(mcde->epod)) { ret = PTR_ERR(mcde->epod); dev_err(dev, "can't get EPOD regulator\n"); goto dev_unref; } ret = regulator_enable(mcde->epod); if (ret) { dev_err(dev, "can't enable EPOD regulator\n"); goto dev_unref; } mcde->vana = devm_regulator_get(dev, "vana"); if (IS_ERR(mcde->vana)) { ret = PTR_ERR(mcde->vana); dev_err(dev, "can't get VANA regulator\n"); goto regulator_epod_off; } ret = regulator_enable(mcde->vana); if (ret) { dev_err(dev, "can't enable VANA regulator\n"); goto regulator_epod_off; } /* * The vendor code uses ESRAM (onchip RAM) and need to activate * the v-esram34 regulator, but we don't use that yet */ /* Clock the silicon so we can access the registers */ mcde->mcde_clk = devm_clk_get(dev, "mcde"); if (IS_ERR(mcde->mcde_clk)) { dev_err(dev, "unable to get MCDE main clock\n"); ret = PTR_ERR(mcde->mcde_clk); goto regulator_off; } ret = clk_prepare_enable(mcde->mcde_clk); if (ret) { dev_err(dev, "failed to enable MCDE main clock\n"); goto regulator_off; } dev_info(dev, "MCDE clk rate %lu Hz\n", clk_get_rate(mcde->mcde_clk)); mcde->lcd_clk = devm_clk_get(dev, "lcd"); if (IS_ERR(mcde->lcd_clk)) { dev_err(dev, "unable to get LCD clock\n"); ret = PTR_ERR(mcde->lcd_clk); goto clk_disable; } mcde->hdmi_clk = devm_clk_get(dev, "hdmi"); if (IS_ERR(mcde->hdmi_clk)) { dev_err(dev, "unable to get HDMI clock\n"); ret = PTR_ERR(mcde->hdmi_clk); goto clk_disable; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mcde->regs = devm_ioremap_resource(dev, res); if (IS_ERR(mcde->regs)) { dev_err(dev, "no MCDE regs\n"); ret = -EINVAL; goto clk_disable; } irq = platform_get_irq(pdev, 0); if (!irq) { ret = -EINVAL; goto clk_disable; } ret = devm_request_irq(dev, irq, mcde_irq, 0, "mcde", mcde); if (ret) { dev_err(dev, "failed to request irq %d\n", ret); goto clk_disable; } /* * Check hardware revision, we only support U8500v2 version * as this was the only version used for mass market deployment, * but surely you can add more versions if you have them and * need them. */ pid = readl(mcde->regs + MCDE_PID); dev_info(dev, "found MCDE HW revision %d.%d (dev %d, metal fix %d)\n", (pid & MCDE_PID_MAJOR_VERSION_MASK) >> MCDE_PID_MAJOR_VERSION_SHIFT, (pid & MCDE_PID_MINOR_VERSION_MASK) >> MCDE_PID_MINOR_VERSION_SHIFT, (pid & MCDE_PID_DEVELOPMENT_VERSION_MASK) >> MCDE_PID_DEVELOPMENT_VERSION_SHIFT, (pid & MCDE_PID_METALFIX_VERSION_MASK) >> MCDE_PID_METALFIX_VERSION_SHIFT); if (pid != 0x03000800) { dev_err(dev, "unsupported hardware revision\n"); ret = -ENODEV; goto clk_disable; } /* Set up the main control, watermark level at 7 */ val = 7 << MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT; /* 24 bits DPI: connect LSB Ch B to D[0:7] */ val |= 3 << MCDE_CONF0_OUTMUX0_SHIFT; /* TV out: connect LSB Ch B to D[8:15] */ val |= 3 << MCDE_CONF0_OUTMUX1_SHIFT; /* Don't care about this muxing */ val |= 0 << MCDE_CONF0_OUTMUX2_SHIFT; /* 24 bits DPI: connect MID Ch B to D[24:31] */ val |= 4 << MCDE_CONF0_OUTMUX3_SHIFT; /* 5: 24 bits DPI: connect MSB Ch B to D[32:39] */ val |= 5 << MCDE_CONF0_OUTMUX4_SHIFT; /* Syncmux bits zero: DPI channel A and B on output pins A and B resp */ writel(val, mcde->regs + MCDE_CONF0); /* Enable automatic clock gating */ val = readl(mcde->regs + MCDE_CR); val |= MCDE_CR_MCDEEN | MCDE_CR_AUTOCLKG_EN; writel(val, mcde->regs + MCDE_CR); /* Clear any pending interrupts */ mcde_display_disable_irqs(mcde); writel(0, mcde->regs + MCDE_IMSCERR); writel(0xFFFFFFFF, mcde->regs + MCDE_RISERR); /* Spawn child devices for the DSI ports */ devm_of_platform_populate(dev); /* Create something that will match the subdrivers when we bind */ for (i = 0; i < ARRAY_SIZE(mcde_component_drivers); i++) { struct device_driver *drv = &mcde_component_drivers[i]->driver; struct device *p = NULL, *d; while ((d = platform_find_device_by_driver(p, drv))) { put_device(p); component_match_add(dev, &match, mcde_compare_dev, d); p = d; } put_device(p); } if (!match) { dev_err(dev, "no matching components\n"); ret = -ENODEV; goto clk_disable; } if (IS_ERR(match)) { dev_err(dev, "could not create component match\n"); ret = PTR_ERR(match); goto clk_disable; } ret = component_master_add_with_match(&pdev->dev, &mcde_drm_comp_ops, match); if (ret) { dev_err(dev, "failed to add component master\n"); goto clk_disable; } return 0; clk_disable: clk_disable_unprepare(mcde->mcde_clk); regulator_off: regulator_disable(mcde->vana); regulator_epod_off: regulator_disable(mcde->epod); dev_unref: drm_dev_put(drm); return ret; }
_______________________________________________ Cocci mailing list Cocci@systeme.lip6.fr https://systeme.lip6.fr/mailman/listinfo/cocci