]> granicus.if.org Git - clang/commitdiff
[MS] Don't emit coverage for deleting dtors
authorReid Kleckner <rnk@google.com>
Tue, 26 Feb 2019 20:42:52 +0000 (20:42 +0000)
committerReid Kleckner <rnk@google.com>
Tue, 26 Feb 2019 20:42:52 +0000 (20:42 +0000)
Summary:
The MS C++ ABI has no constructor variants, but it has destructor
variants, so we should move the deleting destructor variant check
outside the check for "does the ABI have constructor variants".

Fixes PR37561, so basic code coverage works on Windows with C++.

Reviewers: vsk

Subscribers: jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58691

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354924 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenPGO.cpp
test/Profile/cxx-abc-deleting-dtor.cpp [new file with mode: 0644]

index 855e249653559b972f6bef66e80666d25a9e1fc0..d10a321dc3d7bc0d7a59e333099de1f5d7cc8b37 100644 (file)
@@ -771,14 +771,14 @@ void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
   // If so, instrument only base variant, others are implemented by delegation
   // to the base one, it would be counted twice otherwise.
   if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
-    if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
-      return;
-
     if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
       if (GD.getCtorType() != Ctor_Base &&
           CodeGenFunction::IsConstructorDelegationValid(CCD))
         return;
   }
+  if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
+    return;
+
   CGM.ClearUnusedCoverageMapping(D);
   setFuncName(Fn);
 
diff --git a/test/Profile/cxx-abc-deleting-dtor.cpp b/test/Profile/cxx-abc-deleting-dtor.cpp
new file mode 100644 (file)
index 0000000..453d4b4
--- /dev/null
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -emit-llvm %s -std=c++11 -o - -fno-rtti \
+// RUN:     -fprofile-instrument=clang -fcoverage-mapping -disable-llvm-passes \
+// RUN:     -triple=x86_64-windows-msvc | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -emit-llvm %s -std=c++11 -o - -fno-rtti \
+// RUN:     -fprofile-instrument=clang -fcoverage-mapping -disable-llvm-passes \
+// RUN:     -triple=x86_64-linux-gnu | FileCheck %s --check-prefix=LINUX
+
+// Check that clang doesn't emit counters or __profn_ variables for deleting
+// destructor variants in both C++ ABIs.
+
+struct ABC {
+  virtual ~ABC() = default;
+  virtual void pure() = 0;
+};
+struct DerivedABC : ABC {
+  ~DerivedABC() override = default;
+  void pure() override {}
+};
+DerivedABC *useABCVTable() { return new DerivedABC(); }
+
+// MSVC-NOT: @"__profn_??_G{{.*}}" =
+// MSVC: @"__profn_??1DerivedABC@@{{.*}}" =
+// MSVC-NOT: @"__profn_??_G{{.*}}" =
+// MSVC: @"__profn_??1ABC@@{{.*}}" =
+// MSVC-NOT: @"__profn_??_G{{.*}}" =
+
+// MSVC-LABEL: define linkonce_odr dso_local i8* @"??_GDerivedABC@@UEAAPEAXI@Z"(%struct.DerivedABC* %this, {{.*}})
+// MSVC-NOT:   call void @llvm.instrprof.increment({{.*}})
+// MSVC:   call void @"??1DerivedABC@@UEAA@XZ"({{.*}})
+// MSVC:   ret void
+
+// MSVC-LABEL: define linkonce_odr dso_local i8* @"??_GABC@@UEAAPEAXI@Z"(%struct.ABC* %this, {{.*}})
+// MSVC-NOT:   call void @llvm.instrprof.increment({{.*}})
+// MSVC:   call void @llvm.trap()
+// MSVC-NEXT:   unreachable
+
+// MSVC-LABEL: define linkonce_odr dso_local void @"??1DerivedABC@@UEAA@XZ"({{.*}})
+// MSVC:   call void @llvm.instrprof.increment({{.*}})
+// MSVC:   call void @"??1ABC@@UEAA@XZ"({{.*}})
+// MSVC:   ret void
+
+// MSVC-LABEL: define linkonce_odr dso_local void @"??1ABC@@UEAA@XZ"({{.*}})
+// MSVC:   call void @llvm.instrprof.increment({{.*}})
+// MSVC:   ret void
+
+
+// D2 is the base, D1 and D0 are deleting and complete dtors.
+
+// LINUX-NOT: @__profn_{{.*D[01]Ev}} =
+// LINUX: @__profn__ZN10DerivedABCD2Ev =
+// LINUX-NOT: @__profn_{{.*D[01]Ev}} =
+// LINUX: @__profn__ZN3ABCD2Ev =
+// LINUX-NOT: @__profn_{{.*D[01]Ev}} =
+
+// LINUX-LABEL: define linkonce_odr void @_ZN10DerivedABCD1Ev(%struct.DerivedABC* %this)
+// LINUX-NOT:   call void @llvm.instrprof.increment({{.*}})
+// LINUX:   call void @_ZN10DerivedABCD2Ev({{.*}})
+// LINUX:   ret void
+
+// LINUX-LABEL: define linkonce_odr void @_ZN10DerivedABCD0Ev(%struct.DerivedABC* %this)
+// LINUX-NOT:   call void @llvm.instrprof.increment({{.*}})
+// LINUX:   call void @_ZN10DerivedABCD1Ev({{.*}})
+// LINUX:   call void @_ZdlPv({{.*}})
+// LINUX:   ret void
+
+// LINUX-LABEL: define linkonce_odr void @_ZN3ABCD1Ev(%struct.ABC* %this)
+// LINUX-NOT:   call void @llvm.instrprof.increment({{.*}})
+// LINUX:   call void @llvm.trap()
+// LINUX-NEXT:   unreachable
+
+// LINUX-LABEL: define linkonce_odr void @_ZN3ABCD0Ev(%struct.ABC* %this)
+// LINUX-NOT:   call void @llvm.instrprof.increment({{.*}})
+// LINUX:   call void @llvm.trap()
+// LINUX-NEXT:   unreachable
+
+// LINUX-LABEL: define linkonce_odr void @_ZN10DerivedABCD2Ev(%struct.DerivedABC* %this)
+// LINUX:   call void @llvm.instrprof.increment({{.*}})
+// LINUX:   call void @_ZN3ABCD2Ev({{.*}})
+// LINUX:   ret void
+
+// LINUX-LABEL: define linkonce_odr void @_ZN3ABCD2Ev(%struct.ABC* %this)
+// LINUX:   call void @llvm.instrprof.increment({{.*}})
+// LINUX:   ret void