]> granicus.if.org Git - clang/commitdiff
Introduce initial transfer function support for __imag__ and __real__. We don't
authorTed Kremenek <kremenek@apple.com>
Thu, 19 Jun 2008 17:55:38 +0000 (17:55 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 19 Jun 2008 17:55:38 +0000 (17:55 +0000)
have complex RValues yet, so this logic is only fully implemented when __imag__
and __real__ are used on non-complex types.

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

lib/Analysis/GRExprEngine.cpp
test/Analysis/complex.c [new file with mode: 0644]

index 2580172d530803750b9bdec1974f8c9c96c63bfb..e8c1ec57a986f373acd8dec3b7f2223a32b094b5 100644 (file)
@@ -1596,7 +1596,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
       
     default:
       break;
-      
+          
     case UnaryOperator::Deref: {
       
       Expr* Ex = U->getSubExpr()->IgnoreParens();
@@ -1616,10 +1616,57 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
 
       return;
     }
-
       
+    case UnaryOperator::Real: {
+      
+      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      NodeSet Tmp;
+      Visit(Ex, Pred, Tmp);
+      
+      for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+        
+        // FIXME: We don't have complex RValues yet.
+        if (Ex->getType()->isAnyComplexType()) {
+          // Just report "Unknown."
+          Dst.Add(*I);
+          continue;
+        }
+        
+        // For all other types, UnaryOperator::Real is an identity operation.
+        assert (U->getType() == Ex->getType());
+        ValueState* St = GetState(*I);
+        MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex)));
+      } 
+      
+      return;
+    }
+      
+    case UnaryOperator::Imag: {
+      
+      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      NodeSet Tmp;
+      Visit(Ex, Pred, Tmp);
+      
+      for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+        // FIXME: We don't have complex RValues yet.
+        if (Ex->getType()->isAnyComplexType()) {
+          // Just report "Unknown."
+          Dst.Add(*I);
+          continue;
+        }
+        
+        // For all other types, UnaryOperator::Float returns 0.
+        assert (Ex->getType()->isIntegerType());
+        ValueState* St = GetState(*I);
+        RVal X = NonLVal::MakeVal(BasicVals, 0, Ex->getType());
+        MakeNode(Dst, U, *I, SetRVal(St, U, X));
+      }
+      
+      return;
+    }
+      
+      // FIXME: Just report "Unknown" for OffsetOf.      
     case UnaryOperator::OffsetOf:
-      // FIXME: Just report "Unknown" known for OffsetOf.
       Dst.Add(Pred);
       return;
       
diff --git a/test/Analysis/complex.c b/test/Analysis/complex.c
new file mode 100644 (file)
index 0000000..7561293
--- /dev/null
@@ -0,0 +1,17 @@
+// RUN: clang -checker-simple -verify %s
+
+#include <stdlib.h>
+
+int f1(int * p) {
+  
+  // This branch should be infeasible
+  // because __imag__ p is 0.
+  if (!p && __imag__ (intptr_t) p)
+    *p = 1; // no-warning
+
+  // If p != 0 then this branch is feasible; otherwise it is not.
+  if (__real__ (intptr_t) p)
+    *p = 1; // no-warning
+    
+  *p = 2; // expected-warning{{Dereference of null pointer}}
+}