]> granicus.if.org Git - clang/commitdiff
Enhance SimpleSValuator::EvalBinOpNN to recognize the trivial case
authorTed Kremenek <kremenek@apple.com>
Mon, 13 Jul 2009 21:55:12 +0000 (21:55 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 13 Jul 2009 21:55:12 +0000 (21:55 +0000)
where we are comparing a symbolic value against itself, regardless of
the nature of that symbolic value.

This enhancement identified a case where RegionStoreManager is not
correctly symbolicating the values of the pointees of parameters.  The
failing test is now in 'test/Analysis/misc-ps-region-store.m', with
that test file now (temporarily) marked XFAIL.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75521 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/SimpleSValuator.cpp
test/Analysis/misc-ps-basic-store.m
test/Analysis/misc-ps-region-store.m
test/Analysis/misc-ps.m

index 76a8bc782eb57e65c0837cfa426417bb7e0ff519..eea50d13cf10230a604ba27dd3fa4e0ab990b928 100644 (file)
@@ -176,7 +176,26 @@ static SVal EvalEquality(ValueManager &ValMgr, Loc lhs, Loc rhs, bool isEqual,
 
 SVal SimpleSValuator::EvalBinOpNN(BinaryOperator::Opcode op,
                                   NonLoc lhs, NonLoc rhs,
-                                  QualType resultTy)  {  
+                                  QualType resultTy)  {
+
+  assert(!lhs.isUnknownOrUndef());
+  assert(!rhs.isUnknownOrUndef());
+
+  // Handle trivial case where left-side and right-side are the same.
+  if (lhs == rhs)
+    switch (op) {
+      default:
+        break;
+      case BinaryOperator::EQ:
+      case BinaryOperator::LE:
+      case BinaryOperator::GE:
+        return ValMgr.makeTruthVal(true, resultTy);
+      case BinaryOperator::LT:
+      case BinaryOperator::GT:
+      case BinaryOperator::NE:
+        return ValMgr.makeTruthVal(false, resultTy);
+    }
+  
   while (1) {
     switch (lhs.getSubKind()) {
     default:
index 55e39cf92cb83291eab21848edf81fdeda151315..8e089d500002c1a1c04a16b741db5993700571e7 100644 (file)
@@ -20,3 +20,17 @@ void checkaccess_union() {
       ).__i))) & 0xff00) >> 8) == 1)
         ret = 1;
 }
+
+// BasicStore handles this case incorrectly because it doesn't reason about
+// the value pointed to by 'x' and thus creates different symbolic values
+// at the declarations of 'a' and 'b' respectively.  See the companion test
+// in 'misc-ps-region-store.m'.
+void test_trivial_symbolic_comparison_pointer_parameter(int *x) {
+  int a = *x;
+  int b = *x;
+  if (a != b) {
+    int *p = 0;
+    *p = 0xDEADBEEF;     // expected-warning{{null}}
+  }
+}
+
index 8c8815ea63eb2ea2896a41b8c20fc90beb23627c..7231353b6b945f9d309480dea04f7740f158e054 100644 (file)
@@ -1,4 +1,5 @@
 // RUN: clang-cc -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s
+// XFAIL
 
 typedef struct objc_selector *SEL;
 typedef signed char BOOL;
@@ -68,3 +69,17 @@ char test2() {
   return 'a';
 }
 
+// *** THIS TEST IS CURRENTLY FAILING ***
+// BasicStore handles this case incorrectly because it doesn't reason about
+// the value pointed to by 'x' and thus creates different symbolic values
+// at the declarations of 'a' and 'b' respectively.  RegionStore handles
+// it correctly. See the companion test in 'misc-ps-basic-store.m'.
+void test_trivial_symbolic_comparison_pointer_parameter(int *x) {
+  int a = *x;
+  int b = *x;
+  if (a != b) {
+    int *p = 0;
+    *p = 0xDEADBEEF;     // no-warning
+  }
+}
+
index 46e8d3703f9eaf61a9da70c319842d9d557fe9b4..93bb1f347c3fe0abb7e3ec491d2bc004eea8f4b9 100644 (file)
@@ -371,3 +371,20 @@ void testB(BStruct *b) {
   }
 }
 
+void test_trivial_symbolic_comparison(int *x) {
+  int test_trivial_symbolic_comparison_aux();
+  int a = test_trivial_symbolic_comparison_aux();
+  int b = a;
+  if (a != b) {
+    int *p = 0;
+    *p = 0xDEADBEEF;     // no-warning
+  }
+  
+  a = a == 1;
+  b = b == 1;
+  if (a != b) {
+    int *p = 0;
+    *p = 0xDEADBEEF;     // no-warning
+  }
+}
+