From 29b7a939350ed4fb577545c56d54e23b06bce6d9 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 9 Jun 2015 00:38:56 +0000 Subject: [PATCH] Narrow the -Wunsupported-dll-base-class-template warning. Don't warn about not being able to propagate dll attribute to a base class template when that base already has a different attribute. MSVC doesn't actually try to do this; the first attribute that was propagated takes precedence, so Clang is already doing the right thing and there's no need to warn. (This is a step towards fixing PR21718.) llvm-svn: 239372 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 +-- clang/lib/Sema/SemaDeclCXX.cpp | 24 ++++++++---------------- clang/test/SemaCXX/dllexport.cpp | 10 +++------- clang/test/SemaCXX/dllimport.cpp | 10 +++------- 4 files changed, 15 insertions(+), 32 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7f313d3..22a010a 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2262,8 +2262,7 @@ def err_attribute_dll_member_of_dll_class : Error< "attribute %q0 cannot be applied to member of %q1 class">; def warn_attribute_dll_instantiated_base_class : Warning< "propagating dll attribute to %select{already instantiated|explicitly specialized}0 " - "base class template " - "%select{without dll attribute|with different dll attribute}1 is not supported">, + "base class template without dll attribute is not supported">, InGroup>, DefaultIgnore; def err_attribute_weakref_not_static : Error< "weakref declaration must have internal linkage">; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index b1dfe0e..b67dfb8 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1364,26 +1364,18 @@ static void propagateDLLAttrToBaseClassTemplate( return; } - bool DifferentAttribute = false; - if (Attr *SpecializationAttr = getDLLAttr(BaseTemplateSpec)) { - if (!SpecializationAttr->isInherited()) { - // The template has previously been specialized or instantiated with an - // explicit attribute. We should not try to change it. - return; - } - if (SpecializationAttr->getKind() == ClassAttr->getKind()) { - // The specialization already has the right attribute. - return; - } - DifferentAttribute = true; + if (getDLLAttr(BaseTemplateSpec)) { + // The template has already been specialized or instantiated with an + // attribute, explicitly or through propagation. We should not try to change + // it. + return; } // The template was previously instantiated or explicitly specialized without - // a dll attribute, or the template was previously instantiated with a - // different inherited attribute. It's too late for us to change the - // attribute, so warn that this is unsupported. + // a dll attribute, It's too late for us to add an attribute, so warn that + // this is unsupported. S.Diag(BaseLoc, diag::warn_attribute_dll_instantiated_base_class) - << BaseTemplateSpec->isExplicitSpecialization() << DifferentAttribute; + << BaseTemplateSpec->isExplicitSpecialization(); S.Diag(ClassAttr->getLocation(), diag::note_attribute); if (BaseTemplateSpec->isExplicitSpecialization()) { S.Diag(BaseTemplateSpec->getLocation(), diff --git a/clang/test/SemaCXX/dllexport.cpp b/clang/test/SemaCXX/dllexport.cpp index e419525..a6009f9 100644 --- a/clang/test/SemaCXX/dllexport.cpp +++ b/clang/test/SemaCXX/dllexport.cpp @@ -447,13 +447,9 @@ class __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTe class DerivedFromTemplateD : public ClassTemplate {}; class __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate {}; -#ifdef MS -// expected-note@+4{{class template 'ClassTemplate' was instantiated here}} -// expected-warning@+4{{propagating dll attribute to already instantiated base class template with different dll attribute is not supported}} -// expected-note@+3{{attribute is here}} -#endif -class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate {}; -class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate {}; +class __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate {}; +// The second derived class doesn't change anything, the attribute that was propagated first wins. +class __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate {}; #ifdef MS // expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}} diff --git a/clang/test/SemaCXX/dllimport.cpp b/clang/test/SemaCXX/dllimport.cpp index 6052ea1..62d4f7b 100644 --- a/clang/test/SemaCXX/dllimport.cpp +++ b/clang/test/SemaCXX/dllimport.cpp @@ -1282,13 +1282,9 @@ class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTe class DerivedFromTemplateD : public ClassTemplate {}; class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate {}; -#ifdef MS -// expected-note@+4{{class template 'ClassTemplate' was instantiated here}} -// expected-warning@+4{{propagating dll attribute to already instantiated base class template with different dll attribute is not supported}} -// expected-note@+3{{attribute is here}} -#endif -class __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate {}; -class __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate {}; +class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate {}; +// The second derived class doesn't change anything, the attribute that was propagated first wins. +class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate {}; template struct ExplicitlySpecializedTemplate { void func() {} }; #ifdef MS -- 2.7.4