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