[analyzer] Convert many existing tests to use clang_analyzer_eval.
authorJordy Rose <jediknil@belkadan.com>
Wed, 16 May 2012 16:01:10 +0000 (16:01 +0000)
committerJordy Rose <jediknil@belkadan.com>
Wed, 16 May 2012 16:01:10 +0000 (16:01 +0000)
llvm-svn: 156920

clang/test/Analysis/additive-folding-range-constraints.c
clang/test/Analysis/additive-folding.cpp
clang/test/Analysis/array-struct-region.c
clang/test/Analysis/base-init.cpp
clang/test/Analysis/bstring.c
clang/test/Analysis/constant-folding.c
clang/test/Analysis/initializer.cpp
clang/test/Analysis/method-call.cpp
clang/test/Analysis/ptr-arith.c
clang/test/Analysis/string-fail.c
clang/test/Analysis/string.c

index a64c910..7eb55ab 100644 (file)
@@ -1,10 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,unix.Malloc -verify -analyzer-constraints=range %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=range %s
+
+void clang_analyzer_eval(int);
 
-// These are used to trigger warnings.
-typedef typeof(sizeof(int)) size_t;
-void *malloc(size_t);
-void free(void *);
-#define NULL ((void*)0)
 #define UINT_MAX (~0U)
 #define INT_MAX (UINT_MAX & (UINT_MAX >> 1))
 #define INT_MIN (-INT_MAX - 1)
@@ -14,43 +11,27 @@ void free(void *);
 // solution range across an overflow boundary (Min for <, Max for >).
 // This corresponds to one set of branches in RangeConstraintManager.
 void smallAdjustmentGT (unsigned a) {
-  void *b = NULL;
   if (a+2 > 1)
-    b = malloc(1);
-  if (a == UINT_MAX-1 || a == UINT_MAX)
-    return; // no-warning
-  else if (a < UINT_MAX-1)
-    free(b);
-  return; // no-warning
+    clang_analyzer_eval(a < UINT_MAX-1); // expected-warning{{TRUE}}
+  else
+    clang_analyzer_eval(a == UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
 }
 
 void smallAdjustmentGE (unsigned a) {
-  void *b = NULL;
   if (a+2 >= 1)
-    b = malloc(1);
-  if (a == UINT_MAX-1)
-    return; // no-warning
-  else if (a < UINT_MAX-1 || a == UINT_MAX)
-    free(b);
-  return; // no-warning
+    clang_analyzer_eval(a < UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
+  else
+    clang_analyzer_eval(a == UINT_MAX-1); // expected-warning{{TRUE}}
 }
 
 void smallAdjustmentLT (unsigned a) {
-  void *b = NULL;
   if (a+1 < 2)
-    b = malloc(1);
-  if (a == 0 || a == UINT_MAX)
-    free(b);
-  return; // no-warning
+    clang_analyzer_eval(a == 0 || a == UINT_MAX); // expected-warning{{TRUE}}
 }
 
 void smallAdjustmentLE (unsigned a) {
-  void *b = NULL;
   if (a+1 <= 2)
-    b = malloc(1);
-  if (a == 0 || a == 1 || a == UINT_MAX)
-    free(b);
-  return; // no-warning
+    clang_analyzer_eval(a == 0 || a == 1 || a == UINT_MAX); // expected-warning{{TRUE}}
 }
 
 
@@ -58,154 +39,102 @@ void smallAdjustmentLE (unsigned a) {
 // comparison value over an overflow boundary (Min for <, Max for >).
 // This corresponds to one set of branches in RangeConstraintManager.
 void largeAdjustmentGT (unsigned a) {
-  void *b = NULL;
   if (a-2 > UINT_MAX-1)
-    b = malloc(1);
-  if (a == 1 || a == 0)
-    free(b);
-  else if (a > 1)
-    free(b);
-  return; // no-warning
+    clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
+  else
+    clang_analyzer_eval(a != 1); // expected-warning{{TRUE}}
 }
 
 void largeAdjustmentGE (unsigned a) {
-  void *b = NULL;
   if (a-2 >= UINT_MAX-1)
-    b = malloc(1);
-  if (a > 1)
-    return; // no-warning
-  else if (a == 1 || a == 0)
-    free(b);
-  return; // no-warning
+    clang_analyzer_eval(a == 1 || a == 0); // expected-warning{{TRUE}}
+  else
+    clang_analyzer_eval(a > 1); // expected-warning{{TRUE}}
 }
 
 void largeAdjustmentLT (unsigned a) {
-  void *b = NULL;
   if (a+2 < 1)
-    b = malloc(1);
-  if (a == UINT_MAX-1 || a == UINT_MAX)
-    free(b);
-  else if (a < UINT_MAX-1)
-    return; // no-warning
-  return; // no-warning
+    clang_analyzer_eval(a == UINT_MAX-1); // expected-warning{{TRUE}}
+  else
+    clang_analyzer_eval(a != UINT_MAX-1); // expected-warning{{TRUE}}
 }
 
 void largeAdjustmentLE (unsigned a) {
-  void *b = NULL;
   if (a+2 <= 1)
-    b = malloc(1);
-  if (a < UINT_MAX-1)
-    return; // no-warning
-  else if (a == UINT_MAX-1 || a == UINT_MAX)
-    free(b);
-  return; // no-warning
+    clang_analyzer_eval(a == UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
+  else
+    clang_analyzer_eval(a < UINT_MAX-1); // expected-warning{{TRUE}}
 }
 
 
 // Test the nine cases in RangeConstraintManager's pinning logic.
+// For out-of-range tautologies, it may be the negation that actually
+// triggers the case in question.
 void mixedComparisons1(signed char a) {
   // Case 1: The range is entirely below the symbol's range.
   int min = INT_MIN;
 
-  if ((a - 2) < (min + 5LL))
-    return; // expected-warning{{never executed}}
+  clang_analyzer_eval((a - 2) >= (min + 5LL)); // expected-warning{{TRUE}}
 
-  if (a == 0)
-    return; // no-warning
-  if (a == 0x7F)
-    return; // no-warning
-  if (a == -0x80)
-    return; // no-warning
-  return; // no-warning
+  clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
 }
 
 void mixedComparisons2(signed char a) {
   // Case 2: Only the lower end of the range is outside.
+  clang_analyzer_eval((a - 5) < (-0x81LL)); // expected-warning{{UNKNOWN}}
+
   if ((a - 5) < (-0x81LL)) {
-    if (a == 0)
-      return; // expected-warning{{never executed}}
-    if (a == 0x7F)
-      return; // expected-warning{{never executed}}
-    if (a == -0x80)
-      return; // no-warning    
-    return; // no-warning
-  } else {
-    return; // no-warning
+    clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
+    clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
+    clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
   }
 }
 
 void mixedComparisons3(signed char a) {
   // Case 3: The entire symbol range is covered.
-  if ((a - 0x200) < -0x100LL) {
-    if (a == 0)
-      return; // no-warning
-    if (a == 0x7F)
-      return; // no-warning
-    if (a == -0x80)
-      return; // no-warning    
-    return; // no-warning
-  } else {
-    return; // expected-warning{{never executed}}
-  }
+  clang_analyzer_eval((a - 0x200) < -0x100LL); // expected-warning{{TRUE}}
+
+  clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
 }
 
 void mixedComparisons4(signed char a) {
   // Case 4: The range wraps around, but the lower wrap is out-of-range.
+  clang_analyzer_eval((a - 5) > 0LL); // expected-warning{{UNKNOWN}}
+
   if ((a - 5) > 0LL) {
-    if (a == 0)
-      return; // expected-warning{{never executed}}
-    if (a == 0x7F)
-      return; // no-warning
-    if (a == -0x80)
-      return; // expected-warning{{never executed}}
-    return; // no-warning
-  } else {
-    return; // no-warning
+    clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
+    clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+    clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
   }
 }
 
 void mixedComparisons5(signed char a) {
-  // Case 5a: The range is inside and does not wrap.
-  if ((a + 5) == 0LL) {
-    if (a == 0)
-      return; // expected-warning{{never executed}}
-    if (a == 0x7F)
-      return; // expected-warning{{never executed}}
-    if (a == -0x80)
-      return; // expected-warning{{never executed}}
-    return; // no-warning
-  } else {
-    return; // no-warning
-  }
-}
+  // Case 5: The range is inside and may or may not wrap.
+  clang_analyzer_eval((a + 5) == 0LL); // expected-warning{{UNKNOWN}}
 
-void mixedComparisons5Wrap(signed char a) {
-  // Case 5b: The range is inside and does wrap.
-  if ((a + 5) != 0LL) {
-    if (a == 0)
-      return; // no-warning
-    if (a == 0x7F)
-      return; // no-warning
-    if (a == -0x80)
-      return; // no-warning
-    return; // no-warning
+  if ((a + 5) == 0LL) {
+    clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
+    clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
+    clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
   } else {
-    return; // no-warning
+    clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
+    clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+    clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
   }
 }
 
 void mixedComparisons6(signed char a) {
   // Case 6: Only the upper end of the range is outside.
+  clang_analyzer_eval((a + 5) > 0x81LL); // expected-warning{{UNKNOWN}}
+
   if ((a + 5) > 0x81LL) {
-    if (a == 0)
-      return; // expected-warning{{never executed}}
-    if (a == 0x7F)
-      return; // no-warning
-    if (a == -0x80)
-      return; // expected-warning{{never executed}}
-    return; // no-warning
-  } else {
-    return; // no-warning
+    clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
+    clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+    clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
   }
 }
 
@@ -213,30 +142,21 @@ void mixedComparisons7(signed char a) {
   // Case 7: The range wraps around but is entirely outside the symbol's range.
   int min = INT_MIN;
 
-  if ((a + 2) < (min + 5LL))
-    return; // expected-warning{{never executed}}
+  clang_analyzer_eval((a + 2) >= (min + 5LL)); // expected-warning{{TRUE}}
 
-  if (a == 0)
-    return; // no-warning
-  if (a == 0x7F)
-    return; // no-warning
-  if (a == -0x80)
-    return; // no-warning
-  return; // no-warning
+  clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
 }
 
 void mixedComparisons8(signed char a) {
   // Case 8: The range wraps, but the upper wrap is out of range.
+  clang_analyzer_eval((a + 5) < 0LL); // expected-warning{{UNKNOWN}}
+
   if ((a + 5) < 0LL) {
-    if (a == 0)
-      return; // expected-warning{{never executed}}
-    if (a == 0x7F)
-      return; // expected-warning{{never executed}}
-    if (a == -0x80)
-      return; // no-warning
-    return; // no-warning
-  } else {
-    return; // no-warning
+    clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
+    clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
+    clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
   }
 }
 
@@ -244,14 +164,9 @@ void mixedComparisons9(signed char a) {
   // Case 9: The range is entirely above the symbol's range.
   int max = INT_MAX;
 
-  if ((a + 2) > (max - 5LL))
-    return; // expected-warning{{never executed}}
+  clang_analyzer_eval((a + 2) <= (max - 5LL)); // expected-warning{{TRUE}}
 
-  if (a == 0)
-    return; // no-warning
-  if (a == 0x7F)
-    return; // no-warning
-  if (a == -0x80)
-    return; // no-warning
-  return; // no-warning
+  clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
 }
index 136dc08..8c132fb 100644 (file)
@@ -1,11 +1,8 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,unix.Malloc -verify -analyzer-constraints=basic %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,unix.Malloc -verify -analyzer-constraints=range %s
-
-// These are used to trigger warnings.
-typedef typeof(sizeof(int)) size_t;
-void *malloc(size_t);
-void free(void *);
-#define NULL ((void*)0)
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=basic -Wno-tautological-compare %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=range -Wno-tautological-compare %s
+
+void clang_analyzer_eval(bool);
+
 #define UINT_MAX (~0U)
 #define INT_MAX (UINT_MAX & (UINT_MAX >> 1))
 #define INT_MIN (-INT_MAX - 1)
@@ -18,10 +15,7 @@ void separateExpressions (int a) {
   int b = a + 1;
   --b;
 
-  void *buf = malloc(1);
-  if (a != 0 && b == 0)
-    return; // expected-warning{{never executed}}
-  free(buf);
+  clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}}
 }
 
 void oneLongExpression (int a) {
@@ -29,26 +23,17 @@ void oneLongExpression (int a) {
   // the first term is on the left.
   int b = 15 + a + 15 - 10 - 20;
 
-  void *buf = malloc(1);
-  if (a != 0 && b == 0)
-    return; // expected-warning{{never executed}}
-  free(buf);
+  clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}}
 }
 
 void mixedTypes (int a) {
-  void *buf = malloc(1);
-
   // Different additive types should not cause crashes when constant-folding.
   // This is part of PR7406.
   int b = a + 1LL;
-  if (a != 0 && (b-1) == 0) // not crash
-    return; // expected-warning{{never executed}}
+  clang_analyzer_eval(a != 0 && (b-1) == 0); // not crash, expected-warning{{FALSE}}
 
   int c = a + 1U;
-  if (a != 0 && (c-1) == 0) // not crash
-    return; // expected-warning{{never executed}}
-
-  free(buf);
+  clang_analyzer_eval(a != 0 && (c-1) == 0); // not crash, expected-warning{{FALSE}}
 }
 
 //---------------
@@ -57,206 +42,101 @@ void mixedTypes (int a) {
 
 // Equality and inequality only
 void eq_ne (unsigned a) {
-  void *b = NULL;
-  if (a == UINT_MAX)
-    b = malloc(1);
-  if (a+1 != 0)
-    return; // no-warning
-  if (a-1 != UINT_MAX-1)
-    return; // no-warning
-  free(b);
-}
-
-void ne_eq (unsigned a) {
-  void *b = NULL;
-  if (a != UINT_MAX)
-    b = malloc(1);
-  if (a+1 == 0)
-    return; // no-warning
-  if (a-1 == UINT_MAX-1)
-    return; // no-warning
-  free(b);
+  if (a == UINT_MAX) {
+    clang_analyzer_eval(a+1 == 0); // expected-warning{{TRUE}}
+    clang_analyzer_eval(a-1 == UINT_MAX-1); // expected-warning{{TRUE}}
+  } else {
+    clang_analyzer_eval(a+1 != 0); // expected-warning{{TRUE}}
+    clang_analyzer_eval(a-1 != UINT_MAX-1); // expected-warning{{TRUE}}
+  }
 }
 
 // Mixed typed inequalities (part of PR7406)
 // These should not crash.
 void mixed_eq_ne (int a) {
-  void *b = NULL;
-  if (a == 1)
-    b = malloc(1);
-  if (a+1U != 2)
-    return; // no-warning
-  if (a-1U != 0)
-    return; // expected-warning{{never executed}}
-  free(b);
-}
-
-void mixed_ne_eq (int a) {
-  void *b = NULL;
-  if (a != 1)
-    b = malloc(1);
-  if (a+1U == 2)
-    return; // no-warning
-  if (a-1U == 0)
-    return; // expected-warning{{never executed}}
-  free(b);
+  if (a == 1) {
+    clang_analyzer_eval(a+1U == 2); // expected-warning{{TRUE}}
+    clang_analyzer_eval(a-1U == 0); // expected-warning{{TRUE}}
+  } else {
+    clang_analyzer_eval(a+1U != 2); // expected-warning{{TRUE}}
+    clang_analyzer_eval(a-1U != 0); // expected-warning{{TRUE}}
+  }
 }
 
 
 // Simple order comparisons with no adjustment
 void baselineGT (unsigned a) {
-  void *b = NULL;
   if (a > 0)
-    b = malloc(1);
-  if (a == 0)
-    return; // no-warning
-  free(b);
+    clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}
+  else
+    clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}
 }
 
 void baselineGE (unsigned a) {
-  void *b = NULL;
   if (a >= UINT_MAX)
-    b = malloc(1);
-  if (a == UINT_MAX)
-    free(b);
-  return; // no-warning
+    clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
+  else
+    clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}
 }
 
 void baselineLT (unsigned a) {
-  void *b = NULL;
   if (a < UINT_MAX)
-    b = malloc(1);
-  if (a == UINT_MAX)
-    return; // no-warning
-  free(b);
+    clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}
+  else
+    clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
 }
 
 void baselineLE (unsigned a) {
-  void *b = NULL;
   if (a <= 0)
-    b = malloc(1);
-  if (a == 0)
-    free(b);
-  return; // no-warning
+    clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}
+  else
+    clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}
 }
 
 
 // Adjustment gives each of these an extra solution!
 void adjustedGT (unsigned a) {
-  void *b = NULL;
-  if (a-1 > UINT_MAX-1)
-    b = malloc(1);
-  return; // expected-warning{{leak}}
+  clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}}
 }
 
 void adjustedGE (unsigned a) {
-  void *b = NULL;
+  clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}}
+
   if (a-1 >= UINT_MAX-1)
