xref: /llvm-project/clang/test/SemaCXX/attr-likelihood.cpp (revision 623b66eded4b1ab2fbb962d3841899458bac6693)
1b2313961SMark de Wever // RUN: %clang_cc1 %s -std=c++17 -fsyntax-only -verify
208196e0bSMark de Wever // RUN: %clang_cc1 %s -DPEDANTIC -pedantic -fsyntax-only -verify
308196e0bSMark de Wever 
408196e0bSMark de Wever #if PEDANTIC
g()508196e0bSMark de Wever void g() {
608196e0bSMark de Wever   if (true)
708196e0bSMark de Wever     [[likely]] {} // expected-warning {{use of the 'likely' attribute is a C++20 extension}}
808196e0bSMark de Wever   else
908196e0bSMark de Wever     [[unlikely]] {} // expected-warning {{use of the 'unlikely' attribute is a C++20 extension}}
1008196e0bSMark de Wever }
1108196e0bSMark de Wever #else
a()1208196e0bSMark de Wever void a() {
1308196e0bSMark de Wever   if (true)
1408196e0bSMark de Wever     [[likely]]; // expected-warning {{conflicting attributes 'likely' are ignored}}
1508196e0bSMark de Wever   else
1608196e0bSMark de Wever     [[likely]]; // expected-note {{conflicting attribute is here}}
1708196e0bSMark de Wever }
1808196e0bSMark de Wever 
b()1908196e0bSMark de Wever void b() {
2008196e0bSMark de Wever   if (true)
2108196e0bSMark de Wever     [[unlikely]]; // expected-warning {{conflicting attributes 'unlikely' are ignored}}
2208196e0bSMark de Wever   else
2308196e0bSMark de Wever     [[unlikely]]; // expected-note {{conflicting attribute is here}}
2408196e0bSMark de Wever }
2508196e0bSMark de Wever 
c()2608196e0bSMark de Wever void c() {
2708196e0bSMark de Wever   if (true)
2808196e0bSMark de Wever     [[likely]];
2908196e0bSMark de Wever }
3008196e0bSMark de Wever 
d()3108196e0bSMark de Wever void d() {
3208196e0bSMark de Wever   if (true)
3308196e0bSMark de Wever     [[unlikely]];
3408196e0bSMark de Wever }
3508196e0bSMark de Wever 
g()3608196e0bSMark de Wever void g() {
3708196e0bSMark de Wever   if (true)
3808196e0bSMark de Wever     [[likely]] {}
3908196e0bSMark de Wever   else
4008196e0bSMark de Wever     [[unlikely]] {}
4108196e0bSMark de Wever }
4208196e0bSMark de Wever 
h()4308196e0bSMark de Wever void h() {
4408196e0bSMark de Wever   if (true)
4508196e0bSMark de Wever     [[likely]] {}
4608196e0bSMark de Wever   else {
4708196e0bSMark de Wever   }
4808196e0bSMark de Wever }
4908196e0bSMark de Wever 
i()5008196e0bSMark de Wever void i() {
5108196e0bSMark de Wever   if (true)
5208196e0bSMark de Wever     [[unlikely]] {}
5308196e0bSMark de Wever   else {
5408196e0bSMark de Wever   }
5508196e0bSMark de Wever }
5608196e0bSMark de Wever 
j()5708196e0bSMark de Wever void j() {
5808196e0bSMark de Wever   if (true) {
5908196e0bSMark de Wever   } else
6008196e0bSMark de Wever     [[likely]] {}
6108196e0bSMark de Wever }
6208196e0bSMark de Wever 
k()6308196e0bSMark de Wever void k() {
6408196e0bSMark de Wever   if (true) {
6508196e0bSMark de Wever   } else
6608196e0bSMark de Wever     [[likely]] {}
6708196e0bSMark de Wever }
6808196e0bSMark de Wever 
l()6908196e0bSMark de Wever void l() {
7008196e0bSMark de Wever   if (true)
7108196e0bSMark de Wever     [[likely]] {}
7208196e0bSMark de Wever   else
7308196e0bSMark de Wever     [[unlikely]] if (false) [[likely]] {}
7408196e0bSMark de Wever }
7508196e0bSMark de Wever 
m()7608196e0bSMark de Wever void m() {
7708196e0bSMark de Wever   [[likely]] int x = 42; // expected-error {{'likely' attribute cannot be applied to a declaration}}
7808196e0bSMark de Wever 
7908196e0bSMark de Wever   if (x)
8008196e0bSMark de Wever     [[unlikely]] {}
8108196e0bSMark de Wever   if (x) {
8208196e0bSMark de Wever     [[unlikely]];
8308196e0bSMark de Wever   }
8408196e0bSMark de Wever   switch (x) {
8508196e0bSMark de Wever   case 1:
8608196e0bSMark de Wever     [[likely]] {}
8708196e0bSMark de Wever     break;
8808196e0bSMark de Wever     [[likely]] case 2 : case 3 : {}
8908196e0bSMark de Wever     break;
9008196e0bSMark de Wever   }
9108196e0bSMark de Wever 
9208196e0bSMark de Wever   do {
9308196e0bSMark de Wever     [[unlikely]];
9408196e0bSMark de Wever   } while (x);
9508196e0bSMark de Wever   do
9608196e0bSMark de Wever     [[unlikely]] {}
9708196e0bSMark de Wever   while (x);
9808196e0bSMark de Wever   do { // expected-note {{to match this 'do'}}
9908196e0bSMark de Wever   }
10008196e0bSMark de Wever   [[unlikely]] while (x); // expected-error {{expected 'while' in do/while loop}}
10108196e0bSMark de Wever   for (;;)
10208196e0bSMark de Wever     [[unlikely]] {}
10308196e0bSMark de Wever   for (;;) {
10408196e0bSMark de Wever     [[unlikely]];
10508196e0bSMark de Wever   }
10608196e0bSMark de Wever   while (x)
10708196e0bSMark de Wever     [[unlikely]] {}
10808196e0bSMark de Wever   while (x) {
10908196e0bSMark de Wever     [[unlikely]];
11008196e0bSMark de Wever   }
11108196e0bSMark de Wever 
11208196e0bSMark de Wever   switch (x)
11308196e0bSMark de Wever     [[unlikely]] {}
11408196e0bSMark de Wever 
11508196e0bSMark de Wever   if (x)
11608196e0bSMark de Wever     goto lbl;
11708196e0bSMark de Wever 
11808196e0bSMark de Wever   // FIXME: allow the attribute on the label
11908196e0bSMark de Wever   [[unlikely]] lbl : // expected-error {{'unlikely' attribute cannot be applied to a declaration}}
12008196e0bSMark de Wever                      [[likely]] x = x + 1;
12108196e0bSMark de Wever 
12208196e0bSMark de Wever   [[likely]]++ x;
12308196e0bSMark de Wever }
12408196e0bSMark de Wever 
n()12508196e0bSMark de Wever void n() [[likely]] // expected-error {{'likely' attribute cannot be applied to types}}
12608196e0bSMark de Wever {
12708196e0bSMark de Wever   try
12808196e0bSMark de Wever     [[likely]] {} // expected-error {{expected '{'}}
12908196e0bSMark de Wever   catch (...) [[likely]] { // expected-error {{expected expression}}
13008196e0bSMark de Wever   }
13108196e0bSMark de Wever }
132b2313961SMark de Wever 
o()133b2313961SMark de Wever void o()
134b2313961SMark de Wever {
135b2313961SMark de Wever   // expected-warning@+2 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
136b2313961SMark de Wever   // expected-note@+1 {{annotating the 'if constexpr' statement here}}
137b2313961SMark de Wever   if constexpr (true) [[likely]];
138b2313961SMark de Wever 
139b2313961SMark de Wever   // expected-note@+1 {{annotating the 'if constexpr' statement here}}
140b2313961SMark de Wever   if constexpr (true) {
141b2313961SMark de Wever   // expected-warning@+1 {{attribute 'unlikely' has no effect when annotating an 'if constexpr' statement}}
142b2313961SMark de Wever   } else [[unlikely]];
143b2313961SMark de Wever 
144b2313961SMark de Wever   // Annotating both branches with conflicting likelihoods generates no diagnostic regarding the conflict.
145b2313961SMark de Wever   // expected-warning@+2 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
146b2313961SMark de Wever   // expected-note@+1 2 {{annotating the 'if constexpr' statement here}}
147b2313961SMark de Wever   if constexpr (true) [[likely]] {
148b2313961SMark de Wever   // expected-warning@+1 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
149b2313961SMark de Wever   } else [[likely]];
150c058a712SAaron Ballman 
151c058a712SAaron Ballman   if (1) [[likely, unlikely]] { // expected-error {{'unlikely' and 'likely' attributes are not compatible}} \
152c058a712SAaron Ballman                                 // expected-note {{conflicting attribute is here}}
153c058a712SAaron Ballman   } else [[unlikely]][[likely]] { // expected-error {{'likely' and 'unlikely' attributes are not compatible}} \
154c058a712SAaron Ballman                                   // expected-note {{conflicting attribute is here}}
155c058a712SAaron Ballman   }
156b2313961SMark de Wever }
1577ebcb7ceSRichard Smith 
constexpr_function()1587ebcb7ceSRichard Smith constexpr int constexpr_function() {
1597ebcb7ceSRichard Smith   [[likely]] return 0;
1607ebcb7ceSRichard Smith }
1617ebcb7ceSRichard Smith static_assert(constexpr_function() == 0);
162*623b66edSDávid Bolvanský 
pow(double x,long long n)163*623b66edSDávid Bolvanský constexpr double pow(double x, long long n) noexcept {
164*623b66edSDávid Bolvanský     if (n > 0) [[likely]]
165*623b66edSDávid Bolvanský         return x * pow(x, n - 1);
166*623b66edSDávid Bolvanský     else [[unlikely]]
167*623b66edSDávid Bolvanský         return 1;
168*623b66edSDávid Bolvanský }
fact(long long n)169*623b66edSDávid Bolvanský constexpr long long fact(long long n) noexcept {
170*623b66edSDávid Bolvanský     if (n > 1) [[likely]]
171*623b66edSDávid Bolvanský         return n * fact(n - 1);
172*623b66edSDávid Bolvanský     else [[unlikely]]
173*623b66edSDávid Bolvanský         return 1;
174*623b66edSDávid Bolvanský }
175*623b66edSDávid Bolvanský 
17608196e0bSMark de Wever #endif
177