diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2018-07-31 19:46:14 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2018-07-31 19:46:14 +0000 |
commit | e1f306210000b805c9870097a75e99b217bdd631 (patch) | |
tree | 3d071f0e0c6491cf486eab71d3f6f66ac6d05834 /clang/lib/Analysis | |
parent | bd880fe1c1235f48d5e537af563362ddc4f8af53 (diff) | |
download | bcm5719-llvm-e1f306210000b805c9870097a75e99b217bdd631.tar.gz bcm5719-llvm-e1f306210000b805c9870097a75e99b217bdd631.zip |
[CFG] [analyzer] Add construction contexts for returning C++ objects in ObjC++.
Like any normal funciton, Objective-C message can return a C++ object
in Objective-C++. Such object would require a construction context.
This patch, therefore, is an extension of r327343 onto Objective-C++.
Differential Revision: https://reviews.llvm.org/D48608
llvm-svn: 338426
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 9e4fbd68899..cef75e91f43 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -743,6 +743,19 @@ private: void addLocalScopeAndDtors(Stmt *S); + const ConstructionContext *retrieveAndCleanupConstructionContext(Expr *E) { + if (!BuildOpts.AddRichCXXConstructors) + return nullptr; + + const ConstructionContextLayer *Layer = ConstructionContextMap.lookup(E); + if (!Layer) + return nullptr; + + cleanupConstructionContext(E); + return ConstructionContext::createFromLayers(cfg->getBumpVectorContext(), + Layer); + } + // Interface to CFGBlock - adding CFGElements. void appendStmt(CFGBlock *B, const Stmt *S) { @@ -755,16 +768,10 @@ private: } void appendConstructor(CFGBlock *B, CXXConstructExpr *CE) { - if (BuildOpts.AddRichCXXConstructors) { - if (const ConstructionContextLayer *Layer = - ConstructionContextMap.lookup(CE)) { - cleanupConstructionContext(CE); - if (const auto *CC = ConstructionContext::createFromLayers( - cfg->getBumpVectorContext(), Layer)) { - B->appendConstructor(CE, CC, cfg->getBumpVectorContext()); - return; - } - } + if (const ConstructionContext *CC = + retrieveAndCleanupConstructionContext(CE)) { + B->appendConstructor(CE, CC, cfg->getBumpVectorContext()); + return; } // No valid construction context found. Fall back to statement. @@ -775,18 +782,10 @@ private: if (alwaysAdd(CE) && cachedEntry) cachedEntry->second = B; - if (BuildOpts.AddRichCXXConstructors) { - if (CFGCXXRecordTypedCall::isCXXRecordTypedCall(CE, *Context)) { - if (const ConstructionContextLayer *Layer = - ConstructionContextMap.lookup(CE)) { - cleanupConstructionContext(CE); - if (const auto *CC = ConstructionContext::createFromLayers( - cfg->getBumpVectorContext(), Layer)) { - B->appendCXXRecordTypedCall(CE, CC, cfg->getBumpVectorContext()); - return; - } - } - } + if (const ConstructionContext *CC = + retrieveAndCleanupConstructionContext(CE)) { + B->appendCXXRecordTypedCall(CE, CC, cfg->getBumpVectorContext()); + return; } // No valid construction context found. Fall back to statement. @@ -809,6 +808,20 @@ private: B->appendMemberDtor(FD, cfg->getBumpVectorContext()); } + void appendObjCMessage(CFGBlock *B, ObjCMessageExpr *ME) { + if (alwaysAdd(ME) && cachedEntry) + cachedEntry->second = B; + + if (const ConstructionContext *CC = + retrieveAndCleanupConstructionContext(ME)) { + B->appendCXXRecordTypedCall(ME, CC, cfg->getBumpVectorContext()); + return; + } + + B->appendStmt(const_cast<ObjCMessageExpr *>(ME), + cfg->getBumpVectorContext()); + } + void appendTemporaryDtor(CFGBlock *B, CXXBindTemporaryExpr *E) { B->appendTemporaryDtor(E, cfg->getBumpVectorContext()); } @@ -1254,6 +1267,8 @@ static const VariableArrayType *FindVA(const Type *t) { void CFGBuilder::consumeConstructionContext( const ConstructionContextLayer *Layer, Expr *E) { + assert((isa<CXXConstructExpr>(E) || isa<CallExpr>(E) || + isa<ObjCMessageExpr>(E)) && "Expression cannot construct an object!"); if (const ConstructionContextLayer *PreviouslyStoredLayer = ConstructionContextMap.lookup(E)) { (void)PreviouslyStoredLayer; @@ -1297,10 +1312,11 @@ void CFGBuilder::findConstructionContexts( case Stmt::CallExprClass: case Stmt::CXXMemberCallExprClass: case Stmt::CXXOperatorCallExprClass: - case Stmt::UserDefinedLiteralClass: { - auto *CE = cast<CallExpr>(Child); - if (CFGCXXRecordTypedCall::isCXXRecordTypedCall(CE, *Context)) - consumeConstructionContext(Layer, CE); + case Stmt::UserDefinedLiteralClass: + case Stmt::ObjCMessageExprClass: { + auto *E = cast<Expr>(Child); + if (CFGCXXRecordTypedCall::isCXXRecordTypedCall(E)) + consumeConstructionContext(Layer, E); break; } case Stmt::ExprWithCleanupsClass: { @@ -3605,7 +3621,7 @@ CFGBlock *CFGBuilder::VisitObjCMessageExpr(ObjCMessageExpr *ME, findConstructionContextsForArguments(ME); autoCreateBlock(); - appendStmt(Block, ME); + appendObjCMessage(Block, ME); return VisitChildren(ME); } |