| 
									
										
										
										
											2012-01-27 21:41:28 +01:00
										 |  |  | /// Compare pointer-typed values to NULL rather than 0 | 
					
						
							|  |  |  | /// | 
					
						
							|  |  |  | //# This makes an effort to choose between !x and x == NULL.  !x is used | 
					
						
							|  |  |  | //# if it has previously been used with the function used to initialize x. | 
					
						
							|  |  |  | //# This relies on type information.  More type information can be obtained | 
					
						
							|  |  |  | //# using the option -all_includes and the option -I to specify an | 
					
						
							|  |  |  | //# include path. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Confidence: High | 
					
						
							|  |  |  | // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2. | 
					
						
							|  |  |  | // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2. | 
					
						
							|  |  |  | // URL: http://coccinelle.lip6.fr/ | 
					
						
							| 
									
										
										
										
											2014-05-28 19:40:47 +05:30
										 |  |  | // Comments: Requires Coccinelle version 1.0.0-rc20 or later | 
					
						
							| 
									
										
										
										
											2012-01-27 21:41:28 +01:00
										 |  |  | // Options: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | virtual patch | 
					
						
							|  |  |  | virtual context | 
					
						
							|  |  |  | virtual org | 
					
						
							|  |  |  | virtual report | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @initialize:ocaml@ | 
					
						
							| 
									
										
										
										
											2014-05-28 19:40:47 +05:30
										 |  |  | @@ | 
					
						
							| 
									
										
										
										
											2012-01-27 21:41:28 +01:00
										 |  |  | let negtable = Hashtbl.create 101 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @depends on patch@ | 
					
						
							|  |  |  | expression *E; | 
					
						
							|  |  |  | identifier f; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ( | 
					
						
							|  |  |  |   (E = f(...)) == | 
					
						
							|  |  |  | - 0 | 
					
						
							|  |  |  | + NULL | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  |   (E = f(...)) != | 
					
						
							|  |  |  | - 0 | 
					
						
							|  |  |  | + NULL | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | - 0 | 
					
						
							|  |  |  | + NULL | 
					
						
							|  |  |  |   == (E = f(...)) | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | - 0 | 
					
						
							|  |  |  | + NULL | 
					
						
							|  |  |  |   != (E = f(...)) | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @t1 depends on !patch@ | 
					
						
							|  |  |  | expression *E; | 
					
						
							|  |  |  | identifier f; | 
					
						
							|  |  |  | position p; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ( | 
					
						
							|  |  |  |   (E = f(...)) == | 
					
						
							|  |  |  | * 0@p | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  |   (E = f(...)) != | 
					
						
							|  |  |  | * 0@p | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | * 0@p | 
					
						
							|  |  |  |   == (E = f(...)) | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | * 0@p | 
					
						
							|  |  |  |   != (E = f(...)) | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @script:python depends on org@ | 
					
						
							|  |  |  | p << t1.p; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @script:python depends on report@ | 
					
						
							|  |  |  | p << t1.p; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Tests of returned values | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @s@ | 
					
						
							|  |  |  | identifier f; | 
					
						
							|  |  |  | expression E,E1; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  E = f(...) | 
					
						
							|  |  |  |  ... when != E = E1 | 
					
						
							|  |  |  |  !E | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @script:ocaml depends on s@ | 
					
						
							|  |  |  | f << s.f; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | try let _ = Hashtbl.find negtable f in () | 
					
						
							|  |  |  | with Not_found -> Hashtbl.add negtable f () | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @ r disable is_zero,isnt_zero exists @ | 
					
						
							|  |  |  | expression *E; | 
					
						
							|  |  |  | identifier f; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | E = f(...) | 
					
						
							|  |  |  | ... | 
					
						
							|  |  |  | (E == 0 | 
					
						
							|  |  |  | |E != 0 | 
					
						
							|  |  |  | |0 == E | 
					
						
							|  |  |  | |0 != E | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @script:ocaml@ | 
					
						
							|  |  |  | f << r.f; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | try let _ = Hashtbl.find negtable f in () | 
					
						
							|  |  |  | with Not_found -> include_match false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This rule may lead to inconsistent path problems, if E is defined in two | 
					
						
							|  |  |  | // places | 
					
						
							|  |  |  | @ depends on patch disable is_zero,isnt_zero @ | 
					
						
							|  |  |  | expression *E; | 
					
						
							|  |  |  | expression E1; | 
					
						
							|  |  |  | identifier r.f; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | E = f(...) | 
					
						
							|  |  |  | <... | 
					
						
							|  |  |  | ( | 
					
						
							|  |  |  | - E == 0 | 
					
						
							|  |  |  | + !E | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | - E != 0 | 
					
						
							|  |  |  | + E | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | - 0 == E | 
					
						
							|  |  |  | + !E | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | - 0 != E | 
					
						
							|  |  |  | + E | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | ...> | 
					
						
							|  |  |  | ?E = E1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @t2 depends on !patch disable is_zero,isnt_zero @ | 
					
						
							|  |  |  | expression *E; | 
					
						
							|  |  |  | expression E1; | 
					
						
							|  |  |  | identifier r.f; | 
					
						
							|  |  |  | position p1; | 
					
						
							|  |  |  | position p2; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | E = f(...) | 
					
						
							|  |  |  | <... | 
					
						
							|  |  |  | ( | 
					
						
							|  |  |  | * E == 0@p1 | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | * E != 0@p2 | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | * 0@p1 == E | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | * 0@p1 != E | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | ...> | 
					
						
							|  |  |  | ?E = E1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @script:python depends on org@ | 
					
						
							|  |  |  | p << t2.p1; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @script:python depends on org@ | 
					
						
							|  |  |  | p << t2.p2; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @script:python depends on report@ | 
					
						
							|  |  |  | p << t2.p1; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @script:python depends on report@ | 
					
						
							|  |  |  | p << t2.p2; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @ depends on patch disable is_zero,isnt_zero @ | 
					
						
							|  |  |  | expression *E; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ( | 
					
						
							|  |  |  |   E == | 
					
						
							|  |  |  | - 0 | 
					
						
							|  |  |  | + NULL | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  |   E != | 
					
						
							|  |  |  | - 0 | 
					
						
							|  |  |  | + NULL | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | - 0 | 
					
						
							|  |  |  | + NULL | 
					
						
							|  |  |  |   == E | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | - 0 | 
					
						
							|  |  |  | + NULL | 
					
						
							|  |  |  |   != E | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @ t3 depends on !patch disable is_zero,isnt_zero @ | 
					
						
							|  |  |  | expression *E; | 
					
						
							|  |  |  | position p; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ( | 
					
						
							|  |  |  | * E == 0@p | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | * E != 0@p | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | * 0@p == E | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | * 0@p != E | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @script:python depends on org@ | 
					
						
							|  |  |  | p << t3.p; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @script:python depends on report@ | 
					
						
							|  |  |  | p << t3.p; | 
					
						
							|  |  |  | @@ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") |