29 #include "llvm/ADT/DenseMap.h"
30 #include "llvm/ADT/SmallVector.h"
31 #include "llvm/Support/Compiler.h"
32 #include "llvm/Support/raw_ostream.h"
51 using namespace clang;
52 using namespace consumed;
60 for (
const auto &B : *Block)
62 return CS->getStmt()->getLocStart();
66 if (Block->succ_size() == 1 && *Block->succ_begin())
76 return StmtNode->getLocStart();
79 BE = Block->
rend(); BI != BE; ++BI) {
81 return CS->getStmt()->getLocStart();
110 llvm_unreachable(
"invalid enum");
116 for (
const auto &
S : CWAttr->callableStates()) {
124 case CallableWhenAttr::Unconsumed:
128 case CallableWhenAttr::Consumed:
133 if (MappedAttrState == State)
146 return RD->hasAttr<ConsumableAttr>();
156 return RD->hasAttr<ConsumableAutoCastAttr>();
163 return RD->hasAttr<ConsumableSetOnReadAttr>();
177 llvm_unreachable(
"invalid enum");
185 return FunDecl->
hasAttr<TestTypestateAttr>();
195 const ConsumableAttr *CAttr =
198 switch (CAttr->getDefaultState()) {
201 case ConsumableAttr::Unconsumed:
203 case ConsumableAttr::Consumed:
206 llvm_unreachable(
"invalid enum");
211 switch (PTAttr->getParamState()) {
214 case ParamTypestateAttr::Unconsumed:
216 case ParamTypestateAttr::Consumed:
219 llvm_unreachable(
"invalid_enum");
224 switch (RTSAttr->getState()) {
227 case ReturnTypestateAttr::Unconsumed:
229 case ReturnTypestateAttr::Consumed:
232 llvm_unreachable(
"invalid enum");
236 switch (STAttr->getNewState()) {
239 case SetTypestateAttr::Unconsumed:
241 case SetTypestateAttr::Consumed:
244 llvm_unreachable(
"invalid_enum");
261 llvm_unreachable(
"invalid enum");
266 switch (FunDecl->
getAttr<TestTypestateAttr>()->getTestState()) {
267 case TestTypestateAttr::Unconsumed:
269 case TestTypestateAttr::Consumed:
272 llvm_unreachable(
"invalid enum");
276 struct VarTestResult {
319 : InfoType(IT_VarTest), VarTest(VarTest) {}
322 : InfoType(IT_VarTest) {
325 VarTest.TestsFor = TestsFor;
329 const VarTestResult <est,
const VarTestResult &RTest)
330 : InfoType(IT_BinTest) {
332 BinTest.Source = Source;
334 BinTest.LTest = LTest;
335 BinTest.RTest = RTest;
341 : InfoType(IT_BinTest) {
343 BinTest.Source = Source;
345 BinTest.LTest.Var = LVar;
346 BinTest.LTest.TestsFor = LTestsFor;
347 BinTest.RTest.Var = RVar;
348 BinTest.RTest.TestsFor = RTestsFor;
352 : InfoType(IT_State), State(State) {}
356 : InfoType(IT_Tmp), Tmp(Tmp) {}
359 assert(InfoType == IT_State);
364 assert(InfoType == IT_VarTest);
369 assert(InfoType == IT_BinTest);
370 return BinTest.LTest;
374 assert(InfoType == IT_BinTest);
375 return BinTest.RTest;
379 assert(InfoType == IT_Var);
384 assert(InfoType == IT_Tmp);
389 assert(isVar() || isTmp() || isState());
402 assert(InfoType == IT_BinTest);
407 assert(InfoType == IT_BinTest);
408 return BinTest.Source;
411 inline bool isValid()
const {
return InfoType != IT_None; }
412 inline bool isState()
const {
return InfoType == IT_State; }
413 inline bool isVarTest()
const {
return InfoType == IT_VarTest; }
414 inline bool isBinTest()
const {
return InfoType == IT_BinTest; }
415 inline bool isVar()
const {
return InfoType == IT_Var; }
416 inline bool isTmp()
const {
return InfoType == IT_Tmp; }
419 return InfoType == IT_VarTest || InfoType == IT_BinTest;
423 return InfoType == IT_Var || InfoType == IT_Tmp;
427 assert(InfoType == IT_VarTest || InfoType == IT_BinTest);
429 if (InfoType == IT_VarTest) {
433 }
else if (InfoType == IT_BinTest) {
458 typedef llvm::DenseMap<const Stmt *, PropagationInfo> MapType;
459 typedef std::pair<const Stmt *, PropagationInfo> PairType;
460 typedef MapType::iterator InfoEntry;
461 typedef MapType::const_iterator ConstInfoEntry;
466 MapType PropagationMap;
468 InfoEntry findInfo(
const Expr *E) {
471 ConstInfoEntry findInfo(
const Expr *E)
const {
478 void forwardInfo(
const Expr *From,
const Expr *To);
488 bool handleCall(
const CallExpr *Call,
const Expr *ObjArg,
492 void VisitCallExpr(
const CallExpr *Call);
493 void VisitCastExpr(
const CastExpr *Cast);
499 void VisitDeclStmt(
const DeclStmt *DelcS);
501 void VisitMemberExpr(
const MemberExpr *MExpr);
505 void VisitVarDecl(
const VarDecl *Var);
509 : AC(AC), Analyzer(Analyzer), StateMap(StateMap) {}
512 ConstInfoEntry Entry = findInfo(StmtNode);
514 if (Entry != PropagationMap.end())
515 return Entry->second;
521 StateMap = NewStateMap;
526 void ConsumedStmtVisitor::forwardInfo(
const Expr *From,
const Expr *To) {
527 InfoEntry Entry = findInfo(From);
528 if (Entry != PropagationMap.end())
529 insertInfo(To, Entry->second);
535 void ConsumedStmtVisitor::copyInfo(
const Expr *From,
const Expr *To,
537 InfoEntry Entry = findInfo(From);
538 if (Entry != PropagationMap.end()) {
551 InfoEntry Entry = findInfo(From);
552 if (Entry != PropagationMap.end()) {
562 InfoEntry Entry = findInfo(To);
563 if (Entry != PropagationMap.end()) {
579 const CallableWhenAttr *CWAttr = FunDecl->
getAttr<CallableWhenAttr>();
589 Analyzer.WarningsHandler.warnUseInInvalidState(
599 Analyzer.WarningsHandler.warnUseOfTempInInvalidState(
611 if (isa<CXXOperatorCallExpr>(Call) && isa<CXXMethodDecl>(FunD))
615 for (
unsigned Index = Offset; Index < Call->
getNumArgs(); ++Index) {
623 InfoEntry Entry = findInfo(Call->
getArg(Index));
625 if (Entry == PropagationMap.end() || Entry->second.isTest())
630 if (ParamTypestateAttr *PTA = Param->
getAttr<ParamTypestateAttr>()) {
634 if (ParamState != ExpectedState)
635 Analyzer.WarningsHandler.warnParamTypestateMismatch(
640 if (!(Entry->second.isVar() || Entry->second.isTmp()))
646 else if (ReturnTypestateAttr *RT = Param->
getAttr<ReturnTypestateAttr>())
658 InfoEntry Entry = findInfo(ObjArg);
659 if (Entry != PropagationMap.end()) {
661 checkCallability(PInfo, FunD, Call->
getExprLoc());
663 if (SetTypestateAttr *STA = FunD->
getAttr<SetTypestateAttr>()) {
668 else if (PInfo.
isTmp()) {
674 PropagationMap.insert(PairType(Call,
682 void ConsumedStmtVisitor::propagateReturnType(
const Expr *Call,
690 if (ReturnTypestateAttr *RTA = Fun->
getAttr<ReturnTypestateAttr>())
704 InfoEntry LEntry = findInfo(BinOp->
getLHS()),
705 REntry = findInfo(BinOp->
getRHS());
707 VarTestResult LTest, RTest;
709 if (LEntry != PropagationMap.end() && LEntry->second.isVarTest()) {
710 LTest = LEntry->second.getVarTest();
717 if (REntry != PropagationMap.end() && REntry->second.isVarTest()) {
718 RTest = REntry->second.getVarTest();
725 if (!(LTest.Var ==
nullptr && RTest.Var ==
nullptr))
727 static_cast<EffectiveOp>(BinOp->
getOpcode() ==
BO_LOr), LTest, RTest)));
734 forwardInfo(BinOp->
getLHS(), BinOp);
755 handleCall(Call,
nullptr, FunDecl);
756 propagateReturnType(Call, FunDecl);
766 InfoEntry Entry = findInfo(Temp->
getSubExpr());
768 if (Entry != PropagationMap.end() && !Entry->second.isTest()) {
769 StateMap->setState(Temp, Entry->second.getAsState(StateMap));
784 if (ReturnTypestateAttr *RTA = Constructor->
getAttr<ReturnTypestateAttr>()) {
789 PropagationMap.insert(PairType(Call,
798 copyInfo(Call->
getArg(0), Call, NS);
814 propagateReturnType(Call, MD);
823 if (!FunDecl)
return;
827 if (!handleCall(Call, Call->
getArg(0), FunDecl))
828 setInfo(Call->
getArg(0), CS);
833 handleCall(MCall, MCall->getImplicitObjectArgument(), FunDecl);
835 handleCall(Call, Call->
getArg(0), FunDecl);
837 propagateReturnType(Call, FunDecl);
841 if (
const VarDecl *Var = dyn_cast_or_null<VarDecl>(DeclRef->
getDecl()))
847 for (
const auto *DI : DeclS->
decls())
848 if (isa<VarDecl>(DI))
849 VisitVarDecl(cast<VarDecl>(DI));
863 forwardInfo(MExpr->
getBase(), MExpr);
871 if (
const ParamTypestateAttr *PTA = Param->
getAttr<ParamTypestateAttr>())
883 StateMap->setState(Param, ParamState);
887 ConsumedState ExpectedState = Analyzer.getExpectedReturnState();
889 if (ExpectedState !=
CS_None) {
892 if (Entry != PropagationMap.end()) {
895 if (RetState != ExpectedState)
896 Analyzer.WarningsHandler.warnReturnTypestateMismatch(
902 StateMap->checkParamsForReturnTypestate(Ret->
getLocStart(),
903 Analyzer.WarningsHandler);
907 InfoEntry Entry = findInfo(UOp->
getSubExpr());
908 if (Entry == PropagationMap.end())
return;
912 PropagationMap.insert(PairType(UOp, Entry->second));
916 if (Entry->second.isTest())
917 PropagationMap.insert(PairType(UOp, Entry->second.invertTest()));
930 if (VIT != PropagationMap.end()) {
935 StateMap->setState(Var, St);
955 ThenStates->
setState(Test.Var, Test.TestsFor);
961 }
else if (VarState == Test.TestsFor) {
969 const VarTestResult <est = PInfo.
getLTest(),
978 ThenStates->
setState(LTest.Var, LTest.TestsFor);
983 }
else if (LState == LTest.TestsFor &&
isKnownState(RState)) {
984 if (RState == RTest.TestsFor)
995 }
else if (LState == LTest.TestsFor) {
1001 if (RState == RTest.TestsFor)
1012 ThenStates->
setState(RTest.Var, RTest.TestsFor);
1020 else if (RState == RTest.TestsFor)
1029 assert(CurrBlock &&
"Block pointer must not be NULL");
1030 assert(TargetBlock &&
"TargetBlock pointer must not be NULL");
1032 unsigned int CurrBlockOrder = VisitOrder[CurrBlock->
getBlockID()];
1034 PE = TargetBlock->
pred_end(); PI != PE; ++PI) {
1035 if (*PI && CurrBlockOrder < VisitOrder[(*PI)->getBlockID()] )
1043 bool &AlreadyOwned) {
1045 assert(Block &&
"Block pointer must not be NULL");
1052 }
else if (AlreadyOwned) {
1056 StateMapsArray[Block->
getBlockID()] = StateMap;
1057 AlreadyOwned =
true;
1064 assert(Block &&
"Block pointer must not be NULL");
1073 StateMapsArray[Block->
getBlockID()] = StateMap;
1078 assert(Block &&
"Block pointer must not be NULL");
1079 assert(StateMapsArray[Block->
getBlockID()] &&
"Block has no block info");
1086 delete StateMapsArray[BlockID];
1087 StateMapsArray[BlockID] =
nullptr;
1091 assert(Block &&
"Block pointer must not be NULL");
1094 if (isBackEdgeTarget(Block)) {
1097 StateMapsArray[Block->
getBlockID()] =
nullptr;
1103 assert(From &&
"From block must not be NULL");
1104 assert(To &&
"From block must not be NULL");
1110 assert(Block &&
"Block pointer must not be NULL");
1117 unsigned int BlockVisitOrder = VisitOrder[Block->
getBlockID()];
1119 PE = Block->
pred_end(); PI != PE; ++PI) {
1120 if (*PI && BlockVisitOrder < VisitOrder[(*PI)->getBlockID()])
1129 for (
const auto &DM : VarMap) {
1130 if (isa<ParmVarDecl>(DM.first)) {
1131 const ParmVarDecl *Param = cast<ParmVarDecl>(DM.first);
1132 const ReturnTypestateAttr *RTA = Param->
getAttr<ReturnTypestateAttr>();
1138 if (DM.second != ExpectedState)
1151 VarMapType::const_iterator Entry = VarMap.find(Var);
1153 if (Entry != VarMap.end())
1154 return Entry->second;
1161 TmpMapType::const_iterator Entry = TmpMap.find(Tmp);
1163 if (Entry != TmpMap.end())
1164 return Entry->second;
1172 if (this->From && this->From == Other->
From && !Other->
Reachable) {
1173 this->markUnreachable();
1177 for (
const auto &DM : Other->
VarMap) {
1178 LocalState = this->getState(DM.first);
1183 if (LocalState != DM.second)
1195 for (
const auto &DM : LoopBackStates->
VarMap) {
1196 LocalState = this->getState(DM.first);
1201 if (LocalState != DM.second) {
1204 DM.first->getNameAsString());
1210 this->Reachable =
false;
1216 VarMap[Var] =
State;
1221 TmpMap[Tmp] =
State;
1229 for (
const auto &DM : Other->
VarMap)
1230 if (this->getState(DM.first) != DM.second)
1240 ReturnType = Constructor->getThisType(CurrContext)->
getPointeeType();
1244 if (
const ReturnTypestateAttr *RTSAttr = D->
getAttr<ReturnTypestateAttr>()) {
1246 if (!RD || !RD->
hasAttr<ConsumableAttr>()) {
1251 WarningsHandler.warnReturnTypestateForUnconsumableType(
1252 RTSAttr->getLocation(), ReturnType.
getAsString());
1253 ExpectedReturnState =
CS_None;
1258 ExpectedReturnState =
CS_None;
1263 ExpectedReturnState =
CS_None;
1266 bool ConsumedAnalyzer::splitState(
const CFGBlock *CurrBlock,
1269 std::unique_ptr<ConsumedStateMap> FalseStates(
1273 if (
const IfStmt *IfNode =
1276 const Expr *Cond = IfNode->getCond();
1278 PInfo = Visitor.getInfo(Cond);
1279 if (!PInfo.
isValid() && isa<BinaryOperator>(Cond))
1280 PInfo = Visitor.getInfo(cast<BinaryOperator>(Cond)->getRHS());
1283 CurrStates->setSource(Cond);
1284 FalseStates->setSource(Cond);
1300 PInfo = Visitor.getInfo(BinOp->getLHS());
1302 if ((BinOp = dyn_cast_or_null<BinaryOperator>(BinOp->getLHS()))) {
1303 PInfo = Visitor.getInfo(BinOp->getRHS());
1313 CurrStates->setSource(BinOp);
1314 FalseStates->setSource(BinOp);
1316 const VarTestResult &Test = PInfo.
getVarTest();
1319 if (BinOp->getOpcode() ==
BO_LAnd) {
1321 CurrStates->setState(Test.Var, Test.TestsFor);
1323 CurrStates->markUnreachable();
1325 }
else if (BinOp->getOpcode() ==
BO_LOr) {
1327 FalseStates->setState(Test.Var,
1329 else if (VarState == Test.TestsFor)
1330 FalseStates->markUnreachable();
1340 BlockInfo.addInfo(*SI, CurrStates);
1345 BlockInfo.addInfo(*SI, FalseStates.release());
1347 CurrStates =
nullptr;
1360 determineExpectedReturnState(AC, D);
1371 for (
const auto *PI : D->
params())
1375 for (
const auto *CurrBlock : *SortedGraph) {
1377 CurrStates = BlockInfo.getInfo(CurrBlock);
1382 }
else if (!CurrStates->isReachable()) {
1384 CurrStates =
nullptr;
1388 Visitor.
reset(CurrStates);
1391 for (
const auto &B : *CurrBlock) {
1392 switch (B.getKind()) {
1404 CurrStates->remove(BTE);
1426 if (!splitState(CurrBlock, Visitor)) {
1427 CurrStates->setSource(
nullptr);
1429 if (CurrBlock->succ_size() > 1 ||
1430 (CurrBlock->succ_size() == 1 &&
1431 (*CurrBlock->succ_begin())->pred_size() > 1)) {
1433 bool OwnershipTaken =
false;
1436 SE = CurrBlock->succ_end(); SI != SE; ++SI) {
1438 if (*SI ==
nullptr)
continue;
1440 if (BlockInfo.isBackEdge(CurrBlock, *SI)) {
1441 BlockInfo.borrowInfo(*SI)->intersectAtLoopHead(*SI, CurrBlock,
1445 if (BlockInfo.allBackEdgesVisited(CurrBlock, *SI))
1446 BlockInfo.discardInfo(*SI);
1448 BlockInfo.addInfo(*SI, CurrStates, OwnershipTaken);
1452 if (!OwnershipTaken)
1455 CurrStates =
nullptr;
1461 CurrStates->checkParamsForReturnTypestate(D->
getLocation(),
1468 WarningsHandler.emitDiagnostics();
A call to an overloaded operator written using operator syntax.
Defines the clang::ASTContext interface.
ASTContext & getASTContext() const
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
QualType getCallResultType() const
Determine the type of an expression that calls this function.
void VisitCastExpr(const CastExpr *Cast)
succ_iterator succ_begin()
Expr * GetTemporaryExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue...
virtual void warnParamReturnTypestateMismatch(SourceLocation Loc, StringRef VariableName, StringRef ExpectedState, StringRef ObservedState)
Warn about parameter typestate mismatches upon return.
std::string getAsString() const
void VisitUnaryOperator(const UnaryOperator *UOp)
bool isInStdNamespace() const
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
bool handleCall(const CallExpr *Call, const Expr *ObjArg, const FunctionDecl *FunD)
const Expr * getInit() const
Represents a call to a C++ constructor.
void run(AnalysisDeclContext &AC)
Check a function's CFG for consumed violations.
SourceLocation getLocStart() const LLVM_READONLY
Represents a C++ constructor within a class.
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
static ConsumedState testsFor(const FunctionDecl *FunDecl)
void setState(const VarDecl *Var, ConsumedState State)
Set the consumed state of a given variable.
SourceLocation getReturnLoc() const
void VisitCXXMemberCallExpr(const CXXMemberCallExpr *Call)
const VarTestResult & getLTest() const
unsigned succ_size() const
QualType getThisType(ASTContext &C) const
Returns the type of the this pointer.
Expr * IgnoreImplicit() LLVM_READONLY
const BinaryOperator * testSourceNode() const
void remove(const CXXBindTemporaryExpr *Tmp)
Remove the temporary value from our state map.
ParmVarDecl - Represents a parameter to a function.
Defines the clang::Expr interface and subclasses for C++ expressions.
PropagationInfo(const VarTestResult &VarTest)
PropagationInfo(const VarDecl *Var)
void intersectAtLoopHead(const CFGBlock *LoopHead, const CFGBlock *LoopBack, const ConsumedStateMap *LoopBackStates, ConsumedWarningsHandlerBase &WarningsHandler)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
ConsumedStmtVisitor(AnalysisDeclContext &AC, ConsumedAnalyzer &Analyzer, ConsumedStateMap *StateMap)
bool isReferenceType() const
Expr * getImplicitObjectArgument() const
Retrieves the implicit object argument for the member call.
const CXXRecordDecl * getPointeeCXXRecordDecl() const
PropagationInfo(const BinaryOperator *Source, EffectiveOp EOp, const VarDecl *LVar, ConsumedState LTestsFor, const VarDecl *RVar, ConsumedState RTestsFor)
static void splitVarStateForIf(const IfStmt *IfNode, const VarTestResult &Test, ConsumedStateMap *ThenStates, ConsumedStateMap *ElseStates)
PropagationInfo invertTest() const
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
bool isMoveConstructor(unsigned &TypeQuals) const
Determine whether this constructor is a move constructor (C++0x [class.copy]p3), which can be used to...
PropagationInfo(const CXXBindTemporaryExpr *Tmp)
static ConsumedState mapReturnTypestateAttrState(const ReturnTypestateAttr *RTSAttr)
void markUnreachable()
Mark the block as unreachable.
const VarTestResult & getVarTest() const
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
ConsumedState getState(const VarDecl *Var) const
Get the consumed state of a given variable.
const VarTestResult & getRTest() const
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...
bool allBackEdgesVisited(const CFGBlock *CurrBlock, const CFGBlock *TargetBlock)
const VarDecl * getVarDecl() const
const CXXBindTemporaryExpr * Tmp
unsigned pred_size() const
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Temp)
A builtin binary operation expression such as "x + y" or "x <= y".
std::string getNameAsString() const
Represents binding an expression to a temporary.
const Decl * getDecl() const
const Stmt * getTriggerStmt() const
static bool isConsumableType(const QualType &QT)
static void splitVarStateForIfBinOp(const PropagationInfo &PInfo, ConsumedStateMap *ThenStates, ConsumedStateMap *ElseStates)
CXXMethodDecl * getMethodDecl() const
Retrieves the declaration of the called method.
QualType getPointeeType() const
virtual void warnLoopStateMismatch(SourceLocation Loc, StringRef VariableName)
Warn that a variable's state doesn't match at the entry and exit of a loop.
static bool isPointerOrRef(QualType ParamType)
bool isBackEdge(const CFGBlock *From, const CFGBlock *To)
void clearTemporaries()
Clear the TmpMap.
static StringRef stateToString(ConsumedState State)
const CXXBindTemporaryExpr * getTmp() const
Defines an enumeration for C++ overloaded operators.
const ParmVarDecl * getParamDecl(unsigned i) const
void VisitDeclRefExpr(const DeclRefExpr *DeclRef)
PropagationInfo(ConsumedState State)
AdjacentBlocks::const_iterator const_pred_iterator
Expr * getSubExpr() const
unsigned getBlockID() const
ConsumedStateMap * getInfo(const CFGBlock *Block)
const ConsumedState & getState() const
bool operator!=(const ConsumedStateMap *Other) const
Tests to see if there is a mismatch in the states stored in two maps.
void checkCallability(const PropagationInfo &PInfo, const FunctionDecl *FunDecl, SourceLocation BlameLoc)
reverse_iterator rbegin()
void VisitVarDecl(const VarDecl *Var)
void VisitReturnStmt(const ReturnStmt *Ret)
void VisitDeclStmt(const DeclStmt *DelcS)
const VarDecl * getVar() const
static ConsumedState mapConsumableAttrState(const QualType QT)
CFGTerminator getTerminator()
void intersect(const ConsumedStateMap *Other)
Merge this state map with another map.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
unsigned getNumParams() const
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isSingleDecl() const
Represents a static or instance method of a struct/union/class.
const Stmt * getStmt() const
static bool isTestingFunction(const FunctionDecl *FunDecl)
static bool isKnownState(ConsumedState State)
PropagationInfo(const BinaryOperator *Source, EffectiveOp EOp, const VarTestResult <est, const VarTestResult &RTest)
void VisitMemberExpr(const MemberExpr *MExpr)
static bool isSetOnReadPtrType(const QualType &QT)
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Call)
AdjacentBlocks::const_iterator const_succ_iterator
const Decl * getSingleDecl() const
SourceLocation getExprLoc() const LLVM_READONLY
pred_iterator pred_begin()
void reset(ConsumedStateMap *NewStateMap)
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
static void setStateForVarOrTmp(ConsumedStateMap *StateMap, const PropagationInfo &PInfo, ConsumedState State)
void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap, bool &AlreadyOwned)
A class that handles the analysis of uniqueness violations.
const Expr * getRetValue() const
unsigned getNumArgs() const
bool isRValueReferenceType() const
static bool isRValueRef(QualType ParamType)
static const TypeInfo & getInfo(unsigned id)
void VisitParmVarDecl(const ParmVarDecl *Param)
ConsumedStateMap * borrowInfo(const CFGBlock *Block)
PropagationInfo(const VarDecl *Var, ConsumedState TestsFor)
virtual ~ConsumedWarningsHandlerBase()
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isDefaultConstructor() const
void discardInfo(const CFGBlock *Block)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
static SourceLocation getFirstStmtLoc(const CFGBlock *Block)
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Defines the clang::SourceLocation class and associated facilities.
void VisitCallExpr(const CallExpr *Call)
void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Temp)
Represents a C++ struct/union/class.
static bool isAutoCastType(const QualType &QT)
void VisitBinaryOperator(const BinaryOperator *BinOp)
CFGElement - Represents a top-level expression in a basic block.
bool isBackEdgeTarget(const CFGBlock *Block)
static ConsumedState mapParamTypestateAttrState(const ParamTypestateAttr *PTAttr)
static bool isCallableInState(const CallableWhenAttr *CWAttr, ConsumedState State)
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
void VisitCXXConstructExpr(const CXXConstructExpr *Call)
bool isPointerToValue() const
const Expr * getSubExpr() const
static SourceLocation getLastStmtLoc(const CFGBlock *Block)
SourceLocation getLocation() const
static ConsumedState mapSetTypestateAttrState(const SetTypestateAttr *STAttr)
PropagationInfo getInfo(const Expr *StmtNode) const
bool isConstQualified() const
Determine whether this type is const-qualified.
unsigned getNumBlockIDs() const
static ConsumedState invertConsumedUnconsumed(ConsumedState State)
ConsumedState getAsState(const ConsumedStateMap *StateMap) const
EffectiveOp testEffectiveOp() const
Expr * IgnoreParens() LLVM_READONLY
bool isPointerType() const