1 // RUN: %clang_cc1 -std=c23 %s -E -verify 2 3 // Test the parsing behavior for __has_embed and all of its parameters to ensure we 4 // recover from failures gracefully. 5 6 // expected-error@+2 {{missing '(' after '__has_embed'}} \ 7 expected-error@+2 {{expected value in expression}} 8 #if __has_embed 9 #endif 10 11 // expected-error@+3 {{expected '>'}} \ 12 expected-note@+3 {{to match this '<'}} \ 13 expected-error@+3 {{expected value in expression}} 14 #if __has_embed(<) 15 #endif 16 17 // expected-error@+3 {{expected "FILENAME" or <FILENAME>}} \ 18 expected-warning@+3 {{missing terminating '"' character}} \ 19 expected-error@+3 {{invalid token at start of a preprocessor expression}} 20 #if __has_embed(") 21 #endif 22 23 // expected-error@+2 {{missing '(' after '__has_embed'}} \ 24 expected-error@+2 {{token is not a valid binary operator in a preprocessor subexpression}} 25 #if __has_embed file.txt 26 #endif 27 28 // OK, no diagnostic for an unknown embed parameter. 29 #if __has_embed("media/empty" xxx) 30 #endif 31 32 // expected-error@+2 {{expected identifier}} \ 33 expected-error@+2 {{expected value in expression}} 34 #if __has_embed("media/empty" xxx::) 35 #endif 36 37 // OK, no diagnostic for an unknown embed parameter. 38 #if __has_embed("media/empty" xxx::xxx) 39 #endif 40 41 // expected-error@+2 {{expected identifier}} \ 42 expected-error@+2 {{expected value in expression}} 43 #if __has_embed("media/empty" xxx::42) 44 #endif 45 46 // expected-error@+2 {{expected '('}} \ 47 expected-error@+2 {{expected value in expression}} 48 #if __has_embed("media/empty" limit) 49 #endif 50 51 // We get the same diagnostic twice intentionally. The first one is because of 52 // the missing value within limit() and the second one is because the #if does 53 // not resolve to a value due to the earlier error. 54 // expected-error@+1 2 {{expected value in expression}} 55 #if __has_embed("media/empty" limit() 56 #endif 57 58 // expected-error@+3 {{missing ')' after '__has_embed'}} \ 59 expected-error@+3 {{expected value in expression}} \ 60 expected-note@+3 {{to match this '('}} 61 #if __has_embed("media/empty" limit(xxx) 62 #endif 63 64 // expected-error@+3 {{missing ')' after '__has_embed'}} \ 65 expected-error@+3 {{expected value in expression}} \ 66 expected-note@+3 {{to match this '('}} 67 #if __has_embed("media/empty" limit(42) 68 #endif 69 70 // expected-error@+2 {{invalid token at start of a preprocessor expression}} \ 71 expected-error@+2 {{expected value in expression}} 72 #if __has_embed("media/empty" limit([) 73 #endif 74 75 // expected-error@+2 {{invalid token at start of a preprocessor expression}} \ 76 expected-error@+2 {{expected value in expression}} 77 #if __has_embed("media/empty" limit([)) 78 #endif 79 80 // expected-error@+2 {{division by zero in preprocessor expression}} \ 81 expected-error@+2 {{expected value in expression}} 82 #if __has_embed("media/empty" limit(1/0)) 83 #endif 84 85 // expected-error@+2 {{expected '('}} \ 86 expected-error@+2 {{expected value in expression}} 87 #if __has_embed("media/empty" clang::offset) 88 #endif 89 90 // We get the same diagnostic twice intentionally. The first one is because of 91 // the missing value within clang::offset() and the second one is because the 92 // #if does not resolve to a value due to the earlier error. 93 // expected-error@+1 2 {{expected value in expression}} 94 #if __has_embed("media/empty" clang::offset() 95 #endif 96 97 // expected-error@+3 {{missing ')' after '__has_embed'}} \ 98 expected-error@+3 {{expected value in expression}} \ 99 expected-note@+3 {{to match this '('}} 100 #if __has_embed("media/empty" clang::offset(xxx) 101 #endif 102 103 // expected-error@+3 {{missing ')' after '__has_embed'}} \ 104 expected-error@+3 {{expected value in expression}} \ 105 expected-note@+3 {{to match this '('}} 106 #if __has_embed("media/empty" clang::offset(42) 107 #endif 108 109 // expected-error@+2 {{invalid token at start of a preprocessor expression}} \ 110 expected-error@+2 {{expected value in expression}} 111 #if __has_embed("media/empty" clang::offset([) 112 #endif 113 114 // expected-error@+2 {{invalid token at start of a preprocessor expression}} \ 115 expected-error@+2 {{expected value in expression}} 116 #if __has_embed("media/empty" clang::offset([)) 117 #endif 118 119 // expected-error@+2 {{division by zero in preprocessor expression}} \ 120 expected-error@+2 {{expected value in expression}} 121 #if __has_embed("media/empty" clang::offset(1/0)) 122 #endif 123 124 // expected-error@+2 {{expected '('}} \ 125 expected-error@+2 {{expected value in expression}} 126 #if __has_embed("media/empty" clang::offset 42) 127 #endif 128 129 // expected-error@+2 {{expected '('}} \ 130 expected-error@+2 {{expected value in expression}} 131 #if __has_embed("media/empty" prefix) 132 #endif 133 134 // expected-error@+3 {{missing ')' after '__has_embed'}} \ 135 expected-error@+3 {{expected value in expression}} \ 136 expected-note@+3 {{to match this '('}} 137 #if __has_embed("media/empty" prefix() 138 #endif 139 140 // expected-error@+3 {{missing ')' after '__has_embed'}} \ 141 expected-error@+3 {{expected value in expression}} \ 142 expected-note@+3 {{to match this '('}} 143 #if __has_embed("media/empty" prefix(xxx) 144 #endif 145 146 #if __has_embed("media/empty" prefix(1/0)) // OK: emitted as tokens, not evaluated yet. 147 #endif 148 #if __has_embed("media/empty" prefix(([{}]))) // OK: delimiters balanced 149 #endif 150 // expected-error@+3 {{expected '}'}} \ 151 expected-note@+3 {{to match this '{'}} \ 152 expected-error@+3 {{expected value in expression}} 153 #if __has_embed("media/empty" prefix(([{)]})) 154 #endif 155 // expected-error@+3 {{expected ']'}} \ 156 expected-note@+3 {{to match this '['}} \ 157 expected-error@+3 {{expected value in expression}} 158 #if __has_embed("media/empty" prefix(([{})})) 159 #endif 160 // expected-error@+3 {{expected ')'}} \ 161 expected-note@+3 {{to match this '('}} \ 162 expected-error@+3 {{expected value in expression}} 163 #if __has_embed("media/empty" prefix(([{}]})) 164 #endif 165 #if __has_embed("media/empty" prefix()) // OK: tokens within parens are optional 166 #endif 167 // expected-error@+2 {{expected '('}} \ 168 expected-error@+2 {{expected value in expression}} 169 #if __has_embed("media/empty" prefix)) 170 #endif 171 172 // expected-error@+2 {{expected '('}} \ 173 expected-error@+2 {{expected value in expression}} 174 #if __has_embed("media/empty" suffix) 175 #endif 176 177 // expected-error@+3 {{missing ')' after '__has_embed'}} \ 178 expected-error@+3 {{expected value in expression}} \ 179 expected-note@+3 {{to match this '('}} 180 #if __has_embed("media/empty" suffix() 181 #endif 182 183 // expected-error@+3 {{missing ')' after '__has_embed'}} \ 184 expected-error@+3 {{expected value in expression}} \ 185 expected-note@+3 {{to match this '('}} 186 #if __has_embed("media/empty" suffix(xxx) 187 #endif 188 189 #if __has_embed("media/empty" suffix(1/0)) // OK: emitted as tokens, not evaluated yet. 190 #endif 191 #if __has_embed("media/empty" suffix(([{}]))) // OK: delimiters balanced 192 #endif 193 // expected-error@+3 {{expected '}'}} \ 194 expected-note@+3 {{to match this '{'}} \ 195 expected-error@+3 {{expected value in expression}} 196 #if __has_embed("media/empty" suffix(([{)]})) 197 #endif 198 // expected-error@+3 {{expected ']'}} \ 199 expected-note@+3 {{to match this '['}} \ 200 expected-error@+3 {{expected value in expression}} 201 #if __has_embed("media/empty" suffix(([{})})) 202 #endif 203 // expected-error@+3 {{expected ')'}} \ 204 expected-note@+3 {{to match this '('}} \ 205 expected-error@+3 {{expected value in expression}} 206 #if __has_embed("media/empty" suffix(([{}]})) 207 #endif 208 #if __has_embed("media/empty" suffix()) // OK: tokens within parens are optional 209 #endif 210 // expected-error@+2 {{expected '('}} \ 211 expected-error@+2 {{expected value in expression}} 212 #if __has_embed("media/empty" suffix)) 213 #endif 214 215 #if __has_embed("media/art.txt" if_empty(1/0)) // OK: emitted as tokens, not evaluated yet. 216 #endif 217 #if __has_embed("media/art.txt" if_empty(([{}]))) // OK: delimiters balanced 218 #endif 219 // expected-error@+3 {{expected '}'}} \ 220 expected-note@+3 {{to match this '{'}} \ 221 expected-error@+3 {{expected value in expression}} 222 #if __has_embed("media/art.txt" if_empty(([{)]})) 223 #endif 224 // expected-error@+3 {{expected ']'}} \ 225 expected-note@+3 {{to match this '['}} \ 226 expected-error@+3 {{expected value in expression}} 227 #if __has_embed("media/art.txt" if_empty(([{})})) 228 #endif 229 // expected-error@+3 {{expected ')'}} \ 230 expected-note@+3 {{to match this '('}} \ 231 expected-error@+3 {{expected value in expression}} 232 #if __has_embed("media/art.txt" if_empty(([{}]})) 233 #endif 234 #if __has_embed("media/art.txt" if_empty()) // OK: tokens within parens are optional 235 #endif 236 // expected-error@+2 {{expected '('}} \ 237 expected-error@+2 {{expected value in expression}} 238 #if __has_embed("media/art.txt" if_empty)) 239 #endif 240 241