]> granicus.if.org Git - clang/commitdiff
Provide a separate warning for weak vtables in explicit template instantiations....
authorDavid Blaikie <dblaikie@gmail.com>
Fri, 9 Dec 2011 18:32:50 +0000 (18:32 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Fri, 9 Dec 2011 18:32:50 +0000 (18:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146265 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/warn-weak-vtables.cpp

index 2031d068a3acc7708201813156c42c589c3310f1..15824849e79581004d04f2400cc568246173175f 100644 (file)
@@ -701,6 +701,10 @@ def warn_weak_vtable : Warning<
   "%0 has no out-of-line virtual method definitions; its vtable will be "
   "emitted in every translation unit">,
   InGroup<DiagGroup<"weak-vtables">>, DefaultIgnore;
+def warn_weak_template_vtable : Warning<
+  "explicit template instantiation %0 will emit a vtable in every "
+  "translation unit">,
+  InGroup<DiagGroup<"weak-template-vtables">>, DefaultIgnore;
 
 def ext_using_undefined_std : ExtWarn<
   "using directive refers to implicitly-defined namespace 'std'">;
index 59c5e7894fd374c8fcf5a42c0b0237c9d5236607..50e07553a1b448c8dcdf7d1265a9093073e5d2fd 100644 (file)
@@ -10617,7 +10617,10 @@ bool Sema::DefineUsedVTables() {
       if (!KeyFunction || 
           (KeyFunction->hasBody(KeyFunctionDef) && 
            KeyFunctionDef->isInlined()))
-        Diag(Class->getLocation(), diag::warn_weak_vtable) << Class;
+        Diag(Class->getLocation(), Class->getTemplateSpecializationKind() ==
+             TSK_ExplicitInstantiationDefinition 
+             ? diag::warn_weak_template_vtable : diag::warn_weak_vtable) 
+          << Class;
     }
   }
   VTableUses.clear();
index 912622f5a7e4391f07c73824fd55c09aadb58f98..135e0342596c4cb0b99685def121dcdaf75b8970 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -Wweak-vtables
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Wweak-vtables -Wweak-template-vtables
 
 struct A { // expected-warning {{'A' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
   virtual void f() { } 
@@ -56,3 +56,23 @@ void uses(Parent &p, Derived &d, VeryDerived &vd) {
   d.getFoo();
   vd.getFoo();
 }
+
+template<typename T> struct TemplVirt {
+  virtual void f();
+};
+
+template class TemplVirt<float>; // expected-warning{{explicit template instantiation 'TemplVirt<float>' will emit a vtable in every translation unit}}
+
+template<> struct TemplVirt<bool> {
+  virtual void f();
+};
+
+template<> struct TemplVirt<long> { // expected-warning{{'TemplVirt<long>' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
+  virtual void f() {}
+};
+
+void uses(TemplVirt<float>& f, TemplVirt<bool>& b, TemplVirt<long>& l) {
+  f.f();
+  b.f();
+  l.f();
+}