From: Ted Kremenek Date: Mon, 4 Apr 2011 23:29:12 +0000 (+0000) Subject: Fix PR 9626 (duplicated self-init warnings under -Wuninitialized) with numerous CFG... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d40066b0fb883839a9100e5455e33190b9b8abac;p=clang Fix PR 9626 (duplicated self-init warnings under -Wuninitialized) with numerous CFG and UninitializedValues analysis changes: 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 --- diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 6428594c8e..97dbce045f 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -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(SubExprs[VAR]); + } + const Expr *getCond() const { return reinterpret_cast(SubExprs[COND]);} void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast(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(SubExprs[VAR]); + } const Expr *getCond() const { return reinterpret_cast(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(SubExprs[VAR]); + } + Expr *getCond() { return reinterpret_cast(SubExprs[COND]); } const Expr *getCond() const { return reinterpret_cast(SubExprs[COND]);} void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast(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(SubExprs[CONDVAR]); + } + Expr *getCond() { return reinterpret_cast(SubExprs[COND]); } Expr *getInc() { return reinterpret_cast(SubExprs[INC]); } Stmt *getBody() { return SubExprs[BODY]; } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index ab8e4bcdde..8cd743f68f 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -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); diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index e91de0366c..b5930cdccf 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -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(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); } } diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp index f775cc5b50..3dde41f227 100644 --- a/lib/Analysis/UninitializedValues.cpp +++ b/lib/Analysis/UninitializedValues.cpp @@ -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(*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); diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 3467dae4ba..ecfa821358 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -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(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(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) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index e52082bbbf..8bf6c84c0b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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(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(RealDecl)) { // With declarators parsed the way they are, the parser cannot diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 3826a12226..a422428b1b 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -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(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(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(S)->getConditionVariable(), S, Pred, Dst); - break; - case Stmt::InitListExprClass: VisitInitListExpr(cast(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(S)->getConditionVariable(), S, Pred, Dst); - break; - case Stmt::UnaryOperatorClass: { const UnaryOperator *U = cast(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(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. diff --git a/test/Analysis/auto-obj-dtors-cfg-output.cpp b/test/Analysis/auto-obj-dtors-cfg-output.cpp index 6dccf9f846..c877061eb6 100644 --- a/test/Analysis/auto-obj-dtors-cfg-output.cpp +++ b/test/Analysis/auto-obj-dtors-cfg-output.cpp @@ -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): + diff --git a/test/Sema/uninit-variables.c b/test/Sema/uninit-variables.c index e0558ccc78..330444bb5c 100644 --- a/test/Sema/uninit-variables.c +++ b/test/Sema/uninit-variables.c @@ -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. diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp index 13ea9688ef..cf75187ab8 100644 --- a/test/SemaCXX/uninitialized.cpp +++ b/test/SemaCXX/uninitialized.cpp @@ -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 2 {{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(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}}