// RUN: %clang_cc1 %s -std=c++17 -fsyntax-only -verify
// RUN: %clang_cc1 %s -DPEDANTIC -pedantic -fsyntax-only -verify
#if PEDANTIC
void g() {
if (true)
[[likely]] {} // expected-warning {{use of the 'likely' attribute is a C++20 extension}}
else
[[unlikely]] {} // expected-warning {{use of the 'unlikely' attribute is a C++20 extension}}
}
#else
void a() {
if (true)
[[likely]]; // expected-warning {{conflicting attributes 'likely' are ignored}}
else
[[likely]]; // expected-note {{conflicting attribute is here}}
}
void b() {
if (true)
[[unlikely]]; // expected-warning {{conflicting attributes 'unlikely' are ignored}}
else
[[unlikely]]; // expected-note {{conflicting attribute is here}}
}
void c() {
if (true)
[[likely]];
}
void d() {
if (true)
[[unlikely]];
}
void g() {
if (true)
[[likely]] {}
else
[[unlikely]] {}
}
void h() {
if (true)
[[likely]] {}
else {
}
}
void i() {
if (true)
[[unlikely]] {}
else {
}
}
void j() {
if (true) {
} else
[[likely]] {}
}
void k() {
if (true) {
} else
[[likely]] {}
}
void l() {
if (true)
[[likely]] {}
else
[[unlikely]] if (false) [[likely]] {}
}
void m() {
[[likely]] int x = 42; // expected-error {{'likely' attribute cannot be applied to a declaration}}
if (x)
[[unlikely]] {}
if (x) {
[[unlikely]];
}
switch (x) {
case 1:
[[likely]] {}
break;
[[likely]] case 2 : case 3 : {}
break;
}
do {
[[unlikely]];
} while (x);
do
[[unlikely]] {}
while (x);
do { // expected-note {{to match this 'do'}}
}
[[unlikely]] while (x); // expected-error {{expected 'while' in do/while loop}}
for (;;)
[[unlikely]] {}
for (;;) {
[[unlikely]];
}
while (x)
[[unlikely]] {}
while (x) {
[[unlikely]];
}
switch (x)
[[unlikely]] {}
if (x)
goto lbl;
// FIXME: allow the attribute on the label
[[unlikely]] lbl : // expected-error {{'unlikely' attribute cannot be applied to a declaration}}
[[likely]] x = x + 1;
[[likely]]++ x;
}
void n() [[likely]] // expected-error {{'likely' attribute cannot be applied to types}}
{
try
[[likely]] {} // expected-error {{expected '{'}}
catch (...) [[likely]] { // expected-error {{expected expression}}
}
}
void o()
{
// expected-warning@+2 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
// expected-note@+1 {{annotating the 'if constexpr' statement here}}
if constexpr (true) [[likely]];
// expected-note@+1 {{annotating the 'if constexpr' statement here}}
if constexpr (true) {
// expected-warning@+1 {{attribute 'unlikely' has no effect when annotating an 'if constexpr' statement}}
} else [[unlikely]];
// Annotating both branches with conflicting likelihoods generates no diagnostic regarding the conflict.
// expected-warning@+2 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
// expected-note@+1 2 {{annotating the 'if constexpr' statement here}}
if constexpr (true) [[likely]] {
// expected-warning@+1 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
} else [[likely]];
if (1) [[likely, unlikely]] { // expected-error {{'unlikely' and 'likely' attributes are not compatible}} \
// expected-note {{conflicting attribute is here}}
} else [[unlikely]][[likely]] { // expected-error {{'likely' and 'unlikely' attributes are not compatible}} \
// expected-note {{conflicting attribute is here}}
}
}
constexpr int constexpr_function() {
[[likely]] return 0;
}
static_assert(constexpr_function() == 0);
constexpr double pow(double x, long long n) noexcept {
if (n > 0) [[likely]]
return x * pow(x, n - 1);
else [[unlikely]]
return 1;
}
constexpr long long fact(long long n) noexcept {
if (n > 1) [[likely]]
return n * fact(n - 1);
else [[unlikely]]
return 1;
}
#endif