dllimport.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -fms-extensions -verify -std=c99 -DMS %s
  2. // RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c11 -DMS %s
  3. // RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c11 -DGNU %s
  4. // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c99 -DGNU %s
  5. // Invalid usage.
  6. __declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
  7. typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
  8. typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
  9. typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables and functions}}
  10. enum __declspec(dllimport) Enum { EnumVal }; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
  11. struct __declspec(dllimport) Record {}; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
  12. //===----------------------------------------------------------------------===//
  13. // Globals
  14. //===----------------------------------------------------------------------===//
  15. // Import declaration.
  16. __declspec(dllimport) extern int ExternGlobalDecl;
  17. // dllimport implies a declaration.
  18. __declspec(dllimport) int GlobalDecl;
  19. int **__attribute__((dllimport))* GlobalDeclChunkAttr;
  20. int GlobalDeclAttr __attribute__((dllimport));
  21. // Address of variables can't be used for initialization in C language modes.
  22. int *VarForInit = &GlobalDecl; // expected-error{{initializer element is not a compile-time constant}}
  23. // Not allowed on definitions.
  24. __declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}}
  25. __declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}}
  26. int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}}
  27. // Declare, then reject definition.
  28. __declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
  29. int ExternGlobalDeclInit = 1; // expected-warning{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
  30. __declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
  31. int GlobalDeclInit = 1; // expected-warning{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
  32. int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
  33. int *GlobalDeclChunkAttrInit = 0; // expected-warning{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
  34. int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
  35. int GlobalDeclAttrInit = 1; // expected-warning{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
  36. // Redeclarations
  37. __declspec(dllimport) extern int GlobalRedecl1;
  38. __declspec(dllimport) extern int GlobalRedecl1;
  39. __declspec(dllimport) int GlobalRedecl2a;
  40. __declspec(dllimport) int GlobalRedecl2a;
  41. int *__attribute__((dllimport)) GlobalRedecl2b;
  42. int *__attribute__((dllimport)) GlobalRedecl2b;
  43. int GlobalRedecl2c __attribute__((dllimport));
  44. int GlobalRedecl2c __attribute__((dllimport));
  45. // NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
  46. // and drop the dllimport with a warning.
  47. __declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
  48. extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
  49. // Adding an attribute on redeclaration.
  50. extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
  51. int useGlobalRedecl4() { return GlobalRedecl4; }
  52. __declspec(dllimport) extern int GlobalRedecl4; // expected-error{{redeclaration of 'GlobalRedecl4' cannot add 'dllimport' attribute}}
  53. // Allow with a warning if the decl hasn't been used yet.
  54. extern int GlobalRedecl5; // expected-note{{previous declaration is here}}
  55. __declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclaration of 'GlobalRedecl5' should not add 'dllimport' attribute}}
  56. // External linkage is required.
  57. __declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}
  58. // Thread local variables are invalid.
  59. __declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}}
  60. // Import in local scope.
  61. __declspec(dllimport) float LocalRedecl1; // expected-note{{previous declaration is here}}
  62. __declspec(dllimport) float LocalRedecl2; // expected-note{{previous declaration is here}}
  63. __declspec(dllimport) float LocalRedecl3; // expected-note{{previous declaration is here}}
  64. __declspec(dllimport) float LocalRedecl4;
  65. void functionScope() {
  66. __declspec(dllimport) int LocalRedecl1; // expected-error{{redeclaration of 'LocalRedecl1' with a different type: 'int' vs 'float'}}
  67. int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redeclaration of 'LocalRedecl2' with a different type: 'int *' vs 'float'}}
  68. int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redeclaration of 'LocalRedecl3' with a different type: 'int' vs 'float'}}
  69. __declspec(dllimport) int LocalVarDecl;
  70. __declspec(dllimport) int LocalVarDef = 1; // expected-error{{definition of dllimport data}}
  71. __declspec(dllimport) extern int ExternLocalVarDecl;
  72. __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}}
  73. __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}}
  74. // Local extern redeclaration does not drop the attribute.
  75. extern float LocalRedecl4;
  76. }
  77. //===----------------------------------------------------------------------===//
  78. // Functions
  79. //===----------------------------------------------------------------------===//
  80. // Import function declaration. Check different placements.
  81. __attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__
  82. __declspec(dllimport) void decl1B();
  83. void __attribute__((dllimport)) decl2A();
  84. void __declspec(dllimport) decl2B();
  85. // Address of functions can be used for initialization in C language modes.
  86. // However, the address of the thunk wrapping the function is used instead of
  87. // the address in the import address table.
  88. void (*FunForInit)() = &decl2A;
  89. // Not allowed on function definitions.
  90. __declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
  91. // Import inline function.
  92. #ifdef GNU
  93. // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
  94. // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
  95. #endif
  96. __declspec(dllimport) inline void inlineFunc1() {}
  97. inline void __attribute__((dllimport)) inlineFunc2() {}
  98. // Redeclarations
  99. __declspec(dllimport) void redecl1();
  100. __declspec(dllimport) void redecl1();
  101. // NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
  102. // and drop the dllimport with a warning.
  103. __declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
  104. void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
  105. __declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
  106. void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
  107. void redecl4(); // expected-note{{previous declaration is here}}
  108. void useRedecl4() { redecl4(); }
  109. __declspec(dllimport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllimport' attribute}}
  110. // Allow with a warning if the decl hasn't been used yet.
  111. void redecl5(); // expected-note{{previous declaration is here}}
  112. __declspec(dllimport) void redecl5(); // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}}
  113. // Inline redeclarations.
  114. #ifdef GNU
  115. // expected-warning@+3{{'redecl6' redeclared inline; 'dllimport' attribute ignored}}
  116. #endif
  117. __declspec(dllimport) void redecl6();
  118. inline void redecl6() {}
  119. #ifdef MS
  120. // expected-note@+5{{previous declaration is here}}
  121. // expected-warning@+5{{redeclaration of 'redecl7' should not add 'dllimport' attribute}}
  122. #else
  123. // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
  124. #endif
  125. void redecl7();
  126. __declspec(dllimport) inline void redecl7() {}
  127. // External linkage is required.
  128. __declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}