aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/stack-addr-ps.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-04-26 21:42:55 +0000
committerJordan Rose <jordan_rose@apple.com>2013-04-26 21:42:55 +0000
commit5e6c06bc7deaaefe130b730032a9acb9cd38bf0c (patch)
tree8e421a4cae28be86511b2f22ec3e2e2986ee5177 /test/Analysis/stack-addr-ps.cpp
parented6847ee6944757dfc4911abb29c6fc2d7cf9d79 (diff)
[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> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180638 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Analysis/stack-addr-ps.cpp')
-rw-r--r--test/Analysis/stack-addr-ps.cpp41
1 files changed, 39 insertions, 2 deletions
diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp
index 7aefea5095..65d757154c 100644
--- a/test/Analysis/stack-addr-ps.cpp
+++ b/test/Analysis/stack-addr-ps.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
-// FIXME: Only the stack-address checking in Sema catches this right now, and
-// the stack analyzer doesn't handle the ImplicitCastExpr (lvalue).
+typedef __INTPTR_TYPE__ intptr_t;
+
const int& g() {
int s;
return s; // expected-warning{{Address of stack memory associated with local variable 's' returned}} expected-warning{{reference to stack memory associated with local variable 's' returned}}
@@ -96,3 +96,40 @@ void *radar13226577() {
return p; // expected-warning {{stack memory associated with local variable 'p' returned to caller}}
}
+namespace rdar13296133 {
+ class ConvertsToBool {
+ public:
+ operator bool() const { return this; }
+ };
+
+ class ConvertsToIntptr {
+ public:
+ operator intptr_t() const { return reinterpret_cast<intptr_t>(this); }
+ };
+
+ class ConvertsToPointer {
+ public:
+ operator const void *() const { return this; }
+ };
+
+ intptr_t returnAsNonLoc() {
+ ConvertsToIntptr obj;
+ return obj; // expected-warning{{Address of stack memory associated with local variable 'obj' returned to caller}}
+ }
+
+ bool returnAsBool() {
+ ConvertsToBool obj;
+ return obj; // no-warning
+ }
+
+ intptr_t returnAsNonLocViaPointer() {
+ ConvertsToPointer obj;
+ return reinterpret_cast<intptr_t>(static_cast<const void *>(obj)); // expected-warning{{Address of stack memory associated with local variable 'obj' returned to caller}}
+ }
+
+ bool returnAsBoolViaPointer() {
+ ConvertsToPointer obj;
+ return obj; // no-warning
+ }
+}
+