How about trying: @@ identifier n; expression E; @@
... when != n = E cartoon_random_generator(&n) Since your code uses inout parameters, you might want to have a second "when" line with when != &n I'll take a look at why your proposition doesn't work shortly. Overall, it seems a bit overspecified, though. julia On Fri, 7 Oct 2011, Håkon Løvdal wrote: > I have a question/problem where I want to detect sending the address > of an uninitialized > variable into a function. The details are described at > http://stackoverflow.com/questions/7685898/detect-passing-pointer-to-uninitialized-variable. > > I know that there is more expertise about coccinelle here on the > mailing list than on stackoverflow, > but the question is so general that when answered it will be of > benefit for many more people when > present there. Feel free to just answer here on the mailing list, I > can update stackoverflow as appropriate. > > BR Håkon Løvdal > > A copy of the question is as follows: > > Some functions have a pointer argument that points to where a result > from calling the function should be stored, but the function also > require that when calling the function this pointer points to some > value used as input value (e.g. an in/out parameter). > > I want to detect cases where such functions are called pointing to > uninitialized variables. Coccinelle should be able to do this, however > I struggle a little to achieve this. > > Example target code: > > #include <string.h> > #include <stdio.h> > > static void cartoon_random_generator(int *n) > { > switch (*n) { > case 4: > *n = 4; /* http://xkcd.com/221/ */ > break; > case 9: > *n = 9; /* http://dilbert.com/strips/comic/2001-10-25/ */ > break; > default: > fprintf(stderr, "*n was not initialized before calling this > function\n"); > break; > } > } > /* alternative links http://i.stack.imgur.com/VvTef.png and > http://i.stack.imgur.com/u0iJ7.gif */ > > static void test(const char *cartoon) > { > // not ok, missing > { > int n1; > > cartoon_random_generator(&n1); > printf("Random number = %d\n", n1); > } > > // ok, declaration > { > int n2 = 4; > > cartoon_random_generator(&n2); > printf("Random number = %d\n", n2); > } > > // ok, statement > { > int n3; > > n3 = 9; > cartoon_random_generator(&n3); > printf("Random number = %d\n", n3); > } > > // both ok and not ok > { > int n4, n9; > > n9 = 9; > //strcmp(cartoon, "XKCD") == 0 ? cartoon_random_generator(&n4) > : cartoon_random_generator(&n9); > if (strcmp(cartoon, "XKCD") == 0) > cartoon_random_generator(&n4); > else > cartoon_random_generator(&n9); > printf("Random numbers = %d, %d\n", n4, n9); > } > } > > I have written the following coccinelle script > > /* It is an error to call cartoon_random_generator with an uninitialized > variable. Detect this. */ > > > /* > * This rule matches an OK case where the in variable is initialized when > * declared. No action is performed for this rule other than giving p1 a > value. > */ > @rule1@ > position p1; > expression init_expression; > identifier n; > @@ > > int n = init_expression; > ... > cartoon_random_generator@p1(&n) > > > /* > * This rule matches an OK case where the in variable is initialized in a > * separate statement. No action is performed for this rule other than > * giving p2 a value. > */ > @rule2@ > position p2; > expression init_expression; > identifier n; > @@ > > int n; > ... > n = init_expression; > ... > cartoon_random_generator@p2(&n) > > > /* If neither rule1 or rule2 have matched so far, > * we have a variable that is uninitialized. */ > > @rule3@ > position p3 != rule1.p1, rule2.p2; > identifier n; > @@ > > int n; > ... > * cartoon_random_generator@p3(&n) > > but rule2 is not taken into account and I do not understand why. > Running it gives: > > $ /opt/coccinelle/bin/spatch -sp_file cartoon_random.cocci cartoon_random.c > init_defs_builtins: /opt/coccinelle/share/coccinelle/standard.h > warning: rule3: inherited metavariable p2 not used in the -, +, or context > code > HANDLING: cartoon_random.c > diff = > --- cartoon_random.c > +++ /tmp/cocci-output-7916-8df75b-cartoon_random.c > @@ -23,7 +23,6 @@ static void test(const char *cartoon) > { > int n1; > > - cartoon_random_generator(&n1); > printf("Random number = %d\n", n1); > } > > @@ -40,7 +39,6 @@ static void test(const char *cartoon) > int n3; > > n3 = 9; > - cartoon_random_generator(&n3); > printf("Random number = %d\n", n3); > } > > @@ -51,9 +49,7 @@ static void test(const char *cartoon) > n9 = 9; > //strcmp(cartoon, "XKCD") == 0 ? > cartoon_random_generator(&n4) : cartoon_random_generator(&n9); > if (strcmp(cartoon, "XKCD") == 0) > - cartoon_random_generator(&n4); > else > - cartoon_random_generator(&n9); > printf("Random numbers = %d, %d\n", n4, n9); > } > } > _______________________________________________ > Cocci mailing list > [email protected] > http://lists.diku.dk/mailman/listinfo/cocci > (Web access from inside DIKUs LAN only) >
_______________________________________________ Cocci mailing list [email protected] http://lists.diku.dk/mailman/listinfo/cocci (Web access from inside DIKUs LAN only)
