aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-02-23 05:11:46 +0000
committerTed Kremenek <kremenek@apple.com>2011-02-23 05:11:46 +0000
commitc56c004e0b8030e8ca8614e7febe581221938b75 (patch)
treef7d3d64d64852d36bcaf01d6698a88d5fcfd8765
parente7455016e5fae3db7e2d88a61633f76ab05fc9d3 (diff)
Teach CFGBuilder about null pointer constants in conditionals, and how they can be used to prune branches. Fixes false null pointer dereference warning in PR 8183.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126305 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/CFG.cpp14
-rw-r--r--test/Sema/exprs.c8
2 files changed, 19 insertions, 3 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 0957875fd2..90b3120cd2 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/CharUnits.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Format.h"
@@ -413,9 +414,16 @@ private:
Expr::EvalResult Result;
if (!S->isTypeDependent() && !S->isValueDependent() &&
- S->Evaluate(Result, *Context) && Result.Val.isInt())
- return Result.Val.getInt().getBoolValue();
-
+ S->Evaluate(Result, *Context)) {
+ if (Result.Val.isInt())
+ return Result.Val.getInt().getBoolValue();
+ if (Result.Val.isLValue()) {
+ Expr *e = Result.Val.getLValueBase();
+ const CharUnits &c = Result.Val.getLValueOffset();
+ if (!e && c.isZero())
+ return false;
+ }
+ }
return TryResult();
}
};
diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c
index 5917e085ea..0d6c5488de 100644
--- a/test/Sema/exprs.c
+++ b/test/Sema/exprs.c
@@ -18,6 +18,14 @@ int test_pr8876() {
return 0;
}
+// PR 8183 - Handle null pointer constants on the left-side of the '&&', and reason about
+// this when determining the reachability of the null pointer dereference on the right side.
+void pr8183(unsigned long long test)
+{
+ (void)((((void*)0)) && (*((unsigned long long*)(((void*)0))) = ((unsigned long long)((test)) % (unsigned long long)((1000000000))))); // no-warning
+ (*((unsigned long long*)(((void*)0))) = ((unsigned long long)((test)) % (unsigned long long)((1000000000)))); // expected-warning {{indirection of non-volatile null pointer will be deleted, not trap}} expected-note {{consider using __builtin_trap() or qualifying pointer with 'volatile'}}
+}
+
// PR1966
_Complex double test1() {
return __extension__ 1.0if;