xref: /llvm-project/clang/test/Sema/builtin-expect-with-probability.cpp (revision d5e2cbd01a17edeb56aad2f161c76ce3f854676f)
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -fexperimental-new-constant-interpreter %s
3 
4 __attribute__((noreturn)) extern void bar();
5 
test_no_warn(int x)6 int test_no_warn(int x) {
7   if (x) {
8     if (__builtin_expect_with_probability(1, 1, 1))
9       bar();
10   } else {
11     return 0;
12   }
13 } // 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
14 
tempf()15 template <int b> void tempf() {
16   static_assert(b == 1, "should be evaluated as 1"); // should not have error here
17 }
18 
constf()19 constexpr int constf() {
20   return __builtin_expect_with_probability(1, 1, 1);
21 }
22 
foo()23 void foo() {
24   tempf<__builtin_expect_with_probability(1, 1, 1)>();
25   constexpr int f = constf();
26   static_assert(f == 1, "should be evaluated as 1"); // should not have error here
27 }
28 
29 extern int global;
30 
31 struct S {
32   static constexpr float prob = 0.7;
33 };
34 
35 template<typename T>
expect_taken(int x)36 void expect_taken(int x) {
37   if (__builtin_expect_with_probability(x > 0, 1, T::prob)) {
38     global++;
39   }
40 }
41 
test(int x,double p)42 void test(int x, double p) { // expected-note {{declared here}}
43   bool dummy;
44   dummy = __builtin_expect_with_probability(x > 0, 1, 0.9);
45   dummy = __builtin_expect_with_probability(x > 0, 1, 1.1); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}}
46   dummy = __builtin_expect_with_probability(x > 0, 1, -1); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}}
47   dummy = __builtin_expect_with_probability(x > 0, 1, p); // expected-error {{probability argument to __builtin_expect_with_probability must be constant floating-point expression}} expected-note {{function parameter 'p'}}
48   dummy = __builtin_expect_with_probability(x > 0, 1, "aa"); // expected-error {{cannot initialize a parameter of type 'double' with an lvalue of type 'const char[3]'}}
49   dummy = __builtin_expect_with_probability(x > 0, 1, __builtin_nan("")); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}}
50   dummy = __builtin_expect_with_probability(x > 0, 1, __builtin_inf()); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}}
51   dummy = __builtin_expect_with_probability(x > 0, 1, -0.0);
52   dummy = __builtin_expect_with_probability(x > 0, 1, 1.0 + __DBL_EPSILON__); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}}
53   dummy = __builtin_expect_with_probability(x > 0, 1, -__DBL_DENORM_MIN__); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}}
54   constexpr double pd = 0.7;
55   dummy = __builtin_expect_with_probability(x > 0, 1, pd);
56   constexpr int pi = 1;
57   dummy = __builtin_expect_with_probability(x > 0, 1, pi);
58   expect_taken<S>(x);
59 }
60