xref: /aosp_15_r20/external/clang/test/Sema/ms-inline-asm.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // REQUIRES: x86-registered-target
2*67e74705SXin Li // RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fms-extensions -fasm-blocks -Wno-microsoft -Wunused-label -verify -fsyntax-only
3*67e74705SXin Li 
t1(void)4*67e74705SXin Li void t1(void) {
5*67e74705SXin Li  __asm __asm // expected-error {{__asm used with no assembly instructions}}
6*67e74705SXin Li }
7*67e74705SXin Li 
f()8*67e74705SXin Li void f() {
9*67e74705SXin Li   int foo;
10*67e74705SXin Li   __asm {
11*67e74705SXin Li     mov eax, eax
12*67e74705SXin Li     .unknowndirective // expected-error {{unknown directive}}
13*67e74705SXin Li   }
14*67e74705SXin Li   f();
15*67e74705SXin Li   __asm {
16*67e74705SXin Li     mov eax, 1+=2 // expected-error {{unknown token in expression}}
17*67e74705SXin Li   }
18*67e74705SXin Li   f();
19*67e74705SXin Li   __asm {
20*67e74705SXin Li     mov eax, 1+++ // expected-error {{unknown token in expression}}
21*67e74705SXin Li   }
22*67e74705SXin Li   f();
23*67e74705SXin Li   __asm {
24*67e74705SXin Li     mov eax, LENGTH bar // expected-error {{unable to lookup expression}}
25*67e74705SXin Li   }
26*67e74705SXin Li   f();
27*67e74705SXin Li   __asm {
28*67e74705SXin Li     mov eax, SIZE bar // expected-error {{unable to lookup expression}}
29*67e74705SXin Li   }
30*67e74705SXin Li   f();
31*67e74705SXin Li   __asm {
32*67e74705SXin Li     mov eax, TYPE bar // expected-error {{unable to lookup expression}} expected-error {{use of undeclared label 'bar'}}
33*67e74705SXin Li   }
34*67e74705SXin Li }
35*67e74705SXin Li 
rdar15318432(void)36*67e74705SXin Li void rdar15318432(void) {
37*67e74705SXin Li   // We used to crash on this.  When LLVM called back to Clang to parse a name
38*67e74705SXin Li   // and do name lookup, if parsing failed, we did not restore the lexer state
39*67e74705SXin Li   // properly.
40*67e74705SXin Li 
41*67e74705SXin Li   __asm {
42*67e74705SXin Li     and ecx, ~15
43*67e74705SXin Li   }
44*67e74705SXin Li 
45*67e74705SXin Li   int x = 0;
46*67e74705SXin Li   __asm {
47*67e74705SXin Li     and ecx, x
48*67e74705SXin Li     and ecx, ~15
49*67e74705SXin Li   }
50*67e74705SXin Li }
51*67e74705SXin Li 
52*67e74705SXin Li static int global;
53*67e74705SXin Li 
t2(int * arr,int i)54*67e74705SXin Li int t2(int *arr, int i) {
55*67e74705SXin Li   __asm {
56*67e74705SXin Li     mov eax, arr;
57*67e74705SXin Li     mov eax, arr[0];
58*67e74705SXin Li     mov eax, arr[1 + 2];
59*67e74705SXin Li     mov eax, arr[1 + (2 * 5) - 3 + 1<<1];
60*67e74705SXin Li   }
61*67e74705SXin Li 
62*67e74705SXin Li   // expected-error@+1 {{cannot use base register with variable reference}}
63*67e74705SXin Li   __asm { mov eax, arr[ebp + 1 + (2 * 5) - 3 + 1<<1] }
64*67e74705SXin Li   // expected-error@+1 {{cannot use index register with variable reference}}
65*67e74705SXin Li   __asm { mov eax, arr[esi * 4] }
66*67e74705SXin Li   // expected-error@+1 {{cannot use more than one symbol in memory operand}}
67*67e74705SXin Li   __asm { mov eax, arr[i] }
68*67e74705SXin Li   // expected-error@+1 {{cannot use more than one symbol in memory operand}}
69*67e74705SXin Li   __asm { mov eax, global[i] }
70*67e74705SXin Li 
71*67e74705SXin Li   // FIXME: Why don't we diagnose this?
72*67e74705SXin Li   // expected-Xerror@+1 {{cannot reference multiple local variables in assembly operand}}
73*67e74705SXin Li   //__asm mov eax, [arr + i];
74*67e74705SXin Li   return 0;
75*67e74705SXin Li }
76*67e74705SXin Li 
77*67e74705SXin Li typedef struct {
78*67e74705SXin Li   int a;
79*67e74705SXin Li   int b;
80*67e74705SXin Li } A;
81*67e74705SXin Li 
t3()82*67e74705SXin Li void t3() {
83*67e74705SXin Li   __asm { mov eax, [eax] UndeclaredId } // expected-error {{unknown token in expression}} expected-error {{use of undeclared label 'UndeclaredId'}}
84*67e74705SXin Li 
85*67e74705SXin Li   // FIXME: Only emit one diagnostic here.
86*67e74705SXin Li   // expected-error@+3 {{use of undeclared label 'A'}}
87*67e74705SXin Li   // expected-error@+2 {{unexpected type name 'A': expected expression}}
88*67e74705SXin Li   // expected-error@+1 {{unknown token in expression}}
89*67e74705SXin Li   __asm { mov eax, [eax] A }
90*67e74705SXin Li }
91*67e74705SXin Li 
t4()92*67e74705SXin Li void t4() {
93*67e74705SXin Li   // The dot in the "intel dot operator" is optional in MSVC.  MSVC also does
94*67e74705SXin Li   // global field lookup, but we don't.
95*67e74705SXin Li   __asm { mov eax, [0] A.a }
96*67e74705SXin Li   __asm { mov eax, [0].A.a }
97*67e74705SXin Li   __asm { mov eax, [0].a } // expected-error {{Unable to lookup field reference!}}
98*67e74705SXin Li   __asm { mov eax, fs:[0] A.a }
99*67e74705SXin Li   __asm { mov eax, fs:[0].A.a }
100*67e74705SXin Li   __asm { mov eax, fs:[0].a } // expected-error {{Unable to lookup field reference!}}
101*67e74705SXin Li   __asm { mov eax, fs:[0]. A.a } // expected-error {{Unexpected token type!}}
102*67e74705SXin Li }
103*67e74705SXin Li 
test_operand_size()104*67e74705SXin Li void test_operand_size() {
105*67e74705SXin Li   __asm { call word t4 } // expected-error {{Expected 'PTR' or 'ptr' token!}}
106*67e74705SXin Li }
107*67e74705SXin Li 
t5(int x)108*67e74705SXin Li __declspec(naked) int t5(int x) { // expected-note {{attribute is here}}
109*67e74705SXin Li   asm { movl eax, x } // expected-error {{parameter references not allowed in naked functions}} expected-error {{use of undeclared label 'x'}}
110*67e74705SXin Li   asm { retl }
111*67e74705SXin Li }
112*67e74705SXin Li 
113*67e74705SXin Li int y;
t6(int x)114*67e74705SXin Li __declspec(naked) int t6(int x) {
115*67e74705SXin Li   asm { mov eax, y } // No error.
116*67e74705SXin Li   asm { ret }
117*67e74705SXin Li }
118*67e74705SXin Li 
t7()119*67e74705SXin Li void t7() {
120*67e74705SXin Li   __asm {
121*67e74705SXin Li     foo: // expected-note {{inline assembly label 'foo' declared here}}
122*67e74705SXin Li     mov eax, 0
123*67e74705SXin Li   }
124*67e74705SXin Li   goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}}
125*67e74705SXin Li }
126*67e74705SXin Li 
t8()127*67e74705SXin Li void t8() {
128*67e74705SXin Li   __asm foo: // expected-note {{inline assembly label 'foo' declared here}}
129*67e74705SXin Li   __asm mov eax, 0
130*67e74705SXin Li   goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}}
131*67e74705SXin Li }
132*67e74705SXin Li 
t9()133*67e74705SXin Li void t9() {
134*67e74705SXin Li   goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}}
135*67e74705SXin Li   __asm {
136*67e74705SXin Li     foo: // expected-note {{inline assembly label 'foo' declared here}}
137*67e74705SXin Li     mov eax, 0
138*67e74705SXin Li   }
139*67e74705SXin Li }
140*67e74705SXin Li 
t10()141*67e74705SXin Li void t10() {
142*67e74705SXin Li   goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}}
143*67e74705SXin Li   __asm foo: // expected-note {{inline assembly label 'foo' declared here}}
144*67e74705SXin Li   __asm mov eax, 0
145*67e74705SXin Li }
146*67e74705SXin Li 
t11()147*67e74705SXin Li void t11() {
148*67e74705SXin Li foo:
149*67e74705SXin Li   __asm mov eax, foo // expected-error {{use of undeclared label 'foo'}} expected-warning {{unused label 'foo'}}
150*67e74705SXin Li }
151*67e74705SXin Li 
t12()152*67e74705SXin Li void t12() {
153*67e74705SXin Li   __asm foo:
154*67e74705SXin Li   __asm bar: // expected-warning {{unused label 'bar'}}
155*67e74705SXin Li   __asm jmp foo
156*67e74705SXin Li }
157