-    b = malloc(1);
-  if (a == UINT_MAX)
-    free(b);
-  return; // expected-warning{{leak}}
+    clang_analyzer_eval(a == UINT_MAX); // expected-warning{{UNKNOWN}}
 }
 
 void adjustedLT (unsigned a) {
-  void *b = NULL;
-  if (a+1 < 1)
-    b = malloc(1);
-  return; // expected-warning{{leak}}
+  clang_analyzer_eval(a+1 < 1); // expected-warning{{UNKNOWN}}
 }
 
 void adjustedLE (unsigned a) {
-  void *b = NULL;
+  clang_analyzer_eval(a+1 <= 1); // expected-warning{{UNKNOWN}}
+
   if (a+1 <= 1)
-    b = malloc(1);
-  if (a == 0)
-    free(b);
-  return; // expected-warning{{leak}}
+    clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
 }
 
 
 // Tautologies
-void tautologyGT (unsigned a) {
-  void *b = malloc(1);
-  if (a > UINT_MAX)
-    return; // no-warning
-  free(b);
-}
-
-void tautologyGE (unsigned a) {
-  void *b = malloc(1);
-  if (a >= 0) // expected-warning{{always true}}
-    free(b);
-  return; // no-warning
-}
-
-void tautologyLT (unsigned a) {
-  void *b = malloc(1);
-  if (a < 0) // expected-warning{{always false}}
-    return; // expected-warning{{never executed}}
-  free(b);
-}
-
-void tautologyLE (unsigned a) {
-  void *b = malloc(1);
-  if (a <= UINT_MAX)
-    free(b);
-  return; // no-warning
+// The negative forms are exercised as well
+// because clang_analyzer_eval tests both possibilities.
+void tautologies(unsigned a) {
+  clang_analyzer_eval(a <= UINT_MAX); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a >= 0); // expected-warning{{TRUE}}
 }
 
 
 // Tautologies from outside the range of the symbol
-void tautologyOutsideGT(unsigned char a) {
-  void *b = malloc(1);
-  if (a > 0x100)
-    return; // expected-warning{{never executed}}
-  if (a > -1)
-    free(b);
-  return; // no-warning
-}
+void tautologiesOutside(unsigned char a) {
+  clang_analyzer_eval(a <= 0x100); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a < 0x100); // expected-warning{{TRUE}}
 
