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