From 4252598a2e58c3f74027511f535ed327f9b32b77 Mon Sep 17 00:00:00 2001 From: DeLesley Hutchins Date: Thu, 29 Aug 2013 22:36:05 +0000 Subject: [PATCH] Consumed analysis: track function parameters. Patch by chris.wailes@gmail.com. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189616 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/Consumed.cpp | 37 ++++++++++++++----- .../SemaCXX/warn-consumed-analysis-strict.cpp | 4 ++ test/SemaCXX/warn-consumed-analysis.cpp | 12 ++++++ 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/lib/Analysis/Consumed.cpp b/lib/Analysis/Consumed.cpp index e5231e07c2..09676a8c23 100644 --- a/lib/Analysis/Consumed.cpp +++ b/lib/Analysis/Consumed.cpp @@ -44,8 +44,6 @@ // (Deferred) // TODO: Test nested conditionals: A) Checking the same value multiple times, // and 2) Checking different values. (Deferred) -// TODO: Test IsFalseVisitor with values in the unknown state. (Deferred) -// TODO: Look into combining IsFalseVisitor and TestedVarsVisitor. (Deferred) using namespace clang; using namespace consumed; @@ -266,11 +264,13 @@ public: void VisitDeclStmt(const DeclStmt *DelcS); void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Temp); void VisitMemberExpr(const MemberExpr *MExpr); + void VisitParmVarDecl(const ParmVarDecl *Param); void VisitUnaryOperator(const UnaryOperator *UOp); void VisitVarDecl(const VarDecl *Var); - ConsumedStmtVisitor(AnalysisDeclContext &AC, ConsumedAnalyzer &Analyzer) - : AC(AC), Analyzer(Analyzer), StateMap(NULL) {} + ConsumedStmtVisitor(AnalysisDeclContext &AC, ConsumedAnalyzer &Analyzer, + ConsumedStateMap *StateMap) + : AC(AC), Analyzer(Analyzer), StateMap(StateMap) {} PropagationInfo getInfo(const Stmt *StmtNode) const { ConstInfoEntry Entry = PropagationMap.find(StmtNode); @@ -664,6 +664,12 @@ void ConsumedStmtVisitor::VisitMemberExpr(const MemberExpr *MExpr) { forwardInfo(MExpr->getBase(), MExpr); } + +void ConsumedStmtVisitor::VisitParmVarDecl(const ParmVarDecl *Param) { + if (Analyzer.isConsumableType(Param->getType())) + StateMap->setState(Param, consumed::CS_Unknown); +} + void ConsumedStmtVisitor::VisitUnaryOperator(const UnaryOperator *UOp) { InfoEntry Entry = PropagationMap.find(UOp->getSubExpr()->IgnoreParens()); if (Entry == PropagationMap.end()) return; @@ -685,11 +691,16 @@ void ConsumedStmtVisitor::VisitUnaryOperator(const UnaryOperator *UOp) { void ConsumedStmtVisitor::VisitVarDecl(const VarDecl *Var) { if (Analyzer.isConsumableType(Var->getType())) { - PropagationInfo PInfo = - PropagationMap.find(Var->getInit())->second; - - StateMap->setState(Var, PInfo.isVar() ? - StateMap->getState(PInfo.getVar()) : PInfo.getState()); + if (Var->hasInit()) { + PropagationInfo PInfo = + PropagationMap.find(Var->getInit())->second; + + StateMap->setState(Var, PInfo.isVar() ? + StateMap->getState(PInfo.getVar()) : PInfo.getState()); + + } else { + StateMap->setState(Var, consumed::CS_Unknown); + } } } }} // end clang::consumed::ConsumedStmtVisitor @@ -1022,7 +1033,13 @@ void ConsumedAnalyzer::run(AnalysisDeclContext &AC) { PostOrderCFGView *SortedGraph = AC.getAnalysis(); CurrStates = new ConsumedStateMap(); - ConsumedStmtVisitor Visitor(AC, *this); + ConsumedStmtVisitor Visitor(AC, *this, CurrStates); + + // Add all trackable parameters to the state map. + for (FunctionDecl::param_const_iterator PI = D->param_begin(), + PE = D->param_end(); PI != PE; ++PI) { + Visitor.VisitParmVarDecl(*PI); + } // Visit all of the function's basic blocks. for (PostOrderCFGView::iterator I = SortedGraph->begin(), diff --git a/test/SemaCXX/warn-consumed-analysis-strict.cpp b/test/SemaCXX/warn-consumed-analysis-strict.cpp index c3b254d781..b8a2982fc5 100644 --- a/test/SemaCXX/warn-consumed-analysis-strict.cpp +++ b/test/SemaCXX/warn-consumed-analysis-strict.cpp @@ -192,6 +192,10 @@ void testNoWarnTestFromMacroExpansion() { } } +void testFunctionParam(ConsumableClass param) { + *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in an unknown state}} +} + void testSimpleForLoop() { ConsumableClass var; diff --git a/test/SemaCXX/warn-consumed-analysis.cpp b/test/SemaCXX/warn-consumed-analysis.cpp index c664655946..adaab647e1 100644 --- a/test/SemaCXX/warn-consumed-analysis.cpp +++ b/test/SemaCXX/warn-consumed-analysis.cpp @@ -224,6 +224,18 @@ void testStateChangeInBranch() { *var; } +void testFunctionParam(ConsumableClass param) { + + if (param.isValid()) { + *param; + } else { + *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}} + } + + param = nullptr; + *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}} +} + void testCallingConventions() { ConsumableClass var(42); -- 2.40.0