ms-inline-asm.c revision 651f13cea278ec967336033dd032faef0e9fc2ec
1// REQUIRES: x86-registered-target
2// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fasm-blocks -Wno-microsoft -verify -fsyntax-only
3
4void t1(void) {
5 __asm __asm // expected-error {{__asm used with no assembly instructions}}
6}
7
8void 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}}
33  }
34}
35
36void 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  // expected-error@+2 {{expected identifier}}
42  __asm {
43    and ecx, ~15
44  }
45
46  int x = 0;
47  // expected-error@+3 {{expected identifier}}
48  __asm {
49    and ecx, x
50    and ecx, ~15
51  }
52}
53
54static int global;
55
56int t2(int *arr, int i) {
57  __asm {
58    mov eax, arr;
59    mov eax, arr[0];
60    mov eax, arr[1 + 2];
61    mov eax, arr[1 + (2 * 5) - 3 + 1<<1];
62  }
63
64  // expected-error@+1 {{cannot use base register with variable reference}}
65  __asm mov eax, arr[ebp + 1 + (2 * 5) - 3 + 1<<1]
66  // expected-error@+1 {{cannot use index register with variable reference}}
67  __asm mov eax, arr[esi * 4]
68  // expected-error@+1 {{cannot use more than one symbol in memory operand}}
69  __asm mov eax, arr[i]
70  // expected-error@+1 {{cannot use more than one symbol in memory operand}}
71  __asm mov eax, global[i]
72
73  // FIXME: Why don't we diagnose this?
74  // expected-Xerror@+1 {{cannot reference multiple local variables in assembly operand}}
75  //__asm mov eax, [arr + i];
76  return 0;
77}
78
79typedef struct {
80  int a;
81  int b;
82} A;
83
84void t3() {
85  __asm mov eax, [eax] UndeclaredId // expected-error {{unknown token in expression}}
86
87  // FIXME: Only emit one diagnostic here.
88  // expected-error@+2 {{unexpected type name 'A': expected expression}}
89  // expected-error@+1 {{unknown token in expression}}
90  __asm mov eax, [eax] A
91}
92
93void t4() {
94  // The dot in the "intel dot operator" is optional in MSVC.  MSVC also does
95  // global field lookup, but we don't.
96  __asm mov eax, [0] A.a
97  __asm mov eax, [0].A.a
98  __asm mov eax, [0].a    // expected-error {{Unable to lookup field reference!}}
99  __asm mov eax, fs:[0] A.a
100  __asm mov eax, fs:[0].A.a
101  __asm mov eax, fs:[0].a // expected-error {{Unable to lookup field reference!}}
102  __asm mov eax, fs:[0]. A.a  // expected-error {{Unexpected token type!}}
103}
104