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