]> granicus.if.org Git - clang/commitdiff
Fix PR 9626 (duplicated self-init warnings under -Wuninitialized) with numerous CFG...
authorTed Kremenek <kremenek@apple.com>
Mon, 4 Apr 2011 23:29:12 +0000 (23:29 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 4 Apr 2011 23:29:12 +0000 (23:29 +0000)
1) Change the CFG to include the DeclStmt for conditional variables, instead of using the condition itself as a faux DeclStmt.
2) Update ExprEngine (the static analyzer) to understand (1), so not to regress.
3) Update UninitializedValues.cpp to initialize all tracked variables to Uninitialized at the start of the function/method.
4) Only use the SelfReferenceChecker (SemaDecl.cpp) on global variables, leaving the dataflow analysis to handle other cases.

The combination of (1) and (3) allows the dataflow-based -Wuninitialized to find self-init problems when the initializer
contained control-flow.

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

include/clang/AST/Stmt.h
include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
lib/Analysis/CFG.cpp
lib/Analysis/UninitializedValues.cpp
lib/Sema/AnalysisBasedWarnings.cpp
lib/Sema/SemaDecl.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp
test/Analysis/auto-obj-dtors-cfg-output.cpp
test/Sema/uninit-variables.c
test/SemaCXX/uninitialized.cpp

index 6428594c8e8c75413486d9925647dca2e617a255..97dbce045f9a73ed6a1eccc92ab4e397d50276b8 100644 (file)
@@ -691,6 +691,12 @@ public:
   VarDecl *getConditionVariable() const;
   void setConditionVariable(ASTContext &C, VarDecl *V);
   
+  /// If this IfStmt has a condition variable, return the faux DeclStmt
+  /// associated with the creation of that condition variable.
+  const DeclStmt *getConditionVariableDeclStmt() const {
+    return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+  }
+  
   const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
   void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
   const Stmt *getThen() const { return SubExprs[THEN]; }
@@ -757,6 +763,12 @@ public:
   /// \endcode
   VarDecl *getConditionVariable() const;
   void setConditionVariable(ASTContext &C, VarDecl *V);
+  
+  /// If this SwitchStmt has a condition variable, return the faux DeclStmt
+  /// associated with the creation of that condition variable.
+  const DeclStmt *getConditionVariableDeclStmt() const {
+    return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+  }
 
   const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
   const Stmt *getBody() const { return SubExprs[BODY]; }
@@ -838,6 +850,12 @@ public:
   VarDecl *getConditionVariable() const;
   void setConditionVariable(ASTContext &C, VarDecl *V);
 
+  /// If this WhileStmt has a condition variable, return the faux DeclStmt
+  /// associated with the creation of that condition variable.
+  const DeclStmt *getConditionVariableDeclStmt() const {
+    return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+  }
+
   Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
   const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
   void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
@@ -942,6 +960,12 @@ public:
   VarDecl *getConditionVariable() const;
   void setConditionVariable(ASTContext &C, VarDecl *V);
   
+  /// If this ForStmt has a condition variable, return the faux DeclStmt
+  /// associated with the creation of that condition variable.
+  const DeclStmt *getConditionVariableDeclStmt() const {
+    return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
+  }
+
   Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
   Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
   Stmt *getBody() { return SubExprs[BODY]; }
index ab8e4bcdde6be7345a50de5f9aa2f8d29a0f5fbf..8cd743f68f567d64ee3cf5c8938a6535a49e6607 100644 (file)
@@ -284,11 +284,6 @@ public:
   /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
   void VisitGuardedExpr(const Expr* Ex, const Expr* L, const Expr* R, 
                         ExplodedNode* Pred, ExplodedNodeSet& Dst);
-
-  /// VisitCondInit - Transfer function for handling the initialization
-  ///  of a condition variable in an IfStmt, SwitchStmt, etc.
-  void VisitCondInit(const VarDecl *VD, const Stmt *S, ExplodedNode *Pred,
-                     ExplodedNodeSet& Dst);
   
   void VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred,
                          ExplodedNodeSet& Dst);
