1 //== AnalysisDeclContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines AnalysisDeclContext, a class that manages the analysis context
11 // data for path sensitive analysis.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/Analysis/AnalysisDeclContext.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/DeclTemplate.h"
20 #include "clang/AST/ParentMap.h"
21 #include "clang/AST/StmtVisitor.h"
22 #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
23 #include "clang/Analysis/Analyses/LiveVariables.h"
24 #include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
25 #include "clang/Analysis/BodyFarm.h"
26 #include "clang/Analysis/CFG.h"
27 #include "clang/Analysis/CFGStmtMap.h"
28 #include "clang/Analysis/Support/BumpVector.h"
29 #include "llvm/ADT/SmallPtrSet.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/SaveAndRestore.h"
32 #include "llvm/Support/raw_ostream.h"
33 
34 using namespace clang;
35 
36 typedef llvm::DenseMap<const void *, ManagedAnalysis *> ManagedAnalysisMap;
37 
38 AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
39                                          const Decl *d,
40                                          const CFG::BuildOptions &buildOptions)
41   : Manager(Mgr),
42     D(d),
43     cfgBuildOptions(buildOptions),
44     forcedBlkExprs(nullptr),
45     builtCFG(false),
46     builtCompleteCFG(false),
47     ReferencedBlockVars(nullptr),
48     ManagedAnalyses(nullptr)
49 {
50   cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
51 }
52 
53 AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
54                                          const Decl *d)
55 : Manager(Mgr),
56   D(d),
57   forcedBlkExprs(nullptr),
58   builtCFG(false),
59   builtCompleteCFG(false),
60   ReferencedBlockVars(nullptr),
61   ManagedAnalyses(nullptr)
62 {
63   cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
64 }
65 
66 AnalysisDeclContextManager::AnalysisDeclContextManager(
67     ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,
68     bool addInitializers, bool addTemporaryDtors, bool addLifetime,
69     bool addLoopExit, bool synthesizeBodies, bool addStaticInitBranch,
70     bool addCXXNewAllocator, CodeInjector *injector)
71     : ASTCtx(ASTCtx), Injector(injector), SynthesizeBodies(synthesizeBodies) {
72   cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
73   cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
74   cfgBuildOptions.AddInitializers = addInitializers;
75   cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
76   cfgBuildOptions.AddLifetime = addLifetime;
77   cfgBuildOptions.AddLoopExit = addLoopExit;
78   cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
79   cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
80 }
81 
82 void AnalysisDeclContextManager::clear() { Contexts.clear(); }
83 
84 Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
85   IsAutosynthesized = false;
86   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
87     Stmt *Body = FD->getBody();
88     if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
89       Body = CoroBody->getBody();
90     if (Manager && Manager->synthesizeBodies()) {
91       Stmt *SynthesizedBody = Manager->getBodyFarm()->getBody(FD);
92       if (SynthesizedBody) {
93         Body = SynthesizedBody;
94         IsAutosynthesized = true;
95       }
96     }
97     return Body;
98   }
99   else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
100     Stmt *Body = MD->getBody();
101     if (Manager && Manager->synthesizeBodies()) {
102       Stmt *SynthesizedBody = Manager->getBodyFarm()->getBody(MD);
103       if (SynthesizedBody) {
104         Body = SynthesizedBody;
105         IsAutosynthesized = true;
106       }
107     }
108     return Body;
109   } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
110     return BD->getBody();
111   else if (const FunctionTemplateDecl *FunTmpl
112            = dyn_cast_or_null<FunctionTemplateDecl>(D))
113     return FunTmpl->getTemplatedDecl()->getBody();
114 
115   llvm_unreachable("unknown code decl");
116 }
117 
118 Stmt *AnalysisDeclContext::getBody() const {
119   bool Tmp;
120   return getBody(Tmp);
121 }
122 
123 bool AnalysisDeclContext::isBodyAutosynthesized() const {
124   bool Tmp;
125   getBody(Tmp);
126   return Tmp;
127 }
128 
129 bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
130   bool Tmp;
131   Stmt *Body = getBody(Tmp);
132   return Tmp && Body->getLocStart().isValid();
133 }
134 
135 /// Returns true if \param VD is an Objective-C implicit 'self' parameter.
136 static bool isSelfDecl(const VarDecl *VD) {
137   return isa<ImplicitParamDecl>(VD) && VD->getName() == "self";
138 }
139 
140 const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
141   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
142     return MD->getSelfDecl();
143   if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
144     // See if 'self' was captured by the block.
145     for (const auto &I : BD->captures()) {
146       const VarDecl *VD = I.getVariable();
147       if (isSelfDecl(VD))
148         return dyn_cast<ImplicitParamDecl>(VD);
149     }
150   }
151 
152   auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
153   if (!CXXMethod)
154     return nullptr;
155 
156   const CXXRecordDecl *parent = CXXMethod->getParent();
157   if (!parent->isLambda())
158     return nullptr;
159 
160   for (const LambdaCapture &LC : parent->captures()) {
161     if (!LC.capturesVariable())
162       continue;
163 
164     VarDecl *VD = LC.getCapturedVar();
165     if (isSelfDecl(VD))
166       return dyn_cast<ImplicitParamDecl>(VD);
167   }
168 
169   return nullptr;
170 }
171 
172 void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
173   if (!forcedBlkExprs)
174     forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
175   // Default construct an entry for 'stmt'.
176   if (const Expr *e = dyn_cast<Expr>(stmt))
177     stmt = e->IgnoreParens();
178   (void) (*forcedBlkExprs)[stmt];
179 }
180 
181 const CFGBlock *
182 AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
183   assert(forcedBlkExprs);
184   if (const Expr *e = dyn_cast<Expr>(stmt))
185     stmt = e->IgnoreParens();
186   CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
187     forcedBlkExprs->find(stmt);
188   assert(itr != forcedBlkExprs->end());
189   return itr->second;
190 }
191 
192 /// Add each synthetic statement in the CFG to the parent map, using the
193 /// source statement's parent.
194 static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
195   if (!TheCFG)
196     return;
197 
198   for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
199                                     E = TheCFG->synthetic_stmt_end();
200        I != E; ++I) {
201     PM.setParent(I->first, PM.getParent(I->second));
202   }
203 }
204 
205 CFG *AnalysisDeclContext::getCFG() {
206   if (!cfgBuildOptions.PruneTriviallyFalseEdges)
207     return getUnoptimizedCFG();
208 
209   if (!builtCFG) {
210     cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
211     // Even when the cfg is not successfully built, we don't
212     // want to try building it again.
213     builtCFG = true;
214 
215     if (PM)
216       addParentsForSyntheticStmts(cfg.get(), *PM);
217 
218     // The Observer should only observe one build of the CFG.
219     getCFGBuildOptions().Observer = nullptr;
220   }
221   return cfg.get();
222 }
223 
224 CFG *AnalysisDeclContext::getUnoptimizedCFG() {
225   if (!builtCompleteCFG) {
226     SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges,
227                                   false);
228     completeCFG =
229         CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
230     // Even when the cfg is not successfully built, we don't
231     // want to try building it again.
232     builtCompleteCFG = true;
233 
234     if (PM)
235       addParentsForSyntheticStmts(completeCFG.get(), *PM);
236 
237     // The Observer should only observe one build of the CFG.
238     getCFGBuildOptions().Observer = nullptr;
239   }
240   return completeCFG.get();
241 }
242 
243 CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
244   if (cfgStmtMap)
245     return cfgStmtMap.get();
246 
247   if (CFG *c = getCFG()) {
248     cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
249     return cfgStmtMap.get();
250   }
251 
252   return nullptr;
253 }
254 
255 CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
256   if (CFA)
257     return CFA.get();
258 
259   if (CFG *c = getCFG()) {
260     CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
261     return CFA.get();
262   }
263 
264   return nullptr;
265 }
266 
267 void AnalysisDeclContext::dumpCFG(bool ShowColors) {
268     getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
269 }
270 
271 ParentMap &AnalysisDeclContext::getParentMap() {
272   if (!PM) {
273     PM.reset(new ParentMap(getBody()));
274     if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
275       for (const auto *I : C->inits()) {
276         PM->addStmt(I->getInit());
277       }
278     }
279     if (builtCFG)
280       addParentsForSyntheticStmts(getCFG(), *PM);
281     if (builtCompleteCFG)
282       addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
283   }
284   return *PM;
285 }
286 
287 PseudoConstantAnalysis *AnalysisDeclContext::getPseudoConstantAnalysis() {
288   if (!PCA)
289     PCA.reset(new PseudoConstantAnalysis(getBody()));
290   return PCA.get();
291 }
292 
293 AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
294   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
295     // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
296     // that has the body.
297     FD->hasBody(FD);
298     D = FD;
299   }
300 
301   std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
302   if (!AC)
303     AC = llvm::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
304   return AC.get();
305 }
306 
307 BodyFarm *AnalysisDeclContextManager::getBodyFarm() {
308   if (!BdyFrm)
309     BdyFrm = new BodyFarm(ASTCtx, Injector.get());
310   return BdyFrm;
311 }
312 
313 const StackFrameContext *
314 AnalysisDeclContext::getStackFrame(LocationContext const *Parent, const Stmt *S,
315                                const CFGBlock *Blk, unsigned Idx) {
316   return getLocationContextManager().getStackFrame(this, Parent, S, Blk, Idx);
317 }
318 
319 const BlockInvocationContext *
320 AnalysisDeclContext::getBlockInvocationContext(const LocationContext *parent,
321                                                const clang::BlockDecl *BD,
322                                                const void *ContextData) {
323   return getLocationContextManager().getBlockInvocationContext(this, parent,
324                                                                BD, ContextData);
325 }
326 
327 bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
328   const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
329   const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
330   if (!ND)
331     return false;
332 
333   while (const DeclContext *Parent = ND->getParent()) {
334     if (!isa<NamespaceDecl>(Parent))
335       break;
336     ND = cast<NamespaceDecl>(Parent);
337   }
338 
339   return ND->isStdNamespace();
340 }
341 
342 LocationContextManager & AnalysisDeclContext::getLocationContextManager() {
343   assert(Manager &&
344          "Cannot create LocationContexts without an AnalysisDeclContextManager!");
345   return Manager->getLocationContextManager();
346 }
347 
348 //===----------------------------------------------------------------------===//
349 // FoldingSet profiling.
350 //===----------------------------------------------------------------------===//
351 
352 void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
353                                     ContextKind ck,
354                                     AnalysisDeclContext *ctx,
355                                     const LocationContext *parent,
356                                     const void *data) {
357   ID.AddInteger(ck);
358   ID.AddPointer(ctx);
359   ID.AddPointer(parent);
360   ID.AddPointer(data);
361 }
362 
363 void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
364   Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block, Index);
365 }
366 
367 void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
368   Profile(ID, getAnalysisDeclContext(), getParent(), Enter);
369 }
370 
371 void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
372   Profile(ID, getAnalysisDeclContext(), getParent(), BD, ContextData);
373 }
374 
375 //===----------------------------------------------------------------------===//
376 // LocationContext creation.
377 //===----------------------------------------------------------------------===//
378 
379 template <typename LOC, typename DATA>
380 const LOC*
381 LocationContextManager::getLocationContext(AnalysisDeclContext *ctx,
382                                            const LocationContext *parent,
383                                            const DATA *d) {
384   llvm::FoldingSetNodeID ID;
385   LOC::Profile(ID, ctx, parent, d);
386   void *InsertPos;
387 
388   LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
389 
390   if (!L) {
391     L = new LOC(ctx, parent, d);
392     Contexts.InsertNode(L, InsertPos);
393   }
394   return L;
395 }
396 
397 const StackFrameContext*
398 LocationContextManager::getStackFrame(AnalysisDeclContext *ctx,
399                                       const LocationContext *parent,
400                                       const Stmt *s,
401                                       const CFGBlock *blk, unsigned idx) {
402   llvm::FoldingSetNodeID ID;
403   StackFrameContext::Profile(ID, ctx, parent, s, blk, idx);
404   void *InsertPos;
405   StackFrameContext *L =
406    cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
407   if (!L) {
408     L = new StackFrameContext(ctx, parent, s, blk, idx);
409     Contexts.InsertNode(L, InsertPos);
410   }
411   return L;
412 }
413 
414 const ScopeContext *
415 LocationContextManager::getScope(AnalysisDeclContext *ctx,
416                                  const LocationContext *parent,
417                                  const Stmt *s) {
418   return getLocationContext<ScopeContext, Stmt>(ctx, parent, s);
419 }
420 
421 const BlockInvocationContext *
422 LocationContextManager::getBlockInvocationContext(AnalysisDeclContext *ctx,
423                                                   const LocationContext *parent,
424                                                   const BlockDecl *BD,
425                                                   const void *ContextData) {
426   llvm::FoldingSetNodeID ID;
427   BlockInvocationContext::Profile(ID, ctx, parent, BD, ContextData);
428   void *InsertPos;
429   BlockInvocationContext *L =
430     cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
431                                                                     InsertPos));
432   if (!L) {
433     L = new BlockInvocationContext(ctx, parent, BD, ContextData);
434     Contexts.InsertNode(L, InsertPos);
435   }
436   return L;
437 }
438 
439 //===----------------------------------------------------------------------===//
440 // LocationContext methods.
441 //===----------------------------------------------------------------------===//
442 
443 const StackFrameContext *LocationContext::getCurrentStackFrame() const {
444   const LocationContext *LC = this;
445   while (LC) {
446     if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC))
447       return SFC;
448     LC = LC->getParent();
449   }
450   return nullptr;
451 }
452 
453 bool LocationContext::inTopFrame() const {
454   return getCurrentStackFrame()->inTopFrame();
455 }
456 
457 bool LocationContext::isParentOf(const LocationContext *LC) const {
458   do {
459     const LocationContext *Parent = LC->getParent();
460     if (Parent == this)
461       return true;
462     else
463       LC = Parent;
464   } while (LC);
465 
466   return false;
467 }
468 
469 void LocationContext::dumpStack(raw_ostream &OS, StringRef Indent) const {
470   ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
471   PrintingPolicy PP(Ctx.getLangOpts());
472   PP.TerseOutput = 1;
473 
474   unsigned Frame = 0;
475   for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
476     switch (LCtx->getKind()) {
477     case StackFrame:
478       OS << Indent << '#' << Frame++ << ' ';
479       cast<StackFrameContext>(LCtx)->getDecl()->print(OS, PP);
480       OS << '\n';
481       break;
482     case Scope:
483       OS << Indent << "    (scope)\n";
484       break;
485     case Block:
486       OS << Indent << "    (block context: "
487                    << cast<BlockInvocationContext>(LCtx)->getContextData()
488                    << ")\n";
489       break;
490     }
491   }
492 }
493 
494 LLVM_DUMP_METHOD void LocationContext::dumpStack() const {
495   dumpStack(llvm::errs());
496 }
497 
498 //===----------------------------------------------------------------------===//
499 // Lazily generated map to query the external variables referenced by a Block.
500 //===----------------------------------------------------------------------===//
501 
502 namespace {
503 class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
504   BumpVector<const VarDecl*> &BEVals;
505   BumpVectorContext &BC;
506   llvm::SmallPtrSet<const VarDecl*, 4> Visited;
507   llvm::SmallPtrSet<const DeclContext*, 4> IgnoredContexts;
508 public:
509   FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
510                             BumpVectorContext &bc)
511   : BEVals(bevals), BC(bc) {}
512 
513   void VisitStmt(Stmt *S) {
514     for (Stmt *Child : S->children())
515       if (Child)
516         Visit(Child);
517   }
518 
519   void VisitDeclRefExpr(DeclRefExpr *DR) {
520     // Non-local variables are also directly modified.
521     if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
522       if (!VD->hasLocalStorage()) {
523         if (Visited.insert(VD).second)
524           BEVals.push_back(VD, BC);
525       }
526     }
527   }
528 
529   void VisitBlockExpr(BlockExpr *BR) {
530     // Blocks containing blocks can transitively capture more variables.
531     IgnoredContexts.insert(BR->getBlockDecl());
532     Visit(BR->getBlockDecl()->getBody());
533   }
534 
535   void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
536     for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(),
537          et = PE->semantics_end(); it != et; ++it) {
538       Expr *Semantic = *it;
539       if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
540         Semantic = OVE->getSourceExpr();
541       Visit(Semantic);
542     }
543   }
544 };
545 } // end anonymous namespace
546 
547 typedef BumpVector<const VarDecl*> DeclVec;
548 
549 static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
550                                               void *&Vec,
551                                               llvm::BumpPtrAllocator &A) {
552   if (Vec)
553     return (DeclVec*) Vec;
554 
555   BumpVectorContext BC(A);
556   DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
557   new (BV) DeclVec(BC, 10);
558 
559   // Go through the capture list.
560   for (const auto &CI : BD->captures()) {
561     BV->push_back(CI.getVariable(), BC);
562   }
563 
564   // Find the referenced global/static variables.
565   FindBlockDeclRefExprsVals F(*BV, BC);
566   F.Visit(BD->getBody());
567 
568   Vec = BV;
569   return BV;
570 }
571 
572 llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
573 AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
574   if (!ReferencedBlockVars)
575     ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
576 
577   const DeclVec *V =
578       LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
579   return llvm::make_range(V->begin(), V->end());
580 }
581 
582 ManagedAnalysis *&AnalysisDeclContext::getAnalysisImpl(const void *tag) {
583   if (!ManagedAnalyses)
584     ManagedAnalyses = new ManagedAnalysisMap();
585   ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
586   return (*M)[tag];
587 }
588 
589 //===----------------------------------------------------------------------===//
590 // Cleanup.
591 //===----------------------------------------------------------------------===//
592 
593 ManagedAnalysis::~ManagedAnalysis() {}
594 
595 AnalysisDeclContext::~AnalysisDeclContext() {
596   delete forcedBlkExprs;
597   delete ReferencedBlockVars;
598   // Release the managed analyses.
599   if (ManagedAnalyses) {
600     ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
601     llvm::DeleteContainerSeconds(*M);
602     delete M;
603   }
604 }
605 
606 AnalysisDeclContextManager::~AnalysisDeclContextManager() {
607   if (BdyFrm)
608     delete BdyFrm;
609 }
610 
611 LocationContext::~LocationContext() {}
612 
613 LocationContextManager::~LocationContextManager() {
614   clear();
615 }
616 
617 void LocationContextManager::clear() {
618   for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
619        E = Contexts.end(); I != E; ) {
620     LocationContext *LC = &*I;
621     ++I;
622     delete LC;
623   }
624 
625   Contexts.clear();
626 }
627 
628