From 8614ee31aa611f641fbb5c4f67c6c02e07226f3b Mon Sep 17 00:00:00 2001 From: kikairoya Date: Fri, 1 Aug 2025 19:29:54 +0900 Subject: [PATCH] [clang][DebugInfo] Disable VTable debug info (#130255) on COFF platforms On COFF platform, d1b0cbff806b50d399826e79b9a53e4726c21302 generates a debug info linked with VTable regardless definition is present or not. If that VTable ends up implicitly dllimported from another DLL, ld.bfd produces a runtime pseudo relocation for it (LLD doesn't, since d17db6066d2524856fab493dd894f8396e896bc7). If the debug section is stripped, the runtime pseudo relocation points to memory space outside of the module, causing an access violation. At this moment, we simply disable VTable debug info on COFF platform to avoid this problem. --- clang/lib/CodeGen/CGDebugInfo.cpp | 3 +- clang/test/CodeGenCXX/debug-info-class.cpp | 46 ++++++++++++------- .../vtable-debug-info-inheritance-simple.cpp | 11 +++-- clang/test/Modules/ExtDebugInfo.cpp | 15 ++++-- 4 files changed, 49 insertions(+), 26 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 1ce834d279aa5..5f50b1ccc5a23 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2630,7 +2630,8 @@ StringRef CGDebugInfo::getVTableName(const CXXRecordDecl *RD) { // existing information in the DWARF. The type is assumed to be 'void *'. void CGDebugInfo::emitVTableSymbol(llvm::GlobalVariable *VTable, const CXXRecordDecl *RD) { - if (!CGM.getTarget().getCXXABI().isItaniumFamily()) + if (!CGM.getTarget().getCXXABI().isItaniumFamily() || + CGM.getTarget().getTriple().isOSBinFormatCOFF()) return; if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly) return; diff --git a/clang/test/CodeGenCXX/debug-info-class.cpp b/clang/test/CodeGenCXX/debug-info-class.cpp index 0bc4fdaa565c3..aa24a63c58cb8 100644 --- a/clang/test/CodeGenCXX/debug-info-class.cpp +++ b/clang/test/CodeGenCXX/debug-info-class.cpp @@ -99,12 +99,12 @@ int main(int argc, char **argv) { return 0; } -// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s -// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s -// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s -// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s -// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s -// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s +// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK -check-prefix=CHECKELF %s +// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK -check-prefix=CHECKCOFF %s +// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK -check-prefix=CHECKELF %s +// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK -check-prefix=CHECKELF %s +// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK -check-prefix=CHECKCOFF %s +// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK -check-prefix=CHECKELF %s // CHECK98: invoke {{.+}} @_ZN1BD1Ev(ptr {{[^,]*}} %b) // CHECK98-NEXT: unwind label %{{.+}}, !dbg ![[EXCEPTLOC:.*]] @@ -122,6 +122,14 @@ int main(int argc, char **argv) { // CHECK-SAME: ){{$}} // CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int" +// CHECKCOFF: !DICompositeType(tag: DW_TAG_structure_type, name: "foo" +// CHECKCOFF: !DICompositeType(tag: DW_TAG_class_type, name: "bar" +// CHECKCOFF: !DICompositeType(tag: DW_TAG_union_type, name: "baz" +// CHECKCOFF: !DICompositeType(tag: DW_TAG_class_type, name: "B" +// CHECKCOFF-NOT: DIFlagFwdDecl +// CHECKCOFF-SAME: ){{$}} +// CHECKCOFF: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B", +// CHECKCOFF-SAME: DIFlagArtificial // CHECK: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C", // CHECK-NOT: DIFlagFwdDecl @@ -137,19 +145,19 @@ int main(int argc, char **argv) { // CHECK-SAME: DIFlagStaticMember // CHECK: [[C_DTOR]] = !DISubprogram(name: "~C" -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "K" -// CHECK-SAME: identifier: "_ZTS1K" -// CHECK-SAME: ){{$}} +// CHECKELF: !DICompositeType(tag: DW_TAG_structure_type, name: "K" +// CHECKELF-SAME: identifier: "_ZTS1K" +// CHECKELF-SAME: ){{$}} -// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B" -// CHECK-NOT: DIFlagFwdDecl -// CHECK-SAME: ){{$}} -// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B", -// CHECK-SAME: DIFlagArtificial +// CHECKELF: !DICompositeType(tag: DW_TAG_class_type, name: "B" +// CHECKELF-NOT: DIFlagFwdDecl +// CHECKELF-SAME: ){{$}} +// CHECKELF: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B", +// CHECKELF-SAME: DIFlagArtificial -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo" -// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "bar" -// CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "baz" +// CHECKELF: !DICompositeType(tag: DW_TAG_structure_type, name: "foo" +// CHECKELF: !DICompositeType(tag: DW_TAG_class_type, name: "bar" +// CHECKELF: !DICompositeType(tag: DW_TAG_union_type, name: "baz" // CHECK: [[D:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "D" // CHECK-SAME: size: @@ -162,6 +170,10 @@ int main(int argc, char **argv) { // CHECK-NOT: identifier: // CHECK-SAME: ){{$}} +// CHECKCOFF: !DICompositeType(tag: DW_TAG_structure_type, name: "K" +// CHECKCOFF-SAME: identifier: "_ZTS1K" +// CHECKCOFF-SAME: ){{$}} + // CHECK: [[L:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "L" // CHECK-SAME: ){{$}} // CHECK: [[L_FUNC_DECL:![0-9]*]] = !DISubprogram(name: "func",{{.*}} scope: [[L]] diff --git a/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp b/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp index 249586f5991f1..b24ece1598327 100644 --- a/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp +++ b/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp @@ -1,5 +1,3 @@ -// REQUIRES: target={{x86_64.*-linux.*}} - // Simple inheritance case: // For CBase and CDerived we check: // - Generation of their vtables (including attributes). @@ -30,13 +28,20 @@ int main() { return 0; } -// RUN: %clang --target=x86_64-linux -Xclang -disable-O0-optnone -Xclang -disable-llvm-passes -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -mrelocation-model pic -pic-is-pie -debug-info-kind=limited -dwarf-version=5 -disable-O0-optnone -disable-llvm-passes %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -mrelocation-model pic -pic-is-pie -debug-info-kind=limited -dwarf-version=5 -disable-O0-optnone -disable-llvm-passes %s -o - | FileCheck %s --check-prefix=COFF // CHECK: $_ZTVN3NSP5CBaseE = comdat any // CHECK: $_ZTV8CDerived = comdat any // CHECK: @_ZTVN3NSP5CBaseE = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8, !dbg [[BASE_VTABLE_VAR:![0-9]*]] // CHECK: @_ZTV8CDerived = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8, !dbg [[DERIVED_VTABLE_VAR:![0-9]*]] +// COFF: @_ZTVN3NSP5CBaseE = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8 +// COFF-NOT: !dbg +// COFF-SAME: {{$}} +// COFF: @_ZTV8CDerived = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8 +// COFF-NOT: !dbg +// COFF-SAME: {{$}} // CHECK: [[BASE_VTABLE_VAR]] = !DIGlobalVariableExpression(var: [[BASE_VTABLE:![0-9]*]], expr: !DIExpression()) // CHECK-NEXT: [[BASE_VTABLE]] = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTVN3NSP5CBaseE" diff --git a/clang/test/Modules/ExtDebugInfo.cpp b/clang/test/Modules/ExtDebugInfo.cpp index 184973bc1783c..3e74e2291d5e4 100644 --- a/clang/test/Modules/ExtDebugInfo.cpp +++ b/clang/test/Modules/ExtDebugInfo.cpp @@ -8,7 +8,7 @@ // RUN: -fmodule-format=obj -fimplicit-module-maps -DMODULES \ // RUN: -triple %itanium_abi_triple \ // RUN: -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t-mod.ll -// RUN: cat %t-mod.ll | FileCheck %s +// RUN: cat %t-mod.ll | FileCheck %s --check-prefix=CHECK %if target={{.*-(win|mingw|cyg).*}} %{--check-prefix=CHECKCOFF%} %else %{--check-prefix=CHECKELF%} // PCH: // RUN: %clang_cc1 -x c++ -std=c++11 -fmodule-format=obj -emit-pch -I%S/Inputs \ @@ -18,7 +18,7 @@ // RUN: -dwarf-ext-refs -fmodule-format=obj \ // RUN: -triple %itanium_abi_triple \ // RUN: -include-pch %t.pch %s -emit-llvm -o %t-pch.ll -// RUN: cat %t-pch.ll | FileCheck %s +// RUN: cat %t-pch.ll | FileCheck %s --check-prefix=CHECK %if target={{.*-(win|mingw|cyg).*}} %{--check-prefix=CHECKCOFF%} %else %{--check-prefix=CHECKELF%} // RUN: cat %t-pch.ll | FileCheck %s --check-prefix=CHECK-PCH #ifdef MODULES @@ -208,9 +208,9 @@ void foo() { // CHECK-SAME: name: "InAnonymousNamespace", {{.*}}DIFlagFwdDecl) // There is a full definition of the type available in the module. -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual", -// CHECK-SAME: DIFlagFwdDecl -// CHECK-SAME: identifier: "_ZTS7Virtual") +// CHECKELF: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual", +// CHECKELF-SAME: DIFlagFwdDecl +// CHECKELF-SAME: identifier: "_ZTS7Virtual") // CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !{{[0-9]+}}, entity: ![[STRUCT]], file: ![[CPP]], line: 50) @@ -222,3 +222,8 @@ void foo() { // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A", // CHECK-SAME: DIFlagFwdDecl + +// There is a full definition of the type available in the module. +// CHECKCOFF: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual", +// CHECKCOFF-SAME: DIFlagFwdDecl +// CHECKCOFF-SAME: identifier: "_ZTS7Virtual")