238 lines
		
	
	
	
		
			3.1 KiB
			
		
	
	
	
		
			Text
		
	
	
	
	
	
		
		
			
		
	
	
			238 lines
		
	
	
	
		
			3.1 KiB
			
		
	
	
	
		
			Text
		
	
	
	
	
	
|   | /// 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/ | ||
|  | // Comments: | ||
|  | // Options: | ||
|  | 
 | ||
|  | virtual patch | ||
|  | virtual context | ||
|  | virtual org | ||
|  | virtual report | ||
|  | 
 | ||
|  | @initialize:ocaml@ | ||
|  | 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") |