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