-void tautologyOutsideGE(unsigned char a) {
-  void *b = malloc(1);
-  if (a >= 0x100)
-    return; // expected-warning{{never executed}}
-  if (a >= -1)
-    free(b);
-  return; // no-warning
-}
+  clang_analyzer_eval(a != 0x100); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a != -1); // expected-warning{{TRUE}}
 
-void tautologyOutsideLT(unsigned char a) {
-  void *b = malloc(1);
-  if (a < -1)
-    return; // expected-warning{{never executed}}
-  if (a < 0x100)
-    free(b);
-  return; // no-warning
-}
-
-void tautologyOutsideLE (unsigned char a) {
-  void *b = malloc(1);
-  if (a <= -1)
-    return; // expected-warning{{never executed}}
-  if (a <= 0x100)
-    free(b);
-  return; // no-warning
-}
-
-void tautologyOutsideEQ(unsigned char a) {
-  if (a == 0x100)
-    malloc(1); // expected-warning{{never executed}}
-  if (a == -1)
-    malloc(1); // expected-warning{{never executed}}
-}
-
-void tautologyOutsideNE(unsigned char a) {
-  void *sentinel = malloc(1);
-  if (a != 0x100)
-    free(sentinel);
-
-  sentinel = malloc(1);
-  if (a != -1)
-    free(sentinel);
+  clang_analyzer_eval(a > -1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a >= -1); // expected-warning{{TRUE}}
 }
 
 
@@ -267,64 +147,32 @@ void mixedWraparoundSanityCheck(int a) {
   int min = INT_MIN;
 
   int b = a + 1;
-  if (a == max && b != min)
-    return; // expected-warning{{never executed}}
-}
-
-void mixedWraparoundGT(int a) {
-  int max = INT_MAX;
-
-  if ((a + 2) > (max + 1LL))
-    return; // expected-warning{{never executed}}
+  clang_analyzer_eval(a == max && b != min); // expected-warning{{FALSE}}
 }
 
-void mixedWraparoundGE(int a) {
+void mixedWraparoundLE_GT(int a) {
   int max = INT_MAX;
   int min = INT_MIN;
 
-  if ((a + 2) >= (max + 1LL))
-    return; // expected-warning{{never executed}}
-
-  void *sentinel = malloc(1);
-  if ((a - 2LL) >= min)
-    free(sentinel);
-  return; // expected-warning{{leak}}
-}
-
-void mixedWraparoundLT(int a) {
-  int min = INT_MIN;
-
-  if ((a - 2) < (min - 1LL))
-    return; // expected-warning{{never executed}}
+  clang_analyzer_eval((a + 2) <= (max + 1LL)); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a - 2) > (min - 1LL)); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a + 2LL) <= max); // expected-warning{{UNKNOWN}}
 }
 
-void mixedWraparoundLE(int a) {
+void mixedWraparoundGE_LT(int a) {
   int max = INT_MAX;
   int min = INT_MIN;
 
-  if ((a - 2) <= (min - 1LL))
-    return; // expected-warning{{never executed}}
-
-  void *sentinel = malloc(1);
-  if ((a + 2LL) <= max)
-    free(sentinel);
-  return; // expected-warning{{leak}}
-}
-
-void mixedWraparoundEQ(int a) {
-  int max = INT_MAX;
-
-  if ((a + 2) == (max + 1LL))
-    return; // expected-warning{{never executed}}
+  clang_analyzer_eval((a + 2) < (max + 1LL)); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a - 2) >= (min - 1LL)); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a - 2LL) >= min); // expected-warning{{UNKNOWN}}
 }
 
-void mixedWraparoundNE(int a) {
+void mixedWraparoundEQ_NE(int a) {
   int max = INT_MAX;
 
-  void *sentinel = malloc(1);
-  if ((a + 2) != (max + 1LL))
-    free(sentinel);
-  return; // no-warning
+  clang_analyzer_eval((a + 2) != (max + 1LL)); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a + 2LL) == (max + 1LL)); // expected-warning{{UNKNOWN}}
 }
 
 
