aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/AnalysisDeclContext.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-09-21 00:09:11 +0000
committerTed Kremenek <kremenek@apple.com>2012-09-21 00:09:11 +0000
commit14f779c4d69098df876c7983549c0e44d9b12aa7 (patch)
treef2e449a96009109e0e6103cf15a517eee1e50d37 /clang/lib/Analysis/AnalysisDeclContext.cpp
parent96ea28046c7ea912a722a6d0b19a20266001e1f1 (diff)
downloadllvm-14f779c4d69098df876c7983549c0e44d9b12aa7.zip
llvm-14f779c4d69098df876c7983549c0e44d9b12aa7.tar.gz
llvm-14f779c4d69098df876c7983549c0e44d9b12aa7.tar.bz2
Implement faux-body-synthesis of well-known functions in the static analyzer when
their implementations are unavailable. Start by simulating dispatch_sync(). This change is largely a bunch of plumbing around something very simple. We use AnalysisDeclContext to conjure up a fake function body (using the current ASTContext) when one does not exist. This is controlled under the analyzer-config option "faux-bodies", which is off by default. The plumbing in this patch is largely to pass the necessary machinery around. CallEvent needs the AnalysisDeclContextManager to get the function definition, as one may get conjured up lazily. BugReporter and PathDiagnosticLocation needed to be relaxed to handle invalid locations, as the conjured body has no real source locations. We do some primitive recovery in diagnostic generation to generate some reasonable locations (for arrows and events), but it can be improved. llvm-svn: 164339
Diffstat (limited to 'clang/lib/Analysis/AnalysisDeclContext.cpp')
-rw-r--r--clang/lib/Analysis/AnalysisDeclContext.cpp31
1 files changed, 25 insertions, 6 deletions
diff --git a/clang/lib/Analysis/AnalysisDeclContext.cpp b/clang/lib/Analysis/AnalysisDeclContext.cpp
index f2ef0de..a4bf8d1 100644
--- a/clang/lib/Analysis/AnalysisDeclContext.cpp
+++ b/clang/lib/Analysis/AnalysisDeclContext.cpp
@@ -29,13 +29,15 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/ErrorHandling.h"
+#include "BodyFarm.h"
+
using namespace clang;
typedef llvm::DenseMap<const void *, ManagedAnalysis *> ManagedAnalysisMap;
AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
- const Decl *d,
- const CFG::BuildOptions &buildOptions)
+ const Decl *d,
+ const CFG::BuildOptions &buildOptions)
: Manager(Mgr),
D(d),
cfgBuildOptions(buildOptions),
@@ -49,7 +51,7 @@ AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
}
AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
- const Decl *d)
+ const Decl *d)
: Manager(Mgr),
D(d),
forcedBlkExprs(0),
@@ -64,7 +66,10 @@ AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG,
bool addImplicitDtors,
bool addInitializers,
- bool addTemporaryDtors) {
+ bool addTemporaryDtors,
+ bool synthesizeBodies)
+ : SynthesizeBodies(synthesizeBodies)
+{
cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
cfgBuildOptions.AddInitializers = addInitializers;
@@ -77,9 +82,18 @@ void AnalysisDeclContextManager::clear() {
Contexts.clear();
}
+static BodyFarm &getBodyFarm(ASTContext &C) {
+ static BodyFarm *BF = new BodyFarm(C);
+ return *BF;
+}
+
Stmt *AnalysisDeclContext::getBody() const {
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- return FD->getBody();
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ Stmt *Body = FD->getBody();
+ if (!Body && Manager && Manager->synthesizeBodies())
+ return getBodyFarm(getASTContext()).getBody(FD);
+ return Body;
+ }
else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
return MD->getBody();
else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
@@ -203,6 +217,11 @@ PseudoConstantAnalysis *AnalysisDeclContext::getPseudoConstantAnalysis() {
}
AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ FD->hasBody(FD);
+ D = FD;
+ }
+
AnalysisDeclContext *&AC = Contexts[D];
if (!AC)
AC = new AnalysisDeclContext(this, D, cfgBuildOptions);