1 // RUN: %clang_cc1 %s -Wno-private-extern -triple i386-pc-linux-gnu -verify -fsyntax-only 2 3 void f(void) { 4 int i; 5 6 asm ("foo\n" : : "a" (i + 2)); 7 asm ("foo\n" : : "a" (f())); // expected-error {{invalid type 'void' in asm input}} 8 9 asm ("foo\n" : "=a" (f())); // expected-error {{invalid lvalue in asm output}} 10 asm ("foo\n" : "=a" (i + 2)); // expected-error {{invalid lvalue in asm output}} 11 12 asm ("foo\n" : [symbolic_name] "=a" (i) : "[symbolic_name]" (i)); 13 asm ("foo\n" : "=a" (i) : "[" (i)); // expected-error {{invalid input constraint '[' in asm}} 14 asm ("foo\n" : "=a" (i) : "[foo" (i)); // expected-error {{invalid input constraint '[foo' in asm}} 15 asm ("foo\n" : "=a" (i) : "[symbolic_name]" (i)); // expected-error {{invalid input constraint '[symbolic_name]' in asm}} 16 17 asm ("foo\n" : : "" (i)); // expected-error {{invalid input constraint '' in asm}} 18 asm ("foo\n" : "=a" (i) : "" (i)); // expected-error {{invalid input constraint '' in asm}} 19 } 20 21 void clobbers(void) { 22 asm ("nop" : : : "ax", "#ax", "%ax"); 23 asm ("nop" : : : "eax", "rax", "ah", "al"); 24 asm ("nop" : : : "0", "%0", "#0"); 25 asm ("nop" : : : "foo"); // expected-error {{unknown register name 'foo' in asm}} 26 asm ("nop" : : : "52"); 27 asm ("nop" : : : "204"); // expected-error {{unknown register name '204' in asm}} 28 asm ("nop" : : : "-1"); // expected-error {{unknown register name '-1' in asm}} 29 asm ("nop" : : : "+1"); // expected-error {{unknown register name '+1' in asm}} 30 register void *clobber_conflict asm ("%rcx"); 31 register void *no_clobber_conflict asm ("%rax"); 32 int a,b,c; 33 asm ("nop" : "=r" (no_clobber_conflict) : "r" (clobber_conflict) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}} 34 asm ("nop" : "=r" (clobber_conflict) : "r" (no_clobber_conflict) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}} 35 asm ("nop" : "=r" (clobber_conflict) : "r" (clobber_conflict) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}} 36 asm ("nop" : "=c" (a) : "r" (no_clobber_conflict) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}} 37 asm ("nop" : "=r" (no_clobber_conflict) : "c" (c) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}} 38 asm ("nop" : "=r" (clobber_conflict) : "c" (c) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}} 39 asm ("nop" : "=a" (a) : "b" (b) : "%rcx", "%rbx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}} 40 } 41 42 void test3(void) { 43 int x; 44 asm(L"foo" : "=r"(x)); // expected-error {{wide string}} 45 asm("foo" : L"=r"(x)); // expected-error {{wide string}} 46 } 47 48 void test4(const volatile void *addr) 49 { 50 asm ("nop" : : "r"(*addr)); /* expected-error {{invalid type 'const volatile void' in asm input for constraint 'r'}} 51 expected-warning {{ISO C does not allow indirection on operand of type 'const volatile void *'}} */ 52 asm ("nop" : : "m"(*addr)); // expected-warning {{ISO C does not allow indirection on operand of type 'const volatile void *'}} 53 54 asm ("nop" : : "r"(test4(addr))); // expected-error {{invalid type 'void' in asm input for constraint 'r'}} 55 asm ("nop" : : "m"(test4(addr))); // expected-error {{invalid lvalue in asm input for constraint 'm'}} 56 57 asm ("nop" : : "m"(f())); // expected-error {{invalid lvalue in asm input for constraint 'm'}} 58 } 59 60 void test5(void) { 61 asm("nop" : : "X" (8)); 62 } 63 64 // PR3385 65 void test6(long i) { 66 asm("nop" : : "er"(i)); 67 } 68 69 void asm_string_tests(int i) { 70 asm("%!"); // simple asm string, %! is not an error. 71 asm("%!" : ); // expected-error {{invalid % escape in inline assembly string}} 72 asm("xyz %" : ); // expected-error {{invalid % escape in inline assembly string}} 73 74 asm ("%[somename]" :: [somename] "i"(4)); // ok 75 asm ("%[somename]" :: "i"(4)); // expected-error {{unknown symbolic operand name in inline assembly string}} 76 asm ("%[somename" :: "i"(4)); // expected-error {{unterminated symbolic operand name in inline assembly string}} 77 asm ("%[]" :: "i"(4)); // expected-error {{empty symbolic operand name in inline assembly string}} 78 79 // PR3258 80 asm("%9" :: "i"(4)); // expected-error {{invalid operand number in inline asm string}} 81 asm("%1" : "+r"(i)); // ok, referring to input. 82 } 83 84 // PR4077 85 int test7(unsigned long long b) { 86 int a; 87 asm volatile("foo %0 %1" : "=a" (a) :"0" (b)); // expected-error {{input with type 'unsigned long long' matching output with type 'int'}} 88 return a; 89 } 90 91 // PR3904 92 void test8(int i) { 93 // A number in an input constraint cannot point to a read-write constraint. 94 asm("" : "+r" (i), "=r"(i) : "0" (i)); // expected-error{{invalid input constraint '0' in asm}} 95 } 96 97 // PR3905 98 void test9(int i) { 99 asm("" : [foo] "=r" (i), "=r"(i) : "1[foo]"(i)); // expected-error{{invalid input constraint '1[foo]' in asm}} 100 asm("" : [foo] "=r" (i), "=r"(i) : "[foo]1"(i)); // expected-error{{invalid input constraint '[foo]1' in asm}} 101 } 102 103 void test10(void){ 104 static int g asm ("g_asm") = 0; 105 extern int gg asm ("gg_asm"); 106 __private_extern__ int ggg asm ("ggg_asm"); 107 108 int a asm ("a_asm"); // expected-warning{{ignored asm label 'a_asm' on automatic variable}} 109 auto int aa asm ("aa_asm"); // expected-warning{{ignored asm label 'aa_asm' on automatic variable}} 110 111 register int r asm ("cx"); 112 register int rr asm ("rr_asm"); // expected-error{{unknown register name 'rr_asm' in asm}} 113 register int rrr asm ("%"); // expected-error{{unknown register name '%' in asm}} 114 } 115 116 // This is just an assert because of the boolean conversion. 117 // Feel free to change the assembly to something sensible if it causes a problem. 118 void test11(void) { 119 _Bool b; 120 asm volatile ("movb %%gs:%P2,%b0" : "=q"(b) : "0"(0), "i"(5L)); 121 } 122 123 void test12(void) { 124 register int cc __asm ("cc"); // expected-error{{unknown register name 'cc' in asm}} 125 } 126 127 // PR10223 128 void test13(void) { 129 void *esp; 130 __asm__ volatile ("mov %%esp, %o" : "=r"(esp) : : ); // expected-error {{invalid % escape in inline assembly string}} 131 } 132 133 struct S; // expected-note 2 {{forward declaration of 'struct S'}} 134 void test14(struct S *s) { 135 __asm("": : "a"(*s)); // expected-error {{dereference of pointer to incomplete type 'struct S'}} 136 __asm("": "=a" (*s) :); // expected-error {{dereference of pointer to incomplete type 'struct S'}} 137 } 138 139 // PR15759. 140 double test15(void) { 141 double ret = 0; 142 __asm("0.0":"="(ret)); // expected-error {{invalid output constraint '=' in asm}} 143 __asm("0.0":"=&"(ret)); // expected-error {{invalid output constraint '=&' in asm}} 144 __asm("0.0":"+?"(ret)); // expected-error {{invalid output constraint '+?' in asm}} 145 __asm("0.0":"+!"(ret)); // expected-error {{invalid output constraint '+!' in asm}} 146 __asm("0.0":"+#"(ret)); // expected-error {{invalid output constraint '+#' in asm}} 147 __asm("0.0":"+*"(ret)); // expected-error {{invalid output constraint '+*' in asm}} 148 __asm("0.0":"=%"(ret)); // expected-error {{invalid output constraint '=%' in asm}} 149 __asm("0.0":"=,="(ret)); // expected-error {{invalid output constraint '=,=' in asm}} 150 __asm("0.0":"=,g"(ret)); // no-error 151 __asm("0.0":"=g"(ret)); // no-error 152 return ret; 153 } 154 155 void iOutputConstraint(int x){ 156 __asm ("nop" : "=ir" (x) : :); // no-error 157 __asm ("nop" : "=ri" (x) : :); // no-error 158 __asm ("nop" : "=ig" (x) : :); // no-error 159 __asm ("nop" : "=im" (x) : :); // no-error 160 __asm ("nop" : "=imr" (x) : :); // no-error 161 __asm ("nop" : "=i" (x) : :); // expected-error{{invalid output constraint '=i' in asm}} 162 __asm ("nop" : "+i" (x) : :); // expected-error{{invalid output constraint '+i' in asm}} 163 __asm ("nop" : "=ii" (x) : :); // expected-error{{invalid output constraint '=ii' in asm}} 164 __asm ("nop" : "=nr" (x) : :); // no-error 165 __asm ("nop" : "=rn" (x) : :); // no-error 166 __asm ("nop" : "=ng" (x) : :); // no-error 167 __asm ("nop" : "=nm" (x) : :); // no-error 168 __asm ("nop" : "=nmr" (x) : :); // no-error 169 __asm ("nop" : "=n" (x) : :); // expected-error{{invalid output constraint '=n' in asm}} 170 __asm ("nop" : "+n" (x) : :); // expected-error{{invalid output constraint '+n' in asm}} 171 __asm ("nop" : "=nn" (x) : :); // expected-error{{invalid output constraint '=nn' in asm}} 172 __asm ("nop" : "=Fr" (x) : :); // no-error 173 __asm ("nop" : "=rF" (x) : :); // no-error 174 __asm ("nop" : "=Fg" (x) : :); // no-error 175 __asm ("nop" : "=Fm" (x) : :); // no-error 176 __asm ("nop" : "=Fmr" (x) : :); // no-error 177 __asm ("nop" : "=F" (x) : :); // expected-error{{invalid output constraint '=F' in asm}} 178 __asm ("nop" : "+F" (x) : :); // expected-error{{invalid output constraint '+F' in asm}} 179 __asm ("nop" : "=FF" (x) : :); // expected-error{{invalid output constraint '=FF' in asm}} 180 __asm ("nop" : "=Er" (x) : :); // no-error 181 __asm ("nop" : "=rE" (x) : :); // no-error 182 __asm ("nop" : "=Eg" (x) : :); // no-error 183 __asm ("nop" : "=Em" (x) : :); // no-error 184 __asm ("nop" : "=Emr" (x) : :); // no-error 185 __asm ("nop" : "=E" (x) : :); // expected-error{{invalid output constraint '=E' in asm}} 186 __asm ("nop" : "+E" (x) : :); // expected-error{{invalid output constraint '+E' in asm}} 187 __asm ("nop" : "=EE" (x) : :); // expected-error{{invalid output constraint '=EE' in asm}} 188 } 189 190 // PR19837 191 struct foo { 192 int a; 193 }; 194 register struct foo bar asm("esp"); // expected-error {{unsupported type for named register variable}} 195 register float baz asm("esp"); // expected-error {{unsupported type for named register variable}} 196 197 register int r0 asm ("edi"); // expected-error {{register 'edi' unsuitable for global register variables on this target}} 198 register long long r1 asm ("esp"); // expected-error {{size of register 'esp' does not match variable size}} 199 register int r2 asm ("esp"); 200 201 double f_output_constraint(void) { 202 double result; 203 __asm("foo1": "=f" (result)); // expected-error {{invalid output constraint '=f' in asm}} 204 return result; 205 } 206 207 double f_output_constraint_2(void) { 208 double result; 209 __asm("foo1": "+f" (result)); // expected-error {{invalid output constraint '+f' in asm}} 210 return result; 211 } 212 213 void fn1(void) { 214 int l; 215 __asm__("" 216 : [l] "=r"(l) 217 : "[l],m"(l)); // expected-error {{asm constraint has an unexpected number of alternatives: 1 vs 2}} 218 } 219 220 void fn2(void) { 221 int l; 222 __asm__("" 223 : "+&m"(l)); // expected-error {{invalid output constraint '+&m' in asm}} 224 } 225 226 void fn3(void) { 227 int l; 228 __asm__("" 229 : "+#r"(l)); // expected-error {{invalid output constraint '+#r' in asm}} 230 } 231 232 void fn4(void) { 233 int l; 234 __asm__("" 235 : "=r"(l) 236 : "m#"(l)); 237 } 238 239 void fn5(void) { 240 int l; 241 __asm__("" 242 : [g] "+r"(l) 243 : "[g]"(l)); // expected-error {{invalid input constraint '[g]' in asm}} 244 } 245 246 void fn6(void) { 247 int a; 248 __asm__("" 249 : "=rm"(a), "=rm"(a) 250 : "11m"(a)); // expected-error {{invalid input constraint '11m' in asm}} 251 } 252 253 // PR14269 254 typedef struct test16_foo { 255 unsigned int field1 : 1; 256 unsigned int field2 : 2; 257 unsigned int field3 : 3; 258 } test16_foo; 259 typedef __attribute__((vector_size(16))) int test16_bar; 260 register int test16_baz asm("esp"); 261 262 void test16(void) 263 { 264 test16_foo a; 265 test16_bar b; 266 267 __asm__("movl $5, %0" 268 : "=rm" (a.field2)); // expected-error {{reference to a bit-field in asm input with a memory constraint '=rm'}} 269 __asm__("movl $5, %0" 270 : 271 : "m" (a.field3)); // expected-error {{reference to a bit-field in asm output with a memory constraint 'm'}} 272 __asm__("movl $5, %0" 273 : "=rm" (b[2])); // expected-error {{reference to a vector element in asm input with a memory constraint '=rm'}} 274 __asm__("movl $5, %0" 275 : 276 : "m" (b[3])); // expected-error {{reference to a vector element in asm output with a memory constraint 'm'}} 277 __asm__("movl $5, %0" 278 : "=rm" (test16_baz)); // expected-error {{reference to a global register variable in asm input with a memory constraint '=rm'}} 279 __asm__("movl $5, %0" 280 : 281 : "m" (test16_baz)); // expected-error {{reference to a global register variable in asm output with a memory constraint 'm'}} 282 } 283 284 int test17(int t0) 285 { 286 int r0, r1; 287 __asm ("addl %2, %2\n\t" 288 "movl $123, %0" 289 : "=a" (r0), 290 "=&r" (r1) 291 : "1" (t0), // expected-note {{constraint '1' is already present here}} 292 "1" (t0)); // expected-error {{more than one input constraint matches the same output '1'}} 293 return r0 + r1; 294 } 295 296 void test18(void) 297 { 298 // expected-error@+2 {{duplicate use of asm operand name "lab"}} 299 // expected-note@+1 {{asm operand name "lab" first referenced here}} 300 asm goto ("" : : : : lab, lab, lab2, lab); 301 // expected-error@+2 {{duplicate use of asm operand name "lab"}} 302 // expected-note@+1 {{asm operand name "lab" first referenced here}} 303 asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab); 304 lab:; 305 lab2:; 306 int x,x1; 307 // expected-error@+2 {{duplicate use of asm operand name "lab"}} 308 // expected-note@+1 {{asm operand name "lab" first referenced here}} 309 asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x)); 310 // expected-error@+2 {{duplicate use of asm operand name "lab"}} 311 // expected-note@+1 {{asm operand name "lab" first referenced here}} 312 asm ("" : [lab] "=r" (x1) : [lab] "r" (x)); 313 // expected-error@+1 {{invalid operand number in inline asm string}} 314 asm ("jne %l0":::); 315 asm goto ("jne %l0"::::lab); 316 } 317 318 typedef struct _st_size64 { 319 int a; 320 char b; 321 } st_size64; 322 323 typedef struct _st_size96 { 324 int a; 325 int b; 326 int c; 327 } st_size96; 328 329 typedef struct _st_size16 { 330 char a; 331 char b; 332 } st_size16; 333 334 typedef struct _st_size32 { 335 char a; 336 char b; 337 char c; 338 char d; 339 } st_size32; 340 341 typedef struct _st_size128 { 342 int a; 343 int b; 344 int c; 345 int d; 346 } st_size128; 347 348 void test19(long long x) 349 { 350 st_size64 a; 351 st_size96 b; 352 st_size16 c; 353 st_size32 d; 354 st_size128 e; 355 asm ("" : "=rm" (a): "0" (1)); // no-error 356 asm ("" : "=rm" (d): "0" (1)); // no-error 357 asm ("" : "=rm" (c): "0" (x)); // no-error 358 // FIXME: This case is actually supported by codegen. 359 asm ("" : "=rm" (x): "0" (a)); // expected-error {{unsupported inline asm: input with type 'st_size64' (aka 'struct _st_size64') matching output with type 'long long'}} 360 // FIXME: This case is actually supported by codegen. 361 asm ("" : "=rm" (a): "0" (d)); // expected-error {{unsupported inline asm: input with type 'st_size32' (aka 'struct _st_size32') matching output with type 'st_size64' (aka 'struct _st_size64')}} 362 asm ("" : "=rm" (b): "0" (1)); // expected-error {{impossible constraint in asm: cannot store value into a register}} 363 // FIXME: This case should be supported by codegen, but it fails now. 364 asm ("" : "=rm" (e): "0" (1)); // no-error 365 // FIXME: This case should be supported by codegen, but it fails now. 366 asm ("" : "=rm" (x): "0" (e)); // expected-error {{unsupported inline asm: input with type 'st_size128' (aka 'struct _st_size128') matching output with type 'long long'}} 367 } 368 369 typedef int int2 __attribute__((ext_vector_type(2))); 370 371 // GH118892 372 void test20(char x) { 373 double d; 374 float f; 375 376 asm ("fabs" : "=t" (d): "0" (x)); // expected-error {{unsupported inline asm: input with type 'char' matching output with type 'double'}} 377 asm ("fabs" : "=t" (x): "0" (d)); // expected-error {{unsupported inline asm: input with type 'double' matching output with type 'char'}} 378 asm ("fabs" : "=t" (f): "0" (d)); // no-error 379 asm ("fabs" : "=t" (d): "0" (f)); // no-error 380 381 st_size64 a; 382 asm ("fabs" : "=t" (d): "0" (a)); // expected-error {{unsupported inline asm: input with type 'st_size64' (aka 'struct _st_size64') matching output with type 'double'}} 383 asm ("fabs" : "=t" (a): "0" (d)); // expected-error {{unsupported inline asm: input with type 'double' matching output with type 'st_size64' (aka 'struct _st_size64')}} 384 385 int2 v; 386 asm ("fabs" : "=t" (d): "0" (v)); // expected-error {{unsupported inline asm: input with type 'int2' (vector of 2 'int' values) matching output with type 'double'}} 387 asm ("fabs" : "=t" (v): "0" (d)); // expected-error {{unsupported inline asm: input with type 'double' matching output with type 'int2' (vector of 2 'int' values)}} 388 } 389