r222204 - InstrProf: Don't emit coverage for uninstantiated templates

Justin Bogner mail at justinbogner.com
Mon Nov 17 16:34:46 PST 2014


Author: bogner
Date: Mon Nov 17 18:34:46 2014
New Revision: 222204

URL: http://llvm.org/viewvc/llvm-project?rev=222204&view=rev
Log:
InstrProf: Don't emit coverage for uninstantiated templates

We include unused functions and methods in -fcoverage-mapping so that
we can differentiate between uninstrumented and unused. This can cause
problems for uninstantiated templates though, since they may involve
an incomplete type that can't be mangled. This shows up in things like
libc++'s <unordered_map> and makes coverage unusable.

Avoid the issue by skipping uninstantiated methods of a templated
class.

Modified:
    cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
    cfe/trunk/test/CoverageMapping/classtemplate.cpp

Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=222204&r1=222203&r2=222204&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Mon Nov 17 18:34:46 2014
@@ -145,9 +145,11 @@ namespace {
       //   } A;
       DeferredInlineMethodDefinitions.push_back(D);
 
-      // Always provide some coverage mapping
-      // even for the methods that aren't emitted.
-      Builder->AddDeferredUnusedCoverageMapping(D);
+      // Provide some coverage mapping even for methods that aren't emitted.
+      // Don't do this for templated classes though, as they may not be
+      // instantiable.
+      if (!D->getParent()->getDescribedClassTemplate())
+        Builder->AddDeferredUnusedCoverageMapping(D);
     }
 
     /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl

Modified: cfe/trunk/test/CoverageMapping/classtemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CoverageMapping/classtemplate.cpp?rev=222204&r1=222203&r2=222204&view=diff
==============================================================================
--- cfe/trunk/test/CoverageMapping/classtemplate.cpp (original)
+++ cfe/trunk/test/CoverageMapping/classtemplate.cpp Mon Nov 17 18:34:46 2014
@@ -12,18 +12,38 @@ public:
   const static int BaseCount = 4;
   double bases[BaseCount];
 
-                                        // CHECK-CONSTRUCTOR: Test
+                                        // CHECK-CONSTRUCTOR: _ZN4TestIjEC
   Test() { }                            // CHECK-CONSTRUCTOR: File 0, [[@LINE]]:10 -> [[@LINE]]:13 = #0 (HasCodeBefore = 0)
-                                        // CHECK-GETTER: get
-  double get(TT position) const {       // CHECK-GETTER: File 0, [[@LINE]]:33 -> [[@LINE+2]]:4 = 0 (HasCodeBefore = 0)
+
+  // FIXME: It would be nice to emit no-coverage for get, but trying to do this
+  // runs afoul of cases like Test3::unmangleable below.
+                                        // FIXME-GETTER: _ZNK4TestIjE3get
+  double get(TT position) const {       // FIXME-GETTER: File 0, [[@LINE]]:33 -> [[@LINE+2]]:4 = 0 (HasCodeBefore = 0)
     return bases[position];
   }
-                                        // CHECK-SETTER: set
+                                        // CHECK-SETTER: _ZN4TestIjE3set
   void set(TT position, double value) { // CHECK-SETTER: File 0, [[@LINE]]:39 -> [[@LINE+2]]:4 = #0 (HasCodeBefore = 0)
     bases[position] = value;
   }
 };
 
+class Test2 {
+                                        // CHECK-CONSTRUCTOR: _ZN5Test2C
+  Test2() { }                           // CHECK-CONSTRUCTOR: File 0, [[@LINE]]:11 -> [[@LINE]]:14 = 0 (HasCodeBefore = 0)
+                                        // CHECK-GETTER: _ZNK5Test23get
+  double get(unsigned position) const { // CHECK-GETTER: File 0, [[@LINE]]:39 -> [[@LINE+2]]:4 = 0 (HasCodeBefore = 0)
+    return 0.0;
+  }
+};
+
+// Test3::unmangleable can't be mangled, since there isn't a complete type for
+// the __is_final type trait expression. This would cause errors if we try to
+// emit a no-coverage mapping for the method.
+template <class T, bool = __is_final(T)> class UninstantiatedClassWithTraits {};
+template <class T> class Test3 {
+  void unmangleable(UninstantiatedClassWithTraits<T> x) {}
+};
+
 int main() {
   Test<unsigned> t;
   t.set(Test<unsigned>::A, 5.5);





More information about the cfe-commits mailing list