]> granicus.if.org Git - clang/commitdiff
Fix assertion failure in -Wuninitialized involving no-op casts. Fixes PR 10577.
authorTed Kremenek <kremenek@apple.com>
Thu, 4 Aug 2011 22:40:57 +0000 (22:40 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 4 Aug 2011 22:40:57 +0000 (22:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136939 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 7df2dc27b826690e708618a2daa41dbd364f8cba..009922ae92c4a22a8fcb4e0c44d1640ead9c4261 100644 (file)
@@ -352,13 +352,19 @@ class TransferFunctions : public StmtVisitor<TransferFunctions> {
   /// possible to either silence the warning in some cases, or we
   /// propagate the uninitialized value.
   CastExpr *lastLoad;
+  
+  /// For some expressions, we want to ignore any post-processing after
+  /// visitation.
+  bool skipProcessUses;
+  
 public:
   TransferFunctions(CFGBlockValues &vals, const CFG &cfg,
                     AnalysisContext &ac,
                     UninitVariablesHandler *handler,
                     bool flagBlockUses)
     : vals(vals), cfg(cfg), ac(ac), handler(handler),
-      flagBlockUses(flagBlockUses), lastDR(0), lastLoad(0) {}
+      flagBlockUses(flagBlockUses), lastDR(0), lastLoad(0),
+      skipProcessUses(false) {}
   
   const CFG &getCFG() { return cfg; }
   void reportUninit(const DeclRefExpr *ex, const VarDecl *vd,
@@ -464,8 +470,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()->IgnoreParens());
+            DeclRefExpr *DR
+              = cast<DeclRefExpr>(lastLoad->
+                  getSubExpr()->IgnoreParenNoopCasts(ac.getASTContext()));
             if (DR->getDecl() == vd) {
               // int x = x;
               // Propagate uninitialized value, but don't immediately report
@@ -537,6 +544,9 @@ void TransferFunctions::VisitCastExpr(clang::CastExpr *ce) {
       }
     }
   }
+  else if (ce->getCastKind() == CK_NoOp) {
+    skipProcessUses = true;
+  }
   else if (CStyleCastExpr *cse = dyn_cast<CStyleCastExpr>(ce)) {
     if (cse->getType()->isVoidType()) {
       // e.g. (void) x;
@@ -551,8 +561,10 @@ void TransferFunctions::VisitCastExpr(clang::CastExpr *ce) {
 }
 
 void TransferFunctions::Visit(clang::Stmt *s) {
+  skipProcessUses = false;
   StmtVisitor<TransferFunctions>::Visit(s);
-  ProcessUses(s);
+  if (!skipProcessUses)
+    ProcessUses(s);
 }
 
 void TransferFunctions::ProcessUses(Stmt *s) {
@@ -568,7 +580,9 @@ 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()->IgnoreParens());
+    DeclRefExpr *DR =
+      cast<DeclRefExpr>(lastLoad->getSubExpr()->
+                          IgnoreParenNoopCasts(ac.getASTContext()));
     VarDecl *VD = cast<VarDecl>(DR->getDecl());
     reportUninit(DR, VD, isAlwaysUninit(vals[VD]));
     lastLoad = 0;
index a850a2f92f1512a6a92867ed3c8a0b800c7fd198..6c5d0068a438987de9ac9ebd3109bcfa265896e3 100644 (file)
@@ -118,4 +118,15 @@ void RDar9251392() {
   }
 }
 
+// Test handling of "no-op" casts.
+void test_noop_cast()
+{
+    int x = 1;
+    int y = (int&)x; // no-warning
+}
+
+void test_noop_cast2() {
+    int x; // expected-note {{declared here}} expected-note {{add initialization}}
+    int y = (int&)x; // expected-warning {{uninitialized when used here}}
+}