1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s 2*f4a2713aSLionel Sambuc 3*f4a2713aSLionel Sambuc void clang_analyzer_eval(int); 4*f4a2713aSLionel Sambuc 5*f4a2713aSLionel Sambuc // There should be no warnings unless otherwise indicated. 6*f4a2713aSLionel Sambuc testComparisons(int a)7*f4a2713aSLionel Sambucvoid testComparisons (int a) { 8*f4a2713aSLionel Sambuc // Sema can already catch the simple comparison a==a, 9*f4a2713aSLionel Sambuc // since that's usually a logic error (and not path-dependent). 10*f4a2713aSLionel Sambuc int b = a; 11*f4a2713aSLionel Sambuc clang_analyzer_eval(b == a); // expected-warning{{TRUE}} 12*f4a2713aSLionel Sambuc clang_analyzer_eval(b >= a); // expected-warning{{TRUE}} 13*f4a2713aSLionel Sambuc clang_analyzer_eval(b <= a); // expected-warning{{TRUE}} 14*f4a2713aSLionel Sambuc clang_analyzer_eval(b != a); // expected-warning{{FALSE}} 15*f4a2713aSLionel Sambuc clang_analyzer_eval(b > a); // expected-warning{{FALSE}} 16*f4a2713aSLionel Sambuc clang_analyzer_eval(b < a); // expected-warning{{FALSE}} 17*f4a2713aSLionel Sambuc } 18*f4a2713aSLionel Sambuc testSelfOperations(int a)19*f4a2713aSLionel Sambucvoid testSelfOperations (int a) { 20*f4a2713aSLionel Sambuc clang_analyzer_eval((a|a) == a); // expected-warning{{TRUE}} 21*f4a2713aSLionel Sambuc clang_analyzer_eval((a&a) == a); // expected-warning{{TRUE}} 22*f4a2713aSLionel Sambuc clang_analyzer_eval((a^a) == 0); // expected-warning{{TRUE}} 23*f4a2713aSLionel Sambuc clang_analyzer_eval((a-a) == 0); // expected-warning{{TRUE}} 24*f4a2713aSLionel Sambuc } 25*f4a2713aSLionel Sambuc testIdempotent(int a)26*f4a2713aSLionel Sambucvoid testIdempotent (int a) { 27*f4a2713aSLionel Sambuc clang_analyzer_eval((a*1) == a); // expected-warning{{TRUE}} 28*f4a2713aSLionel Sambuc clang_analyzer_eval((a/1) == a); // expected-warning{{TRUE}} 29*f4a2713aSLionel Sambuc clang_analyzer_eval((a+0) == a); // expected-warning{{TRUE}} 30*f4a2713aSLionel Sambuc clang_analyzer_eval((a-0) == a); // expected-warning{{TRUE}} 31*f4a2713aSLionel Sambuc clang_analyzer_eval((a<<0) == a); // expected-warning{{TRUE}} 32*f4a2713aSLionel Sambuc clang_analyzer_eval((a>>0) == a); // expected-warning{{TRUE}} 33*f4a2713aSLionel Sambuc clang_analyzer_eval((a^0) == a); // expected-warning{{TRUE}} 34*f4a2713aSLionel Sambuc clang_analyzer_eval((a&(~0)) == a); // expected-warning{{TRUE}} 35*f4a2713aSLionel Sambuc clang_analyzer_eval((a|0) == a); // expected-warning{{TRUE}} 36*f4a2713aSLionel Sambuc } 37*f4a2713aSLionel Sambuc testReductionToConstant(int a)38*f4a2713aSLionel Sambucvoid testReductionToConstant (int a) { 39*f4a2713aSLionel Sambuc clang_analyzer_eval((a*0) == 0); // expected-warning{{TRUE}} 40*f4a2713aSLionel Sambuc clang_analyzer_eval((a&0) == 0); // expected-warning{{TRUE}} 41*f4a2713aSLionel Sambuc clang_analyzer_eval((a|(~0)) == (~0)); // expected-warning{{TRUE}} 42*f4a2713aSLionel Sambuc } 43*f4a2713aSLionel Sambuc testSymmetricIntSymOperations(int a)44*f4a2713aSLionel Sambucvoid testSymmetricIntSymOperations (int a) { 45*f4a2713aSLionel Sambuc clang_analyzer_eval((2+a) == (a+2)); // expected-warning{{TRUE}} 46*f4a2713aSLionel Sambuc clang_analyzer_eval((2*a) == (a*2)); // expected-warning{{TRUE}} 47*f4a2713aSLionel Sambuc clang_analyzer_eval((2&a) == (a&2)); // expected-warning{{TRUE}} 48*f4a2713aSLionel Sambuc clang_analyzer_eval((2^a) == (a^2)); // expected-warning{{TRUE}} 49*f4a2713aSLionel Sambuc clang_analyzer_eval((2|a) == (a|2)); // expected-warning{{TRUE}} 50*f4a2713aSLionel Sambuc } 51*f4a2713aSLionel Sambuc testAsymmetricIntSymOperations(int a)52*f4a2713aSLionel Sambucvoid testAsymmetricIntSymOperations (int a) { 53*f4a2713aSLionel Sambuc clang_analyzer_eval(((~0) >> a) == (~0)); // expected-warning{{TRUE}} 54*f4a2713aSLionel Sambuc clang_analyzer_eval((0 >> a) == 0); // expected-warning{{TRUE}} 55*f4a2713aSLionel Sambuc clang_analyzer_eval((0 << a) == 0); // expected-warning{{TRUE}} 56*f4a2713aSLionel Sambuc 57*f4a2713aSLionel Sambuc // Unsigned right shift shifts in zeroes. 58*f4a2713aSLionel Sambuc clang_analyzer_eval(((~0U) >> a) != (~0U)); // expected-warning{{UNKNOWN}} 59*f4a2713aSLionel Sambuc } 60*f4a2713aSLionel Sambuc testLocations(char * a)61*f4a2713aSLionel Sambucvoid testLocations (char *a) { 62*f4a2713aSLionel Sambuc char *b = a; 63*f4a2713aSLionel Sambuc clang_analyzer_eval(b == a); // expected-warning{{TRUE}} 64*f4a2713aSLionel Sambuc clang_analyzer_eval(b >= a); // expected-warning{{TRUE}} 65*f4a2713aSLionel Sambuc clang_analyzer_eval(b <= a); // expected-warning{{TRUE}} 66*f4a2713aSLionel Sambuc clang_analyzer_eval(b != a); // expected-warning{{FALSE}} 67*f4a2713aSLionel Sambuc clang_analyzer_eval(b > a); // expected-warning{{FALSE}} 68*f4a2713aSLionel Sambuc clang_analyzer_eval(b < a); // expected-warning{{FALSE}} 69*f4a2713aSLionel Sambuc } 70*f4a2713aSLionel Sambuc testMixedTypeComparisons(char a,unsigned long b)71*f4a2713aSLionel Sambucvoid testMixedTypeComparisons (char a, unsigned long b) { 72*f4a2713aSLionel Sambuc if (a != 0) return; 73*f4a2713aSLionel Sambuc if (b != 0x100) return; 74*f4a2713aSLionel Sambuc 75*f4a2713aSLionel Sambuc clang_analyzer_eval(a <= b); // expected-warning{{TRUE}} 76*f4a2713aSLionel Sambuc clang_analyzer_eval(b >= a); // expected-warning{{TRUE}} 77*f4a2713aSLionel Sambuc clang_analyzer_eval(a != b); // expected-warning{{TRUE}} 78*f4a2713aSLionel Sambuc } 79