r205915 - Thread Safety Analysis: some minor cleanups to the latest thread safety changes. No functional changes intended.
Aaron Ballman
aaron at aaronballman.com
Wed Apr 9 10:45:45 PDT 2014
Author: aaronballman
Date: Wed Apr 9 12:45:44 2014
New Revision: 205915
URL: http://llvm.org/viewvc/llvm-project?rev=205915&view=rev
Log:
Thread Safety Analysis: some minor cleanups to the latest thread safety changes. No functional changes intended.
* Adds an iterator_range interface to CallExpr to get the arguments
* Modifies SExpr such that it must be allocated in the Arena, and cannot be deleted
* Minor const-correctness and nullptr updates
* Adds some operator!= implementations to complement operator==
* Removes unused functionality
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=205915&r1=205914&r2=205915&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Wed Apr 9 12:45:44 2014
@@ -2227,6 +2227,13 @@ public:
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
+ typedef llvm::iterator_range<arg_iterator> arg_range;
+ typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+
+ arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
+ arg_const_range arguments() const {
+ return arg_const_range(arg_begin(), arg_end());
+ }
arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
arg_iterator arg_end() {
Modified: cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyCommon.h?rev=205915&r1=205914&r2=205915&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyCommon.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyCommon.h Wed Apr 9 12:45:44 2014
@@ -42,35 +42,32 @@
namespace clang {
namespace threadSafety {
-
-// Simple Visitor class for traversing a clang CFG.
-class CFGVisitor {
-public:
- // Enter the CFG for Decl D, and perform any initial setup operations.
- void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First) {}
-
- // Enter a CFGBlock.
- void enterCFGBlock(const CFGBlock *B) {}
-
- // Process an ordinary statement.
- void handleStatement(const Stmt *S) {}
-
- // Process a destructor call
- void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD) {}
-
- // Process a successor edge.
- void handleSuccessor(const CFGBlock *Succ) {}
-
- // Process a successor back edge to a previously visited block.
- void handleSuccessorBackEdge(const CFGBlock *Succ) {}
-
- // Leave a CFGBlock.
- void exitCFGBlock(const CFGBlock *B) {}
-
- // Leave the CFG, and perform any final cleanup operations.
- void exitCFG(const CFGBlock *Last) {}
-};
-
+// CFG traversal uses templates instead of virtual function dispatch. Visitors
+// must implement the following functions:
+//
+// Enter the CFG for Decl D, and perform any initial setup operations.
+// void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First) {}
+//
+// Enter a CFGBlock.
+// void enterCFGBlock(const CFGBlock *B) {}
+//
+// Process an ordinary statement.
+// void handleStatement(const Stmt *S) {}
+//
+// Process a destructor call
+// void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD) {}
+//
+// Process a successor edge.
+// void handleSuccessor(const CFGBlock *Succ) {}
+//
+// Process a successor back edge to a previously visited block.
+// void handleSuccessorBackEdge(const CFGBlock *Succ) {}
+//
+// Leave a CFGBlock.
+// void exitCFGBlock(const CFGBlock *B) {}
+//
+// Leave the CFG, and perform any final cleanup operations.
+// void exitCFG(const CFGBlock *Last) {}
// Walks the clang CFG, and invokes methods on a given CFGVisitor.
class CFGWalker {
@@ -104,13 +101,13 @@ public:
V.enterCFG(CFGraph, FDecl, &CFGraph->getEntry());
- for (const CFGBlock* CurrBlock : *SortedGraph) {
+ for (const auto *CurrBlock : *SortedGraph) {
VisitedBlocks.insert(CurrBlock);
V.enterCFGBlock(CurrBlock);
// Process statements
- for (auto BI : *CurrBlock) {
+ for (const auto &BI : *CurrBlock) {
switch (BI.getKind()) {
case CFGElement::Statement: {
V.handleStatement(BI.castAs<CFGStmt>().getStmt());
Modified: cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyTIL.h?rev=205915&r1=205914&r2=205915&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyTIL.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyTIL.h Wed Apr 9 12:45:44 2014
@@ -207,6 +207,10 @@ public:
// compare all subexpressions, following the comparator interface
// }
+ void *operator new(size_t S, clang::threadSafety::til::MemRegionRef &R) {
+ return ::operator new(S, R);
+ }
+
protected:
SExpr(TIL_Opcode Op) : Opcode(Op), Reserved(0), Flags(0) {}
SExpr(const SExpr &E) : Opcode(E.Opcode), Reserved(0), Flags(E.Flags) {}
@@ -216,7 +220,15 @@ protected:
unsigned short Flags;
private:
- SExpr();
+ // Note, this cannot be explicitly deleted due to initializers automatically
+ // referencing destructor declarations. However, it does not need to be
+ // defined because that reference does not require an definition.
+ ~SExpr();
+ SExpr() = delete;
+
+ // SExpr objects must be created in an arena and cannot be deleted.
+ void *operator new(size_t) = delete;
+ void operator delete(void *) = delete;
};
@@ -227,7 +239,7 @@ class SExprRef {
public:
SExprRef() : Ptr(nullptr) { }
SExprRef(std::nullptr_t P) : Ptr(nullptr) { }
- SExprRef(SExprRef &&R) : Ptr(R.Ptr) { }
+ SExprRef(SExprRef &&R) : Ptr(R.Ptr) { R.Ptr = nullptr; }
// Defined after Variable and Future, below.
inline SExprRef(SExpr *P);
@@ -242,9 +254,12 @@ public:
SExpr &operator*() { return *Ptr; }
const SExpr &operator*() const { return *Ptr; }
- bool operator==(const SExprRef& R) const { return Ptr == R.Ptr; }
- bool operator==(const SExpr* P) const { return Ptr == P; }
- bool operator==(std::nullptr_t P) const { return Ptr == nullptr; }
+ bool operator==(const SExprRef &R) const { return Ptr == R.Ptr; }
+ bool operator!=(const SExprRef &R) const { return !operator==(R); }
+ bool operator==(const SExpr *P) const { return Ptr == P; }
+ bool operator!=(const SExpr *P) const { return !operator==(P); }
+ bool operator==(std::nullptr_t) const { return Ptr == nullptr; }
+ bool operator!=(std::nullptr_t) const { return Ptr != nullptr; }
inline void reset(SExpr *E);
@@ -252,28 +267,17 @@ private:
inline void attach();
inline void detach();
- SExprRef(const SExprRef& R) : Ptr(R.Ptr) { }
-
SExpr *Ptr;
};
// Contains various helper functions for SExprs.
-class ThreadSafetyTIL {
-public:
- static const int MaxOpcode = COP_MAX;
-
- static inline bool isTrivial(SExpr *E) {
- unsigned Op = E->opcode();
- return Op == COP_Variable || Op == COP_Literal || Op == COP_LiteralPtr;
- }
-
- static inline bool isLargeValue(SExpr *E) {
- unsigned Op = E->opcode();
- return (Op >= COP_Function && Op <= COP_Code);
- }
-};
-
+namespace ThreadSafetyTIL {
+static bool isTrivial(SExpr *E) {
+ unsigned Op = E->opcode();
+ return Op == COP_Variable || Op == COP_Literal || Op == COP_LiteralPtr;
+}
+}
class Function;
class SFunction;
@@ -311,7 +315,7 @@ public:
VariableKind kind() const { return static_cast<VariableKind>(Flags); }
- StringRef name() const { return Cvdecl ? Cvdecl->getName() : "_x"; }
+ const StringRef name() const { return Cvdecl ? Cvdecl->getName() : "_x"; }
const clang::ValueDecl *clangDecl() const { return Cvdecl; }
// Returns the definition (for let vars) or type (for parameter & self vars)
@@ -320,8 +324,8 @@ public:
void attachVar() const { ++NumUses; }
void detachVar() const { assert(NumUses > 0); --NumUses; }
- unsigned getID() { return Id; }
- unsigned getBlockID() { return BlockID; }
+ unsigned getID() const { return Id; }
+ unsigned getBlockID() const { return BlockID; }
void setID(unsigned Bid, unsigned I) {
BlockID = static_cast<unsigned short>(Bid);
@@ -369,7 +373,7 @@ public:
Future() :
SExpr(COP_Future), Status(FS_pending), Result(nullptr), Location(nullptr)
{}
- virtual ~Future() {}
+ virtual ~Future() = delete;
// Registers the location in the AST where this future is stored.
// Forcing the future will automatically update the AST.
Modified: cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp?rev=205915&r1=205914&r2=205915&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp (original)
+++ cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp Wed Apr 9 12:45:44 2014
@@ -37,11 +37,11 @@ typedef SExprBuilder::CallingContext Cal
til::SExpr *SExprBuilder::lookupStmt(const Stmt *S) {
if (!SMap)
- return 0;
+ return nullptr;
auto It = SMap->find(S);
if (It != SMap->end())
return It->second;
- return 0;
+ return nullptr;
}
void SExprBuilder::insertStmt(const Stmt *S, til::Variable *V) {
@@ -160,8 +160,8 @@ til::SExpr *SExprBuilder::translateCallE
CallingContext *Ctx) {
// TODO -- Lock returned
til::SExpr *E = translate(CE->getCallee(), Ctx);
- for (unsigned I = 0, N = CE->getNumArgs(); I < N; ++I) {
- til::SExpr *A = translate(CE->getArg(I), Ctx);
+ for (const auto *Arg : CE->arguments()) {
+ til::SExpr *A = translate(Arg, Ctx);
E = new (Arena) til::Apply(E, A);
}
return new (Arena) til::Call(E, CE);
@@ -200,10 +200,9 @@ til::SExpr *SExprBuilder::translateUnary
case UO_LNot:
case UO_Real:
case UO_Imag:
- case UO_Extension: {
- til::SExpr *E0 = translate(UO->getSubExpr(), Ctx);
- return new (Arena) til::UnaryOp(UO->getOpcode(), E0);
- }
+ case UO_Extension:
+ return new (Arena)
+ til::UnaryOp(UO->getOpcode(), translate(UO->getSubExpr(), Ctx));
}
return new (Arena) til::Undefined(UO);
}
@@ -232,16 +231,15 @@ til::SExpr *SExprBuilder::translateBinar
case BO_Xor:
case BO_Or:
case BO_LAnd:
- case BO_LOr: {
- til::SExpr *E0 = translate(BO->getLHS(), Ctx);
- til::SExpr *E1 = translate(BO->getRHS(), Ctx);
- return new (Arena) til::BinaryOp(BO->getOpcode(), E0, E1);
- }
- case BO_Assign: {
- til::SExpr *E0 = translate(BO->getLHS(), Ctx);
- til::SExpr *E1 = translate(BO->getRHS(), Ctx);
- return new (Arena) til::Store(E0, E1);
- }
+ case BO_LOr:
+ return new (Arena)
+ til::BinaryOp(BO->getOpcode(), translate(BO->getLHS(), Ctx),
+ translate(BO->getRHS(), Ctx));
+
+ case BO_Assign:
+ return new (Arena)
+ til::Store(translate(BO->getLHS(), Ctx), translate(BO->getRHS(), Ctx));
+
case BO_MulAssign:
case BO_DivAssign:
case BO_RemAssign:
@@ -284,42 +282,39 @@ til::SExpr *SExprBuilder::translateCastE
}
}
-
-til::SExpr *SExprBuilder::translateArraySubscriptExpr(
- const ArraySubscriptExpr *E, CallingContext *Ctx) {
+til::SExpr *
+SExprBuilder::translateArraySubscriptExpr(const ArraySubscriptExpr *E,
+ CallingContext *Ctx) {
return new (Arena) til::Undefined(E);
}
-
-til::SExpr *SExprBuilder::translateConditionalOperator(
- const ConditionalOperator *C, CallingContext *Ctx) {
+til::SExpr *
+SExprBuilder::translateConditionalOperator(const ConditionalOperator *C,
+ CallingContext *Ctx) {
return new (Arena) til::Undefined(C);
}
-
til::SExpr *SExprBuilder::translateBinaryConditionalOperator(
const BinaryConditionalOperator *C, CallingContext *Ctx) {
return new (Arena) til::Undefined(C);
}
-
// Build a complete SCFG from a clang CFG.
-class SCFGBuilder : public CFGVisitor {
-public:
- til::Variable *addStatement(til::SExpr* E, const Stmt *S) {
+class SCFGBuilder {
+ void addStatement(til::SExpr* E, const Stmt *S) {
if (!E)
- return 0;
+ return;
if (til::ThreadSafetyTIL::isTrivial(E))
- return 0;
+ return;
til::Variable *V = new (Arena) til::Variable(til::Variable::VK_Let, E);
V->setID(CurrentBlockID, CurrentVarID++);
CurrentBB->addInstr(V);
if (S)
BuildEx.insertStmt(S, V);
- return V;
}
+public:
// Enter the CFG for Decl D, and perform any initial setup operations.
void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First) {
Scfg = new (Arena) til::SCFG(Arena, Cfg->getNumBlockIDs());
@@ -345,7 +340,7 @@ public:
til::SExpr *Sf = new (Arena) til::LiteralPtr(VD);
til::SExpr *Dr = new (Arena) til::LiteralPtr(DD);
til::SExpr *Ap = new (Arena) til::Apply(Dr, Sf);
- til::SExpr *E = new (Arena) til::Call(Ap, 0);
+ til::SExpr *E = new (Arena) til::Call(Ap);
addStatement(E, nullptr);
}
@@ -363,20 +358,15 @@ public:
// Leave the CFG, and perform any final cleanup operations.
void exitCFG(const CFGBlock *Last) {
- if (CallCtx) {
- delete CallCtx;
- CallCtx = nullptr;
- }
+ delete CallCtx;
+ CallCtx = nullptr;
}
SCFGBuilder(til::MemRegionRef A)
- : Arena(A), Scfg(0), CurrentBB(0), CurrentBlockID(0),
- CallCtx(0), SMap(new SExprBuilder::StatementMap()),
- BuildEx(A, SMap)
- { }
- ~SCFGBuilder() {
- delete SMap;
- }
+ : Arena(A), Scfg(nullptr), CurrentBB(nullptr), CurrentBlockID(0),
+ CurrentVarID(0), CallCtx(nullptr),
+ SMap(new SExprBuilder::StatementMap()), BuildEx(A, SMap) {}
+ ~SCFGBuilder() { delete SMap; }
til::SCFG *getCFG() const { return Scfg; }
More information about the cfe-commits
mailing list