sp4r74n-117 created this revision. sp4r74n-117 added reviewers: george.karpenkov, dcoughlin, dergachev.a. sp4r74n-117 created this object with visibility "All Users". Herald added subscribers: cfe-commits, a.sidorin, szepet, xazax.hun.
Added evaluation of __builtin_constant_p to the dedicated StaticAnalyzer checker along with a test case. Tested via: make clang-test Repository: rC Clang https://reviews.llvm.org/D42745 Files: lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp test/Analysis/builtin-functions.cpp Index: test/Analysis/builtin-functions.cpp =================================================================== --- test/Analysis/builtin-functions.cpp +++ test/Analysis/builtin-functions.cpp @@ -64,3 +64,18 @@ // 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)); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i)); // expected-warning {{FALSE}} + clang_analyzer_eval(__builtin_constant_p(j)); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(k)); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i + 42)); // expected-warning {{FALSE}} + clang_analyzer_eval(__builtin_constant_p(j + 42)); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(k + 42)); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(" ")); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(test_constant_p)); // expected-warning {{FALSE}} +} Index: lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -113,6 +113,24 @@ C.addTransition(state->BindExpr(CE, LCtx, V)); return true; } + + case Builtin::BI__builtin_constant_p: { + SVal V; + SValBuilder& SVB = C.getSValBuilder(); + + llvm::APSInt Result; + // Model semantics as 'A return of 0 does not indicate that the value is + // not a constant, but merely that GCC cannot prove it is a constant [...]' + if (CE->EvaluateAsInt(Result, C.getASTContext(), Expr::SE_NoSideEffects)) { + SVB.getBasicValueFactory().getAPSIntType(CE->getType()).apply(Result); + V = SVB.makeIntVal(Result); + } + else + V = SVB.makeZeroVal(CE->getType()); + + C.addTransition(state->BindExpr(CE, LCtx, V)); + return true; + } } }
Index: test/Analysis/builtin-functions.cpp =================================================================== --- test/Analysis/builtin-functions.cpp +++ test/Analysis/builtin-functions.cpp @@ -64,3 +64,18 @@ // 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)); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i)); // expected-warning {{FALSE}} + clang_analyzer_eval(__builtin_constant_p(j)); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(k)); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i + 42)); // expected-warning {{FALSE}} + clang_analyzer_eval(__builtin_constant_p(j + 42)); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(k + 42)); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(" ")); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(test_constant_p)); // expected-warning {{FALSE}} +} Index: lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -113,6 +113,24 @@ C.addTransition(state->BindExpr(CE, LCtx, V)); return true; } + + case Builtin::BI__builtin_constant_p: { + SVal V; + SValBuilder& SVB = C.getSValBuilder(); + + llvm::APSInt Result; + // Model semantics as 'A return of 0 does not indicate that the value is + // not a constant, but merely that GCC cannot prove it is a constant [...]' + if (CE->EvaluateAsInt(Result, C.getASTContext(), Expr::SE_NoSideEffects)) { + SVB.getBasicValueFactory().getAPSIntType(CE->getType()).apply(Result); + V = SVB.makeIntVal(Result); + } + else + V = SVB.makeZeroVal(CE->getType()); + + C.addTransition(state->BindExpr(CE, LCtx, V)); + return true; + } } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits