aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
diff options
context:
space:
mode:
authormartinboehme <mboehme@google.com>2024-01-16 12:52:55 +0100
committerGitHub <noreply@github.com>2024-01-16 12:52:55 +0100
commitc19cacfa34f52b65addeb7239d564b20e3cf2c61 (patch)
tree51d9cec5cf215405252a5967c3d0ecb93f0337c0 /clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
parent032c832719b5b2c44b78359ed54b91964ef15b79 (diff)
downloadllvm-c19cacfa34f52b65addeb7239d564b20e3cf2c61.zip
llvm-c19cacfa34f52b65addeb7239d564b20e3cf2c61.tar.gz
llvm-c19cacfa34f52b65addeb7239d564b20e3cf2c61.tar.bz2
[clang][dataflow] Tighten checking for existence of a function body. (#78163)
In various places, we would previously call `FunctionDecl::hasBody()` (which checks whether any redeclaration of the function has a body, not necessarily the one on which `hasBody()` is being called). This is bug-prone, as a recent bug in Crubit's nullability checker has shown ([fix](https://github.com/google/crubit/commit/4b01ed0f14d953cda20f92d62256e7365d206b2e), [fix for the fix](https://github.com/google/crubit/commit/e0c5d8ddd7d647da483c2ae198ff91d131c12055)). Instead, we now use `FunctionDecl::doesThisDeclarationHaveABody()` which, as the name implies, checks whether the specific redeclaration it is being called on has a body. Alternatively, I considered being more lenient and "canonicalizing" to the `FunctionDecl` that has the body if the `FunctionDecl` being passed is a different redeclaration. However, this also risks hiding bugs: A caller might inadverently perform the analysis for all redeclarations of a function and end up duplicating work without realizing it. By accepting only the redeclaration that contains the body, we prevent this. I've checked, and all clients that I'm aware of do currently pass in the redeclaration that contains the function body. Typically this is because they use the `ast_matchers::hasBody()` matcher which, unlike `FunctionDecl::hasBody()`, only matches for the redeclaration containing the body.
Diffstat (limited to 'clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp')
-rw-r--r--clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp4
1 files changed, 2 insertions, 2 deletions
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 96fe6df..a50ee57 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -386,7 +386,7 @@ void Environment::initialize() {
return;
if (const auto *FuncDecl = dyn_cast<FunctionDecl>(DeclCtx)) {
- assert(FuncDecl->getBody() != nullptr);
+ assert(FuncDecl->doesThisDeclarationHaveABody());
initFieldsGlobalsAndFuncs(FuncDecl);
@@ -426,7 +426,7 @@ void Environment::initialize() {
// FIXME: Add support for resetting globals after function calls to enable
// the implementation of sound analyses.
void Environment::initFieldsGlobalsAndFuncs(const FunctionDecl *FuncDecl) {
- assert(FuncDecl->getBody() != nullptr);
+ assert(FuncDecl->doesThisDeclarationHaveABody());
FieldSet Fields;
llvm::DenseSet<const VarDecl *> Vars;