1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// REQUIRES: x86-registered-target
2b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fms-extensions -fasm-blocks -Wno-microsoft -Wunused-label -verify -fsyntax-only
3b0f6b9c94077446ceb29167add2e87fb99733a55Bob Wilson
4b0f6b9c94077446ceb29167add2e87fb99733a55Bob Wilsonvoid t1(void) {
55f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman __asm __asm // expected-error {{__asm used with no assembly instructions}}
65f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman}
75f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman
85f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedmanvoid f() {
90adc4d29d64107bd82016dd5adc023c5b6c89302Chad Rosier  int foo;
105f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman  __asm {
115f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman    mov eax, eax
125f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman    .unknowndirective // expected-error {{unknown directive}}
135f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman  }
145f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman  f();
155f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman  __asm {
16db60e42e35d980119c12b1a2e8b627817c8449f4Bill Wendling    mov eax, 1+=2 // expected-error {{unknown token in expression}}
175f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman  }
185f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman  f();
195f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman  __asm {
20db60e42e35d980119c12b1a2e8b627817c8449f4Bill Wendling    mov eax, 1+++ // expected-error {{unknown token in expression}}
215f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman  }
2296bd14bf5833e26db0744fb94cfc85b2a67ae5c5Chad Rosier  f();
2396bd14bf5833e26db0744fb94cfc85b2a67ae5c5Chad Rosier  __asm {
24db60e42e35d980119c12b1a2e8b627817c8449f4Bill Wendling    mov eax, LENGTH bar // expected-error {{unable to lookup expression}}
2596bd14bf5833e26db0744fb94cfc85b2a67ae5c5Chad Rosier  }
2696bd14bf5833e26db0744fb94cfc85b2a67ae5c5Chad Rosier  f();
2796bd14bf5833e26db0744fb94cfc85b2a67ae5c5Chad Rosier  __asm {
28db60e42e35d980119c12b1a2e8b627817c8449f4Bill Wendling    mov eax, SIZE bar // expected-error {{unable to lookup expression}}
2996bd14bf5833e26db0744fb94cfc85b2a67ae5c5Chad Rosier  }
3096bd14bf5833e26db0744fb94cfc85b2a67ae5c5Chad Rosier  f();
3196bd14bf5833e26db0744fb94cfc85b2a67ae5c5Chad Rosier  __asm {
32176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mov eax, TYPE bar // expected-error {{unable to lookup expression}} expected-error {{use of undeclared label 'bar'}}
3396bd14bf5833e26db0744fb94cfc85b2a67ae5c5Chad Rosier  }
34b0f6b9c94077446ceb29167add2e87fb99733a55Bob Wilson}
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid rdar15318432(void) {
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // We used to crash on this.  When LLVM called back to Clang to parse a name
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // and do name lookup, if parsing failed, we did not restore the lexer state
39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // properly.
40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __asm {
42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    and ecx, ~15
43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int x = 0;
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __asm {
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    and ecx, x
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    and ecx, ~15
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic int global;
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint t2(int *arr, int i) {
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __asm {
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    mov eax, arr;
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    mov eax, arr[0];
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    mov eax, arr[1 + 2];
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    mov eax, arr[1 + (2 * 5) - 3 + 1<<1];
60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // expected-error@+1 {{cannot use base register with variable reference}}
63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, arr[ebp + 1 + (2 * 5) - 3 + 1<<1] }
64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // expected-error@+1 {{cannot use index register with variable reference}}
65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, arr[esi * 4] }
66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // expected-error@+1 {{cannot use more than one symbol in memory operand}}
67176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, arr[i] }
68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // expected-error@+1 {{cannot use more than one symbol in memory operand}}
69176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, global[i] }
70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // FIXME: Why don't we diagnose this?
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // expected-Xerror@+1 {{cannot reference multiple local variables in assembly operand}}
73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  //__asm mov eax, [arr + i];
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return 0;
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct {
78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int a;
79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int b;
80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} A;
81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid t3() {
83176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, [eax] UndeclaredId } // expected-error {{unknown token in expression}} expected-error {{use of undeclared label 'UndeclaredId'}}
84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // FIXME: Only emit one diagnostic here.
86176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // expected-error@+3 {{use of undeclared label 'A'}}
87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // expected-error@+2 {{unexpected type name 'A': expected expression}}
88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // expected-error@+1 {{unknown token in expression}}
89176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, [eax] A }
90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid t4() {
93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // The dot in the "intel dot operator" is optional in MSVC.  MSVC also does
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // global field lookup, but we don't.
95176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, [0] A.a }
96176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, [0].A.a }
97176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, [0].a } // expected-error {{Unable to lookup field reference!}}
98176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, fs:[0] A.a }
99176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, fs:[0].A.a }
100176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, fs:[0].a } // expected-error {{Unable to lookup field reference!}}
101176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { mov eax, fs:[0]. A.a } // expected-error {{Unexpected token type!}}
102176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
103176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
104176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid test_operand_size() {
105176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm { call word t4 } // expected-error {{Expected 'PTR' or 'ptr' token!}}
106176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
107176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
108176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines__declspec(naked) int t5(int x) { // expected-note {{attribute is here}}
109176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  asm { movl eax, x } // expected-error {{parameter references not allowed in naked functions}} expected-error {{use of undeclared label 'x'}}
110176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  asm { retl }
111176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
112176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
113176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesint y;
114176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines__declspec(naked) int t6(int x) {
115176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  asm { mov eax, y } // No error.
116176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  asm { ret }
117176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
118176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
119176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid t7() {
120176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm {
121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    foo: // expected-note {{inline assembly label 'foo' declared here}}
122176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mov eax, 0
123176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
124176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}}
125176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
126176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
127176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid t8() {
128176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm foo: // expected-note {{inline assembly label 'foo' declared here}}
129176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm mov eax, 0
130176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}}
131176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
132176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
133176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid t9() {
134176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}}
135176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm {
136176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    foo: // expected-note {{inline assembly label 'foo' declared here}}
137176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mov eax, 0
138176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
139176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
140176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
141176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid t10() {
142176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  goto foo; // expected-error {{cannot jump from this goto statement to label 'foo' inside an inline assembly block}}
143176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm foo: // expected-note {{inline assembly label 'foo' declared here}}
144176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm mov eax, 0
145176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
146176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
147176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid t11() {
148176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesfoo:
149176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm mov eax, foo // expected-error {{use of undeclared label 'foo'}} expected-warning {{unused label 'foo'}}
150176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
151176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
152176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid t12() {
153176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm foo:
154176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm bar: // expected-warning {{unused label 'bar'}}
155176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __asm jmp foo
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
157