diff options
-rw-r--r-- | clang/lib/CodeGen/ModuleBuilder.cpp | 8 | ||||
-rw-r--r-- | clang/test/CoverageMapping/classtemplate.cpp | 28 |
2 files changed, 29 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index 6c60b4e62c1..ee6f6f94c71 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -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 diff --git a/clang/test/CoverageMapping/classtemplate.cpp b/clang/test/CoverageMapping/classtemplate.cpp index e6938d625ad..6062266fd47 100644 --- a/clang/test/CoverageMapping/classtemplate.cpp +++ b/clang/test/CoverageMapping/classtemplate.cpp @@ -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); |