1 // RUN: %clang_cc1 %s -std=c++17 -fsyntax-only -verify
2 // RUN: %clang_cc1 %s -DPEDANTIC -pedantic -fsyntax-only -verify
3
4 #if PEDANTIC
g()5 void g() {
6 if (true)
7 [[likely]] {} // expected-warning {{use of the 'likely' attribute is a C++20 extension}}
8 else
9 [[unlikely]] {} // expected-warning {{use of the 'unlikely' attribute is a C++20 extension}}
10 }
11 #else
a()12 void a() {
13 if (true)
14 [[likely]]; // expected-warning {{conflicting attributes 'likely' are ignored}}
15 else
16 [[likely]]; // expected-note {{conflicting attribute is here}}
17 }
18
b()19 void b() {
20 if (true)
21 [[unlikely]]; // expected-warning {{conflicting attributes 'unlikely' are ignored}}
22 else
23 [[unlikely]]; // expected-note {{conflicting attribute is here}}
24 }
25
c()26 void c() {
27 if (true)
28 [[likely]];
29 }
30
d()31 void d() {
32 if (true)
33 [[unlikely]];
34 }
35
g()36 void g() {
37 if (true)
38 [[likely]] {}
39 else
40 [[unlikely]] {}
41 }
42
h()43 void h() {
44 if (true)
45 [[likely]] {}
46 else {
47 }
48 }
49
i()50 void i() {
51 if (true)
52 [[unlikely]] {}
53 else {
54 }
55 }
56
j()57 void j() {
58 if (true) {
59 } else
60 [[likely]] {}
61 }
62
k()63 void k() {
64 if (true) {
65 } else
66 [[likely]] {}
67 }
68
l()69 void l() {
70 if (true)
71 [[likely]] {}
72 else
73 [[unlikely]] if (false) [[likely]] {}
74 }
75
m()76 void m() {
77 [[likely]] int x = 42; // expected-error {{'likely' attribute cannot be applied to a declaration}}
78
79 if (x)
80 [[unlikely]] {}
81 if (x) {
82 [[unlikely]];
83 }
84 switch (x) {
85 case 1:
86 [[likely]] {}
87 break;
88 [[likely]] case 2 : case 3 : {}
89 break;
90 }
91
92 do {
93 [[unlikely]];
94 } while (x);
95 do
96 [[unlikely]] {}
97 while (x);
98 do { // expected-note {{to match this 'do'}}
99 }
100 [[unlikely]] while (x); // expected-error {{expected 'while' in do/while loop}}
101 for (;;)
102 [[unlikely]] {}
103 for (;;) {
104 [[unlikely]];
105 }
106 while (x)
107 [[unlikely]] {}
108 while (x) {
109 [[unlikely]];
110 }
111
112 switch (x)
113 [[unlikely]] {}
114
115 if (x)
116 goto lbl;
117
118 // FIXME: allow the attribute on the label
119 [[unlikely]] lbl : // expected-error {{'unlikely' attribute cannot be applied to a declaration}}
120 [[likely]] x = x + 1;
121
122 [[likely]]++ x;
123 }
124
n()125 void n() [[likely]] // expected-error {{'likely' attribute cannot be applied to types}}
126 {
127 try
128 [[likely]] {} // expected-error {{expected '{'}}
129 catch (...) [[likely]] { // expected-error {{expected expression}}
130 }
131 }
132
o()133 void o()
134 {
135 // expected-warning@+2 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
136 // expected-note@+1 {{annotating the 'if constexpr' statement here}}
137 if constexpr (true) [[likely]];
138
139 // expected-note@+1 {{annotating the 'if constexpr' statement here}}
140 if constexpr (true) {
141 // expected-warning@+1 {{attribute 'unlikely' has no effect when annotating an 'if constexpr' statement}}
142 } else [[unlikely]];
143
144 // Annotating both branches with conflicting likelihoods generates no diagnostic regarding the conflict.
145 // expected-warning@+2 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
146 // expected-note@+1 2 {{annotating the 'if constexpr' statement here}}
147 if constexpr (true) [[likely]] {
148 // expected-warning@+1 {{attribute 'likely' has no effect when annotating an 'if constexpr' statement}}
149 } else [[likely]];
150
151 if (1) [[likely, unlikely]] { // expected-error {{'unlikely' and 'likely' attributes are not compatible}} \
152 // expected-note {{conflicting attribute is here}}
153 } else [[unlikely]][[likely]] { // expected-error {{'likely' and 'unlikely' attributes are not compatible}} \
154 // expected-note {{conflicting attribute is here}}
155 }
156 }
157 #endif
158