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 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 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 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 26 void c() { 27 if (true) 28 [[likely]]; 29 } 30 31 void d() { 32 if (true) 33 [[unlikely]]; 34 } 35 36 void g() { 37 if (true) 38 [[likely]] {} 39 else 40 [[unlikely]] {} 41 } 42 43 void h() { 44 if (true) 45 [[likely]] {} 46 else { 47 } 48 } 49 50 void i() { 51 if (true) 52 [[unlikely]] {} 53 else { 54 } 55 } 56 57 void j() { 58 if (true) { 59 } else 60 [[likely]] {} 61 } 62 63 void k() { 64 if (true) { 65 } else 66 [[likely]] {} 67 } 68 69 void l() { 70 if (true) 71 [[likely]] {} 72 else 73 [[unlikely]] if (false) [[likely]] {} 74 } 75 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 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 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