aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp48
1 files changed, 41 insertions, 7 deletions
diff --git a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index 500e1a7a9390..bbf7526adce9 100644
--- a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -20,7 +20,9 @@
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/NoopAnalysis.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/OperatorKinds.h"
@@ -46,8 +48,9 @@ static BoolValue &evaluateBooleanEquality(const Expr &LHS, const Expr &RHS,
class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
public:
- TransferVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env)
- : StmtToEnv(StmtToEnv), Env(Env) {}
+ TransferVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env,
+ TransferOptions Options)
+ : StmtToEnv(StmtToEnv), Env(Env), Options(Options) {}
void VisitBinaryOperator(const BinaryOperator *S) {
const Expr *LHS = S->getLHS();
@@ -503,6 +506,35 @@ public:
if (ArgLoc == nullptr)
return;
Env.setStorageLocation(*S, *ArgLoc);
+ } else if (const FunctionDecl *F = S->getDirectCallee()) {
+ // This case is for context-sensitive analysis, which we only do if we
+ // have the callee body available in the translation unit.
+ if (!Options.ContextSensitive || F->getBody() == nullptr)
+ return;
+
+ auto &ASTCtx = F->getASTContext();
+
+ // FIXME: Cache these CFGs.
+ auto CFCtx = ControlFlowContext::build(F, F->getBody(), &ASTCtx);
+ // FIXME: Handle errors here and below.
+ assert(CFCtx);
+ auto ExitBlock = CFCtx->getCFG().getExit().getBlockID();
+
+ auto CalleeEnv = Env.pushCall(S);
+
+ // FIXME: Use the same analysis as the caller for the callee.
+ DataflowAnalysisOptions Options;
+ auto Analysis = NoopAnalysis(ASTCtx, Options);
+
+ auto BlockToOutputState =
+ dataflow::runDataflowAnalysis(*CFCtx, Analysis, CalleeEnv);
+ assert(BlockToOutputState);
+ assert(ExitBlock < BlockToOutputState->size());
+
+ auto ExitState = (*BlockToOutputState)[ExitBlock];
+ assert(ExitState);
+
+ Env = ExitState->Env;
}
}
@@ -564,11 +596,11 @@ public:
Env.setValue(Loc, *Val);
if (Type->isStructureOrClassType()) {
- for (auto IT : llvm::zip(Type->getAsRecordDecl()->fields(), S->inits())) {
- const FieldDecl *Field = std::get<0>(IT);
+ for (auto It : llvm::zip(Type->getAsRecordDecl()->fields(), S->inits())) {
+ const FieldDecl *Field = std::get<0>(It);
assert(Field != nullptr);
- const Expr *Init = std::get<1>(IT);
+ const Expr *Init = std::get<1>(It);
assert(Init != nullptr);
if (Value *InitVal = Env.getValue(*Init, SkipPast::None))
@@ -633,10 +665,12 @@ private:
const StmtToEnvMap &StmtToEnv;
Environment &Env;
+ TransferOptions Options;
};
-void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env) {
- TransferVisitor(StmtToEnv, Env).Visit(&S);
+void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env,
+ TransferOptions Options) {
+ TransferVisitor(StmtToEnv, Env, Options).Visit(&S);
}
} // namespace dataflow