@@ -332,10 +180,9 @@ void mixedWraparoundNE(int a) {
 void mixedSignedness(int a, unsigned b) {
   int sMin = INT_MIN;
   unsigned uMin = INT_MIN;
-  if (a == sMin && a != uMin)
-    return; // expected-warning{{never executed}}
-  if (b == uMin && b != sMin)
-    return; // expected-warning{{never executed}}
+
+  clang_analyzer_eval(a == sMin && a != uMin); // expected-warning{{FALSE}}
+  clang_analyzer_eval(b == uMin && b != sMin); // expected-warning{{FALSE}}
 }
 
 
@@ -365,16 +212,12 @@ void PR12206(int x) {
   // turning the symbol into a ConcreteInt, rather than ExprEngine.
 
   // Test relational operators.
-  if ((local + 1) < 2)
-    malloc(1); // expected-warning{{never executed}}
-  if (2 > (local + 1))
-    malloc(1); // expected-warning{{never executed}}
+  clang_analyzer_eval((local + 1) >= 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(2 <= (local + 1)); // expected-warning{{TRUE}}
 
   // Test equality operators.
-  if ((local + 1) == 1) 
-    malloc(1); // expected-warning{{never executed}}
-  if (1 == (local + 1))
-    malloc(1); // expected-warning{{never executed}}
+  clang_analyzer_eval((local + 1) != 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(1 != (local + 1)); // expected-warning{{TRUE}}
 }
 
 void PR12206_truncation(signed char x) {
@@ -393,24 +236,19 @@ void PR12206_truncation(signed char x) {
   signed int value = 1 + (1 << 8);
 
   // Test relational operators.
-  if ((local + 1) >= value)
-    malloc(1); // expected-warning{{never executed}}
-  if (value <= (local + 1))
-    malloc(1); // expected-warning{{never executed}}
+  clang_analyzer_eval((local + 1) < value); // expected-warning{{TRUE}}
+  clang_analyzer_eval(value > (local + 1)); // expected-warning{{TRUE}}
 
   // Test equality operators.
-  if ((local + 1) == value) 
-    malloc(1); // expected-warning{{never executed}}
-  if (value == (local + 1))
-    malloc(1); // expected-warning{{never executed}}
+  clang_analyzer_eval((local + 1) != value); // expected-warning{{TRUE}}
+  clang_analyzer_eval(value != (local + 1)); // expected-warning{{TRUE}}
 }
 
 void multiplicativeSanityTest(int x) {
   // At one point we were ignoring the *4 completely -- the constraint manager
-  // would see x < 8 and then declare the next part unreachable.
+  // would see x < 8 and then declare the assertion to be known false.
   if (x*4 < 8)
     return;
-  if (x == 3)
-    malloc(1);
-  return; // expected-warning{{leak}}
+
+  clang_analyzer_eval(x == 3); // expected-warning{{UNKNOWN}}
 }
index 18d5b2a..c1eddcd 100644 (file)
@@ -1,25 +1,21 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,experimental.deadcode.UnreachableCode -analyzer-store=region -analyzer-constraints=basic -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,experimental.deadcode.UnreachableCode -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify %s
+
+void clang_analyzer_eval(int);
 
 int string_literal_init() {
   char a[] = "abc";
   char b[2] = "abc"; // expected-warning{{too long}}
   char c[5] = "abc";
 
-  if (a[1] != 'b')
-    return 0; // expected-warning{{never executed}}
-  if (b[1] != 'b')
-    return 0; // expected-warning{{never executed}}
-  if (c[1] != 'b')
-    return 0; // expected-warning{{never executed}}
+  clang_analyzer_eval(a[1] == 'b'); // expected-warning{{TRUE}}
+  clang_analyzer_eval(b[1] == 'b'); // expected-warning{{TRUE}}
+  clang_analyzer_eval(c[1] == 'b'); // expected-warning{{TRUE}}
 
-  if (a[3] != 0)
-    return 0; // expected-warning{{never executed}}
-  if (c[3] != 0)
-    return 0; // expected-warning{{never executed}}
+  clang_analyzer_eval(a[3] == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(c[3] == 0); // expected-warning{{TRUE}}
 
-  if (c[4] != 0)
-    return 0; // expected-warning{{never executed}}
+  clang_analyzer_eval(c[4] == 0); // expected-warning{{TRUE}}
 
   return 42;
 }
@@ -48,13 +44,16 @@ void nested_compound_literals_float(float rad) {
 
 
 void struct_as_array() {
-  struct simple { int x; };
+  struct simple { int x; int y; };
   struct simple a;
   struct simple *p = &a;
+
   p->x = 5;
-  if (!p[0].x)
-    return; // expected-warning{{never executed}}
-  if (p[0].x)
-    return; // no-warning
+  clang_analyzer_eval(a.x == 5); // expected-warning{{TRUE}}
+  clang_analyzer_eval(p[0].x == 5); // expected-warning{{TRUE}}
+
+  p[0].y = 5;
+  clang_analyzer_eval(a.y == 5); // expected-warning{{TRUE}}
+  clang_analyzer_eval(p->y == 5); // expected-warning{{TRUE}}
 }
 
index 8fd7abc..ae99d53 100644 (file)
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -analyzer-inline-call -cfg-add-initializers -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -cfg-add-initializers -verify %s
 // XFAIL: *
 
+void clang_analyzer_eval(bool);
+
 class A {
   int x;
 public:
@@ -24,8 +26,5 @@ B::B() {
 
 void f() {
   B b;
-  if (b.getx() != 0) {
-    int *p = 0;
-    *p = 0; // no-warning
-  }
+  clang_analyzer_eval(b.getx() == 0); // expected-warning{{TRUE}}
 }
index 87c9161..d383d42 100644 (file)
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,experimental.unix.cstring -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,experimental.unix.cstring -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,experimental.unix.cstring -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring.NullArg,experimental.unix.cstring.OutOfBounds,experimental.unix.cstring.BufferOverlap,experimental.unix.cstring.NotNullTerminated -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
 
 //===----------------------------------------------------------------------===
 // Declarations
@@ -26,6 +26,8 @@
 
 typedef typeof(sizeof(int)) size_t;
 
+void clang_analyzer_eval(int);
+
 //===----------------------------------------------------------------------===
 // memcpy()
 //===----------------------------------------------------------------------===
@@ -52,12 +54,11 @@ void memcpy0 () {
 
   memcpy(dst, src, 4); // no-warning
 
-  if (memcpy(dst, src, 4) != dst) {
-    (void)*(char*)0; // no-warning
-  }
+  clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}}
 
-  if (dst[0] != 0)
-    (void)*(char*)0; // expected-warning{{null}}
+  // If we actually model the copy, we can make this known.
+  // The important thing for now is that the old value has been invalidated.
+  clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
 }
 
 void memcpy1 () {
@@ -138,14 +139,13 @@ void memcpy13() {
 
 void memcpy_unknown_size (size_t n) {
   char a[4], b[4] = {1};
-  if (memcpy(a, b, n) != a)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(memcpy(a, b, n) == a); // expected-warning{{TRUE}}
 }
 
 void memcpy_unknown_size_warn (size_t n) {
   char a[4];
-  if (memcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}}
-    (void)*(char*)0; // no-warning
+  void *result = memcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
+  clang_analyzer_eval(result == a); // no-warning (above is fatal)
 }
 
 //===----------------------------------------------------------------------===
@@ -174,12 +174,11 @@ void mempcpy0 () {
 
   mempcpy(dst, src, 4); // no-warning
 
-  if (mempcpy(dst, src, 4) != &dst[4]) {
-    (void)*(char*)0; // no-warning
-  }
+  clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}}
 
-  if (dst[0] != 0)
-    (void)*(char*)0; // expected-warning{{null}}
+  // If we actually model the copy, we can make this known.
+  // The important thing for now is that the old value has been invalidated.
+  clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
 }
 
 void mempcpy1 () {
@@ -260,8 +259,8 @@ void mempcpy13() {
 
 void mempcpy_unknown_size_warn (size_t n) {
   char a[4];
-  if (mempcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}}
-    (void)*(char*)0; // no-warning
+  void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
+  clang_analyzer_eval(result == a); // no-warning (above is fatal)
 }
 
 void mempcpy_unknownable_size (char *src, float n) {
@@ -295,12 +294,11 @@ void memmove0 () {
 
   memmove(dst, src, 4); // no-warning
 
-  if (memmove(dst, src, 4) != dst) {
-    (void)*(char*)0; // no-warning
-  }
+  clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}}
 
-  if (dst[0] != 0)
-    (void)*(char*)0; // expected-warning{{null}}
+  // If we actually model the copy, we can make this known.
+  // The important thing for now is that the old value has been invalidated.
+  clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
 }
 
 void memmove1 () {
@@ -327,7 +325,7 @@ void memmove2 () {
 // __builtin_bcmp is not defined with const in Builtins.def.
 int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
 #define memcmp bcmp
-
+// 
 #else /* VARIANT */
 
 #define memcmp BUILTIN(memcmp)
@@ -360,34 +358,32 @@ void memcmp2 () {
 void memcmp3 () {
   char a[] = {1, 2, 3, 4};
 
-  if (memcmp(a, a, 4))
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}}
 }
 
 void memcmp4 (char *input) {
   char a[] = {1, 2, 3, 4};
 
-  if (memcmp(a, input, 4))
-    (void)*(char*)0; // expected-warning{{null}}
+  clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}}
 }
 
 void memcmp5 (char *input) {
   char a[] = {1, 2, 3, 4};
 
-  if (memcmp(a, 0, 0)) // no-warning
-    (void)*(char*)0;   // no-warning
-  if (memcmp(0, a, 0)) // no-warning
-    (void)*(char*)0;   // no-warning
-  if (memcmp(a, input, 0)) // no-warning
-    (void)*(char*)0;   // no-warning
+  clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}}
 }
 
 void memcmp6 (char *a, char *b, size_t n) {
   int result = memcmp(a, b, n);
   if (result != 0)
-    return;
-  if (n == 0)
-    (void)*(char*)0; // expected-warning{{null}}
+    clang_analyzer_eval(n != 0); // expected-warning{{TRUE}}
+  // else
+  //   analyzer_assert_unknown(n == 0);
+
+  // We can't do the above comparison because n has already been constrained.
+  // On one path n == 0, on the other n != 0.
 }
 
 int memcmp7 (char *a, size_t x, size_t y, size_t n) {
@@ -411,8 +407,9 @@ void bcopy0 () {
 
   bcopy(src, dst, 4); // no-warning
 
-  if (dst[0] != 0)
-    (void)*(char*)0; // expected-warning{{null}}
+  // If we actually model the copy, we can make this known.
+  // The important thing for now is that the old value has been invalidated.
+  clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
 }
 
 void bcopy1 () {
index c650473..81d1193 100644 (file)
@@ -1,7 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
 
-// Trigger a warning if the analyzer reaches this point in the control flow.
-#define WARN ((void)*(char*)0)
+void clang_analyzer_eval(int);
 
 // There should be no warnings unless otherwise indicated.
 
@@ -9,73 +8,71 @@ void testComparisons (int a) {
   // Sema can already catch the simple comparison a==a,
   // since that's usually a logic error (and not path-dependent).
   int b = a;
-  if (!(b==a)) WARN; // expected-warning{{never executed}}
-  if (!(b>=a)) WARN; // expected-warning{{never executed}}
-  if (!(b<=a)) WARN; // expected-warning{{never executed}}
-  if (b!=a) WARN;    // expected-warning{{never executed}}
-  if (b>a) WARN;     // expected-warning{{never executed}}
-  if (b<a) WARN;     // expected-warning{{never executed}}
+  clang_analyzer_eval(b == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval(b >= a); // expected-warning{{TRUE}}
+  clang_analyzer_eval(b <= a); // expected-warning{{TRUE}}
+  clang_analyzer_eval(b != a); // expected-warning{{FALSE}}
+  clang_analyzer_eval(b > a); // expected-warning{{FALSE}}
+  clang_analyzer_eval(b < a); // expected-warning{{FALSE}}
 }
 
 void testSelfOperations (int a) {
-  if ((a|a) != a) WARN; // expected-warning{{never executed}}
-  if ((a&a) != a) WARN; // expected-warning{{never executed}}
-  if ((a^a) != 0) WARN; // expected-warning{{never executed}}
-  if ((a-a) != 0) WARN; // expected-warning{{never executed}}
+  clang_analyzer_eval((a|a) == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a&a) == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a^a) == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a-a) == 0); // expected-warning{{TRUE}}
 }
 
 void testIdempotent (int a) {
-  if ((a*1) != a) WARN;    // expected-warning{{never executed}}
-  if ((a/1) != a) WARN;    // expected-warning{{never executed}}
-  if ((a+0) != a) WARN;    // expected-warning{{never executed}}
-  if ((a-0) != a) WARN;    // expected-warning{{never executed}}
-  if ((a<<0) != a) WARN;   // expected-warning{{never executed}}
-  if ((a>>0) != a) WARN;   // expected-warning{{never executed}}
-  if ((a^0) != a) WARN;    // expected-warning{{never executed}}
-  if ((a&(~0)) != a) WARN; // expected-warning{{never executed}}
-  if ((a|0) != a) WARN;    // expected-warning{{never executed}}
+  clang_analyzer_eval((a*1) == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a/1) == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a+0) == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a-0) == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a<<0) == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a>>0) == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a^0) == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a&(~0)) == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a|0) == a); // expected-warning{{TRUE}}
 }
 
 void testReductionToConstant (int a) {
-  if ((a*0) != 0) WARN; // expected-warning{{never executed}}
-  if ((a&0) != 0) WARN; // expected-warning{{never executed}}
-  if ((a|(~0)) != (~0)) WARN; // expected-warning{{never executed}}
+  clang_analyzer_eval((a*0) == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a&0) == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a|(~0)) == (~0)); // expected-warning{{TRUE}}
 }
 
 void testSymmetricIntSymOperations (int a) {
-  if ((2+a) != (a+2)) WARN; // expected-warning{{never executed}}
-  if ((2*a) != (a*2)) WARN; // expected-warning{{never executed}}
-  if ((2&a) != (a&2)) WARN; // expected-warning{{never executed}}
-  if ((2^a) != (a^2)) WARN; // expected-warning{{never executed}}
-  if ((2|a) != (a|2)) WARN; // expected-warning{{never executed}}
+  clang_analyzer_eval((2+a) == (a+2)); // expected-warning{{TRUE}}
+  clang_analyzer_eval((2*a) == (a*2)); // expected-warning{{TRUE}}
+  clang_analyzer_eval((2&a) == (a&2)); // expected-warning{{TRUE}}
+  clang_analyzer_eval((2^a) == (a^2)); // expected-warning{{TRUE}}
+  clang_analyzer_eval((2|a) == (a|2)); // expected-warning{{TRUE}}
 }
 
 void testAsymmetricIntSymOperations (int a) {
-  if (((~0) >> a) != (~0)) WARN; // expected-warning{{never executed}}
-  if ((0 >> a) != 0) WARN; // expected-warning{{never executed}}
-  if ((0 << a) != 0) WARN; // expected-warning{{never executed}}
+  clang_analyzer_eval(((~0) >> a) == (~0)); // expected-warning{{TRUE}}
+  clang_analyzer_eval((0 >> a) == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval((0 << a) == 0); // expected-warning{{TRUE}}
 
   // Unsigned right shift shifts in zeroes.
-  if ((((unsigned)(~0)) >> ((unsigned) a)) != ((unsigned)(~0)))
-    WARN; // expected-warning{{}}
+  clang_analyzer_eval(((~0U) >> a) != (~0U)); // expected-warning{{UNKNOWN}}
 }
 
 void testLocations (char *a) {
   char *b = a;
-  if (!(b==a)) WARN; // expected-warning{{never executed}}
-  if (!(b>=a)) WARN; // expected-warning{{never executed}}
-  if (!(b<=a)) WARN; // expected-warning{{never executed}}
-  if (b!=a) WARN; // expected-warning{{never executed}}
-  if (b>a) WARN; // expected-warning{{never executed}}
-  if (b<a) WARN; // expected-warning{{never executed}}
-  if (b-a) WARN; // expected-warning{{never executed}}
+  clang_analyzer_eval(b == a); // expected-warning{{TRUE}}
+  clang_analyzer_eval(b >= a); // expected-warning{{TRUE}}
+  clang_analyzer_eval(b <= a); // expected-warning{{TRUE}}
+  clang_analyzer_eval(b != a); // expected-warning{{FALSE}}
+  clang_analyzer_eval(b > a); // expected-warning{{FALSE}}
+  clang_analyzer_eval(b < a); // expected-warning{{FALSE}}
 }
 
 void testMixedTypeComparisons (char a, unsigned long b) {
   if (a != 0) return;
   if (b != 0x100) return;
 
-  if (a > b) WARN; // expected-warning{{never executed}}
-  if (b < a) WARN; // expected-warning{{never executed}}
-  if (a == b) WARN; // expected-warning{{never executed}}
+  clang_analyzer_eval(a <= b); // expected-warning{{TRUE}}
+  clang_analyzer_eval(b >= a); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a != b); // expected-warning{{TRUE}}
 }
