1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 __attribute__((noreturn)) extern void bar();
4 
test_no_warn(int x)5 int test_no_warn(int x) {
6   if (x) {
7     if (__builtin_expect_with_probability(1, 1, 1))
8       bar();
9   } else {
10     return 0;
11   }
12 } // 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
13 
tempf()14 template <int b> void tempf() {
15   static_assert(b == 1, "should be evaluated as 1"); // should not have error here
16 }
17 
constf()18 constexpr int constf() {
19   return __builtin_expect_with_probability(1, 1, 1);
20 }
21 
foo()22 void foo() {
23   tempf<__builtin_expect_with_probability(1, 1, 1)>();
24   constexpr int f = constf();
25   static_assert(f == 1, "should be evaluated as 1"); // should not have error here
26 }
27 
28 extern int global;
29 
30 struct S {
31   static constexpr float prob = 0.7;
32 };
33 
34 template<typename T>
expect_taken(int x)35 void expect_taken(int x) {
36   if (__builtin_expect_with_probability(x > 0, 1, T::prob)) {
37     global++;
38   }
39 }
40 
test(int x,double p)41 void test(int x, double p) { // expected-note {{declared here}}
42   bool dummy;
43   dummy = __builtin_expect_with_probability(x > 0, 1, 0.9);
44   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]}}
45   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]}}
46   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 {{read of non-constexpr variable 'p' is not allowed in a constant expression}}
47   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]'}}
48   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]}}
49   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]}}
50   dummy = __builtin_expect_with_probability(x > 0, 1, -0.0);
51   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]}}
52   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]}}
53   constexpr double pd = 0.7;
54   dummy = __builtin_expect_with_probability(x > 0, 1, pd);
55   constexpr int pi = 1;
56   dummy = __builtin_expect_with_probability(x > 0, 1, pi);
57   expect_taken<S>(x);
58 }
59