diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-04-26 21:42:55 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-04-26 21:42:55 +0000 |
commit | 5e6c06bc7deaaefe130b730032a9acb9cd38bf0c (patch) | |
tree | 8e421a4cae28be86511b2f22ec3e2e2986ee5177 /test/Analysis/casts.c | |
parent | ed6847ee6944757dfc4911abb29c6fc2d7cf9d79 (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/casts.c')
-rw-r--r-- | test/Analysis/casts.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c index 087bd978e1..3e2f8077ed 100644 --- a/test/Analysis/casts.c +++ b/test/Analysis/casts.c @@ -1,6 +1,7 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s -// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s -// expected-no-diagnostics +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s +// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s + +extern void clang_analyzer_eval(_Bool); // Test if the 'storage' region gets properly initialized after it is cast to // 'struct sockaddr *'. @@ -85,3 +86,34 @@ int foo (int* p) { } return 0; } + +void castsToBool() { + clang_analyzer_eval(0); // expected-warning{{FALSE}} + clang_analyzer_eval(0U); // expected-warning{{FALSE}} + clang_analyzer_eval((void *)0); // expected-warning{{FALSE}} + + clang_analyzer_eval(1); // expected-warning{{TRUE}} + clang_analyzer_eval(1U); // expected-warning{{TRUE}} + clang_analyzer_eval(-1); // expected-warning{{TRUE}} + clang_analyzer_eval(0x100); // expected-warning{{TRUE}} + clang_analyzer_eval(0x100U); // expected-warning{{TRUE}} + clang_analyzer_eval((void *)0x100); // expected-warning{{TRUE}} + + extern int symbolicInt; + clang_analyzer_eval(symbolicInt); // expected-warning{{UNKNOWN}} + if (symbolicInt) + clang_analyzer_eval(symbolicInt); // expected-warning{{TRUE}} + + extern void *symbolicPointer; + clang_analyzer_eval(symbolicPointer); // expected-warning{{UNKNOWN}} + if (symbolicPointer) + clang_analyzer_eval(symbolicPointer); // expected-warning{{TRUE}} + + int localInt; + clang_analyzer_eval(&localInt); // expected-warning{{TRUE}} + clang_analyzer_eval(&castsToBool); // expected-warning{{TRUE}} + clang_analyzer_eval("abc"); // expected-warning{{TRUE}} + + extern float globalFloat; + clang_analyzer_eval(globalFloat); // expected-warning{{UNKNOWN}} +} |