index 656a8bf..6640e1f 100644 (file)
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -cfg-add-initializers -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -cfg-add-initializers -verify %s
+
+void clang_analyzer_eval(bool);
 
 class A {
   int x;
@@ -7,8 +9,5 @@ public:
 };
 
 A::A() : x(0) {
-  if (x != 0) {
-    int *p = 0;
-    *p = 0; // no-warning
-  }
+  clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
 }
index 323fffe..91da532 100644 (file)
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-inline-call -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-store region -verify %s
 // XFAIL: *
 
+void clang_analyzer_eval(bool);
+
 struct A {
   int x;
   A(int a) { x = a; }
@@ -9,33 +11,15 @@ struct A {
 
 void f1() {
   A x(3);
-  if (x.getx() == 3) {
-    int *p = 0;
-    *p = 3;  // expected-warning{{Dereference of null pointer}}
-  } else {
-    int *p = 0;
-    *p = 3;  // no-warning
-  }
+  clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
 }
 
 void f2() {
   const A &x = A(3);
-  if (x.getx() == 3) {
-    int *p = 0;
-    *p = 3;  // expected-warning{{Dereference of null pointer}}
-  } else {
-    int *p = 0;
-    *p = 3;  // no-warning
-  }
+  clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
 }
 
 void f3() {
   const A &x = (A)3;
-  if (x.getx() == 3) {
-    int *p = 0;
-    *p = 3;  // expected-warning{{Dereference of null pointer}}
-  } else {
-    int *p = 0;
-    *p = 3;  // no-warning
-  }
+  clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
 }
index fb37f1c..6567000 100644 (file)
@@ -1,8 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub -analyzer-store=region -verify -triple i686-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 %s
 
-// Used to trigger warnings for unreachable paths.
-#define WARN do { int a, b; int c = &b-&a; } while (0)
+void clang_analyzer_eval(int);
 
 void f1() {
   int a[10];
@@ -67,111 +66,48 @@ void f6(int *p, int *q) {
 void null_operand(int *a) {
 start:
   // LHS is a label, RHS is NULL
-  if (&&start == 0)
-    WARN; // no-warning
-  if (&&start <  0)
-    WARN; // no-warning
-  if (&&start <= 0)
-    WARN; // no-warning
-  if (!(&&start != 0))
-    WARN; // no-warning
-  if (!(&&start >  0))
-    WARN; // no-warning
-  if (!(&&start >= 0))
-    WARN; // no-warning
-  if (!(&&start - 0))
-    WARN; // no-warning
+  clang_analyzer_eval(&&start != 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&&start >= 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&&start > 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval((&&start - 0) != 0); // expected-warning{{TRUE}}
 
   // LHS is a non-symbolic value, RHS is NULL
-  if (&a == 0)
-    WARN; // no-warning
-  if (&a <  0)
-    WARN; // no-warning
-  if (&a <= 0)
-    WARN; // no-warning
-  if (!(&a != 0))
-    WARN; // no-warning
-  if (!(&a >  0))
-    WARN; // no-warning
-  if (!(&a >= 0))
-    WARN; // no-warning
-
-  if (!(&a - 0)) // expected-warning{{Pointer arithmetic done on non-array variables}}
-    WARN; // no-warning
+  clang_analyzer_eval(&a != 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&a >= 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&a > 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval((&a - 0) != 0); // expected-warning{{TRUE}} expected-warning{{Pointer arithmetic done on non-array variables}}
 
   // LHS is NULL, RHS is non-symbolic
   // The same code is used for labels and non-symbolic values.
-  if (0 == &a)
-    WARN; // no-warning
-  if (0 >  &a)
-    WARN; // no-warning
-  if (0 >= &a)
-    WARN; // no-warning
-  if (!(0 != &a))
-    WARN; // no-warning
-  if (!(0 <  &a))
-    WARN; // no-warning
-  if (!(0 <= &a))
-    WARN; // no-warning
+  clang_analyzer_eval(0 != &a); // expected-warning{{TRUE}}
+  clang_analyzer_eval(0 <= &a); // expected-warning{{TRUE}}
+  clang_analyzer_eval(0 < &a); // expected-warning{{TRUE}}
 
   // LHS is a symbolic value, RHS is NULL
-  if (a == 0)
-    WARN; // expected-warning{{}}
-  if (a <  0)
-    WARN; // no-warning
-  if (a <= 0)
-    WARN; // expected-warning{{}}
-  if (!(a != 0))
-    WARN; // expected-warning{{}}
-  if (!(a >  0))
-    WARN; // expected-warning{{}}
-  if (!(a >= 0))
-    WARN; // no-warning
-  if (!(a - 0))
-    WARN; // expected-warning{{}}
+  clang_analyzer_eval(a != 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(a >= 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a <= 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval((a - 0) != 0); // expected-warning{{UNKNOWN}}
 
   // LHS is NULL, RHS is a symbolic value
-  if (0 == a)
-    WARN; // expected-warning{{}}
-  if (0 >  a)
-    WARN; // no-warning
-  if (0 >= a)
-    WARN; // expected-warning{{}}
-  if (!(0 != a))
-    WARN; // expected-warning{{}}
-  if (!(0 <  a))
-    WARN; // expected-warning{{}}
-  if (!(0 <= a))
-    WARN; // no-warning
+  clang_analyzer_eval(0 != a); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(0 <= a); // expected-warning{{TRUE}}
+  clang_analyzer_eval(0 < a); // expected-warning{{UNKNOWN}}
 }
 
 void const_locs() {
   char *a = (char*)0x1000;
   char *b = (char*)0x1100;
 start:
-  if (a==b)
-    WARN; // no-warning
-  if (!(a!=b))
-    WARN; // no-warning
-  if (a>b)
-    WARN; // no-warning
-  if (b<a)
-    WARN; // no-warning
-  if (a>=b)
-    WARN; // no-warning
-  if (b<=a)
-    WARN; // no-warning
-  if (b-a != 0x100)
-    WARN; // no-warning
-
-  if (&&start == a)
-    WARN; // expected-warning{{}}
-  if (a == &&start)
-    WARN; // expected-warning{{}}
-  if (&a == (char**)a)
-    WARN; // expected-warning{{}}
-  if ((char**)a == &a)
-    WARN; // expected-warning{{}}
+  clang_analyzer_eval(a != b); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a < b); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a <= b); // expected-warning{{TRUE}}
+  clang_analyzer_eval((b-a) == 0x100); // expected-warning{{TRUE}}
+
+  clang_analyzer_eval(&&start == a); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(a == &&start); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(&a == (char**)a); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval((char**)a == &a); // expected-warning{{UNKNOWN}}
 }
 
 void array_matching_types() {
@@ -179,20 +115,10 @@ void array_matching_types() {
   int *a = &array[2];
   int *b = &array[5];
 
-  if (a==b)
-    WARN; // no-warning
-  if (!(a!=b))
-    WARN; // no-warning
-  if (a>b)
-    WARN; // no-warning
-  if (b<a)
-    WARN; // no-warning
-  if (a>=b)
-    WARN; // no-warning
-  if (b<=a)
-    WARN; // no-warning
-  if ((b-a) == 0)
-    WARN; // no-warning
+  clang_analyzer_eval(a != b); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a < b); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a <= b); // expected-warning{{TRUE}}
+  clang_analyzer_eval((b-a) != 0); // expected-warning{{TRUE}}
 }
 
 // This takes a different code path than array_matching_types()
@@ -201,49 +127,22 @@ void array_different_types() {
   int *a = &array[2];
   char *b = (char*)&array[5];
 
-  if (a==b) // expected-warning{{comparison of distinct pointer types}}
-    WARN; // no-warning
-  if (!(a!=b)) // expected-warning{{comparison of distinct pointer types}}
-    WARN; // no-warning
-  if (a>b) // expected-warning{{comparison of distinct pointer types}}
-    WARN; // no-warning
-  if (b<a) // expected-warning{{comparison of distinct pointer types}}
-    WARN; // no-warning
-  if (a>=b) // expected-warning{{comparison of distinct pointer types}}
-    WARN; // no-warning
-  if (b<=a) // expected-warning{{comparison of distinct pointer types}}
-    WARN; // no-warning
+  clang_analyzer_eval(a != b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
+  clang_analyzer_eval(a < b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
+  clang_analyzer_eval(a <= b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
 }
 
 struct test { int x; int y; };
 void struct_fields() {
   struct test a, b;
 
-  if (&a.x == &a.y)
-    WARN; // no-warning
-  if (!(&a.x != &a.y))
-    WARN; // no-warning
-  if (&a.x > &a.y)
-    WARN; // no-warning
-  if (&a.y < &a.x)
-    WARN; // no-warning
-  if (&a.x >= &a.y)
-    WARN; // no-warning
-  if (&a.y <= &a.x)
-    WARN; // no-warning
+  clang_analyzer_eval(&a.x != &a.y); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&a.x < &a.y); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&a.x <= &a.y); // expected-warning{{TRUE}}
 
-  if (&a.x == &b.x)
-    WARN; // no-warning
-  if (!(&a.x != &b.x))
-    WARN; // no-warning
-  if (&a.x > &b.x)
-    WARN; // expected-warning{{}}
-  if (&b.x < &a.x)
-    WARN; // expected-warning{{}}
-  if (&a.x >= &b.x)
-    WARN; // expected-warning{{}}
-  if (&b.x <= &a.x)
-    WARN; // expected-warning{{}}
+  clang_analyzer_eval(&a.x != &b.x); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&a.x > &b.x); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(&a.x >= &b.x); // expected-warning{{UNKNOWN}}
 }
 
 void mixed_region_types() {
@@ -251,35 +150,17 @@ void mixed_region_types() {
   int array[2];
   void *a = &array, *b = &s;
 
-  if (&a == &b)
-    WARN; // no-warning
-  if (!(&a != &b))
-    WARN; // no-warning
-  if (&a > &b)
-    WARN; // expected-warning{{}}
-  if (&b < &a)
-    WARN; // expected-warning{{}}
-  if (&a >= &b)
-    WARN; // expected-warning{{}}
-  if (&b <= &a)
-    WARN; // expected-warning{{}}
+  clang_analyzer_eval(&a != &b); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&a > &b); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(&a >= &b); // expected-warning{{UNKNOWN}}
 }
 
 void symbolic_region(int *p) {
   int a;
 
-  if (&a == p)
-    WARN; // no-warning
-  if (&a != p)
-    WARN; // expected-warning{{}}
-  if (&a > p)
-    WARN; // expected-warning{{}}
-  if (&a < p)
-    WARN; // expected-warning{{}}
-  if (&a >= p)
-    WARN; // expected-warning{{}}
-  if (&a <= p)
-    WARN; // expected-warning{{}}
+  clang_analyzer_eval(&a != p); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&a > p); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(&a >= p); // expected-warning{{UNKNOWN}}
 }
 
 void PR7527 (int *p) {
index 3bff6d4..ac5c6d0 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.unix.CString,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,experimental.unix.CString,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
 // XFAIL: *
 
 // This file is for tests that may eventually go into string.c, or may be
@@ -32,6 +32,7 @@
 #define NULL 0
 typedef typeof(sizeof(int)) size_t;
 
+void clang_analyzer_eval(int);
 
 //===----------------------------------------------------------------------===
 // strnlen()
@@ -43,8 +44,7 @@ size_t strnlen(const char *s, size_t maxlen);
 void strnlen_liveness(const char *x) {
   if (strnlen(x, 10) < 5)
     return;
-  if (strnlen(x, 10) < 5)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strnlen(x, 10) < 5); // expected-warning{{FALSE}}
 }
 
 void strnlen_subregion() {
@@ -57,43 +57,43 @@ void strnlen_subregion() {
   size_t a = strnlen(z.a, 10);
   z.b[0] = 5;
   size_t b = strnlen(z.a, 10);
-  if (a == 0 && b != 0)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  if (a == 0)
+    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
 
   use_two_stringsn(&z);
 
   size_t c = strnlen(z.a, 10);
-  if (a == 0 && c != 0)
-    (void)*(char*)0; // expected-warning{{null}}
+  if (a == 0)
+    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
 }
 
 extern void use_stringn(char *);
 void strnlen_argument(char *x) {
   size_t a = strnlen(x, 10);
   size_t b = strnlen(x, 10);
-  if (a == 0 && b != 0)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  if (a == 0)
+    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
 
   use_stringn(x);
 
   size_t c = strnlen(x, 10);
-  if (a == 0 && c != 0)
-    (void)*(char*)0; // expected-warning{{null}}  
+  if (a == 0)
+    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
 }
 
 extern char global_strn[];
 void strnlen_global() {
   size_t a = strnlen(global_strn, 10);
   size_t b = strnlen(global_strn, 10);
-  if (a == 0 && b != 0)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  if (a == 0)
+    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
 
   // Call a function with unknown effects, which should invalidate globals.
   use_stringn(0);
 
   size_t c = strnlen(global_strn, 10);
-  if (a == 0 && c != 0)
-    (void)*(char*)0; // expected-warning{{null}}  
+  if (a == 0)
+    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
 }
 
 void strnlen_indirect(char *x) {
@@ -101,13 +101,13 @@ void strnlen_indirect(char *x) {
   char *p = x;
   char **p2 = &p;
   size_t b = strnlen(x, 10);
-  if (a == 0 && b != 0)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  if (a == 0)
+    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
 
   extern void use_stringn_ptr(char*const*);
   use_stringn_ptr(p2);
 
   size_t c = strnlen(x, 10);
-  if (a == 0 && c != 0)
-    (void)*(char*)0; // expected-warning{{null}}
+  if (a == 0)
+    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
 }
index dc38681..4e9d51f 100644 (file)
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,experimental.unix.cstring,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,experimental.unix.cstring,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,experimental.unix.cstring,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=experimental.security.taint,core,unix.cstring,experimental.unix.cstring,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=experimental.security.taint,core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
 
 //===----------------------------------------------------------------------===
 // Declarations
@@ -26,6 +26,9 @@
 
 #define NULL 0
 typedef typeof(sizeof(int)) size_t;
+
+void clang_analyzer_eval(int);
+
 int scanf(const char *restrict format, ...);
 
 //===----------------------------------------------------------------------===
@@ -36,23 +39,20 @@ int scanf(const char *restrict format, ...);
 size_t strlen(const char *s);
 
 void strlen_constant0() {
-  if (strlen("123") != 3)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strlen("123") == 3); // expected-warning{{TRUE}}
 }
 
 void strlen_constant1() {
   const char *a = "123";
-  if (strlen(a) != 3)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
 }
 
 void strlen_constant2(char x) {
   char a[] = "123";
-  if (strlen(a) != 3)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
+
   a[0] = x;
-  if (strlen(a) != 3)
-    (void)*(char*)0; // expected-warning{{null}}
+  clang_analyzer_eval(strlen(a) == 3); // expected-warning{{UNKNOWN}}
 }
 
 size_t strlen_null() {
@@ -78,43 +78,46 @@ void strlen_subregion() {
   size_t a = strlen(z.a);
   z.b[0] = 5;
   size_t b = strlen(z.a);
-  if (a == 0 && b != 0)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  if (a == 0)
+    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
 
   use_two_strings(&z);
 
   size_t c = strlen(z.a);
-  if (a == 0 && c != 0)
-    (void)*(char*)0; // expected-warning{{null}}
+  if (a == 0)
+    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
 }
 
 extern void use_string(char *);
 void strlen_argument(char *x) {
   size_t a = strlen(x);
   size_t b = strlen(x);
-  if (a == 0 && b != 0)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  if (a == 0)
+    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
 
   use_string(x);
 
   size_t c = strlen(x);
-  if (a == 0 && c != 0)
-    (void)*(char*)0; // expected-warning{{null}}  
+  if (a == 0)
+    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
 }
 
 extern char global_str[];
 void strlen_global() {
   size_t a = strlen(global_str);
   size_t b = strlen(global_str);
-  if (a == 0 && b != 0)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  if (a == 0) {
+    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
+    // Make sure clang_analyzer_eval does not invalidate globals.
+    clang_analyzer_eval(strlen(global_str) == 0); // expected-warning{{TRUE}}    
+  }
 
   // Call a function with unknown effects, which should invalidate globals.
   use_string(0);
 
   size_t c = strlen(global_str);
-  if (a == 0 && c != 0)
-    (void)*(char*)0; // expected-warning{{null}}  
+  if (a == 0)
+    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
 }
 
 void strlen_indirect(char *x) {
@@ -122,15 +125,15 @@ void strlen_indirect(char *x) {
   char *p = x;
   char **p2 = &p;
   size_t b = strlen(x);
-  if (a == 0 && b != 0)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  if (a == 0)
+    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
 
   extern void use_string_ptr(char*const*);
   use_string_ptr(p2);
 
   size_t c = strlen(x);
-  if (a == 0 && c != 0)
-    (void)*(char*)0; // expected-warning{{null}}
+  if (a == 0)
+    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
 }
 
 void strlen_indirect2(char *x) {
@@ -141,15 +144,14 @@ void strlen_indirect2(char *x) {
   use_string_ptr2(p2);
 
   size_t c = strlen(x);
-  if (a == 0 && c != 0)
-    (void)*(char*)0; // expected-warning{{null}}
+  if (a == 0)
+    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
 }
 
 void strlen_liveness(const char *x) {
   if (strlen(x) < 5)
     return;
-  if (strlen(x) < 5)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strlen(x) < 5); // expected-warning{{FALSE}}
 }
 
 //===----------------------------------------------------------------------===
@@ -159,43 +161,35 @@ void strlen_liveness(const char *x) {
 size_t strnlen(const char *s, size_t maxlen);
 
 void strnlen_constant0() {
-  if (strnlen("123", 10) != 3)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  clang_analyzer_eval(strnlen("123", 10) == 3); // expected-warning{{TRUE}}
 }
 
 void strnlen_constant1() {
   const char *a = "123";
-  if (strnlen(a, 10) != 3)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
 }
 
 void strnlen_constant2(char x) {
   char a[] = "123";
-  if (strnlen(a, 10) != 3)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
   a[0] = x;
-  if (strnlen(a, 10) != 3)
-    (void)*(char*)0; // expected-warning{{null}}
+  clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{UNKNOWN}}
 }
 
 void strnlen_constant4() {
-  if (strnlen("123456", 3) != 3)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  clang_analyzer_eval(strnlen("123456", 3) == 3); // expected-warning{{TRUE}}
 }
 
 void strnlen_constant5() {
   const char *a = "123456";
-  if (strnlen(a, 3) != 3)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
 }
 
 void strnlen_constant6(char x) {
   char a[] = "123456";
-  if (strnlen(a, 3) != 3)
-    (void)*(char*)0; // expected-warning{{never executed}}
+  clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
   a[0] = x;
-  if (strnlen(a, 3) != 3)
-    (void)*(char*)0; // expected-warning{{null}}
+  clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{UNKNOWN}}
 }
 
 size_t strnlen_null() {
@@ -212,10 +206,8 @@ label:
 }
 
 void strnlen_zero() {
-  if (strnlen("abc", 0) != 0)
-    (void)*(char*)0; // expected-warning{{never executed}}
-  if (strnlen(NULL, 0) != 0) // no-warning
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strnlen("abc", 0) == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(strnlen(NULL, 0) == 0); // expected-warning{{TRUE}}
 }
 
 size_t strnlen_compound_literal() {
@@ -230,40 +222,26 @@ size_t strnlen_unknown_limit(float f) {
 }
 
 void strnlen_is_not_strlen(char *x) {
-  if (strnlen(x, 10) != strlen(x))
-    (void)*(char*)0; // expected-warning{{null}}
+  clang_analyzer_eval(strnlen(x, 10) == strlen(x)); // expected-warning{{UNKNOWN}}
 }
 
 void strnlen_at_limit(char *x) {
   size_t len = strnlen(x, 10);
-  if (len > 10)
-    (void)*(char*)0; // expected-warning{{never executed}}
-  if (len == 10)
-    (void)*(char*)0; // expected-warning{{null}}
-}
-
-void strnlen_less_than_limit(char *x) {
-  size_t len = strnlen(x, 10);
-  if (len > 10)
-    (void)*(char*)0; // expected-warning{{never executed}}
-  if (len < 10)
-    (void)*(char*)0; // expected-warning{{null}}
+  clang_analyzer_eval(len <= 10); // expected-warning{{TRUE}}
+  clang_analyzer_eval(len == 10); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(len < 10); // expected-warning{{UNKNOWN}}
 }
 
 void strnlen_at_actual(size_t limit) {
   size_t len = strnlen("abc", limit);
-  if (len > 3)
-    (void)*(char*)0; // expected-warning{{never executed}}
-  if (len == 3)
-    (void)*(char*)0; // expected-warning{{null}}
-}
-
-void strnlen_less_than_actual(size_t limit) {
-  size_t len = strnlen("abc", limit);
-  if (len > 3)
-    (void)*(char*)0; // expected-warning{{never executed}}
-  if (len < 3)
-    (void)*(char*)0; // expected-warning{{null}}
+  clang_analyzer_eval(len <= 3); // expected-warning{{TRUE}}
+  // This is due to eager assertion in strnlen.
+  if (limit == 0) {
+    clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}
+  } else {
+    clang_analyzer_eval(len == 3); // expected-warning{{UNKNOWN}}
+    clang_analyzer_eval(len < 3); // expected-warning{{UNKNOWN}}
+  }
 }
 
 //===----------------------------------------------------------------------===
@@ -304,14 +282,9 @@ void strcpy_fn_const(char *x) {
 void strcpy_effects(char *x, char *y) {
   char a = x[0];
 
-  if (strcpy(x, y) != x)
-    (void)*(char*)0; // no-warning
-
-  if (strlen(x) != strlen(y))
-    (void)*(char*)0; // no-warning
-
-  if (a != x[0])
-    (void)*(char*)0; // expected-warning{{null}}
+  clang_analyzer_eval(strcpy(x, y) == x); // expected-warning{{TRUE}}
+  clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
 }
 
 void strcpy_overflow(char *y) {
@@ -348,14 +321,9 @@ char *stpcpy(char *restrict s1, const char *restrict s2);
 void stpcpy_effect(char *x, char *y) {
   char a = x[0];
 
-  if (stpcpy(x, y) != &x[strlen(y)])
-    (void)*(char*)0; // no-warning
-
-  if (strlen(x) != strlen(y))
-    (void)*(char*)0; // no-warning
-
-  if (a != x[0])
-    (void)*(char*)0; // expected-warning{{null}}
+  clang_analyzer_eval(stpcpy(x, y) == &x[strlen(y)]); // expected-warning{{TRUE}}
+  clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
+  clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
 }
 
 void stpcpy_overflow(char *y) {
@@ -409,11 +377,8 @@ void strcat_effects(char *y) {
   if (strlen(y) != 4)
     return;
 
-  if (strcat(x, y) != x)
-    (void)*(char*)0; // no-warning
-
-  if ((int)strlen(x) != (orig_len + strlen(y)))
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcat(x, y) == x); // expected-warning{{TRUE}}
+  clang_analyzer_eval((int)strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
 }
 
 void strcat_overflow_0(char *y) {
@@ -442,29 +407,25 @@ void strcat_no_overflow(char *y) {
 
 void strcat_symbolic_dst_length(char *dst) {
        strcat(dst, "1234");
-       if (strlen(dst) < 4)
-               (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
 }
 
 void strcat_symbolic_src_length(char *src) {
        char dst[8] = "1234";
        strcat(dst, src);
-       if (strlen(dst) < 4)
-               (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
 }
 
 void strcat_symbolic_dst_length_taint(char *dst) {
   scanf("%s", dst); // Taint data.
   strcat(dst, "1234");
-  if (strlen(dst) < 4)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
 }
 
 void strcat_unknown_src_length(char *src, int offset) {
        char dst[8] = "1234";
        strcat(dst, &src[offset]);
-       if (strlen(dst) < 4)
-               (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
 }
 
 // There is no strcat_unknown_dst_length because if we can't get a symbolic
@@ -513,14 +474,9 @@ void strncpy_fn(char *x) {
 void strncpy_effects(char *x, char *y) {
   char a = x[0];
 
-  if (strncpy(x, y, 5) != x)
-    (void)*(char*)0; // no-warning
-
-  if (strlen(x) != strlen(y))
-    (void)*(char*)0; // expected-warning{{null}}
-
-  if (a != x[0])
-    (void)*(char*)0; // expected-warning{{null}}
+  clang_analyzer_eval(strncpy(x, y, 5) == x); // expected-warning{{TRUE}}
+  clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
 }
 
 void strncpy_overflow(char *y) {
@@ -562,8 +518,7 @@ void strncpy_exactly_matching_buffer(char *y) {
 
        // strncpy does not null-terminate, so we have no idea what the strlen is
        // after this.
-       if (strlen(x) > 4)
-               (void)*(int*)0; // expected-warning{{null}}
+  clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}}
 }
 
 void strncpy_exactly_matching_buffer2(char *y) {
@@ -574,8 +529,7 @@ void strncpy_exactly_matching_buffer2(char *y) {
        strncpy(x, y, 4); // no-warning
 
        // This time, we know that y fits in x anyway.
-       if (strlen(x) > 3)
-               (void)*(int*)0; // no-warning
+  clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{TRUE}}
 }
 
 void strncpy_zero(char *src) {
@@ -628,11 +582,8 @@ void strncat_effects(char *y) {
   if (strlen(y) != 4)
     return;
 
-  if (strncat(x, y, strlen(y)) != x)
-    (void)*(char*)0; // no-warning
-
-  if (strlen(x) != orig_len + strlen(y))
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}}
+  clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
 }
 
 void strncat_overflow_0(char *y) {
@@ -672,15 +623,13 @@ void strncat_no_overflow_2(char *y) {
 
 void strncat_symbolic_dst_length(char *dst) {
   strncat(dst, "1234", 5);
-  if (strlen(dst) < 4)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
 }
 
 void strncat_symbolic_src_length(char *src) {
   char dst[8] = "1234";
   strncat(dst, src, 3);
-  if (strlen(dst) < 4)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
 
   char dst2[8] = "1234";
   strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
@@ -689,8 +638,7 @@ void strncat_symbolic_src_length(char *src) {
 void strncat_unknown_src_length(char *src, int offset) {
   char dst[8] = "1234";
   strncat(dst, &src[offset], 3);
-  if (strlen(dst) < 4)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
 
   char dst2[8] = "1234";
   strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
@@ -703,20 +651,18 @@ void strncat_symbolic_limit(unsigned limit) {
   char dst[6] = "1234";
   char src[] = "567";
   strncat(dst, src, limit); // no-warning
-  if (strlen(dst) < 4)
-    (void)*(char*)0; // no-warning
-  if (strlen(dst) == 4)
-    (void)*(char*)0; // expected-warning{{null}}
+
+  clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
+  clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
 }
 
 void strncat_unknown_limit(float limit) {
   char dst[6] = "1234";
   char src[] = "567";
   strncat(dst, src, (size_t)limit); // no-warning
-  if (strlen(dst) < 4)
-    (void)*(char*)0; // no-warning
-  if (strlen(dst) == 4)
-    (void)*(char*)0; // expected-warning{{null}}
+
+  clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
+  clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
 }
 
 void strncat_too_big(char *dst, char *src) {
@@ -746,41 +692,35 @@ void strncat_empty() {
 int strcmp(const char * s1, const char * s2);
 
 void strcmp_constant0() {
-  if (strcmp("123", "123") != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}}
 }
 
 void strcmp_constant_and_var_0() {
   char *x = "123";
-  if (strcmp(x, "123") != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}}
 }
 
 void strcmp_constant_and_var_1() {
   char *x = "123";
-    if (strcmp("123", x) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}}
 }
 
 void strcmp_0() {
   char *x = "123";
   char *y = "123";
-  if (strcmp(x, y) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}}
 }
 
 void strcmp_1() {
   char *x = "234";
   char *y = "123";
-  if (strcmp(x, y) != 1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
 }
 
 void strcmp_2() {
   char *x = "123";
   char *y = "234";
-  if (strcmp(x, y) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
 }
 
 void strcmp_null_0() {
@@ -798,39 +738,33 @@ void strcmp_null_1() {
 void strcmp_diff_length_0() {
   char *x = "12345";
   char *y = "234";
-  if (strcmp(x, y) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
 }
 
 void strcmp_diff_length_1() {
   char *x = "123";
   char *y = "23456";
-  if (strcmp(x, y) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
 }
 
 void strcmp_diff_length_2() {
   char *x = "12345";
   char *y = "123";
-  if (strcmp(x, y) != 1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
 }
 
 void strcmp_diff_length_3() {
   char *x = "123";
   char *y = "12345";
-  if (strcmp(x, y) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
 }
 
 void strcmp_embedded_null () {
-       if (strcmp("\0z", "\0y") != 0)
-               (void)*(char*)0; // no-warning
+       clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}}
 }
 
 void strcmp_unknown_arg (char *unknown) {
-       if (strcmp(unknown, unknown) != 0)
-               (void)*(char*)0; // no-warning
+       clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}}
 }
 
 //===----------------------------------------------------------------------===
@@ -841,41 +775,35 @@ void strcmp_unknown_arg (char *unknown) {
 int strncmp(const char *s1, const char *s2, size_t n);
 
 void strncmp_constant0() {
-  if (strncmp("123", "123", 3) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}}
 }
 
 void strncmp_constant_and_var_0() {
   char *x = "123";
-  if (strncmp(x, "123", 3) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}}
 }
 
 void strncmp_constant_and_var_1() {
   char *x = "123";
-  if (strncmp("123", x, 3) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}}
 }
 
 void strncmp_0() {
   char *x = "123";
   char *y = "123";
-  if (strncmp(x, y, 3) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
 }
 
 void strncmp_1() {
   char *x = "234";
   char *y = "123";
-  if (strncmp(x, y, 3) != 1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
 }
 
 void strncmp_2() {
   char *x = "123";
   char *y = "234";
-  if (strncmp(x, y, 3) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
 }
 
 void strncmp_null_0() {
@@ -893,55 +821,47 @@ void strncmp_null_1() {
 void strncmp_diff_length_0() {
   char *x = "12345";
   char *y = "234";
-  if (strncmp(x, y, 5) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
 }
 
 void strncmp_diff_length_1() {
   char *x = "123";
   char *y = "23456";
-  if (strncmp(x, y, 5) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
 }
 
 void strncmp_diff_length_2() {
   char *x = "12345";
   char *y = "123";
-  if (strncmp(x, y, 5) != 1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp(x, y, 5) == 1); // expected-warning{{TRUE}}
 }
 
 void strncmp_diff_length_3() {
   char *x = "123";
   char *y = "12345";
-  if (strncmp(x, y, 5) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
 }
 
 void strncmp_diff_length_4() {
   char *x = "123";
   char *y = "12345";
-  if (strncmp(x, y, 3) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
 }
 
 void strncmp_diff_length_5() {
   char *x = "012";
   char *y = "12345";
-  if (strncmp(x, y, 3) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
 }
 
 void strncmp_diff_length_6() {
   char *x = "234";
   char *y = "12345";
-  if (strncmp(x, y, 3) != 1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
 }
 
 void strncmp_embedded_null () {
-       if (strncmp("ab\0zz", "ab\0yy", 4) != 0)
-               (void)*(char*)0; // no-warning
+       clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
 }
 
 //===----------------------------------------------------------------------===
@@ -952,41 +872,35 @@ void strncmp_embedded_null () {
 int strcasecmp(const char *s1, const char *s2);
 
 void strcasecmp_constant0() {
-  if (strcasecmp("abc", "Abc") != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}}
 }
 
 void strcasecmp_constant_and_var_0() {
   char *x = "abc";
-  if (strcasecmp(x, "Abc") != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}}
 }
 
 void strcasecmp_constant_and_var_1() {
   char *x = "abc";
-    if (strcasecmp("Abc", x) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}}
 }
 
 void strcasecmp_0() {
   char *x = "abc";
   char *y = "Abc";
-  if (strcasecmp(x, y) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}}
 }
 
 void strcasecmp_1() {
   char *x = "Bcd";
   char *y = "abc";
-  if (strcasecmp(x, y) != 1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
 }
 
 void strcasecmp_2() {
   char *x = "abc";
   char *y = "Bcd";
-  if (strcasecmp(x, y) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
 }
 
 void strcasecmp_null_0() {
@@ -1004,34 +918,29 @@ void strcasecmp_null_1() {
 void strcasecmp_diff_length_0() {
   char *x = "abcde";
   char *y = "aBd";
-  if (strcasecmp(x, y) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
 }
 
 void strcasecmp_diff_length_1() {
   char *x = "abc";
   char *y = "aBdef";
-  if (strcasecmp(x, y) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
 }
 
 void strcasecmp_diff_length_2() {
   char *x = "aBcDe";
   char *y = "abc";
-  if (strcasecmp(x, y) != 1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
 }
 
 void strcasecmp_diff_length_3() {
   char *x = "aBc";
   char *y = "abcde";
-  if (strcasecmp(x, y) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
 }
 
 void strcasecmp_embedded_null () {
-       if (strcasecmp("ab\0zz", "ab\0yy") != 0)
-               (void)*(char*)0; // no-warning
+       clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}}
 }
 
 //===----------------------------------------------------------------------===
@@ -1042,41 +951,35 @@ void strcasecmp_embedded_null () {
 int strncasecmp(const char *s1, const char *s2, size_t n);
 
 void strncasecmp_constant0() {
-  if (strncasecmp("abc", "Abc", 3) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_constant_and_var_0() {
   char *x = "abc";
-  if (strncasecmp(x, "Abc", 3) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_constant_and_var_1() {
   char *x = "abc";
-  if (strncasecmp("Abc", x, 3) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_0() {
   char *x = "abc";
   char *y = "Abc";
-  if (strncasecmp(x, y, 3) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_1() {
   char *x = "Bcd";
   char *y = "abc";
-  if (strncasecmp(x, y, 3) != 1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_2() {
   char *x = "abc";
   char *y = "Bcd";
-  if (strncasecmp(x, y, 3) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_null_0() {
@@ -1094,55 +997,47 @@ void strncasecmp_null_1() {
 void strncasecmp_diff_length_0() {
   char *x = "abcde";
   char *y = "aBd";
-  if (strncasecmp(x, y, 5) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_diff_length_1() {
   char *x = "abc";
   char *y = "aBdef";
-  if (strncasecmp(x, y, 5) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_diff_length_2() {
   char *x = "aBcDe";
   char *y = "abc";
-  if (strncasecmp(x, y, 5) != 1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp(x, y, 5) == 1); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_diff_length_3() {
   char *x = "aBc";
   char *y = "abcde";
-  if (strncasecmp(x, y, 5) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_diff_length_4() {
   char *x = "abcde";
   char *y = "aBc";
-  if (strncasecmp(x, y, 3) != 0)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_diff_length_5() {
   char *x = "abcde";
   char *y = "aBd";
-  if (strncasecmp(x, y, 3) != -1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_diff_length_6() {
   char *x = "aBDe";
   char *y = "abc";
-  if (strncasecmp(x, y, 3) != 1)
-    (void)*(char*)0; // no-warning
+  clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
 }
 
 void strncasecmp_embedded_null () {
-       if (strncasecmp("ab\0zz", "ab\0yy", 4) != 0)
-               (void)*(char*)0; // no-warning
+       clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
 }
 
 //===----------------------------------------------------------------------===
@@ -1169,10 +1064,10 @@ void PR12206(const char *x) {
   if (strlen(x) != value) return;
 
   // Test relational operators.
-  if (strlen(x) < 2) { (void)*(char*)0; } // no-warning
-  if (2 > strlen(x)) { (void)*(char*)0; } // no-warning
+  clang_analyzer_eval(strlen(x) >= 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(2 <= strlen(x)); // expected-warning{{TRUE}}
 
   // Test equality operators.
-  if (strlen(x) == 1) { (void)*(char*)0; } // no-warning
-  if (1 == strlen(x)) { (void)*(char*)0; } // no-warning
+  clang_analyzer_eval(strlen(x) != 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(1 != strlen(x)); // expected-warning{{TRUE}}
 }