[clang] 4d4d903 - Fix warning caused by __builtin_expect_with_probability was not handled

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 9 08:01:46 PDT 2020


Author: Zhi Zhuang
Date: 2020-07-09T08:01:33-07:00
New Revision: 4d4d9037670a3537c14092807a717284ea0c4f92

URL: https://github.com/llvm/llvm-project/commit/4d4d9037670a3537c14092807a717284ea0c4f92
DIFF: https://github.com/llvm/llvm-project/commit/4d4d9037670a3537c14092807a717284ea0c4f92.diff

LOG: Fix warning caused by __builtin_expect_with_probability was not handled
in places such as constant folding

Previously some places that should have handled
__builtin_expect_with_probability is missing, so in some case it acts
differently than __builtin_expect.
For example it was not handled in constant folding, thus in the
following program, the "if" condition should be constantly true and
folded, but previously it was not handled and cause warning "control may
reach end of non-void function" (while __builtin_expect does not):

__attribute__((noreturn)) extern void bar();
int foo(int x, int y) {
  if (y) {
    if (__builtin_expect_with_probability(1, 1, 1))
      bar();
  }
  else
    return 0;
}

Now it's fixed.

Differential Revisions: https://reviews.llvm.org/D83362

Added: 
    

Modified: 
    clang/lib/AST/ExprConstant.cpp
    clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
    clang/test/Sema/builtin-expect-with-probability.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d6dbfb14e60b..a4dc0ccad1e0 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11231,6 +11231,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
   }
 
   case Builtin::BI__builtin_expect:
+  case Builtin::BI__builtin_expect_with_probability:
     return Visit(E->getArg(0));
 
   case Builtin::BI__builtin_ffs:

diff  --git a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
index 3eeb1e9a3502..233ce57c3ac9 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -64,10 +64,12 @@ bool BuiltinFunctionChecker::evalCall(const CallEvent &Call,
 
   case Builtin::BI__builtin_unpredictable:
   case Builtin::BI__builtin_expect:
+  case Builtin::BI__builtin_expect_with_probability:
   case Builtin::BI__builtin_assume_aligned:
   case Builtin::BI__builtin_addressof: {
-    // For __builtin_unpredictable, __builtin_expect, and
-    // __builtin_assume_aligned, just return the value of the subexpression.
+    // For __builtin_unpredictable, __builtin_expect,
+    // __builtin_expect_with_probability and __builtin_assume_aligned,
+    // just return the value of the subexpression.
     // __builtin_addressof is going from a reference to a pointer, but those
     // are represented the same way in the analyzer.
     assert (Call.getNumArgs() > 0);

diff  --git a/clang/test/Sema/builtin-expect-with-probability.cpp b/clang/test/Sema/builtin-expect-with-probability.cpp
index 4a5b62a55bbc..3aa20cb0e6dd 100644
--- a/clang/test/Sema/builtin-expect-with-probability.cpp
+++ b/clang/test/Sema/builtin-expect-with-probability.cpp
@@ -1,4 +1,30 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+
+__attribute__((noreturn)) extern void bar();
+
+int test_no_warn(int x) {
+  if (x) {
+    if (__builtin_expect_with_probability(1, 1, 1))
+      bar();
+  } else {
+    return 0;
+  }
+} // should not emit warn "control may reach end of non-void function" here since expr is constantly true, so the "if(__bui..)" should be constantly true condition and be ignored
+
+template <int b> void tempf() {
+  static_assert(b == 1, "should be evaluated as 1"); // should not have error here
+}
+
+constexpr int constf() {
+  return __builtin_expect_with_probability(1, 1, 1);
+}
+
+void foo() {
+  tempf<__builtin_expect_with_probability(1, 1, 1)>();
+  constexpr int f = constf();
+  static_assert(f == 1, "should be evaluated as 1"); // should not have error here
+}
+
 extern int global;
 
 struct S {


        


More information about the cfe-commits mailing list