index e91de0366c605ff89c5ba653004ab4e654d1f5c2..b5930cdccf4744fc23677b3dc7383797d0e7721b 100644 (file)
@@ -393,11 +393,11 @@ private:
   void addLocalScopeAndDtors(Stmt* S);
 
   // Interface to CFGBlock - adding CFGElements.
-  void appendStmt(CFGBlock *B, Stmt *S) {
+  void appendStmt(CFGBlock *B, const Stmt *S) {
     if (alwaysAdd(S))
       cachedEntry->second = B;
 
-    B->appendStmt(S, cfg->getBumpVectorContext());
+    B->appendStmt(const_cast<Stmt*>(S), cfg->getBumpVectorContext());
   }
   void appendInitializer(CFGBlock *B, CXXCtorInitializer *I) {
     B->appendInitializer(I, cfg->getBumpVectorContext());
@@ -1495,7 +1495,7 @@ CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) {
   if (VarDecl *VD = I->getConditionVariable()) {
     if (Expr *Init = VD->getInit()) {
       autoCreateBlock();
-      appendStmt(Block, I);
+      appendStmt(Block, I->getConditionVariableDeclStmt());
       addStmt(Init);
     }
   }
@@ -1633,7 +1633,7 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
     if (VarDecl *VD = F->getConditionVariable()) {
       if (Expr *Init = VD->getInit()) {
         autoCreateBlock();
-        appendStmt(Block, F);
+        appendStmt(Block, F->getConditionVariableDeclStmt());
         EntryConditionBlock = addStmt(Init);
         assert(Block == EntryConditionBlock);
       }
@@ -1917,7 +1917,7 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
     if (VarDecl *VD = W->getConditionVariable()) {
       if (Expr *Init = VD->getInit()) {
         autoCreateBlock();
-        appendStmt(Block, W);
+        appendStmt(Block, W->getConditionVariableDeclStmt());        
         EntryConditionBlock = addStmt(Init);
         assert(Block == EntryConditionBlock);
       }
@@ -2279,7 +2279,7 @@ CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* Terminator) {
   if (VarDecl *VD = Terminator->getConditionVariable()) {
     if (Expr *Init = VD->getInit()) {
       autoCreateBlock();
-      appendStmt(Block, Terminator);
+      appendStmt(Block, Terminator->getConditionVariableDeclStmt());
       addStmt(Init);
     }
   }
index f775cc5b500208b54df4d87323d0d9d70173c674..3dde41f2272ee5bac3a5939737ac2d57f2da7fc0 100644 (file)
@@ -138,6 +138,8 @@ public:
   CFGBlockValues(const CFG &cfg);
   ~CFGBlockValues();
   
+  unsigned getNumEntries() const { return declToIndex.size(); }
+  
   void computeSetOfDeclarations(const DeclContext &dc);  
   ValueVector &getValueVector(const CFGBlock *block,
                                 const CFGBlock *dstBlock);
@@ -470,7 +472,6 @@ void TransferFunctions::VisitDeclStmt(DeclStmt *ds) {
        DI != DE; ++DI) {
     if (VarDecl *vd = dyn_cast<VarDecl>(*DI)) {
       if (isTrackedVar(vd)) {
-        vals[vd] = Uninitialized;
         if (Stmt *init = vd->getInit()) {
           Visit(init);
           vals[vd] = Initialized;
@@ -669,9 +670,23 @@ void clang::runUninitializedVariablesAnalysis(const DeclContext &dc,
   vals.computeSetOfDeclarations(dc);
   if (vals.hasNoDeclarations())
     return;
+
+  // Mark all variables uninitialized at the entry.
+  const CFGBlock &entry = cfg.getEntry();
+  for (CFGBlock::const_succ_iterator i = entry.succ_begin(), 
+        e = entry.succ_end(); i != e; ++i) {
+    if (const CFGBlock *succ = *i) {
+      ValueVector &vec = vals.getValueVector(&entry, succ);
+      const unsigned n = vals.getNumEntries();
+      for (unsigned j = 0; j < n ; ++j) {
+        vec[j] = Uninitialized;
+      }
+    }
+  }
+
+  // Proceed with the workist.
   DataflowWorklist worklist(cfg);
   llvm::BitVector previouslyVisited(cfg.getNumBlockIDs());
-  
   worklist.enqueueSuccessors(&cfg.getEntry());
   llvm::BitVector wasAnalyzed(cfg.getNumBlockIDs(), false);
 
index 3467dae4ba67424dd14a921d626813f322b238ce..ecfa82135847fec390cab7d8c63151ac355caaf2 100644 (file)
@@ -470,14 +470,25 @@ public:
       for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi)
       {
         const bool isAlwaysUninit = vi->second;
+        bool showDefinition = true;
+
         if (const DeclRefExpr *dr = dyn_cast<DeclRefExpr>(vi->first)) {
-          S.Diag(dr->getLocStart(),
-                 isAlwaysUninit ?
-                  (isSelfInit(S.Context, vd, dr) 
-                    ? diag::warn_uninit_self_reference_in_init
-                    : diag::warn_uninit_var)
-                  : diag::warn_maybe_uninit_var)
-            << vd->getDeclName() << dr->getSourceRange();          
+          if (isAlwaysUninit) {
+            if (isSelfInit(S.Context, vd, dr)) {
+              S.Diag(dr->getLocStart(), 
+                     diag::warn_uninit_self_reference_in_init)
+              << vd->getDeclName() << vd->getLocation() << dr->getSourceRange();             
+              showDefinition = false;
+            }
+            else {
+              S.Diag(dr->getLocStart(), diag::warn_uninit_var)
+                << vd->getDeclName() << dr->getSourceRange();          
+            }
+          }
+          else {
+            S.Diag(dr->getLocStart(), diag::warn_maybe_uninit_var)
+              << vd->getDeclName() << dr->getSourceRange();          
+          }          
         }
         else {
           const BlockExpr *be = cast<BlockExpr>(vi->first);
@@ -488,8 +499,9 @@ public:
         }
         
         // Report where the variable was declared.
-        S.Diag(vd->getLocStart(), diag::note_uninit_var_def)
-          << vd->getDeclName();
+        if (showDefinition)
+          S.Diag(vd->getLocStart(), diag::note_uninit_var_def)
+            << vd->getDeclName();
 
         // Only report the fixit once.
         if (fixitIssued)
index e52082bbbfc13c7551a3227980ee6e2a5d49fbc3..8bf6c84c0b3dd3eabed766a4ec70ae99dc11a742 100644 (file)
@@ -4715,7 +4715,16 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
   if (RealDecl == 0 || RealDecl->isInvalidDecl())
     return;
 
-  SelfReferenceChecker(*this, RealDecl).VisitExpr(Init);
+  // Check for self-references within variable initializers.
+  if (VarDecl *vd = dyn_cast<VarDecl>(RealDecl)) {
+    // Variables declared within a function/method body are handled
+    // by a dataflow analysis.
+    if (!vd->hasLocalStorage() && !vd->isStaticLocal())
+      SelfReferenceChecker(*this, RealDecl).VisitExpr(Init);    
+  }
+  else {
+    SelfReferenceChecker(*this, RealDecl).VisitExpr(Init);
+  }
 
   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) {
     // With declarators parsed the way they are, the parser cannot
index 3826a122260aa89fa9fc55ee5ffd8c264a24fd83..a422428b1bfd05f63af36b8a8901b47810cb9112 100644 (file)
@@ -459,11 +459,15 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
     case Stmt::ContinueStmtClass:
     case Stmt::DefaultStmtClass:
     case Stmt::DoStmtClass:
+    case Stmt::ForStmtClass:
     case Stmt::GotoStmtClass:
+    case Stmt::IfStmtClass:
     case Stmt::IndirectGotoStmtClass:
     case Stmt::LabelStmtClass:
     case Stmt::NoStmtClass:
     case Stmt::NullStmtClass:
+    case Stmt::SwitchStmtClass:
+    case Stmt::WhileStmtClass:
       llvm_unreachable("Stmt should not be in analyzer evaluation loop");
       break;
 
@@ -620,12 +624,6 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
       VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
       break;
 
-    case Stmt::ForStmtClass:
-      // This case isn't for branch processing, but for handling the
-      // initialization of a condition variable.
-      VisitCondInit(cast<ForStmt>(S)->getConditionVariable(), S, Pred, Dst);
-      break;
-
     case Stmt::ImplicitCastExprClass:
     case Stmt::CStyleCastExprClass:
     case Stmt::CXXStaticCastExprClass:
@@ -638,12 +636,6 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
       break;
     }
 
-    case Stmt::IfStmtClass:
-      // This case isn't for branch processing, but for handling the
-      // initialization of a condition variable.
-      VisitCondInit(cast<IfStmt>(S)->getConditionVariable(), S, Pred, Dst);
-      break;
-
     case Stmt::InitListExprClass:
       VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
       break;
@@ -713,12 +705,6 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
       return;
     }
 
-    case Stmt::SwitchStmtClass:
-      // This case isn't for branch processing, but for handling the
-      // initialization of a condition variable.
-      VisitCondInit(cast<SwitchStmt>(S)->getConditionVariable(), S, Pred, Dst);
-      break;
-
     case Stmt::UnaryOperatorClass: {
       const UnaryOperator *U = cast<UnaryOperator>(S);
       if (AMgr.shouldEagerlyAssume()&&(U->getOpcode() == UO_LNot)) {
@@ -730,12 +716,6 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
         VisitUnaryOperator(U, Pred, Dst);
       break;
     }
-
-    case Stmt::WhileStmtClass:
-      // This case isn't for branch processing, but for handling the
-      // initialization of a condition variable.
-      VisitCondInit(cast<WhileStmt>(S)->getConditionVariable(), S, Pred, Dst);
-      break;
   }
 }
 
@@ -2308,33 +2288,6 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
   }
 }
 
-void ExprEngine::VisitCondInit(const VarDecl *VD, const Stmt *S,
-                                 ExplodedNode *Pred, ExplodedNodeSet& Dst) {
-
-  const Expr* InitEx = VD->getInit();
-  ExplodedNodeSet Tmp;
-  Visit(InitEx, Pred, Tmp);
-
-  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-    ExplodedNode *N = *I;
-    const GRState *state = GetState(N);
-
-    const LocationContext *LC = N->getLocationContext();
-    SVal InitVal = state->getSVal(InitEx);
-
-    // Recover some path-sensitivity if a scalar value evaluated to
-    // UnknownVal.
-    if (InitVal.isUnknown() ||
-        !getConstraintManager().canReasonAbout(InitVal)) {
-      InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx,
-                                            Builder->getCurrentBlockCount());
-    }
-
-    evalBind(Dst, S, N, state,
-             loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
-  }
-}
-
 namespace {
   // This class is used by VisitInitListExpr as an item in a worklist
   // for processing the values contained in an InitListExpr.
index 6dccf9f846e3eeccb1c75f023745dd948af664d7..c877061eb6aeeafdb08003b8389cd719da6003d6 100644 (file)
@@ -159,7 +159,7 @@ void test_catch_copy() {
 // CHECK:    Predecessors (0):
 // CHECK:    Successors (1): B1
 // CHECK: [ B1 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
 // CHECK:      3: const A &b = a;
 // CHECK:      4: A()
@@ -175,9 +175,9 @@ void test_catch_copy() {
 // CHECK:    Predecessors (0):
 // CHECK:    Successors (1): B1
 // CHECK: [ B1 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a[2];
-// CHECK:      3: 
+// CHECK:      3:
 // CHECK:      4: A b[0];
 // CHECK:      5: [B1.2].~A() (Implicit destructor)
 // CHECK:    Predecessors (1): B2
@@ -189,15 +189,15 @@ void test_catch_copy() {
 // CHECK:    Predecessors (0):
 // CHECK:    Successors (1): B1
 // CHECK: [ B1 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
-// CHECK:      3: 
+// CHECK:      3:
 // CHECK:      4: A c;
-// CHECK:      5: 
+// CHECK:      5:
 // CHECK:      6: A d;
 // CHECK:      7: [B1.6].~A() (Implicit destructor)
 // CHECK:      8: [B1.4].~A() (Implicit destructor)
-// CHECK:      9: 
+// CHECK:      9:
 // CHECK:     10: A b;
 // CHECK:     11: [B1.10].~A() (Implicit destructor)
 // CHECK:     12: [B1.2].~A() (Implicit destructor)
@@ -210,7 +210,7 @@ void test_catch_copy() {
 // CHECK:    Predecessors (0):
 // CHECK:    Successors (1): B3
 // CHECK: [ B1 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: [B1.2].~A() (Implicit destructor)
 // CHECK:      4: [B3.4].~A() (Implicit destructor)
@@ -224,9 +224,9 @@ void test_catch_copy() {
 // CHECK:    Predecessors (1): B3
 // CHECK:    Successors (1): B0
 // CHECK: [ B3 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
-// CHECK:      3: 
+// CHECK:      3:
 // CHECK:      4: A b;
 // CHECK:      5: UV
 // CHECK:      T: if [B3.5]
@@ -240,7 +240,7 @@ void test_catch_copy() {
 // CHECK:    Successors (1): B7
 // CHECK: [ B1 ]
 // CHECK:    l1:
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: [B1.2].~A() (Implicit destructor)
 // CHECK:      4: [B6.2].~A() (Implicit destructor)
@@ -248,7 +248,7 @@ void test_catch_copy() {
 // CHECK:    Predecessors (2): B2 B3
 // CHECK:    Successors (1): B0
 // CHECK: [ B2 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A b;
 // CHECK:      3: [B2.2].~A() (Implicit destructor)
 // CHECK:      4: [B6.4].~A() (Implicit destructor)
@@ -272,16 +272,16 @@ void test_catch_copy() {
 // CHECK:    Successors (1): B6
 // CHECK: [ B6 ]
 // CHECK:    l0:
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A b;
-// CHECK:      3: 
+// CHECK:      3:
 // CHECK:      4: A a;
 // CHECK:      5: UV
 // CHECK:      T: if [B6.5]
 // CHECK:    Predecessors (2): B7 B5
 // CHECK:    Successors (2): B5 B4
 // CHECK: [ B7 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
 // CHECK:    Predecessors (1): B8
 // CHECK:    Successors (1): B6
@@ -297,24 +297,23 @@ void test_catch_copy() {
 // CHECK:    Predecessors (2): B2 B3
 // CHECK:    Successors (1): B0
 // CHECK: [ B2 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: [B2.2].~A() (Implicit destructor)
 // CHECK:    Predecessors (1): B4
 // CHECK:    Successors (1): B1
 // CHECK: [ B3 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: [B3.2].~A() (Implicit destructor)
 // CHECK:    Predecessors (1): B4
 // CHECK:    Successors (1): B1
 // CHECK: [ B4 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
 // CHECK:      3: a
-// CHECK:      4: if ([B4.6])
-// CHECK:[B3.2]else
-// CHECK:[B2.2]      5: b.operator int()
+// CHECK:      4: A b = a;
+// CHECK:      5: b.operator int()
 // CHECK:      6: [B4.5]
 // CHECK:      T: if [B4.6]
 // CHECK:    Predecessors (1): B5
@@ -327,14 +326,14 @@ void test_catch_copy() {
 // CHECK:    Successors (1): B8
 // CHECK: [ B1 ]
 // CHECK:      1: [B8.4].~A() (Implicit destructor)
-// CHECK:      2: 
+// CHECK:      2:
 // CHECK:      3: A e;
 // CHECK:      4: [B1.3].~A() (Implicit destructor)
 // CHECK:      5: [B8.2].~A() (Implicit destructor)
 // CHECK:    Predecessors (2): B2 B5
 // CHECK:    Successors (1): B0
 // CHECK: [ B2 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A d;
 // CHECK:      3: [B2.2].~A() (Implicit destructor)
 // CHECK:      4: [B4.2].~A() (Implicit destructor)
@@ -348,14 +347,14 @@ void test_catch_copy() {
 // CHECK:    Predecessors (1): B4
 // CHECK:    Successors (1): B0
 // CHECK: [ B4 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: UV
 // CHECK:      T: if [B4.3]
 // CHECK:    Predecessors (1): B8
 // CHECK:    Successors (2): B3 B2
 // CHECK: [ B5 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A d;
 // CHECK:      3: [B5.2].~A() (Implicit destructor)
 // CHECK:      4: [B7.2].~A() (Implicit destructor)
@@ -369,21 +368,17 @@ void test_catch_copy() {
 // CHECK:    Predecessors (1): B7
 // CHECK:    Successors (1): B0
 // CHECK: [ B7 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: UV
 // CHECK:      T: if [B7.3]
 // CHECK:    Predecessors (1): B8
 // CHECK:    Successors (2): B6 B5
 // CHECK: [ B8 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
 // CHECK:      3: a
-// CHECK:      4: if ([B8.6]) {
-// CHECK:[B7.2]    if ([B7.3])
-// CHECK:[B6.1][B5.2]} else {
-// CHECK:[B4.2]    if ([B4.3])
-// CHECK:[B3.1][B2.2]}
+// CHECK:      4: A b = a;
 // CHECK:      5: b.operator int()
 // CHECK:      6: [B8.5]
 // CHECK:      T: if [B8.6]
@@ -402,8 +397,8 @@ void test_catch_copy() {
 // CHECK:    Successors (1): B0
 // CHECK: [ B2 ]
 // CHECK:      1: a
-// CHECK:      2: while ([B2.4])
-// CHECK:[B4.2]      3: b.operator int()
+// CHECK:      2: A b = a;
+// CHECK:      3: b.operator int()
 // CHECK:      4: [B2.3]
 // CHECK:      T: while [B2.4]
 // CHECK:    Predecessors (2): B3 B5
@@ -412,14 +407,14 @@ void test_catch_copy() {
 // CHECK:    Predecessors (1): B4
 // CHECK:    Successors (1): B2
 // CHECK: [ B4 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: [B4.2].~A() (Implicit destructor)
 // CHECK:      4: [B2.2].~A() (Implicit destructor)
 // CHECK:    Predecessors (1): B2
 // CHECK:    Successors (1): B3
 // CHECK: [ B5 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
 // CHECK:    Predecessors (1): B6
 // CHECK:    Successors (1): B2
@@ -431,7 +426,7 @@ void test_catch_copy() {
 // CHECK:    Successors (1): B11
 // CHECK: [ B1 ]
 // CHECK:      1: [B2.2].~A() (Implicit destructor)
-// CHECK:      2: 
+// CHECK:      2:
 // CHECK:      3: A e;
 // CHECK:      4: [B1.3].~A() (Implicit destructor)
 // CHECK:      5: [B11.2].~A() (Implicit destructor)
@@ -439,14 +434,7 @@ void test_catch_copy() {
 // CHECK:    Successors (1): B0
 // CHECK: [ B2 ]
 // CHECK:      1: a
-// CHECK:      2: while ([B2.4])
-// CHECK:    {
-// CHECK:[B10.2]        if ([B10.3])
-// CHECK:            break;
-// CHECK:        if ([B8.1])
-// CHECK:            continue;
-// CHECK:        if ([B6.1])
-// CHECK:[B5.1][B4.2]    }
+// CHECK:      2: A b = a;
 // CHECK:      3: b.operator int()
 // CHECK:      4: [B2.3]
 // CHECK:      T: while [B2.4]
@@ -456,7 +444,7 @@ void test_catch_copy() {
 // CHECK:    Predecessors (2): B4 B7
 // CHECK:    Successors (1): B2
 // CHECK: [ B4 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A d;
 // CHECK:      3: [B4.2].~A() (Implicit destructor)
 // CHECK:      4: [B10.2].~A() (Implicit destructor)
@@ -492,14 +480,14 @@ void test_catch_copy() {
 // CHECK:    Predecessors (1): B10
 // CHECK:    Successors (1): B1
 // CHECK: [ B10 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: UV
 // CHECK:      T: if [B10.3]
 // CHECK:    Predecessors (1): B2
 // CHECK:    Successors (2): B9 B8
 // CHECK: [ B11 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
 // CHECK:    Predecessors (1): B12
 // CHECK:    Successors (1): B2
@@ -515,7 +503,7 @@ void test_catch_copy() {
 // CHECK:    Predecessors (1): B2
 // CHECK:    Successors (2): B3 B0
 // CHECK: [ B2 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
 // CHECK:      3: [B2.2].~A() (Implicit destructor)
 // CHECK:    Predecessors (2): B3 B4
@@ -530,7 +518,7 @@ void test_catch_copy() {
 // CHECK:    Predecessors (0):
 // CHECK:    Successors (1): B11
 // CHECK: [ B1 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A d;
 // CHECK:      3: [B1.2].~A() (Implicit destructor)
 // CHECK:      4: [B11.2].~A() (Implicit destructor)
@@ -542,7 +530,7 @@ void test_catch_copy() {
 // CHECK:    Predecessors (2): B3 B6
 // CHECK:    Successors (2): B10 B1
 // CHECK: [ B3 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: [B3.2].~A() (Implicit destructor)
 // CHECK:      4: [B9.2].~A() (Implicit destructor)
@@ -575,7 +563,7 @@ void test_catch_copy() {
 // CHECK:    Predecessors (1): B9
 // CHECK:    Successors (1): B1
 // CHECK: [ B9 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A b;
 // CHECK:      3: UV
 // CHECK:      T: if [B9.3]
@@ -585,7 +573,7 @@ void test_catch_copy() {
 // CHECK:    Predecessors (1): B2
 // CHECK:    Successors (1): B9
 // CHECK: [ B11 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
 // CHECK:    Predecessors (1): B12
 // CHECK:    Successors (1): B9
@@ -601,16 +589,16 @@ void test_catch_copy() {
 // CHECK:    Predecessors (2): B3 B2
 // CHECK:    Successors (1): B0
 // CHECK: [ B2 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
 // CHECK:      3: a
-// CHECK:      4: switch ([B2.5])
-// CHECK:[B3.2]      5: b.operator int()
+// CHECK:      4: A b = a;
+// CHECK:      5: b.operator int()
 // CHECK:      T: switch [B2.5]
 // CHECK:    Predecessors (1): B4
 // CHECK:    Successors (1): B1
 // CHECK: [ B3 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: [B3.2].~A() (Implicit destructor)
 // CHECK:    Predecessors (0):
@@ -623,26 +611,17 @@ void test_catch_copy() {
 // CHECK:    Successors (1): B2
 // CHECK: [ B1 ]
 // CHECK:      1: [B2.4].~A() (Implicit destructor)
-// CHECK:      2: 
+// CHECK:      2:
 // CHECK:      3: A g;
 // CHECK:      4: [B1.3].~A() (Implicit destructor)
 // CHECK:      5: [B2.2].~A() (Implicit destructor)
 // CHECK:    Predecessors (3): B3 B7 B2
 // CHECK:    Successors (1): B0
 // CHECK: [ B2 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
 // CHECK:      3: a
-// CHECK:      4: switch ([B2.5]) {
-// CHECK:  case 0:
-// CHECK:    {
-// CHECK:[B8.2]        if ([B8.3])
-// CHECK:            break;
-// CHECK:        if ([B6.1])
-// CHECK:[B5.1][B4.2]    }
-// CHECK:  case 1:
-// CHECK:    break;
-// CHECK:}
+// CHECK:      4: A b = a;
 // CHECK:      5: b.operator int()
 // CHECK:      T: switch [B2.5]
 // CHECK:    Predecessors (1): B9
@@ -654,7 +633,7 @@ void test_catch_copy() {
 // CHECK:    Predecessors (2): B2 B4
 // CHECK:    Successors (1): B1
 // CHECK: [ B4 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A f;
 // CHECK:      3: [B4.2].~A() (Implicit destructor)
 // CHECK:      4: [B8.2].~A() (Implicit destructor)
@@ -679,7 +658,7 @@ void test_catch_copy() {
 // CHECK:    Successors (1): B1
 // CHECK: [ B8 ]
 // CHECK:    case 0:
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: UV
 // CHECK:      T: if [B8.3]
@@ -698,8 +677,8 @@ void test_catch_copy() {
 // CHECK:    Successors (1): B0
 // CHECK: [ B2 ]
 // CHECK:      1: a
-// CHECK:      2: for (A a; [B2.4];) 
-// CHECK:[B4.2]      3: b.operator int()
+// CHECK:      2: A b = a;
+// CHECK:      3: b.operator int()
 // CHECK:      4: [B2.3]
 // CHECK:      T: for (...; [B2.4]; )
 // CHECK:    Predecessors (2): B3 B5
@@ -709,13 +688,13 @@ void test_catch_copy() {
 // CHECK:    Predecessors (1): B4
 // CHECK:    Successors (1): B2
 // CHECK: [ B4 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A c;
 // CHECK:      3: [B4.2].~A() (Implicit destructor)
 // CHECK:    Predecessors (1): B2
 // CHECK:    Successors (1): B3
 // CHECK: [ B5 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
 // CHECK:    Predecessors (1): B6
 // CHECK:    Successors (1): B2
@@ -728,7 +707,7 @@ void test_catch_copy() {
 // CHECK: [ B1 ]
 // CHECK:      1: [B2.2].~A() (Implicit destructor)
 // CHECK:      2: [B11.4].~A() (Implicit destructor)
-// CHECK:      3: 
+// CHECK:      3:
 // CHECK:      4: A f;
 // CHECK:      5: [B1.4].~A() (Implicit destructor)
 // CHECK:      6: [B11.2].~A() (Implicit destructor)
@@ -736,13 +715,7 @@ void test_catch_copy() {
 // CHECK:    Successors (1): B0
 // CHECK: [ B2 ]
 // CHECK:      1: b
-// CHECK:      2: for (A b; [B2.4];) {
-// CHECK:[B10.2]    if ([B10.3])
-// CHECK:        break;
-// CHECK:    if ([B8.1])
-// CHECK:        continue;
-// CHECK:    if ([B6.1])
-// CHECK:[B5.1][B4.2]}
+// CHECK:      2: A c = b;
 // CHECK:      3: c.operator int()
 // CHECK:      4: [B2.3]
 // CHECK:      T: for (...; [B2.4]; )
@@ -753,7 +726,7 @@ void test_catch_copy() {
 // CHECK:    Predecessors (2): B4 B7
 // CHECK:    Successors (1): B2
 // CHECK: [ B4 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A e;
 // CHECK:      3: [B4.2].~A() (Implicit destructor)
 // CHECK:      4: [B10.2].~A() (Implicit destructor)
@@ -788,16 +761,16 @@ void test_catch_copy() {
 // CHECK:    Predecessors (1): B10
 // CHECK:    Successors (1): B1
 // CHECK: [ B10 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A d;
 // CHECK:      3: UV
 // CHECK:      T: if [B10.3]
 // CHECK:    Predecessors (1): B2
 // CHECK:    Successors (2): B9 B8
 // CHECK: [ B11 ]
-// CHECK:      1: 
+// CHECK:      1:
 // CHECK:      2: A a;
-// CHECK:      3: 
+// CHECK:      3:
 // CHECK:      4: A b;
 // CHECK:    Predecessors (1): B12
 // CHECK:    Successors (1): B2
@@ -833,3 +806,4 @@ void test_catch_copy() {
 // CHECK: [ B0 (EXIT) ]
 // CHECK:    Predecessors (3): B2 B1 B3
 // CHECK:    Successors (0):
+
index e0558ccc78c6c5effa755bd5280be409e870f11a..330444bb5c4703b40ebbb4e611067208c078d911 100644 (file)
@@ -92,7 +92,7 @@ void test14() {
 }
 
 void test15() {
-  int x = x; // expected-warning{{variable 'x' is uninitialized when used within its own initialization}} expected-note{{variable 'x' is declared here}}
+  int x = x; // expected-warning{{variable 'x' is uninitialized when used within its own initialization}}
 }
 
 // Don't warn in the following example; shows dataflow confluence.
index 13ea9688efe95635f1ac7ee89d9eeeab8becf4f3..cf75187ab8e16cec6b5f4f0cdf4d5280def209a9 100644 (file)
@@ -11,7 +11,7 @@ int a = a; // FIXME: This doesn't warn!? Seems it doesn't cast 'a' to an RValue.
 int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
 int c = (c + c); // expected-warning 2 {{variable 'c' is uninitialized when used within its own initialization}}
 void test() {
-  int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}}
+  int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}}
 }
 int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
 int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}