;
56using namespaceconsumed;
64 for(
const auto&B : *
Block)
65 if(std::optional<CFGStmt> CS = B.getAs<
CFGStmt>())
66 returnCS->getStmt()->getBeginLoc();
80 returnStmtNode->getBeginLoc();
84 if(std::optional<CFGStmt> CS = BI->getAs<
CFGStmt>())
85 returnCS->getStmt()->getBeginLoc();
114llvm_unreachable(
"invalid enum");
119 for(
const auto&S : CWAttr->callableStates()) {
123 caseCallableWhenAttr::Unknown:
127 caseCallableWhenAttr::Unconsumed:
131 caseCallableWhenAttr::Consumed:
136 if(MappedAttrState == State)
148 returnRD->hasAttr<ConsumableAttr>();
158 returnRD->hasAttr<ConsumableAutoCastAttr>();
165 returnRD->hasAttr<ConsumableSetOnReadAttr>();
178llvm_unreachable(
"invalid enum");
186 returnFunDecl->
hasAttr<TestTypestateAttr>();
192 constConsumableAttr *CAttr =
195 switch(CAttr->getDefaultState()) {
196 caseConsumableAttr::Unknown:
198 caseConsumableAttr::Unconsumed:
200 caseConsumableAttr::Consumed:
203llvm_unreachable(
"invalid enum");
208 switch(PTAttr->getParamState()) {
209 caseParamTypestateAttr::Unknown:
211 caseParamTypestateAttr::Unconsumed:
213 caseParamTypestateAttr::Consumed:
216llvm_unreachable(
"invalid_enum");
221 switch(RTSAttr->getState()) {
222 caseReturnTypestateAttr::Unknown:
224 caseReturnTypestateAttr::Unconsumed:
226 caseReturnTypestateAttr::Consumed:
229llvm_unreachable(
"invalid enum");
233 switch(STAttr->getNewState()) {
234 caseSetTypestateAttr::Unknown:
236 caseSetTypestateAttr::Unconsumed:
238 caseSetTypestateAttr::Consumed:
241llvm_unreachable(
"invalid_enum");
253 return "unconsumed";
258llvm_unreachable(
"invalid enum");
263 switch(FunDecl->
getAttr<TestTypestateAttr>()->getTestState()) {
264 caseTestTypestateAttr::Unconsumed:
266 caseTestTypestateAttr::Consumed:
269llvm_unreachable(
"invalid enum");
274structVarTestResult {
297} InfoType = IT_None;
320: InfoType(IT_VarTest) {
326 constVarTestResult <est,
constVarTestResult &RTest)
327: InfoType(IT_BinTest) {
337: InfoType(IT_BinTest) {
341 BinTest.LTest.TestsFor = LTestsFor;
343 BinTest.RTest.TestsFor = RTestsFor;
350: InfoType(IT_Tmp),
Tmp(
Tmp) {}
353assert(InfoType == IT_State);
358assert(InfoType == IT_VarTest);
363assert(InfoType == IT_BinTest);
368assert(InfoType == IT_BinTest);
373assert(InfoType == IT_Var);
378assert(InfoType == IT_Tmp);
396assert(InfoType == IT_BinTest);
401assert(InfoType == IT_BinTest);
405 bool isValid()
const{
returnInfoType != IT_None; }
406 bool isState()
const{
returnInfoType == IT_State; }
407 bool isVarTest()
const{
returnInfoType == IT_VarTest; }
408 bool isBinTest()
const{
returnInfoType == IT_BinTest; }
409 bool isVar()
const{
returnInfoType == IT_Var; }
410 bool isTmp()
const{
returnInfoType == IT_Tmp; }
413 returnInfoType == IT_VarTest || InfoType == IT_BinTest;
417 returnInfoType == IT_Var || InfoType == IT_Tmp;
421assert(InfoType == IT_VarTest || InfoType == IT_BinTest);
423 if(InfoType == IT_VarTest) {
427}
else if(InfoType == IT_BinTest) {
456 usingMapType = llvm::DenseMap<const Stmt *, PropagationInfo>;
457 usingPairType= std::pair<const Stmt *, PropagationInfo>;
458 usingInfoEntry = MapType::iterator;
459 usingConstInfoEntry = MapType::const_iterator;
463MapType PropagationMap;
465InfoEntry findInfo(
const Expr*
E) {
466 if(
const autoCleanups = dyn_cast<ExprWithCleanups>(
E))
467 if(!Cleanups->cleanupsHaveSideEffects())
468 E= Cleanups->getSubExpr();
472ConstInfoEntry findInfo(
const Expr*
E)
const{
473 if(
const autoCleanups = dyn_cast<ExprWithCleanups>(
E))
474 if(!Cleanups->cleanupsHaveSideEffects())
475 E= Cleanups->getSubExpr();
483 voidforwardInfo(
const Expr*From,
const Expr*To);
513: Analyzer(Analyzer), StateMap(StateMap) {}
516ConstInfoEntry Entry = findInfo(StmtNode);
518 if(Entry != PropagationMap.end())
519 returnEntry->second;
525StateMap = NewStateMap;
532voidConsumedStmtVisitor::forwardInfo(
const Expr*From,
const Expr*To) {
533InfoEntry Entry = findInfo(From);
534 if(Entry != PropagationMap.end())
535insertInfo(To, Entry->second);
540voidConsumedStmtVisitor::copyInfo(
const Expr*From,
const Expr*To,
542InfoEntry Entry = findInfo(From);
543 if(Entry != PropagationMap.end()) {
555InfoEntry Entry = findInfo(From);
556 if(Entry != PropagationMap.end()) {
565InfoEntry Entry = findInfo(To);
566 if(Entry != PropagationMap.end()) {
578assert(!PInfo.
isTest());
580 constCallableWhenAttr *CWAttr = FunDecl->
getAttr<CallableWhenAttr>();
584 if(PInfo.
isVar()) {
610 if(isa<CXXOperatorCallExpr>(
Call) && isa<CXXMethodDecl>(FunD))
614 for(
unsignedIndex = Offset; Index <
Call->getNumArgs(); ++Index) {
622InfoEntry Entry = findInfo(
Call->getArg(Index));
624 if(Entry == PropagationMap.end() || Entry->second.isTest())
629 if(ParamTypestateAttr *PTA = Param->
getAttr<ParamTypestateAttr>()) {
633 if(ParamState != ExpectedState)
635 Call->getArg(Index)->getExprLoc(),
639 if(!(Entry->second.isVar() || Entry->second.isTmp()))
643 if(ReturnTypestateAttr *RT = Param->
getAttr<ReturnTypestateAttr>())
657InfoEntry Entry = findInfo(ObjArg);
658 if(Entry != PropagationMap.end()) {
662 if(SetTypestateAttr *STA = FunD->
getAttr<SetTypestateAttr>()) {
663 if(PInfo.
isVar()) {
667 else if(PInfo.
isTmp()) {
673PropagationMap.insert(PairType(
Call,
680voidConsumedStmtVisitor::propagateReturnType(
const Expr*
Call,
688 if(ReturnTypestateAttr *RTA = Fun->
getAttr<ReturnTypestateAttr>())
701InfoEntry LEntry = findInfo(BinOp->
getLHS()),
702REntry = findInfo(BinOp->
getRHS());
704VarTestResult LTest, RTest;
706 if(LEntry != PropagationMap.end() && LEntry->second.isVarTest()) {
707LTest = LEntry->second.getVarTest();
709LTest.Var =
nullptr;
713 if(REntry != PropagationMap.end() && REntry->second.isVarTest()) {
714RTest = REntry->second.getVarTest();
716RTest.Var =
nullptr;
720 if(!(LTest.Var ==
nullptr&& RTest.Var ==
nullptr))
728forwardInfo(BinOp->
getLHS(), BinOp);
743 if(
Call->isCallToStdMove()) {
749propagateReturnType(
Call, FunDecl);
753forwardInfo(Cast->getSubExpr(), Cast);
759InfoEntry Entry = findInfo(Temp->
getSubExpr());
761 if(Entry != PropagationMap.end() && !Entry->second.isTest()) {
762StateMap->
setState(Temp, Entry->second.getAsState(StateMap));
770 QualTypeThisType = Constructor->getFunctionObjectParameterType();
776 if(ReturnTypestateAttr *RTA = Constructor->getAttr<ReturnTypestateAttr>()) {
780}
else if(Constructor->isDefaultConstructor()) {
781PropagationMap.insert(PairType(
Call,
783}
else if(Constructor->isMoveConstructor()) {
785}
else if(Constructor->isCopyConstructor()) {
790copyInfo(
Call->getArg(0),
Call, NS);
805propagateReturnType(
Call, MD);
810 const auto*FunDecl = dyn_cast_or_null<FunctionDecl>(
Call->getDirectCallee());
811 if(!FunDecl)
return;
813 if(
Call->getOperator() == OO_Equal) {
816setInfo(
Call->getArg(0), CS);
820 if(
const auto*MCall = dyn_cast<CXXMemberCallExpr>(
Call))
821 handleCall(MCall, MCall->getImplicitObjectArgument(), FunDecl);
825propagateReturnType(
Call, FunDecl);
829 if(
const auto*Var = dyn_cast_or_null<VarDecl>(DeclRef->
getDecl()))
835 for(
const auto*DI : DeclS->
decls())
836 if(isa<VarDecl>(DI))
840 if(
const auto*Var = dyn_cast_or_null<VarDecl>(DeclS->
getSingleDecl()))
850forwardInfo(MExpr->
getBase(), MExpr);
857 if(
constParamTypestateAttr *PTA = Param->
getAttr<ParamTypestateAttr>())
869StateMap->
setState(Param, ParamState);
875 if(ExpectedState !=
CS_None) {
876InfoEntry Entry = findInfo(Ret->getRetValue());
878 if(Entry != PropagationMap.end()) {
881 if(RetState != ExpectedState)
893InfoEntry Entry = findInfo(UOp->
getSubExpr());
894 if(Entry == PropagationMap.end())
return;
898PropagationMap.insert(PairType(UOp, Entry->second));
902 if(Entry->second.isTest())
903PropagationMap.insert(PairType(UOp, Entry->second.invertTest()));
916 if(VIT != PropagationMap.end()) {
937ThenStates->
setState(Test.Var, Test.TestsFor);
941}
else if(VarState == Test.TestsFor) {
949 constVarTestResult <est = PInfo.
getLTest(),
958ThenStates->
setState(LTest.Var, LTest.TestsFor);
961}
else if(LState == LTest.TestsFor &&
isKnownState(RState)) {
962 if(RState == RTest.TestsFor)
971}
else if(LState == LTest.TestsFor) {
975 if(RState == RTest.TestsFor)
986ThenStates->
setState(RTest.Var, RTest.TestsFor);
993 else if(RState == RTest.TestsFor)
1001assert(CurrBlock &&
"Block pointer must not be NULL");
1002assert(TargetBlock &&
"TargetBlock pointer must not be NULL");
1004 unsigned intCurrBlockOrder = VisitOrder[CurrBlock->
getBlockID()];
1006PE = TargetBlock->
pred_end(); PI != PE; ++PI) {
1007 if(*PI && CurrBlockOrder < VisitOrder[(*PI)->getBlockID()] )
1015std::unique_ptr<ConsumedStateMap> &OwnedStateMap) {
1016assert(
Block&&
"Block pointer must not be NULL");
1018 auto&Entry = StateMapsArray[
Block->getBlockID()];
1021Entry->intersect(*StateMap);
1022}
else if(OwnedStateMap)
1023Entry = std::move(OwnedStateMap);
1025Entry = std::make_unique<ConsumedStateMap>(*StateMap);
1029std::unique_ptr<ConsumedStateMap> StateMap) {
1030assert(
Block&&
"Block pointer must not be NULL");
1032 auto&Entry = StateMapsArray[
Block->getBlockID()];
1035Entry->intersect(*StateMap);
1037Entry = std::move(StateMap);
1042assert(
Block&&
"Block pointer must not be NULL");
1043assert(StateMapsArray[
Block->getBlockID()] &&
"Block has no block info");
1045 returnStateMapsArray[
Block->getBlockID()].get();
1049StateMapsArray[
Block->getBlockID()] =
nullptr;
1052std::unique_ptr<ConsumedStateMap>
1054assert(
Block&&
"Block pointer must not be NULL");
1056 auto&Entry = StateMapsArray[
Block->getBlockID()];
1062assert(From &&
"From block must not be NULL");
1063assert(To &&
"From block must not be NULL");
1069assert(
Block&&
"Block pointer must not be NULL");
1073 if(
Block->pred_size() < 2)
1076 unsigned intBlockVisitOrder = VisitOrder[
Block->getBlockID()];
1078PE =
Block->pred_end(); PI != PE; ++PI) {
1079 if(*PI && BlockVisitOrder < VisitOrder[(*PI)->getBlockID()])
1088 for(
const auto&DM :
VarMap) {
1089 if(isa<ParmVarDecl>(DM.first)) {
1090 const auto*Param = cast<ParmVarDecl>(DM.first);
1091 constReturnTypestateAttr *RTA = Param->getAttr<ReturnTypestateAttr>();
1097 if(DM.second != ExpectedState)
1110VarMapType::const_iterator Entry =
VarMap.find(Var);
1112 if(Entry !=
VarMap.end())
1113 returnEntry->second;
1120TmpMapType::const_iterator Entry =
TmpMap.find(Tmp);
1122 if(Entry !=
TmpMap.end())
1123 returnEntry->second;
1131 if(this->From && this->From ==
Other.From && !
Other.Reachable) {
1136 for(
const auto&DM :
Other.VarMap) {
1137LocalState = this->
getState(DM.first);
1142 if(LocalState != DM.second)
1154 for(
const auto&DM : LoopBackStates->
VarMap) {
1155LocalState = this->
getState(DM.first);
1160 if(LocalState != DM.second) {
1163DM.first->getNameAsString());
1188 for(
const auto&DM :
Other->VarMap)
1189 if(this->
getState(DM.first) != DM.second)
1197 if(
const auto*Constructor = dyn_cast<CXXConstructorDecl>(
D)) {
1198ReturnType = Constructor->getFunctionObjectParameterType();
1200ReturnType =
D->getCallResultType();
1202 if(
constReturnTypestateAttr *RTSAttr =
D->
getAttr<ReturnTypestateAttr>()) {
1204 if(!RD || !RD->
hasAttr<ConsumableAttr>()) {
1210RTSAttr->getLocation(), ReturnType.
getAsString());
1211ExpectedReturnState =
CS_None;
1216ExpectedReturnState =
CS_None;
1221ExpectedReturnState =
CS_None;
1224boolConsumedAnalyzer::splitState(
const CFGBlock*CurrBlock,
1226std::unique_ptr<ConsumedStateMap> FalseStates(
1230 if(
const auto*IfNode =
1232 if(IfNode->isConsteval())
1235 const Expr*Cond = IfNode->getCond();
1237PInfo = Visitor.getInfo(Cond);
1238 if(!PInfo.
isValid() && isa<BinaryOperator>(Cond))
1239PInfo = Visitor.getInfo(cast<BinaryOperator>(Cond)->getRHS());
1242CurrStates->setSource(Cond);
1243FalseStates->setSource(Cond);
1253}
else if(
const auto*BinOp =
1255PInfo = Visitor.getInfo(BinOp->getLHS());
1257 if((BinOp = dyn_cast_or_null<BinaryOperator>(BinOp->getLHS()))) {
1258PInfo = Visitor.getInfo(BinOp->getRHS());
1267CurrStates->setSource(BinOp);
1268FalseStates->setSource(BinOp);
1270 constVarTestResult &Test = PInfo.
getVarTest();
1273 if(BinOp->getOpcode() == BO_LAnd) {
1275CurrStates->setState(Test.Var, Test.TestsFor);
1277CurrStates->markUnreachable();
1279}
else if(BinOp->getOpcode() == BO_LOr) {
1281FalseStates->setState(Test.Var,
1283 else if(VarState == Test.TestsFor)
1284FalseStates->markUnreachable();
1293BlockInfo.
addInfo(*SI, std::move(CurrStates));
1295CurrStates =
nullptr;
1298BlockInfo.
addInfo(*SI, std::move(FalseStates));
1304 const auto*
D= dyn_cast_or_null<FunctionDecl>(AC.getDecl());
1308 CFG*CFGraph = AC.getCFG();
1312determineExpectedReturnState(AC,
D);
1319CurrStates = std::make_unique<ConsumedStateMap>();
1323 for(
const auto*PI :
D->parameters())
1327 for(
const auto*CurrBlock : *SortedGraph) {
1329CurrStates = BlockInfo.getInfo(CurrBlock);
1333}
else if(!CurrStates->isReachable()) {
1334CurrStates =
nullptr;
1338Visitor.
reset(CurrStates.get());
1341 for(
const auto&B : *CurrBlock) {
1342 switch(B.getKind()) {
1354CurrStates->remove(BTE);
1376 if(!splitState(CurrBlock, Visitor)) {
1377CurrStates->setSource(
nullptr);
1379 if(CurrBlock->succ_size() > 1 ||
1380(CurrBlock->succ_size() == 1 &&
1381(*CurrBlock->succ_begin())->pred_size() > 1)) {
1383 auto*RawState = CurrStates.get();
1386SE = CurrBlock->succ_end(); SI != SE; ++SI) {
1387 if(*SI ==
nullptr)
continue;
1389 if(BlockInfo.isBackEdge(CurrBlock, *SI)) {
1390BlockInfo.borrowInfo(*SI)->intersectAtLoopHead(
1393 if(BlockInfo.allBackEdgesVisited(CurrBlock, *SI))
1394BlockInfo.discardInfo(*SI);
1396BlockInfo.addInfo(*SI, RawState, CurrStates);
1400CurrStates =
nullptr;
1404 if(CurrBlock == &AC.getCFG()->getExit() &&
1405 D->getCallResultType()->isVoidType())
1406CurrStates->checkParamsForReturnTypestate(
D->
getLocation(),
1411CurrStates =
nullptr;
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
static void splitVarStateForIfBinOp(const PropagationInfo &PInfo, ConsumedStateMap *ThenStates, ConsumedStateMap *ElseStates)
static ConsumedState invertConsumedUnconsumed(ConsumedState State)
static bool isCallableInState(const CallableWhenAttr *CWAttr, ConsumedState State)
static ConsumedState mapParamTypestateAttrState(const ParamTypestateAttr *PTAttr)
static bool isRValueRef(QualType ParamType)
static ConsumedState mapReturnTypestateAttrState(const ReturnTypestateAttr *RTSAttr)
static ConsumedState testsFor(const FunctionDecl *FunDecl)
static bool isConsumableType(const QualType &QT)
static StringRef stateToString(ConsumedState State)
static void splitVarStateForIf(const IfStmt *IfNode, const VarTestResult &Test, ConsumedStateMap *ThenStates, ConsumedStateMap *ElseStates)
static bool isTestingFunction(const FunctionDecl *FunDecl)
static bool isAutoCastType(const QualType &QT)
static SourceLocation getFirstStmtLoc(const CFGBlock *Block)
static void setStateForVarOrTmp(ConsumedStateMap *StateMap, const PropagationInfo &PInfo, ConsumedState State)
static ConsumedState mapConsumableAttrState(const QualType QT)
static ConsumedState mapSetTypestateAttrState(const SetTypestateAttr *STAttr)
static SourceLocation getLastStmtLoc(const CFGBlock *Block)
static bool isSetOnReadPtrType(const QualType &QT)
static bool isKnownState(ConsumedState State)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines an enumeration for C++ overloaded operators.
Defines the clang::SourceLocation class and associated facilities.
C Language Family Type Representation.
AnalysisDeclContext contains the context data for the function, method or block under analysis.
A builtin binary operation expression such as "x + y" or "x <= y".
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
const VarDecl * getVarDecl() const
const Stmt * getTriggerStmt() const
Represents a single basic block in a source-level CFG.
reverse_iterator rbegin()
CFGTerminator getTerminator() const
succ_iterator succ_begin()
Stmt * getTerminatorStmt()
AdjacentBlocks::const_iterator const_pred_iterator
unsigned pred_size() const
pred_iterator pred_begin()
unsigned getBlockID() const
AdjacentBlocks::const_iterator const_succ_iterator
unsigned succ_size() const
Represents a top-level expression in a basic block.
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
const Stmt * getStmt() const
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
unsigned getNumBlockIDs() const
Returns the total number of BlockIDs allocated (which start at 0).
Represents binding an expression to a temporary.
const Expr * getSubExpr() const
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
Represents a call to a member function that may be written either with member call syntax (e....
Represents a static or instance method of a struct/union/class.
A call to an overloaded operator written using operator syntax.
Represents a C++ struct/union/class.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
const Decl * getSingleDecl() const
SourceLocation getLocation() const
This represents one expression.
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
QualType getCallResultType() const
Determine the type of an expression that calls this function.
IfStmt - This represents an if/then/else.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Represents a parameter to a function.
A (possibly-)qualified type.
bool isConstQualified() const
Determine whether this type is const-qualified.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
RetTy Visit(PTR(Stmt) S, ParamTys... P)
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isRValueReferenceType() const
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isPointerOrReferenceType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represents a variable declaration or definition.
const Expr * getInit() const
A class that handles the analysis of uniqueness violations.
ConsumedWarningsHandlerBase & WarningsHandler
ConsumedState getExpectedReturnState() const
void run(AnalysisDeclContext &AC)
Check a function's CFG for consumed violations.
ConsumedStateMap * borrowInfo(const CFGBlock *Block)
bool isBackEdgeTarget(const CFGBlock *Block)
std::unique_ptr< ConsumedStateMap > getInfo(const CFGBlock *Block)
void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap, std::unique_ptr< ConsumedStateMap > &OwnedStateMap)
void discardInfo(const CFGBlock *Block)
bool allBackEdgesVisited(const CFGBlock *CurrBlock, const CFGBlock *TargetBlock)
bool isBackEdge(const CFGBlock *From, const CFGBlock *To)
void clearTemporaries()
Clear the TmpMap.
void checkParamsForReturnTypestate(SourceLocation BlameLoc, ConsumedWarningsHandlerBase &WarningsHandler) const
Warn if any of the parameters being tracked are not in the state they were declared to be in upon ret...
void intersect(const ConsumedStateMap &Other)
Merge this state map with another map.
ConsumedState getState(const VarDecl *Var) const
Get the consumed state of a given variable.
void intersectAtLoopHead(const CFGBlock *LoopHead, const CFGBlock *LoopBack, const ConsumedStateMap *LoopBackStates, ConsumedWarningsHandlerBase &WarningsHandler)
void remove(const CXXBindTemporaryExpr *Tmp)
Remove the temporary value from our state map.
void markUnreachable()
Mark the block as unreachable.
bool operator!=(const ConsumedStateMap *Other) const
Tests to see if there is a mismatch in the states stored in two maps.
void setState(const VarDecl *Var, ConsumedState State)
Set the consumed state of a given variable.
void VisitUnaryOperator(const UnaryOperator *UOp)
PropagationInfo getInfo(const Expr *StmtNode) const
void VisitVarDecl(const VarDecl *Var)
void VisitCXXMemberCallExpr(const CXXMemberCallExpr *Call)
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Temp)
void VisitMemberExpr(const MemberExpr *MExpr)
void reset(ConsumedStateMap *NewStateMap)
void VisitReturnStmt(const ReturnStmt *Ret)
void VisitDeclStmt(const DeclStmt *DelcS)
void checkCallability(const PropagationInfo &PInfo, const FunctionDecl *FunDecl, SourceLocation BlameLoc)
void VisitCallExpr(const CallExpr *Call)
void VisitDeclRefExpr(const DeclRefExpr *DeclRef)
void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Temp)
bool handleCall(const CallExpr *Call, const Expr *ObjArg, const FunctionDecl *FunD)
ConsumedStmtVisitor(ConsumedAnalyzer &Analyzer, ConsumedStateMap *StateMap)
void VisitCXXConstructExpr(const CXXConstructExpr *Call)
void VisitBinaryOperator(const BinaryOperator *BinOp)
void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Call)
void VisitCastExpr(const CastExpr *Cast)
void VisitParmVarDecl(const ParmVarDecl *Param)
virtual void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State, SourceLocation Loc)
Warn about use-while-consumed errors.
virtual void warnParamTypestateMismatch(SourceLocation LOC, StringRef ExpectedState, StringRef ObservedState)
virtual void warnLoopStateMismatch(SourceLocation Loc, StringRef VariableName)
Warn that a variable's state doesn't match at the entry and exit of a loop.
virtual void warnUseInInvalidState(StringRef MethodName, StringRef VariableName, StringRef State, SourceLocation Loc)
Warn about use-while-consumed errors.
virtual void emitDiagnostics()
Emit the warnings and notes left by the analysis.
virtual void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState, StringRef ObservedState)
Warn about return typestate mismatches.
virtual void warnReturnTypestateForUnconsumableType(SourceLocation Loc, StringRef TypeName)
Warn about return typestates set for unconsumable types.
virtual ~ConsumedWarningsHandlerBase()
virtual void warnParamReturnTypestateMismatch(SourceLocation Loc, StringRef VariableName, StringRef ExpectedState, StringRef ObservedState)
Warn about parameter typestate mismatches upon return.
const VarTestResult & getRTest() const
PropagationInfo(const BinaryOperator *Source, EffectiveOp EOp, const VarTestResult <est, const VarTestResult &RTest)
const CXXBindTemporaryExpr * Tmp
PropagationInfo(const VarTestResult &VarTest)
EffectiveOp testEffectiveOp() const
PropagationInfo(const BinaryOperator *Source, EffectiveOp EOp, const VarDecl *LVar, ConsumedState LTestsFor, const VarDecl *RVar, ConsumedState RTestsFor)
const ConsumedState & getState() const
const VarTestResult & getVarTest() const
const VarDecl * getVar() const
PropagationInfo(ConsumedState State)
PropagationInfo(const VarDecl *Var)
PropagationInfo(const VarDecl *Var, ConsumedState TestsFor)
PropagationInfo(const CXXBindTemporaryExpr *Tmp)
const VarTestResult & getLTest() const
bool isPointerToValue() const
PropagationInfo()=default
const CXXBindTemporaryExpr * getTmp() const
PropagationInfo invertTest() const
ConsumedState getAsState(const ConsumedStateMap *StateMap) const
const BinaryOperator * testSourceNode() const
The JSON file list parser is used to communicate input to InstallAPI.
@ Other
Other implicit parameter.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4