[analyzer] Model casts to bool differently from other numbers.
Casts to bool (and _Bool) are equivalent to checks against zero,
not truncations to 1 bit or 8 bits.
This improved reasoning does cause a change in the behavior of the alpha
BoolAssignment checker. Previously, this checker complained about statements
like "bool x = y" if 'y' was known not to be 0 or 1. Now it does not, since
that conversion is well-defined. It's hard to say what the "best" behavior
here is: this conversion is safe, but might be better written as an explicit
comparison against zero.
More usefully, besides improving our model of booleans, this fixes spurious
warnings when returning the address of a local variable cast to bool.
<rdar://problem/13296133>
llvm-svn: 180638
diff --git a/clang/test/Analysis/stackaddrleak.c b/clang/test/Analysis/stackaddrleak.c
index 10564fa..4f81f66 100644
--- a/clang/test/Analysis/stackaddrleak.c
+++ b/clang/test/Analysis/stackaddrleak.c
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -std=c99 -Dbool=_Bool %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -x c++ %s
+typedef __INTPTR_TYPE__ intptr_t;
char const *p;
void f0() {
@@ -15,7 +17,7 @@
void f2() {
p = (const char *) __builtin_alloca(12);
-} // expected-warning{{Address of stack memory allocated by call to alloca() on line 17 is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}
+} // expected-warning{{Address of stack memory allocated by call to alloca() on line 19 is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}
// PR 7383 - previosly the stack address checker would crash on this example
// because it would attempt to do a direct load from 'pr7383_list'.
@@ -32,3 +34,25 @@
a = &x;
b = &x;
} // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'a' upon returning}} expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'b' upon returning}}
+
+intptr_t returnAsNonLoc() {
+ int x;
+ return (intptr_t)&x; // expected-warning{{Address of stack memory associated with local variable 'x' returned to caller}}
+}
+
+bool returnAsBool() {
+ int x;
+ return &x; // no-warning
+}
+
+void assignAsNonLoc() {
+ extern intptr_t ip;
+ int x;
+ ip = (intptr_t)&x;
+} // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'ip' upon returning}}
+
+void assignAsBool() {
+ extern bool b;
+ int x;
+ b = &x;
+} // no-warning