forked from OSchip/llvm-project
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
This commit is contained in:
parent
beb52b12cb
commit
4d4d903767
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue