From: DeLesley Hutchins Date: Thu, 20 Mar 2014 20:39:20 +0000 (+0000) Subject: Consumed Analysis: IgnoreParens bugfix. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b3efa4b347a86d939928bd867cfaa8a2492eaecc;p=clang Consumed Analysis: IgnoreParens bugfix. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204395 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/Consumed.cpp b/lib/Analysis/Consumed.cpp index 5551a21e59..7b6ad574b7 100644 --- a/lib/Analysis/Consumed.cpp +++ b/lib/Analysis/Consumed.cpp @@ -471,11 +471,21 @@ class ConsumedStmtVisitor : public ConstStmtVisitor { ConsumedStateMap *StateMap; MapType PropagationMap; - void forwardInfo(const Stmt *From, const Stmt *To); - void copyInfo(const Stmt *From, const Stmt *To, ConsumedState CS); - ConsumedState getInfo(const Stmt *From); - void setInfo(const Stmt *To, ConsumedState NS); - void propagateReturnType(const Stmt *Call, const FunctionDecl *Fun); + InfoEntry findInfo(const Expr *E) { + return PropagationMap.find(E->IgnoreParens()); + } + ConstInfoEntry findInfo(const Expr *E) const { + return PropagationMap.find(E->IgnoreParens()); + } + void insertInfo(const Expr *E, const PropagationInfo &PI) { + PropagationMap.insert(PairType(E->IgnoreParens(), PI)); + } + + void forwardInfo(const Expr *From, const Expr *To); + void copyInfo(const Expr *From, const Expr *To, ConsumedState CS); + ConsumedState getInfo(const Expr *From); + void setInfo(const Expr *To, ConsumedState NS); + void propagateReturnType(const Expr *Call, const FunctionDecl *Fun); public: void checkCallability(const PropagationInfo &PInfo, @@ -504,8 +514,8 @@ public: ConsumedStateMap *StateMap) : AC(AC), Analyzer(Analyzer), StateMap(StateMap) {} - PropagationInfo getInfo(const Stmt *StmtNode) const { - ConstInfoEntry Entry = PropagationMap.find(StmtNode); + PropagationInfo getInfo(const Expr *StmtNode) const { + ConstInfoEntry Entry = findInfo(StmtNode); if (Entry != PropagationMap.end()) return Entry->second; @@ -519,23 +529,23 @@ public: }; -void ConsumedStmtVisitor::forwardInfo(const Stmt *From, const Stmt *To) { - InfoEntry Entry = PropagationMap.find(From); +void ConsumedStmtVisitor::forwardInfo(const Expr *From, const Expr *To) { + InfoEntry Entry = findInfo(From); if (Entry != PropagationMap.end()) - PropagationMap.insert(PairType(To, Entry->second)); + insertInfo(To, Entry->second); } // Create a new state for To, which is initialized to the state of From. // If NS is not CS_None, sets the state of From to NS. -void ConsumedStmtVisitor::copyInfo(const Stmt *From, const Stmt *To, +void ConsumedStmtVisitor::copyInfo(const Expr *From, const Expr *To, ConsumedState NS) { - InfoEntry Entry = PropagationMap.find(From); + InfoEntry Entry = findInfo(From); if (Entry != PropagationMap.end()) { PropagationInfo& PInfo = Entry->second; ConsumedState CS = PInfo.getAsState(StateMap); if (CS != CS_None) - PropagationMap.insert(PairType(To, CS)); + insertInfo(To, PropagationInfo(CS)); if (NS != CS_None && PInfo.isPointerToValue()) setStateForVarOrTmp(StateMap, PInfo, NS); } @@ -543,8 +553,8 @@ void ConsumedStmtVisitor::copyInfo(const Stmt *From, const Stmt *To, // Get the ConsumedState for From -ConsumedState ConsumedStmtVisitor::getInfo(const Stmt *From) { - InfoEntry Entry = PropagationMap.find(From); +ConsumedState ConsumedStmtVisitor::getInfo(const Expr *From) { + InfoEntry Entry = findInfo(From); if (Entry != PropagationMap.end()) { PropagationInfo& PInfo = Entry->second; return PInfo.getAsState(StateMap); @@ -554,14 +564,14 @@ ConsumedState ConsumedStmtVisitor::getInfo(const Stmt *From) { // If we already have info for To then update it, otherwise create a new entry. -void ConsumedStmtVisitor::setInfo(const Stmt *To, ConsumedState NS) { - InfoEntry Entry = PropagationMap.find(To); +void ConsumedStmtVisitor::setInfo(const Expr *To, ConsumedState NS) { + InfoEntry Entry = findInfo(To); if (Entry != PropagationMap.end()) { PropagationInfo& PInfo = Entry->second; if (PInfo.isPointerToValue()) setStateForVarOrTmp(StateMap, PInfo, NS); } else if (NS != CS_None) { - PropagationMap.insert(PairType(To, PropagationInfo(NS))); + insertInfo(To, PropagationInfo(NS)); } } @@ -616,7 +626,7 @@ bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg, const ParmVarDecl *Param = FunD->getParamDecl(Index - Offset); QualType ParamType = Param->getType(); - InfoEntry Entry = PropagationMap.find(Call->getArg(Index)); + InfoEntry Entry = findInfo(Call->getArg(Index)); if (Entry == PropagationMap.end() || Entry->second.isTest()) continue; @@ -651,7 +661,7 @@ bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg, return false; // check implicit 'self' parameter, if present - InfoEntry Entry = PropagationMap.find(ObjArg); + InfoEntry Entry = findInfo(ObjArg); if (Entry != PropagationMap.end()) { PropagationInfo PInfo = Entry->second; checkCallability(PInfo, FunD, Call->getExprLoc()); @@ -675,7 +685,7 @@ bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg, } -void ConsumedStmtVisitor::propagateReturnType(const Stmt *Call, +void ConsumedStmtVisitor::propagateReturnType(const Expr *Call, const FunctionDecl *Fun) { QualType RetType = Fun->getCallResultType(); if (RetType->isReferenceType()) @@ -697,8 +707,8 @@ void ConsumedStmtVisitor::VisitBinaryOperator(const BinaryOperator *BinOp) { switch (BinOp->getOpcode()) { case BO_LAnd: case BO_LOr : { - InfoEntry LEntry = PropagationMap.find(BinOp->getLHS()), - REntry = PropagationMap.find(BinOp->getRHS()); + InfoEntry LEntry = findInfo(BinOp->getLHS()), + REntry = findInfo(BinOp->getRHS()); VarTestResult LTest, RTest; @@ -770,7 +780,7 @@ void ConsumedStmtVisitor::VisitCastExpr(const CastExpr *Cast) { void ConsumedStmtVisitor::VisitCXXBindTemporaryExpr( const CXXBindTemporaryExpr *Temp) { - InfoEntry Entry = PropagationMap.find(Temp->getSubExpr()); + InfoEntry Entry = findInfo(Temp->getSubExpr()); if (Entry != PropagationMap.end() && !Entry->second.isTest()) { StateMap->setState(Temp, Entry->second.getAsState(StateMap)); @@ -894,7 +904,7 @@ void ConsumedStmtVisitor::VisitReturnStmt(const ReturnStmt *Ret) { ConsumedState ExpectedState = Analyzer.getExpectedReturnState(); if (ExpectedState != CS_None) { - InfoEntry Entry = PropagationMap.find(Ret->getRetValue()); + InfoEntry Entry = findInfo(Ret->getRetValue()); if (Entry != PropagationMap.end()) { ConsumedState RetState = Entry->second.getAsState(StateMap); @@ -911,7 +921,7 @@ void ConsumedStmtVisitor::VisitReturnStmt(const ReturnStmt *Ret) { } void ConsumedStmtVisitor::VisitUnaryOperator(const UnaryOperator *UOp) { - InfoEntry Entry = PropagationMap.find(UOp->getSubExpr()->IgnoreParens()); + InfoEntry Entry = findInfo(UOp->getSubExpr()); if (Entry == PropagationMap.end()) return; switch (UOp->getOpcode()) { @@ -933,8 +943,7 @@ void ConsumedStmtVisitor::VisitUnaryOperator(const UnaryOperator *UOp) { void ConsumedStmtVisitor::VisitVarDecl(const VarDecl *Var) { if (isConsumableType(Var->getType())) { if (Var->hasInit()) { - MapType::iterator VIT = PropagationMap.find( - Var->getInit()->IgnoreImplicit()); + MapType::iterator VIT = findInfo(Var->getInit()->IgnoreImplicit()); if (VIT != PropagationMap.end()) { PropagationInfo PInfo = VIT->second; ConsumedState St = PInfo.getAsState(StateMap); @@ -1292,7 +1301,7 @@ bool ConsumedAnalyzer::splitState(const CFGBlock *CurrBlock, if (const IfStmt *IfNode = dyn_cast_or_null(CurrBlock->getTerminator().getStmt())) { - const Stmt *Cond = IfNode->getCond(); + const Expr *Cond = IfNode->getCond(); PInfo = Visitor.getInfo(Cond); if (!PInfo.isValid() && isa(Cond)) diff --git a/test/SemaCXX/warn-consumed-analysis.cpp b/test/SemaCXX/warn-consumed-analysis.cpp index 3923f69439..bd091c6f1c 100644 --- a/test/SemaCXX/warn-consumed-analysis.cpp +++ b/test/SemaCXX/warn-consumed-analysis.cpp @@ -684,6 +684,8 @@ class CONSUMABLE(unconsumed) int code; public: + static Status OK; + Status() RETURN_TYPESTATE(consumed); Status(int c) RETURN_TYPESTATE(unconsumed); @@ -693,6 +695,8 @@ public: Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed"); Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed"); + bool operator==(const Status &other) const SET_TYPESTATE(consumed); + bool check() const SET_TYPESTATE(consumed); void ignore() const SET_TYPESTATE(consumed); // Status& markAsChecked() { return *this; } @@ -710,6 +714,11 @@ void handleStatusRef(Status& s); void handleStatusPtr(Status* s); void handleStatusUnmarked(const Status& s); +void log(const char* msg); +void fail() __attribute__((noreturn)); +void checkStat(const Status& s); + + void testSimpleTemporaries0() { doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}} } @@ -870,6 +879,29 @@ Status testReturnAutocast() { return s; // should autocast back to unconsumed } + +namespace TestParens { + +void test3() { + checkStat((doSomething())); +} + +void test4() { + Status s = (doSomething()); + s.check(); +} + +void test5() { + (doSomething()).check(); +} + +void test6() { + if ((doSomething()) == Status::OK) + return; +} + +} // end namespace TestParens + } // end namespace InitializerAssertionFailTest @@ -899,3 +931,4 @@ namespace PR18260 { std::__1::move(x); } } // end namespace PR18260 +