]> granicus.if.org Git - clang/commitdiff
Fix another -Wuninitialized assertion failure (this one involving bit casts) resultin...
authorTed Kremenek <kremenek@apple.com>
Mon, 8 Aug 2011 21:43:08 +0000 (21:43 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 8 Aug 2011 21:43:08 +0000 (21:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137068 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/UninitializedValues.cpp
test/SemaCXX/uninit-variables.cpp

index 009922ae92c4a22a8fcb4e0c44d1640ead9c4261..8bc9506c850c4148cad4335f58421fd4c5ec5648 100644 (file)
@@ -389,6 +389,20 @@ public:
 };
 }
 
+static const Expr *stripCasts(ASTContext &C, const Expr *Ex) {
+  while (Ex) {
+    Ex = Ex->IgnoreParenNoopCasts(C);
+    if (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
+      if (CE->getCastKind() == CK_LValueBitCast) {
+        Ex = CE->getSubExpr();
+        continue;
+      }
+    }
+    break;
+  }
+  return Ex;
+}
+
 void TransferFunctions::reportUninit(const DeclRefExpr *ex,
                                      const VarDecl *vd, bool isAlwaysUnit) {
   if (handler) handler->handleUseOfUninitVariable(ex, vd, isAlwaysUnit);
@@ -470,9 +484,9 @@ void TransferFunctions::VisitDeclStmt(DeclStmt *ds) {
           // appropriately, but we need to continue to analyze subsequent uses
           // of the variable.
           if (init == lastLoad) {
-            DeclRefExpr *DR
-              = cast<DeclRefExpr>(lastLoad->
-                  getSubExpr()->IgnoreParenNoopCasts(ac.getASTContext()));
+            const DeclRefExpr *DR
+              = cast<DeclRefExpr>(stripCasts(ac.getASTContext(),
+                                             lastLoad->getSubExpr()));
             if (DR->getDecl() == vd) {
               // int x = x;
               // Propagate uninitialized value, but don't immediately report
@@ -544,7 +558,8 @@ void TransferFunctions::VisitCastExpr(clang::CastExpr *ce) {
       }
     }
   }
-  else if (ce->getCastKind() == CK_NoOp) {
+  else if (ce->getCastKind() == CK_NoOp ||
+           ce->getCastKind() == CK_LValueBitCast) {
     skipProcessUses = true;
   }
   else if (CStyleCastExpr *cse = dyn_cast<CStyleCastExpr>(ce)) {
@@ -580,10 +595,10 @@ void TransferFunctions::ProcessUses(Stmt *s) {
     // If we reach here, we have seen a load of an uninitialized value
     // and it hasn't been casted to void or otherwise handled.  In this
     // situation, report the incident.
-    DeclRefExpr *DR =
-      cast<DeclRefExpr>(lastLoad->getSubExpr()->
-                          IgnoreParenNoopCasts(ac.getASTContext()));
-    VarDecl *VD = cast<VarDecl>(DR->getDecl());
+    const DeclRefExpr *DR =
+      cast<DeclRefExpr>(stripCasts(ac.getASTContext(),
+                                   lastLoad->getSubExpr()));
+    const VarDecl *VD = cast<VarDecl>(DR->getDecl());
     reportUninit(DR, VD, isAlwaysUninit(vals[VD]));
     lastLoad = 0;
     
index 6c5d0068a438987de9ac9ebd3109bcfa265896e3..9abccf07510cb65764240fbfd0ac677b3c68239e 100644 (file)
@@ -130,3 +130,14 @@ void test_noop_cast2() {
     int y = (int&)x; // expected-warning {{uninitialized when used here}}
 }
 
+// Test handling of bit casts.
+void test_bitcasts() {
+  int x = 1;
+  int y = (float &)x; // no-warning
+}
+
+void test_bitcasts_2() {
+  int x;  // expected-note {{declared here}} expected-note {{add initialization}}
+  int y = (float &)x; // expected-warning {{uninitialized when used here}}
+}
+