Fix PR 4631. The compound initializers of unions were not being evaluated, which
authorTed Kremenek <kremenek@apple.com>
Tue, 28 Jul 2009 20:46:55 +0000 (20:46 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 28 Jul 2009 20:46:55 +0000 (20:46 +0000)
could cause false positives if any the subexpressions had side-effects. These
initializers weren't evaluated because the StoreManager would need to handle
them, but that's an orthogonal problem of whether or not the StoreManager can
handle the binding.

llvm-svn: 77361

clang/lib/Analysis/GRExprEngine.cpp
clang/test/Analysis/uninit-vals-ps.c

index eb31f84..ee8865b 100644 (file)
@@ -2228,7 +2228,8 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred,
   QualType T = getContext().getCanonicalType(E->getType());
   unsigned NumInitElements = E->getNumInits();  
 
-  if (T->isArrayType() || T->isStructureType()) {
+  if (T->isArrayType() || T->isStructureType() ||
+      T->isUnionType() || T->isVectorType()) {
 
     llvm::ImmutableList<SVal> StartVals = getBasicVals().getEmptySValList();
     
@@ -2283,13 +2284,6 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred,
     return;
   }
 
-  if (T->isUnionType() || T->isVectorType()) {
-    // FIXME: to be implemented.
-    // Note: That vectors can return true for T->isIntegerType()
-    MakeNode(Dst, E, Pred, state);
-    return;
-  }
-  
   if (Loc::IsLocType(T) || T->isIntegerType()) {
     assert (E->getNumInits() == 1);
     NodeSet Tmp;
index 4482b13..5f402ee 100644 (file)
@@ -102,3 +102,25 @@ int pr_4630(char *a, int y) {
   }
 }
 
+// PR 4631 - False positive with union initializer
+//  Previously the analyzer didn't examine the compound initializers of unions,
+//  resulting in some false positives for initializers with side-effects.
+union u_4631 { int a; };
+struct s_4631 { int a; };
+int pr4631_f2(int *p);
+int pr4631_f3(void *q);
+int pr4631_f1(void)
+{
+  int x;
+  union u_4631 m = { pr4631_f2(&x) };
+  pr4631_f3(&m); // tell analyzer that we use m
+  return x;  // no-warning
+}
+int pr4631_f1_b(void)
+{
+  int x;
+  struct s_4631 m = { pr4631_f2(&x) };
+  pr4631_f3(&m); // tell analyzer that we use m
+  return x;  // no-warning
+}
+