Go to the documentation of this file.
21 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
22 #define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
32 #include "llvm/ADT/DenseMap.h"
33 #include "llvm/ADT/PointerIntPair.h"
34 #include "llvm/ADT/SmallVector.h"
35 #include "llvm/Support/Casting.h"
43 class AbstractConditionalOperator;
44 class ArraySubscriptExpr;
48 class CXXDestructorDecl;
49 class CXXMemberCallExpr;
50 class CXXOperatorCallExpr;
59 namespace threadSafety {
72 if (isa<til::Wildcard>(E1))
73 return isa<til::Wildcard>(E2);
74 if (isa<til::Wildcard>(E2))
75 return isa<til::Wildcard>(E1);
81 const auto *PE1 = dyn_cast_or_null<til::Project>(E1);
84 const auto *PE2 = dyn_cast_or_null<til::Project>(E2);
87 return PE1->clangDecl() == PE2->clangDecl();
106 void enterCFGBlock(
const CFGBlock *B) {}
109 bool visitPredecessors() {
return true; }
112 void handlePredecessor(
const CFGBlock *Pred) {}
115 void handlePredecessorBackEdge(
const CFGBlock *Pred) {}
118 void enterCFGBlockBody(
const CFGBlock *B) {}
121 void handleStatement(
const Stmt *S) {}
127 void exitCFGBlockBody(
const CFGBlock *B) {}
130 bool visitSuccessors() {
return true; }
133 void handleSuccessor(
const CFGBlock *Succ) {}
136 void handleSuccessorBackEdge(
const CFGBlock *Succ) {}
139 void exitCFGBlock(
const CFGBlock *B) {}
159 if (!isa_and_nonnull<NamedDecl>(AC.
getDecl()))
170 template <
class Visitor>
176 for (
const auto *CurrBlock : *SortedGraph) {
177 VisitedBlocks.
insert(CurrBlock);
179 V.enterCFGBlock(CurrBlock);
182 if (
V.visitPredecessors()) {
186 SE = CurrBlock->pred_end();
192 BackEdges.push_back(*SI);
195 V.handlePredecessor(*SI);
198 for (
auto *Blk : BackEdges)
199 V.handlePredecessorBackEdge(Blk);
202 V.enterCFGBlockBody(CurrBlock);
205 for (
const auto &BI : *CurrBlock) {
206 switch (BI.getKind()) {
216 V.handleDestructorCall(VD, DD);
224 V.exitCFGBlockBody(CurrBlock);
227 if (
V.visitSuccessors()) {
232 SE = CurrBlock->succ_end();
238 ForwardEdges.push_back(*SI);
241 V.handleSuccessorBackEdge(*SI);
244 for (
auto *Blk : ForwardEdges)
245 V.handleSuccessor(Blk);
248 V.exitCFGBlock(CurrBlock);
257 return dyn_cast<NamedDecl>(ACtx->
getDecl());
263 CFG *CFGraph =
nullptr;
274 llvm::PointerIntPair<const til::SExpr *, 1, bool> CapExpr;
282 : CapExpr(E, Neg), CapKind(
Kind) {}
292 return CapabilityExpr(CapExpr.getPointer(), CapKind, !CapExpr.getInt());
317 if (
const auto *
P = dyn_cast<til::Project>(
sexpr()))
318 return P->clangDecl();
319 if (
const auto *
P = dyn_cast<til::LiteralPtr>(
sexpr()))
320 return P->clangDecl();
411 const Expr *SelfE =
nullptr);
429 til::SExpr *translateAbstractConditionalOperator(
435 using StatementMap = llvm::DenseMap<const Stmt *, til::SExpr *>;
438 using LVarIndexMap = llvm::DenseMap<const ValueDecl *, unsigned>;
441 using NameVarPair = std::pair<const ValueDecl *, til::SExpr *>;
446 bool HasBackEdges =
false;
449 unsigned UnprocessedSuccessors = 0;
452 unsigned ProcessedPredecessors = 0;
454 BlockInfo() =
default;
455 BlockInfo(BlockInfo &&) =
default;
456 BlockInfo &operator=(BlockInfo &&) =
default;
460 void enterCFGBlock(
const CFGBlock *B);
461 bool visitPredecessors() {
return true; }
462 void handlePredecessor(
const CFGBlock *Pred);
463 void handlePredecessorBackEdge(
const CFGBlock *Pred);
464 void enterCFGBlockBody(
const CFGBlock *B);
465 void handleStatement(
const Stmt *S);
467 void exitCFGBlockBody(
const CFGBlock *B);
468 bool visitSuccessors() {
return true; }
469 void handleSuccessor(
const CFGBlock *Succ);
470 void handleSuccessorBackEdge(
const CFGBlock *Succ);
471 void exitCFGBlock(
const CFGBlock *B);
472 void exitCFG(
const CFGBlock *Last);
474 void insertStmt(
const Stmt *S, til::SExpr *E) {
475 SMap.insert(std::make_pair(S, E));
478 til::SExpr *getCurrentLVarDefinition(
const ValueDecl *VD);
480 til::SExpr *addStatement(til::SExpr *E,
const Stmt *S,
481 const ValueDecl *VD =
nullptr);
482 til::SExpr *lookupVarDecl(
const ValueDecl *VD);
483 til::SExpr *addVarDecl(
const ValueDecl *VD, til::SExpr *E);
484 til::SExpr *updateVarDecl(
const ValueDecl *VD, til::SExpr *E);
486 void makePhiNodeVar(
unsigned i,
unsigned NPreds, til::SExpr *E);
487 void mergeEntryMap(LVarDefinitionMap Map);
488 void mergeEntryMapBackEdge();
489 void mergePhiNodesBackEdge(
const CFGBlock *Blk);
494 static const bool CapabilityExprMode =
true;
496 til::MemRegionRef Arena;
499 til::Variable *SelfVar =
nullptr;
501 til::SCFG *Scfg =
nullptr;
507 LVarIndexMap LVarIdxMap;
510 std::vector<til::BasicBlock *> BlockMap;
513 std::vector<BlockInfo> BBInfo;
515 LVarDefinitionMap CurrentLVarMap;
516 std::vector<til::Phi *> CurrentArguments;
517 std::vector<til::SExpr *> CurrentInstructions;
518 std::vector<til::Phi *> IncompleteArgs;
519 til::BasicBlock *CurrentBB =
nullptr;
520 BlockInfo *CurrentBlockInfo =
nullptr;
529 #endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
bool equals(const til::SExpr *E1, const til::SExpr *E2)
ASTContext & getASTContext() const
til::SExpr * lookupStmt(const Stmt *S)
bool shouldIgnore() const
til::BasicBlock * lookupBlock(const CFGBlock *B)
static bool compareExprs(const SExpr *E1, const SExpr *E2)
bool matchesUniv(const CapabilityExpr &CapE) const
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
This represents a decl that may have a name.
unsigned getBlockID() const
AnalysisDeclContext contains the context data for the function, method or block under analysis.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
TIL_BinaryOpcode
Opcode for binary arithmetic operations.
AdjacentBlocks::const_iterator const_succ_iterator
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
CapabilityExpr operator!() const
const VarDecl * getVarDecl() const
Represents a single basic block in a source-level CFG.
const NamedDecl * getDecl() const
bool matches(const CapabilityExpr &other) const
void printSCFG(CFGWalker &Walker)
SExprBuilder(til::MemRegionRef A)
A builtin binary operation expression such as "x + y" or "x <= y".
til::SCFG * buildCFG(CFGWalker &Walker)
std::string toString(const til::SExpr *E)
bool partiallyMatches(const til::SExpr *E1, const til::SExpr *E2)
const ValueDecl * valueDecl() const
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
CapabilityExpr translateAttrExpr(const Expr *AttrExp, const NamedDecl *D, const Expr *DeclExp, VarDecl *SelfD=nullptr)
Translate a clang expression in an attribute to a til::SExpr.
StringRef getKind() const
Represents a C++ destructor within a class.
Represents a variable declaration or definition.
SExprBuilder::CallingContext CallingContext
const PostOrderCFGView * getSortedGraph() const
llvm::DenseMap< const Stmt *, CFGBlock * > SMap
const CFG * getGraph() const
static void print(const SExpr *E, std::ostream &SS)
CallingContext(CallingContext *P, const NamedDecl *D=nullptr)
Encapsulates the lexical context of a function call.
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
const Stmt * getStmt() const
CapabilityExpr(const til::SExpr *E, StringRef Kind, bool Neg)
bool matches(const til::SExpr *E1, const til::SExpr *E2)
@ VK_SFun
SFunction (self) parameter.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Represents the this expression in C++.
A basic block is part of an SCFG.
const Expr *const * FunArgs
bool partiallyMatches(const CapabilityExpr &other) const
const Decl * getDecl() const
Stmt - This represents one statement.
bool equals(const CapabilityExpr &other) const
const NamedDecl * AttrDecl
std::string toString() const
std::pair< llvm::NoneType, bool > insert(const CFGBlock *Block)
Set the bit associated with a particular CFGBlock.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
til::SExpr * translate(const Stmt *S, CallingContext *Ctx)
bool init(AnalysisDeclContext &AC)
Implements a set of CFGBlocks using a BitVector.
static bool compareExprs(const SExpr *E1, const SExpr *E2)
This represents one expression.
An SCFG is a control-flow graph.
const til::SCFG * getCFG() const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
bool alreadySet(const CFGBlock *Block)
Check if the bit for a CFGBlock has been already set.
A reference to a declared variable, function, enum, etc.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
A call to an overloaded operator written using operator syntax.
const til::SExpr * sexpr() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Represents a call to a member function that may be written either with member call syntax (e....
AdjacentBlocks::const_iterator const_pred_iterator
void setKind(VariableKind K)
Base class for AST nodes in the typed intermediate language.