Home | History | Annotate | Download | only in Sema
      1 // RUN: %clang_cc1 %s -Wno-private-extern -triple i386-pc-linux-gnu -verify -fsyntax-only
      2 
      3 
      4 void f() {
      5   int i;
      6 
      7   asm ("foo\n" : : "a" (i + 2));
      8   asm ("foo\n" : : "a" (f())); // expected-error {{invalid type 'void' in asm input}}
      9 
     10   asm ("foo\n" : "=a" (f())); // expected-error {{invalid lvalue in asm output}}
     11   asm ("foo\n" : "=a" (i + 2)); // expected-error {{invalid lvalue in asm output}}
     12 
     13   asm ("foo\n" : [symbolic_name] "=a" (i) : "[symbolic_name]" (i));
     14   asm ("foo\n" : "=a" (i) : "[" (i)); // expected-error {{invalid input constraint '[' in asm}}
     15   asm ("foo\n" : "=a" (i) : "[foo" (i)); // expected-error {{invalid input constraint '[foo' in asm}}
     16   asm ("foo\n" : "=a" (i) : "[symbolic_name]" (i)); // expected-error {{invalid input constraint '[symbolic_name]' in asm}}
     17 
     18   asm ("foo\n" : : "" (i)); // expected-error {{invalid input constraint '' in asm}}
     19   asm ("foo\n" : "=a" (i) : "" (i)); // expected-error {{invalid input constraint '' in asm}}
     20 }
     21 
     22 void clobbers() {
     23   asm ("nop" : : : "ax", "#ax", "%ax");
     24   asm ("nop" : : : "eax", "rax", "ah", "al");
     25   asm ("nop" : : : "0", "%0", "#0");
     26   asm ("nop" : : : "foo"); // expected-error {{unknown register name 'foo' in asm}}
     27   asm ("nop" : : : "52");
     28   asm ("nop" : : : "204"); // expected-error {{unknown register name '204' in asm}}
     29   asm ("nop" : : : "-1"); // expected-error {{unknown register name '-1' in asm}}
     30   asm ("nop" : : : "+1"); // expected-error {{unknown register name '+1' in asm}}
     31 }
     32 
     33 // rdar://6094010
     34 void test3() {
     35   int x;
     36   asm(L"foo" : "=r"(x)); // expected-error {{wide string}}
     37   asm("foo" : L"=r"(x)); // expected-error {{wide string}}
     38 }
     39 
     40 // <rdar://problem/6156893>
     41 void test4(const volatile void *addr)
     42 {
     43     asm ("nop" : : "r"(*addr)); // expected-error {{invalid type 'const volatile void' in asm input for constraint 'r'}}
     44     asm ("nop" : : "m"(*addr));
     45 
     46     asm ("nop" : : "r"(test4(addr))); // expected-error {{invalid type 'void' in asm input for constraint 'r'}}
     47     asm ("nop" : : "m"(test4(addr))); // expected-error {{invalid lvalue in asm input for constraint 'm'}}
     48 
     49     asm ("nop" : : "m"(f())); // expected-error {{invalid lvalue in asm input for constraint 'm'}}
     50 }
     51 
     52 // <rdar://problem/6512595>
     53 void test5() {
     54   asm("nop" : : "X" (8));
     55 }
     56 
     57 // PR3385
     58 void test6(long i) {
     59   asm("nop" : : "er"(i));
     60 }
     61 
     62 void asm_string_tests(int i) {
     63   asm("%!");   // simple asm string, %! is not an error.
     64   asm("%!" : );   // expected-error {{invalid % escape in inline assembly string}}
     65   asm("xyz %" : );   // expected-error {{invalid % escape in inline assembly string}}
     66 
     67   asm ("%[somename]" :: [somename] "i"(4)); // ok
     68   asm ("%[somename]" :: "i"(4)); // expected-error {{unknown symbolic operand name in inline assembly string}}
     69   asm ("%[somename" :: "i"(4)); // expected-error {{unterminated symbolic operand name in inline assembly string}}
     70   asm ("%[]" :: "i"(4)); // expected-error {{empty symbolic operand name in inline assembly string}}
     71 
     72   // PR3258
     73   asm("%9" :: "i"(4)); // expected-error {{invalid operand number in inline asm string}}
     74   asm("%1" : "+r"(i)); // ok, referring to input.
     75 }
     76 
     77 // PR4077
     78 int test7(unsigned long long b) {
     79   int a;
     80   asm volatile("foo %0 %1" : "=a" (a) :"0" (b)); // expected-error {{input with type 'unsigned long long' matching output with type 'int'}}
     81   return a;
     82 }
     83 
     84 // <rdar://problem/7574870>
     85 asm volatile (""); // expected-warning {{meaningless 'volatile' on asm outside function}}
     86 
     87 // PR3904
     88 void test8(int i) {
     89   // A number in an input constraint can't point to a read-write constraint.
     90   asm("" : "+r" (i), "=r"(i) :  "0" (i)); // expected-error{{invalid input constraint '0' in asm}}
     91 }
     92 
     93 // PR3905
     94 void test9(int i) {
     95   asm("" : [foo] "=r" (i), "=r"(i) : "1[foo]"(i)); // expected-error{{invalid input constraint '1[foo]' in asm}}
     96   asm("" : [foo] "=r" (i), "=r"(i) : "[foo]1"(i)); // expected-error{{invalid input constraint '[foo]1' in asm}}
     97 }
     98 
     99 void test10(void){
    100   static int g asm ("g_asm") = 0;
    101   extern int gg asm ("gg_asm");
    102   __private_extern__ int ggg asm ("ggg_asm");
    103 
    104   int a asm ("a_asm"); // expected-warning{{ignored asm label 'a_asm' on automatic variable}}
    105   auto int aa asm ("aa_asm"); // expected-warning{{ignored asm label 'aa_asm' on automatic variable}}
    106 
    107   register int r asm ("cx");
    108   register int rr asm ("rr_asm"); // expected-error{{unknown register name 'rr_asm' in asm}}
    109   register int rrr asm ("%"); // expected-error{{unknown register name '%' in asm}}
    110 }
    111 
    112 // This is just an assert because of the boolean conversion.
    113 // Feel free to change the assembly to something sensible if it causes a problem.
    114 // rdar://problem/9414925
    115 void test11(void) {
    116   _Bool b;
    117   asm volatile ("movb %%gs:%P2,%b0" : "=q"(b) : "0"(0), "i"(5L));
    118 }
    119 
    120 void test12(void) {
    121   register int cc __asm ("cc"); // expected-error{{unknown register name 'cc' in asm}}
    122 }
    123 
    124 // PR10223
    125 void test13(void) {
    126   void *esp;
    127   __asm__ volatile ("mov %%esp, %o" : "=r"(esp) : : ); // expected-error {{invalid % escape in inline assembly string}}
    128 }
    129 
    130 // <rdar://problem/12700799>
    131 struct S;  // expected-note 2 {{forward declaration of 'struct S'}}
    132 void test14(struct S *s) {
    133   __asm("": : "a"(*s)); // expected-error {{dereference of pointer to incomplete type 'struct S'}}
    134   __asm("": "=a" (*s) :); // expected-error {{dereference of pointer to incomplete type 'struct S'}}
    135 }
    136 
    137 // PR15759.
    138 double test15() {
    139   double ret = 0;
    140   __asm("0.0":"="(ret)); // expected-error {{invalid output constraint '=' in asm}}
    141   __asm("0.0":"=&"(ret)); // expected-error {{invalid output constraint '=&' in asm}}
    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":"=,g"(ret)); // no-error
    149   __asm("0.0":"=g"(ret)); // no-error
    150   return ret;
    151 }
    152 
    153 // PR19837
    154 struct foo {
    155   int a;
    156 };
    157 register struct foo bar asm("esp"); // expected-error {{bad type for named register variable}}
    158 register float baz asm("esp"); // expected-error {{bad type for named register variable}}
    159 
    160 register int r0 asm ("edi"); // expected-error {{register 'edi' unsuitable for global register variables on this target}}
    161 register long long r1 asm ("esp"); // expected-error {{size of register 'esp' does not match variable size}}
    162 register int r2 asm ("esp");
    163 
    164 double f_output_constraint(void) {
    165   double result;
    166   __asm("foo1": "=f" (result)); // expected-error {{invalid output constraint '=f' in asm}}
    167   return result;
    168 }
    169 
    170 void fn1() {
    171   int l;
    172   __asm__(""
    173           : [l] "=r"(l)
    174           : "[l],m"(l)); // expected-error {{asm constraint has an unexpected number of alternatives: 1 vs 2}}
    175 }
    176 
    177 void fn2() {
    178   int l;
    179  __asm__(""
    180           : "+&m"(l)); // expected-error {{invalid output constraint '+&m' in asm}}
    181 }
    182 
    183 void fn3() {
    184   int l;
    185  __asm__(""
    186           : "+#r"(l)); // expected-error {{invalid output constraint '+#r' in asm}}
    187 }
    188 
    189 void fn4() {
    190   int l;
    191  __asm__(""
    192           : "=r"(l)
    193           : "m#"(l));
    194 }
    195 
    196 void fn5() {
    197   int l;
    198     __asm__(""
    199           : [g] "+r"(l)
    200           : "[g]"(l)); // expected-error {{invalid input constraint '[g]' in asm}}
    201 }
    202 
    203 void fn6() {
    204     int a;
    205   __asm__(""
    206             : "=rm"(a), "=rm"(a)
    207             : "11m"(a)) // expected-error {{invalid input constraint '11m' in asm}}
    208 }
    209 
    210 // PR14269
    211 typedef struct test16_foo {
    212   unsigned int field1 : 1;
    213   unsigned int field2 : 2;
    214   unsigned int field3 : 3;
    215 } test16_foo;
    216 typedef __attribute__((vector_size(16))) int test16_bar;
    217 register int test16_baz asm("esp");
    218 
    219 void test16()
    220 {
    221   test16_foo a;
    222   test16_bar b;
    223 
    224   __asm__("movl $5, %0"
    225           : "=rm" (a.field2)); // expected-error {{reference to a bit-field in asm input with a memory constraint '=rm'}}
    226   __asm__("movl $5, %0"
    227           :
    228           : "m" (a.field3)); // expected-error {{reference to a bit-field in asm output with a memory constraint 'm'}}
    229   __asm__("movl $5, %0"
    230           : "=rm" (b[2])); // expected-error {{reference to a vector element in asm input with a memory constraint '=rm'}}
    231   __asm__("movl $5, %0"
    232           :
    233           : "m" (b[3])); // expected-error {{reference to a vector element in asm output with a memory constraint 'm'}}
    234   __asm__("movl $5, %0"
    235           : "=rm" (test16_baz)); // expected-error {{reference to a global register variable in asm input with a memory constraint '=rm'}}
    236   __asm__("movl $5, %0"
    237           :
    238           : "m" (test16_baz)); // expected-error {{reference to a global register variable in asm output with a memory constraint 'm'}}
    239 }
    240 
    241 int test17(int t0)
    242 {
    243   int r0, r1;
    244   __asm ("addl %2, %2\n\t"
    245          "movl $123, %0"
    246          : "=a" (r0),
    247            "=&r" (r1)
    248          : "1" (t0),   // expected-note {{constraint '1' is already present here}}
    249            "1" (t0));  // expected-error {{more than one input constraint matches the same output '1'}}
    250   return r0 + r1;
    251 }
    252 
    253