ms-inline-asm.c 4.4 KB

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