summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CoverageMappingGen.cpp20
-rw-r--r--test/CoverageMapping/default-method.cpp17
2 files changed, 33 insertions, 4 deletions
diff --git a/lib/CodeGen/CoverageMappingGen.cpp b/lib/CodeGen/CoverageMappingGen.cpp
index 732ecd05ab..35962c73d9 100644
--- a/lib/CodeGen/CoverageMappingGen.cpp
+++ b/lib/CodeGen/CoverageMappingGen.cpp
@@ -656,12 +656,15 @@ struct CounterCoverageMappingBuilder
return RegionStack.back();
}
- /// Propagate counts through the children of \c S.
- Counter propagateCounts(Counter TopCount, const Stmt *S) {
+ /// Propagate counts through the children of \p S if \p VisitChildren is true.
+ /// Otherwise, only emit a count for \p S itself.
+ Counter propagateCounts(Counter TopCount, const Stmt *S,
+ bool VisitChildren = true) {
SourceLocation StartLoc = getStart(S);
SourceLocation EndLoc = getEnd(S);
size_t Index = pushRegion(TopCount, StartLoc, EndLoc);
- Visit(S);
+ if (VisitChildren)
+ Visit(S);
Counter ExitCount = getRegion().getCounter();
popRegions(Index);
@@ -874,7 +877,16 @@ struct CounterCoverageMappingBuilder
if (Body && SM.isInSystemHeader(SM.getSpellingLoc(getStart(Body))))
return;
- propagateCounts(getRegionCounter(Body), Body);
+ // Do not visit the artificial children nodes of defaulted methods. The
+ // lexer may not be able to report back precise token end locations for
+ // these children nodes (llvm.org/PR39822), and moreover users will not be
+ // able to see coverage for them.
+ bool Defaulted = false;
+ if (auto *Method = dyn_cast<CXXMethodDecl>(D))
+ Defaulted = Method->isDefaulted();
+
+ propagateCounts(getRegionCounter(Body), Body,
+ /*VisitChildren=*/!Defaulted);
assert(RegionStack.empty() && "Regions entered but never exited");
// Discard the last uncompleted deferred region in a decl, if one exists.
diff --git a/test/CoverageMapping/default-method.cpp b/test/CoverageMapping/default-method.cpp
new file mode 100644
index 0000000000..e097a168bb
--- /dev/null
+++ b/test/CoverageMapping/default-method.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++17 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name default-method.cpp -w %s | FileCheck %s -implicit-check-not="->"
+
+namespace PR39822 {
+ struct unique_ptr {
+ unique_ptr &operator=(unique_ptr &);
+ };
+
+ class foo {
+ foo &operator=(foo &);
+ unique_ptr convertable_values_[2];
+ };
+
+ // CHECK: _ZN7PR398223fooaSERS0_:
+ // CHECK-NEXT: File 0, [[@LINE+1]]:28 -> [[@LINE+1]]:29 = #0
+ foo &foo::operator=(foo &) = default;
+} // namespace PR39822
+