]> granicus.if.org Git - clang/commitdiff
[analyzer] Add support for __builtin_constant_p.
authorArtem Dergachev <artem.dergachev@gmail.com>
Sat, 10 Feb 2018 00:51:47 +0000 (00:51 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Sat, 10 Feb 2018 00:51:47 +0000 (00:51 +0000)
This builtin is evaluated in compile time. But in the analyzer we don't yet
automagically evaluate all calls that can be evaluated in compile time.

Patch by Felix Kostenzer!

Differential Revision: https://reviews.llvm.org/D42745

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@324789 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
test/Analysis/builtin-functions.cpp

index 93c9bfa043ac53012b144cb6f9e619ff7b897e15..0e781d08e24c89dceb2eaf258a963da708e6438f 100644 (file)
@@ -96,7 +96,8 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
     return true;
   }
 
-  case Builtin::BI__builtin_object_size: {
+  case Builtin::BI__builtin_object_size:
+  case Builtin::BI__builtin_constant_p: {
     // This must be resolvable at compile time, so we defer to the constant
     // evaluator for a value.
     SVal V = UnknownVal();
index 2c1950251145ce3138c71f4f4401bea9496f1344..19984963b4fa8ecfb7e00f235db52688a28353b6 100644 (file)
@@ -64,3 +64,20 @@ void g(int i) {
                                     // We give up the analysis on this path.
   }
 }
+
+void test_constant_p() {
+  int i = 1;
+  const int j = 2;
+  constexpr int k = 3;
+  clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning {{FALSE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning {{TRUE}}
+}