From cb6ec96eeea42e18e786ac66e6eb10b06454ca05 Mon Sep 17 00:00:00 2001 From: Nico Rieck Date: Fri, 23 May 2014 19:07:49 +0000 Subject: [PATCH] Sema: Add more tests for dll attributes on inline functions git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209542 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Sema/dllexport.c | 3 +++ test/Sema/dllimport.c | 5 +++- test/SemaCXX/dllexport.cpp | 20 +++++++++++++++ test/SemaCXX/dllimport.cpp | 50 +++++++++++++++++++++++++++++++++++++- 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/test/Sema/dllexport.c b/test/Sema/dllexport.c index 3a80b0be15..c6d04dc634 100644 --- a/test/Sema/dllexport.c +++ b/test/Sema/dllexport.c @@ -88,6 +88,9 @@ __declspec(dllexport) void redecl3(); void redecl4(); // expected-note{{previous declaration is here}} __declspec(dllexport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllexport' attribute}} + void redecl5(); // expected-note{{previous declaration is here}} +__declspec(dllexport) inline void redecl5() {} // expected-error{{redeclaration of 'redecl5' cannot add 'dllexport' attribute}} + // External linkage is required. __declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}} diff --git a/test/Sema/dllimport.c b/test/Sema/dllimport.c index 2c504d1f77..f4d26fb8c8 100644 --- a/test/Sema/dllimport.c +++ b/test/Sema/dllimport.c @@ -120,7 +120,10 @@ __declspec(dllimport) void redecl4(); // expected-error{{redeclaration of 'redec // Inline redeclarations are fine. __declspec(dllimport) void redecl5(); -inline void redecl5() {} + inline void redecl5() {} + + void redecl6(); // expected-note{{previous declaration is here}} +__declspec(dllimport) inline void redecl6() {} // expected-error{{redeclaration of 'redecl6' cannot add 'dllimport' attribute}} // External linkage is required. __declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}} diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp index 6d67ec25da..4d3538e329 100644 --- a/test/SemaCXX/dllexport.cpp +++ b/test/SemaCXX/dllexport.cpp @@ -111,15 +111,20 @@ __declspec(dllexport) void redecl2(); void redecl3(); // expected-note{{previous declaration is here}} __declspec(dllexport) void redecl3(); // expected-error{{redeclaration of 'redecl3' cannot add 'dllexport' attribute}} + void redecl4(); // expected-note{{previous declaration is here}} +__declspec(dllexport) inline void redecl4() {} // expected-error{{redeclaration of 'redecl4' cannot add 'dllexport' attribute}} + // Friend functions struct FuncFriend { friend __declspec(dllexport) void friend1(); friend __declspec(dllexport) void friend2(); friend void friend3(); // expected-note{{previous declaration is here}} + friend void friend4(); // expected-note{{previous declaration is here}} }; __declspec(dllexport) void friend1() {} void friend2() {} __declspec(dllexport) void friend3() {} // expected-error{{redeclaration of 'friend3' cannot add 'dllexport' attribute}} +__declspec(dllexport) inline void friend4() {} // expected-error{{redeclaration of 'friend4' cannot add 'dllexport' attribute}} // Implicit declarations can be redeclared with dllexport. __declspec(dllexport) void* operator new(__SIZE_TYPE__ n); @@ -143,6 +148,16 @@ template void __declspec(dllexport) funcTmplDecl2(); // Export function template definition. template __declspec(dllexport) void funcTmplDef() {} +// Export inline function template. +template __declspec(dllexport) inline void inlineFuncTmpl1() {} +template inline void __attribute__((dllexport)) inlineFuncTmpl2() {} + +template __declspec(dllexport) inline void inlineFuncTmplDecl(); +template void inlineFuncTmplDecl() {} + +template __declspec(dllexport) void inlineFuncTmplDef(); +template inline void inlineFuncTmplDef() {} + // Redeclarations template __declspec(dllexport) void funcTmplRedecl1(); template __declspec(dllexport) void funcTmplRedecl1() {} @@ -153,15 +168,20 @@ template void funcTmplRedecl2() {} template void funcTmplRedecl3(); // expected-note{{previous declaration is here}} template __declspec(dllexport) void funcTmplRedecl3(); // expected-error{{redeclaration of 'funcTmplRedecl3' cannot add 'dllexport' attribute}} +template void funcTmplRedecl4(); // expected-note{{previous declaration is here}} +template __declspec(dllexport) inline void funcTmplRedecl4() {} // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllexport' attribute}} + // Function template friends struct FuncTmplFriend { template friend __declspec(dllexport) void funcTmplFriend1(); template friend __declspec(dllexport) void funcTmplFriend2(); template friend void funcTmplFriend3(); // expected-note{{previous declaration is here}} + template friend void funcTmplFriend4(); // expected-note{{previous declaration is here}} }; template __declspec(dllexport) void funcTmplFriend1() {} template void funcTmplFriend2() {} template __declspec(dllexport) void funcTmplFriend3() {} // expected-error{{redeclaration of 'funcTmplFriend3' cannot add 'dllexport' attribute}} +template __declspec(dllexport) inline void funcTmplFriend4() {} // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllexport' attribute}} // External linkage is required. template __declspec(dllexport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllexport'}} diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp index cf883b3f5d..2e7bd149a3 100644 --- a/test/SemaCXX/dllimport.cpp +++ b/test/SemaCXX/dllimport.cpp @@ -125,6 +125,12 @@ extern "C" __declspec(dllimport) void externC(); __declspec(dllimport) inline void inlineFunc1() {} inline void __attribute__((dllimport)) inlineFunc2() {} +__declspec(dllimport) inline void inlineDecl(); + void inlineDecl() {} + +__declspec(dllimport) void inlineDef(); + inline void inlineDef() {} + // Redeclarations __declspec(dllimport) void redecl1(); __declspec(dllimport) void redecl1(); @@ -140,17 +146,22 @@ __declspec(dllimport) void redecl3(); // expected-note{{previous declaration is void redecl4(); // expected-note{{previous declaration is here}} __declspec(dllimport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllimport' attribute}} + void redecl5(); // expected-note{{previous declaration is here}} +__declspec(dllimport) inline void redecl5() {} // expected-error{{redeclaration of 'redecl5' cannot add 'dllimport' attribute}} + // Friend functions struct FuncFriend { friend __declspec(dllimport) void friend1(); friend __declspec(dllimport) void friend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} friend void friend4(); // expected-note{{previous declaration is here}} + friend void friend5(); // expected-note{{previous declaration is here}} }; __declspec(dllimport) void friend1(); void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} void friend3() {} // expected-warning{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} __declspec(dllimport) void friend4(); // expected-error{{redeclaration of 'friend4' cannot add 'dllimport' attribute}} +__declspec(dllimport) inline void friend5() {} // expected-error{{redeclaration of 'friend5' cannot add 'dllimport' attribute}} // Implicit declarations can be redeclared with dllimport. __declspec(dllimport) void* operator new(__SIZE_TYPE__ n); @@ -171,6 +182,19 @@ namespace ns { __declspec(dllimport) void externalFunc(); } template __declspec(dllimport) void funcTmplDecl1(); template void __declspec(dllimport) funcTmplDecl2(); +// Import function template definition. +template __declspec(dllimport) void funcTmplDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} + +// Import inline function template. +template __declspec(dllimport) inline void inlineFuncTmpl1() {} +template inline void __attribute__((dllimport)) inlineFuncTmpl2() {} + +template __declspec(dllimport) inline void inlineFuncTmplDecl(); +template void inlineFuncTmplDecl() {} + +template __declspec(dllimport) void inlineFuncTmplDef(); +template inline void inlineFuncTmplDef() {} + // Redeclarations template __declspec(dllimport) void funcTmplRedecl1(); template __declspec(dllimport) void funcTmplRedecl1(); @@ -184,17 +208,22 @@ template void funcTmplRedecl3() {} // expected template void funcTmplRedecl4(); // expected-note{{previous declaration is here}} template __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}} +template void funcTmplRedecl5(); // expected-note{{previous declaration is here}} +template __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}} + // Function template friends struct FuncTmplFriend { template friend __declspec(dllimport) void funcTmplFriend1(); template friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} template friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} template friend void funcTmplFriend4(); // expected-note{{previous declaration is here}} + template friend __declspec(dllimport) inline void funcTmplFriend5(); }; template __declspec(dllimport) void funcTmplFriend1(); template void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} template void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} template __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}} +template inline void funcTmplFriend5() {} // External linkage is required. template __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}} @@ -204,7 +233,21 @@ namespace ns { template __declspec(dllimport) void externalFuncTmpl( template void funcTmpl() {} -template __declspec(dllimport) void importedFuncTmpl(); +template inline void inlineFuncTmpl() {} +template __declspec(dllimport) void importedFuncTmplDecl(); +template __declspec(dllimport) inline void importedFuncTmpl() {} + +// Import implicit instantiation of an imported function template. +void useFunTmplDecl() { importedFuncTmplDecl(); } +void useFunTmplDef() { importedFuncTmpl(); } + +// Import explicit instantiation declaration of an imported function template. +extern template void importedFuncTmpl(); + +// Import explicit instantiation definition of an imported function template. +// NB: MSVC fails this instantiation without explicit dllimport which is most +// likely a bug because an implicit instantiation is accepted. +template void importedFuncTmpl(); // Import specialization of an imported function template. A definition must be // declared inline. @@ -219,6 +262,11 @@ template<> void importedFuncTmpl() {} // Import explicit instantiation declaration of a non-imported function template. extern template __declspec(dllimport) void funcTmpl(); +extern template __declspec(dllimport) void inlineFuncTmpl(); + +// Import explicit instantiation definition of a non-imported function template. +template __declspec(dllimport) void funcTmpl(); +template __declspec(dllimport) void inlineFuncTmpl(); // Import specialization of a non-imported function template. A definition must // be declared inline. -- 2.40.0