diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-02-13 03:11:06 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-02-13 03:11:06 +0000 |
commit | 38f68ef19cb51d5876e9025b5fceb44b33ec9ed7 (patch) | |
tree | 068ddb9e8bdda120632d421a06ddc96d7bdc13cc /test | |
parent | 04870edbea6cf88412c8c9c1eba65f7fc1fa12d9 (diff) |
[analyzer] Use Clang's evaluation for global constants and default arguments.
Previously, we were handling only simple integer constants for globals and
the smattering of implicitly-valued expressions handled by Environment for
default arguments. Now, we can use any integer constant expression that
Clang can evaluate, in addition to everything we handled before.
PR15094 / <rdar://problem/12830437>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175026 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/Analysis/global-region-invalidation.c | 20 | ||||
-rw-r--r-- | test/Analysis/inline.cpp | 42 |
2 files changed, 50 insertions, 12 deletions
diff --git a/test/Analysis/global-region-invalidation.c b/test/Analysis/global-region-invalidation.c index 113e6ae363..77de9dd326 100644 --- a/test/Analysis/global-region-invalidation.c +++ b/test/Analysis/global-region-invalidation.c @@ -67,15 +67,29 @@ int constIntGlob() { return 3 / *m; // expected-warning {{Division by zero}} } -extern const int x; +extern const int y; int constIntGlobExtern() { - if (x == 0) { + if (y == 0) { foo(); - return 5 / x; // expected-warning {{Division by zero}} + return 5 / y; // expected-warning {{Division by zero}} } return 0; } +static void * const ptr = 0; +void constPtrGlob() { + clang_analyzer_eval(ptr == 0); // expected-warning{{TRUE}} + foo(); + clang_analyzer_eval(ptr == 0); // expected-warning{{TRUE}} +} + +static const int x2 = x; +void constIntGlob2() { + clang_analyzer_eval(x2 == 0); // expected-warning{{TRUE}} + foo(); + clang_analyzer_eval(x2 == 0); // expected-warning{{TRUE}} +} + void testAnalyzerEvalIsPure() { extern int someGlobal; if (someGlobal == 0) { diff --git a/test/Analysis/inline.cpp b/test/Analysis/inline.cpp index 873b046eb1..f0e69ddfc2 100644 --- a/test/Analysis/inline.cpp +++ b/test/Analysis/inline.cpp @@ -216,7 +216,7 @@ namespace DefaultArgs { class Secret { public: - static const int value = 42; + static const int value = 40 + 2; int get(int i = value) { return i; } @@ -225,16 +225,40 @@ namespace DefaultArgs { void testMethod() { Secret obj; clang_analyzer_eval(obj.get(1) == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(obj.get() == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(Secret::value == 42); // expected-warning{{TRUE}} + } - // FIXME: Should be 'TRUE'. See PR13673 or <rdar://problem/11720796>. - clang_analyzer_eval(obj.get() == 42); // expected-warning{{UNKNOWN}} + enum ABC { + A = 0, + B = 1, + C = 2 + }; - // FIXME: Even if we constrain the variable, we still have a problem. - // See PR13385 or <rdar://problem/12156507>. - if (Secret::value != 42) - return; - clang_analyzer_eval(Secret::value == 42); // expected-warning{{TRUE}} - clang_analyzer_eval(obj.get() == 42); // expected-warning{{UNKNOWN}} + int enumUser(ABC input = B) { + return static_cast<int>(input); + } + + void testEnum() { + clang_analyzer_eval(enumUser(C) == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(enumUser() == 1); // expected-warning{{TRUE}} + } + + + int exprUser(int input = 2 * 4) { + return input; + } + + int complicatedExprUser(int input = 2 * Secret::value) { + return input; + } + + void testExprs() { + clang_analyzer_eval(exprUser(1) == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(exprUser() == 8); // expected-warning{{TRUE}} + + clang_analyzer_eval(complicatedExprUser(1) == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(complicatedExprUser() == 84); // expected-warning{{TRUE}} } } |