r205197 - Sema: Check dll attributes on redeclarations

Alp Toker alp at nuanti.com
Mon Jul 14 07:33:11 PDT 2014


Hi Nico,

We just started internal integration testing for 3.5. This commit breaks 
cross-compilation bootstrap builds to Windows from Fedora 20, Ubuntu 
14.04 and other current distributions, I believe due to a MinGW64 header 
bug that was only fixed upstream in April 2014.

We'll want to remove setInvalidDecl() and make the diagnostic either (a) 
a DefaultError warning complete with a warning group name or (b) a 
SuppressInSystemHeader error.

Do you know what the correct recovery is when accepting the invalid 
code? Should we drop or accept the attribute, and does that decision 
change based on whether we're in GCC or MSVC compatibility mode?

Alp.



On 31/03/2014 17:56, Nico Rieck wrote:
> Author: nrieck
> Date: Mon Mar 31 09:56:15 2014
> New Revision: 205197
>
> URL: http://llvm.org/viewvc/llvm-project?rev=205197&view=rev
> Log:
> Sema: Check dll attributes on redeclarations
>
> A redeclaration may not add dllimport or dllexport attributes. dllexport is
> sticky and can be omitted on redeclarations while dllimport cannot.
>
> Modified:
>      cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>      cfe/trunk/lib/Sema/SemaDecl.cpp
>      cfe/trunk/test/Sema/dllexport.c
>      cfe/trunk/test/Sema/dllimport.c
>      cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
>      cfe/trunk/test/SemaCXX/dllexport.cpp
>      cfe/trunk/test/SemaCXX/dllimport.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=205197&r1=205196&r2=205197&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Mar 31 09:56:15 2014
> @@ -2077,6 +2077,8 @@ def err_attribute_selectany_non_extern_d
>   def warn_attribute_invalid_on_definition : Warning<
>     "'%0' attribute cannot be specified on a definition">,
>     InGroup<IgnoredAttributes>;
> +def err_attribute_dll_redeclaration : Error<
> +  "redeclaration of %q0 cannot add %q1 attribute">;
>   def err_attribute_dllimport_data_definition : Error<
>     "definition of dllimport data">;
>   def err_attribute_weakref_not_static : Error<
>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=205197&r1=205196&r2=205197&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Mar 31 09:56:15 2014
> @@ -4845,6 +4845,56 @@ static void checkAttributesAfterMerging(
>     }
>   }
>   
> +static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
> +                                           NamedDecl *NewDecl,
> +                                           bool IsSpecialization) {
> +  if (TemplateDecl *OldTD = dyn_cast<TemplateDecl>(OldDecl))
> +    OldDecl = OldTD->getTemplatedDecl();
> +  if (TemplateDecl *NewTD = dyn_cast<TemplateDecl>(NewDecl))
> +    NewDecl = NewTD->getTemplatedDecl();
> +
> +  if (!OldDecl || !NewDecl)
> +      return;
> +
> +  const DLLImportAttr *OldImportAttr = OldDecl->getAttr<DLLImportAttr>();
> +  const DLLExportAttr *OldExportAttr = OldDecl->getAttr<DLLExportAttr>();
> +  const DLLImportAttr *NewImportAttr = NewDecl->getAttr<DLLImportAttr>();
> +  const DLLExportAttr *NewExportAttr = NewDecl->getAttr<DLLExportAttr>();
> +
> +  // dllimport and dllexport are inheritable attributes so we have to exclude
> +  // inherited attribute instances.
> +  bool HasNewAttr = (NewImportAttr && !NewImportAttr->isInherited()) ||
> +                    (NewExportAttr && !NewExportAttr->isInherited());
> +
> +  // A redeclaration is not allowed to add a dllimport or dllexport attribute,
> +  // the only exception being explicit specializations.
> +  // Implicitly generated declarations are also excluded for now because there
> +  // is no other way to switch these to use dllimport or dllexport.
> +  bool AddsAttr = !(OldImportAttr || OldExportAttr) && HasNewAttr;
> +  if (AddsAttr && !IsSpecialization && !OldDecl->isImplicit()) {
> +    S.Diag(NewDecl->getLocation(), diag::err_attribute_dll_redeclaration)
> +      << NewDecl
> +      << (NewImportAttr ? (const Attr *)NewImportAttr : NewExportAttr);
> +    S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
> +    NewDecl->setInvalidDecl();
> +    return;
> +  }
> +
> +  // A redeclaration is not allowed to drop a dllimport attribute, the only
> +  // exception being inline function definitions.
> +  // FIXME: Handle inline functions.
> +  // NB: MSVC converts such a declaration to dllexport.
> +  if (OldImportAttr && !HasNewAttr) {
> +    S.Diag(NewDecl->getLocation(),
> +           diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
> +      << NewDecl << OldImportAttr;
> +    S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
> +    S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute);
> +    OldDecl->dropAttr<DLLImportAttr>();
> +    NewDecl->dropAttr<DLLImportAttr>();
> +  }
> +}
> +
>   /// Given that we are within the definition of the given function,
>   /// will that definition behave like C99's 'inline', where the
>   /// definition is discarded except for optimization purposes?
> @@ -5497,6 +5547,12 @@ Sema::ActOnVariableDeclarator(Scope *S,
>       }
>     }
>   
> +  if (D.isRedeclaration() && !Previous.empty()) {
> +    checkDLLAttributeRedeclaration(
> +        *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewVD,
> +        IsExplicitSpecialization);
> +  }
> +
>     if (NewTemplate) {
>       if (NewVD->isInvalidDecl())
>         NewTemplate->setInvalidDecl();
> @@ -7318,6 +7374,12 @@ Sema::ActOnFunctionDeclarator(Scope *S,
>     // Set this FunctionDecl's range up to the right paren.
>     NewFD->setRangeEnd(D.getSourceRange().getEnd());
>   
> +  if (D.isRedeclaration() && !Previous.empty()) {
> +    checkDLLAttributeRedeclaration(
> +        *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewFD,
> +        isExplicitSpecialization || isFunctionTemplateSpecialization);
> +  }
> +
>     if (getLangOpts().CPlusPlus) {
>       if (FunctionTemplate) {
>         if (NewFD->isInvalidDecl())
> @@ -9679,17 +9741,6 @@ Decl *Sema::ActOnStartOfFunctionDef(Scop
>         FD->setInvalidDecl();
>         return D;
>       }
> -
> -    // Visual C++ appears to not think this is an issue, so only issue
> -    // a warning when Microsoft extensions are disabled.
> -    if (!LangOpts.MicrosoftExt) {
> -      // If a symbol previously declared dllimport is later defined, the
> -      // attribute is ignored in subsequent references, and a warning is
> -      // emitted.
> -      Diag(FD->getLocation(),
> -           diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
> -        << FD << DA;
> -    }
>     }
>     // We want to attach documentation to original Decl (which might be
>     // a function template).
>
> Modified: cfe/trunk/test/Sema/dllexport.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllexport.c?rev=205197&r1=205196&r2=205197&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/dllexport.c (original)
> +++ cfe/trunk/test/Sema/dllexport.c Mon Mar 31 09:56:15 2014
> @@ -31,6 +31,16 @@ int __declspec(dllexport) GlobalInit2 =
>   __declspec(dllexport) extern int GlobalDeclInit;
>   int GlobalDeclInit = 1;
>   
> +// Redeclarations
> +__declspec(dllexport) extern int GlobalRedecl1;
> +__declspec(dllexport)        int GlobalRedecl1;
> +
> +__declspec(dllexport) extern int GlobalRedecl2;
> +                             int GlobalRedecl2;
> +
> +                      extern int GlobalRedecl3; // expected-note{{previous declaration is here}}
> +__declspec(dllexport) extern int GlobalRedecl3; // expected-error{{redeclaration of 'GlobalRedecl3' cannot add 'dllexport' attribute}}
> +
>   // Export in local scope.
>   void functionScope() {
>     __declspec(dllexport) extern int ExternLocalVarDecl;
> @@ -69,6 +79,9 @@ __declspec(dllexport) void redecl2();
>   __declspec(dllexport) void redecl3();
>                         void redecl3() {}
>   
> +                      void redecl4(); // expected-note{{previous declaration is here}}
> +__declspec(dllexport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllexport' attribute}}
> +
>   
>   
>   //===----------------------------------------------------------------------===//
>
> Modified: cfe/trunk/test/Sema/dllimport.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllimport.c?rev=205197&r1=205196&r2=205197&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/dllimport.c (original)
> +++ cfe/trunk/test/Sema/dllimport.c Mon Mar 31 09:56:15 2014
> @@ -31,17 +31,17 @@ __declspec(dllimport) int GlobalInit1 =
>   int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}}
>   
>   // Declare, then reject definition.
> -__declspec(dllimport) extern int ExternGlobalDeclInit;
> -int ExternGlobalDeclInit = 1; // expected-error{{definition of dllimport data}}
> +__declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +int ExternGlobalDeclInit = 1; // expected-warning{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
>   
> -__declspec(dllimport) int GlobalDeclInit;
> -int GlobalDeclInit = 1; // expected-error{{definition of dllimport data}}
> +__declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +int GlobalDeclInit = 1; // expected-warning{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
>   
> -int *__attribute__((dllimport)) GlobalDeclChunkAttrInit;
> -int *GlobalDeclChunkAttrInit = 0; // expected-error{{definition of dllimport data}}
> +int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +int *GlobalDeclChunkAttrInit = 0; // expected-warning{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
>   
> -int GlobalDeclAttrInit __attribute__((dllimport));
> -int GlobalDeclAttrInit = 1; // expected-error{{definition of dllimport data}}
> +int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +int GlobalDeclAttrInit = 1; // expected-warning{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
>   
>   // Redeclarations
>   __declspec(dllimport) extern int GlobalRedecl1;
> @@ -56,6 +56,14 @@ int *__attribute__((dllimport)) GlobalRe
>   int GlobalRedecl2c __attribute__((dllimport));
>   int GlobalRedecl2c __attribute__((dllimport));
>   
> +// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
> +// and drop the dllimport with a warning.
> +__declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +                      extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
> +
> +                      extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
> +__declspec(dllimport) extern int GlobalRedecl4; // expected-error{{redeclaration of 'GlobalRedecl4' cannot add 'dllimport' attribute}}
> +
>   // Import in local scope.
>   __declspec(dllimport) float LocalRedecl1; // expected-note{{previous definition is here}}
>   __declspec(dllimport) float LocalRedecl2; // expected-note{{previous definition is here}}
> @@ -95,5 +103,13 @@ inline void __attribute__((dllimport)) i
>   __declspec(dllimport) void redecl1();
>   __declspec(dllimport) void redecl1();
>   
> -__declspec(dllimport) void redecl3();
> +// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
> +// and drop the dllimport with a warning.
> +__declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +                      void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
> +
> +__declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
>                         void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
> +
> +                      void redecl4(); // expected-note{{previous declaration is here}}
> +__declspec(dllimport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllimport' attribute}}
>
> Modified: cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=205197&r1=205196&r2=205197&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp (original)
> +++ cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Mon Mar 31 09:56:15 2014
> @@ -119,10 +119,11 @@ enum : long long {  // expected-warning{
>   
>   class AAA {
>   __declspec(dllimport) void f(void) { }
> -void f2(void);
> +void f2(void); // expected-note{{previous declaration is here}}
>   };
>   
> -__declspec(dllimport) void AAA::f2(void) { // expected-error {{'dllimport' attribute can be applied only to symbol}}
> +__declspec(dllimport) void AAA::f2(void) { // expected-error{{'dllimport' attribute can be applied only to symbol}}
> +                                           // expected-error at -1{{redeclaration of 'AAA::f2' cannot add 'dllimport' attribute}}
>   
>   }
>   
>
> Modified: cfe/trunk/test/SemaCXX/dllexport.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllexport.cpp?rev=205197&r1=205196&r2=205197&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/dllexport.cpp (original)
> +++ cfe/trunk/test/SemaCXX/dllexport.cpp Mon Mar 31 09:56:15 2014
> @@ -43,6 +43,16 @@ int __declspec(dllexport) GlobalInit2 =
>   __declspec(dllexport) extern int GlobalDeclInit;
>   int GlobalDeclInit = 1;
>   
> +// Redeclarations
> +__declspec(dllexport) extern int GlobalRedecl1;
> +__declspec(dllexport)        int GlobalRedecl1;
> +
> +__declspec(dllexport) extern int GlobalRedecl2;
> +                             int GlobalRedecl2;
> +
> +                      extern int GlobalRedecl3; // expected-note{{previous declaration is here}}
> +__declspec(dllexport) extern int GlobalRedecl3; // expected-error{{redeclaration of 'GlobalRedecl3' cannot add 'dllexport' attribute}}
> +
>   // Export in local scope.
>   void functionScope() {
>     __declspec(dllexport) extern int ExternLocalVarDecl;
> @@ -84,6 +94,22 @@ __declspec(dllexport) void redecl1() {}
>   __declspec(dllexport) void redecl2();
>                         void redecl2() {}
>   
> +                      void redecl3(); // expected-note{{previous declaration is here}}
> +__declspec(dllexport) void redecl3(); // expected-error{{redeclaration of 'redecl3' 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}}
> +};
> +__declspec(dllexport) void friend1() {}
> +                      void friend2() {}
> +__declspec(dllexport) void friend3() {} // expected-error{{redeclaration of 'friend3' cannot add 'dllexport' attribute}}
> +
> +// Implicit declarations can be redeclared with dllexport.
> +__declspec(dllexport) void* operator new(__SIZE_TYPE__ n);
> +
>   
>   
>   //===----------------------------------------------------------------------===//
> @@ -104,8 +130,18 @@ template<typename T> __declspec(dllexpor
>   template<typename T> __declspec(dllexport) void funcTmplRedecl2();
>   template<typename T>                       void funcTmplRedecl2() {}
>   
> -template<typename T> __declspec(dllexport) void funcTmplRedecl3();
> -template<typename T>                       void funcTmplRedecl3() {}
> +template<typename T>                       void funcTmplRedecl3(); // expected-note{{previous declaration is here}}
> +template<typename T> __declspec(dllexport) void funcTmplRedecl3(); // expected-error{{redeclaration of 'funcTmplRedecl3' cannot add 'dllexport' attribute}}
> +
> +// Function template friends
> +struct FuncTmplFriend {
> +  template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
> +  template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
> +  template<typename T> friend                       void funcTmplFriend3(); // expected-note{{previous declaration is here}}
> +};
> +template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
> +template<typename T>                       void funcTmplFriend2() {}
> +template<typename T> __declspec(dllexport) void funcTmplFriend3() {} // expected-error{{redeclaration of 'funcTmplFriend3' cannot add 'dllexport' attribute}}
>   
>   
>   template<typename T> void funcTmpl() {}
>
> Modified: cfe/trunk/test/SemaCXX/dllimport.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllimport.cpp?rev=205197&r1=205196&r2=205197&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/dllimport.cpp (original)
> +++ cfe/trunk/test/SemaCXX/dllimport.cpp Mon Mar 31 09:56:15 2014
> @@ -43,17 +43,17 @@ __declspec(dllimport) int GlobalInit1 =
>   int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}}
>   
>   // Declare, then reject definition.
> -__declspec(dllimport) extern int ExternGlobalDeclInit;
> -int ExternGlobalDeclInit = 1; // expected-error{{definition of dllimport data}}
> +__declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +int ExternGlobalDeclInit = 1; // expected-warning{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
>   
> -__declspec(dllimport) int GlobalDeclInit;
> -int GlobalDeclInit = 1; // expected-error{{definition of dllimport data}}
> +__declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +int GlobalDeclInit = 1; // expected-warning{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
>   
> -int *__attribute__((dllimport)) GlobalDeclChunkAttrInit;
> -int *GlobalDeclChunkAttrInit = 0; // expected-error{{definition of dllimport data}}
> +int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +int *GlobalDeclChunkAttrInit = 0; // expected-warning{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
>   
> -int GlobalDeclAttrInit __attribute__((dllimport));
> -int GlobalDeclAttrInit = 1; // expected-error{{definition of dllimport data}}
> +int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +int GlobalDeclAttrInit = 1; // expected-warning{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
>   
>   // Redeclarations
>   __declspec(dllimport) extern int GlobalRedecl1;
> @@ -68,6 +68,14 @@ int *__attribute__((dllimport)) GlobalRe
>   int GlobalRedecl2c __attribute__((dllimport));
>   int GlobalRedecl2c __attribute__((dllimport));
>   
> +// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
> +// and drop the dllimport with a warning.
> +__declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +                      extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
> +
> +                      extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
> +__declspec(dllimport) extern int GlobalRedecl4; // expected-error{{redeclaration of 'GlobalRedecl4' cannot add 'dllimport' attribute}}
> +
>   // Import in local scope.
>   __declspec(dllimport) float LocalRedecl1; // expected-note{{previous definition is here}}
>   __declspec(dllimport) float LocalRedecl2; // expected-note{{previous definition is here}}
> @@ -110,9 +118,32 @@ inline void __attribute__((dllimport)) i
>   __declspec(dllimport) void redecl1();
>   __declspec(dllimport) void redecl1();
>   
> -__declspec(dllimport) void redecl3();
> +// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
> +// and drop the dllimport with a warning.
> +__declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +                      void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
> +
> +__declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
>                         void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
>   
> +                      void redecl4(); // expected-note{{previous declaration is here}}
> +__declspec(dllimport) void redecl4(); // expected-error{{redeclaration of 'redecl4' 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}}
> +};
> +__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}}
> +
> +// Implicit declarations can be redeclared with dllimport.
> +__declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
> +
>   
>   
>   //===----------------------------------------------------------------------===//
> @@ -127,12 +158,27 @@ template<typename T> void __declspec(dll
>   template<typename T> __declspec(dllimport) void funcTmplRedecl1();
>   template<typename T> __declspec(dllimport) void funcTmplRedecl1();
>   
> -template<typename T> __declspec(dllimport) void funcTmplRedecl2();
> -template<typename T>                       void funcTmplRedecl2();
> +template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +template<typename T>                       void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
>   
> -template<typename T> __declspec(dllimport) void funcTmplRedecl3();
> +template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
>   template<typename T>                       void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
>   
> +template<typename T>                       void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
> +template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}}
> +
> +// Function template friends
> +struct FuncTmplFriend {
> +  template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
> +  template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +  template<typename T> friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
> +  template<typename T> friend                       void funcTmplFriend4(); // expected-note{{previous declaration is here}}
> +};
> +template<typename T> __declspec(dllimport) void funcTmplFriend1();
> +template<typename T>                       void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
> +template<typename T>                       void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
> +template<typename T> __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}}
> +
>   
>   template<typename T> void funcTmpl() {}
>   template<typename T> __declspec(dllimport) void importedFuncTmpl();
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

-- 
http://www.nuanti.com
the browser experts




More information about the cfe-commits mailing list