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 | |
4 | void t1(void) { |
5 | __asm __asm // expected-error {{__asm used with no assembly instructions}} |
6 | } |
7 | |
8 | void f() { |
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 | |
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 | |
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 | |
77 | void t3() { |
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@+3 {{use of undeclared label 'A'}} |
82 | // expected-error@+2 {{unexpected type name 'A': expected expression}} |
83 | // expected-error@+1 {{unknown token in expression}} |
84 | __asm { mov eax, [eax] A } |
85 | } |
86 | |
87 | void t4() { |
88 | // The dot in the "intel dot operator" is optional in MSVC. MSVC also does |
89 | // global field lookup, but we don't. |
90 | __asm { mov eax, [0] A.a } |
91 | __asm { mov eax, [0].A.a } |
92 | __asm { mov eax, [0].a } // expected-error {{Unable to lookup field reference!}} |
93 | __asm { mov eax, fs:[0] A.a } |
94 | __asm { mov eax, fs:[0].A.a } |
95 | __asm { mov eax, fs:[0].a } // expected-error {{Unable to lookup field reference!}} |
96 | __asm { mov eax, fs:[0]. A.a } // expected-error {{unexpected token in argument list}} |
97 | } |
98 | |
99 | void test_operand_size() { |
100 | __asm { call word t4 } // expected-error {{Expected 'PTR' or 'ptr' token!}} |
101 | } |
102 | |
103 | __declspec(naked) int t5(int x) { // expected-note {{attribute is here}} |
104 | asm { movl eax, x } // expected-error {{parameter references not allowed in naked functions}} expected-error {{use of undeclared label 'x'}} |
105 | asm { retl } |
106 | } |
107 | |
108 | int y; |
109 | __declspec(naked) int t6(int x) { |
110 | asm { mov eax, y } // No error. |
111 | asm { ret } |
112 | } |
113 | |
114 | void t7() { |
115 | __asm { |
116 | foo: // expected-note {{inline assembly label 'foo' declared here}} |
117 | mov eax, 0 |
118 | } |
119 | goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}} |
120 | } |
121 | |
122 | void t8() { |
123 | __asm foo: // expected-note {{inline assembly label 'foo' declared here}} |
124 | __asm mov eax, 0 |
125 | goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}} |
126 | } |
127 | |
128 | void t9() { |
129 | goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}} |
130 | __asm { |
131 | foo: // expected-note {{inline assembly label 'foo' declared here}} |
132 | mov eax, 0 |
133 | } |
134 | } |
135 | |
136 | void t10() { |
137 | goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}} |
138 | __asm foo: // expected-note {{inline assembly label 'foo' declared here}} |
139 | __asm mov eax, 0 |
140 | } |
141 | |
142 | void t11() { |
143 | foo: |
144 | __asm mov eax, foo // expected-error {{use of undeclared label 'foo'}} expected-warning {{unused label 'foo'}} |
145 | } |
146 | |
147 | void t12() { |
148 | __asm foo: |
149 | __asm bar: // expected-warning {{unused label 'bar'}} |
150 | __asm jmp foo |
151 | } |
152 | |