summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2013-02-05 19:52:28 +0000
committerAnna Zaks <ganna@apple.com>2013-02-05 19:52:28 +0000
commitfe9c7c87c9e06d52d2108f1ee583e9659bf1b8c3 (patch)
tree4c4175efc0545ca3eca4afa93eaec2df8dfb5cc6
parent064185a8ce68a1511942de4420c41f1a9d5f23a5 (diff)
downloadbcm5719-llvm-fe9c7c87c9e06d52d2108f1ee583e9659bf1b8c3.tar.gz
bcm5719-llvm-fe9c7c87c9e06d52d2108f1ee583e9659bf1b8c3.zip
[analyzer] Teach the analyzer to use a symbol for p when evaluating
(void*)p. Addresses the false positives similar to the test case. llvm-svn: 174436
-rw-r--r--clang/lib/StaticAnalyzer/Core/SValBuilder.cpp27
-rw-r--r--clang/test/Analysis/casts.c11
2 files changed, 27 insertions, 11 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index a1a87b0a1f6..96e46b801f9 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -284,14 +284,14 @@ DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state,
}
/// Recursively check if the pointer types are equal modulo const, volatile,
-/// and restrict qualifiers. Assumes the input types are canonical.
-/// TODO: This is based off of code in SemaCast; can we reuse it.
-static bool haveSimilarTypes(ASTContext &Context, QualType T1,
- QualType T2) {
- while (Context.UnwrapSimilarPointerTypes(T1, T2)) {
+/// and restrict qualifiers. Also, assume that all types are similar to 'void'.
+/// Assumes the input types are canonical.
+static bool shouldBeModeledWithNoOp(ASTContext &Context, QualType ToTy,
+ QualType FromTy) {
+ while (Context.UnwrapSimilarPointerTypes(ToTy, FromTy)) {
Qualifiers Quals1, Quals2;
- T1 = Context.getUnqualifiedArrayType(T1, Quals1);
- T2 = Context.getUnqualifiedArrayType(T2, Quals2);
+ ToTy = Context.getUnqualifiedArrayType(ToTy, Quals1);
+ FromTy = Context.getUnqualifiedArrayType(FromTy, Quals2);
// Make sure that non cvr-qualifiers the other qualifiers (e.g., address
// spaces) are identical.
@@ -301,7 +301,12 @@ static bool haveSimilarTypes(ASTContext &Context, QualType T1,
return false;
}
- if (T1 != T2)
+ // If we are casting to void, the 'From' value can be used to represent the
+ // 'To' value.
+ if (ToTy->isVoidType())
+ return true;
+
+ if (ToTy != FromTy)
return false;
return true;
@@ -314,10 +319,10 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
if (val.isUnknownOrUndef() || castTy == originalTy)
return val;
- // For const casts, just propagate the value.
+ // For const casts, casts to void, just propagate the value.
if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
- if (haveSimilarTypes(Context, Context.getPointerType(castTy),
- Context.getPointerType(originalTy)))
+ if (shouldBeModeledWithNoOp(Context, Context.getPointerType(castTy),
+ Context.getPointerType(originalTy)))
return val;
// Check for casts from pointers to integers.
diff --git a/clang/test/Analysis/casts.c b/clang/test/Analysis/casts.c
index 1c0f35749b2..087bd978e11 100644
--- a/clang/test/Analysis/casts.c
+++ b/clang/test/Analysis/casts.c
@@ -74,3 +74,14 @@ char ttt(int intSeconds) {
return 0;
return 0;
}
+
+int foo (int* p) {
+ int y = 0;
+ if (p == 0) {
+ if ((*((void**)&p)) == (void*)0) // Test that the cast to void preserves the symbolic region.
+ return 0;
+ else
+ return 5/y; // This code should be unreachable: no-warning.
+ }
+ return 0;
+}
OpenPOWER on IntegriCloud