Narrow the -Wunsupported-dll-base-class-template warning.
authorHans Wennborg <hans@hanshq.net>
Tue, 9 Jun 2015 00:38:56 +0000 (00:38 +0000)
committerHans Wennborg <hans@hanshq.net>
Tue, 9 Jun 2015 00:38:56 +0000 (00:38 +0000)
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
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/SemaCXX/dllexport.cpp
clang/test/SemaCXX/dllimport.cpp

index 7f313d3..22a010a 100644 (file)
@@ -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<DiagGroup<"unsupported-dll-base-class-template">>, DefaultIgnore;
 def err_attribute_weakref_not_static : Error<
   "weakref declaration must have internal linkage">;
index b1dfe0e..b67dfb8 100644 (file)
@@ -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(),
index e419525..a6009f9 100644 (file)
@@ -447,13 +447,9 @@ class __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTe
 class DerivedFromTemplateD : public ClassTemplate<double> {};
 class __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
 
-#ifdef MS
-// expected-note@+4{{class template 'ClassTemplate<bool>' 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<bool> {};
-class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+class __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+// The second derived class doesn't change anything, the attribute that was propagated first wins.
+class __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
 
 #ifdef MS
 // expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
index 6052ea1..62d4f7b 100644 (file)
@@ -1282,13 +1282,9 @@ class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTe
 class DerivedFromTemplateD : public ClassTemplate<double> {};
 class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
 
-#ifdef MS
-// expected-note@+4{{class template 'ClassTemplate<bool>' 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<bool> {};
-class __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+// The second derived class doesn't change anything, the attribute that was propagated first wins.
+class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
 
 template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
 #ifdef MS