On Wed, 20 Nov 2019, Ondřej Surý wrote: > Hi, > > this is the error we started getting with upgrade to 1.0.7 (from 1.0.6). > > EXN: Failure("rule starting on line 1: already tagged token:\nC code context\nFile \"./lib/dns/client.c\", line 1342, column 1, charpos = 33224\n around = 'if',\n whole content = \tif (rctx == NULL)“) > > EXN: Failure("rule starting on line 1: already tagged token:\nC code context\nFile \"./lib/ns/tests/nstest.c\", line 704, column 1, charpos = 15998\n around = 'if',\n whole content = \tif (qctx != NULL) {") > > The minimal reproducer is: > > @@ > statement S1, S2; > expression V; > @@ > > V = isc_mem_get(...); > - if (V == NULL) S1 else { S2 } > + S2 I would need the C code as well. Maybe it would help to write: - if (V == NULL) S1 else { S2 - } > > -- > > On related note, what would be the correct way to write a rule for: > > foo = isc_mem_get(…); > bar = isc_mem_get(…); > > if (foo == NULL || bar == NULL) { … }; > > my naive approach: > > @@ > statement S; > expression V, E; > @@ > > V = isc_mem_get(...); > ... > - if (V == NULL || E) S > + if (E) S > > doesn’t really work (it matches only a simple case, but not when there’s more than two memory allocations). Try replacing E by ... Then reorganize the pattern so that there is only - code, not + code. I'm not sure this will actually work for transformation though. You may have to be resigned to just searching for the problem, ie V = isc_mem_get(...); ... * if (V == NULL || E) S and not actually doing the update. > I thought something like this might work: > > @@ > statement S; > expression V, E; > @@ > > V = isc_mem_get(...); > ... > if (... > -|| V == NULL > ...) S The ... right after NULL doesn't work. It could be || ... > @@ > statement S; > expression V, E; > @@ > > V = isc_mem_get(...); > ... > if (... > - V == NULL || > ...) S > > would work, but it says: > > minus: parse error: > File "x", line 10, column 0, charpos = 86 > around = '...', > whole content = ...) S Likewise, you would need ... || > > -- > > And one last question: > > Is there a simple way how to merge these these rules together? It seems > like it should be possible, but I wasn’t able to decipher the syntax for > making parts of the match to be remove to be optional (but if you point > me to an example in the base files or coccinellery, I would try harder). > > @@ > statement S1, S2; > expression V; > @@ > > V = isc_mem_get(...); > - if (V == NULL) S1 else { S2 } > + S2 > > @@ > statement S; > expression V; > @@ > > V = isc_mem_get(...); > - if (V == NULL) S > > @@ > type T; > statement S; > expression V; > @@ > > V = (T *)isc_mem_get(...); > - if (V == NULL) S If you had just (T) rather than (T*), then this rule would also cover everything covered by the previous rule. But if you want to specify that it has to be a pointer type then a specific rule is needed. > > @@ > statement S; > expression V; > @@ > > if (V == NULL) V = isc_mem_get(...); > - if (V == NULL) S > > @@ > type T; > expression V, E1, E2; > @@ > > - V = (T)isc_mem_get(E1, E2); > + V = isc_mem_get(E1, E2); If you put this rule first, then the other rules would not have to consider the type case. julia > > Thank you, > -- > Ondřej Surý > ondrej@sury.org > > > > _______________________________________________ > Cocci mailing list > Cocci@systeme.lip6.fr > https://systeme.lip6.fr/mailman/listinfo/cocci >