mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Fix mangling collision for C++ class template specializations (#7269)
Carbon-side thunks (for example the `Copy`/`Destroy` witness thunks generated for imported C++ types) are mangled by Carbon, and their names incorporate a fingerprint of the involved types. The instruction fingerprinter identifies a class only by its name and parent scope, which is sufficient for Carbon classes but not for imported C++ classes: different specializations of one class template (and other cases such as types in anonymous namespaces) share a Carbon name and parent scope. As a result, the thunks for two distinct specializations could mangle to the same name, producing a single LLVM function with two definitions and failing `verifyModule` during lowering. When fingerprinting a class imported from C++, also include the Clang mangled name of its type. Test: toolchain/lower/testdata/interop/cpp/thunks.carbon gains a split with two specializations of one class template, each requiring a thunk; their thunks now get distinct mangled names instead of colliding. Assisted-by: Claude Code --------- Co-authored-by: Christopher Di Bella <cjdb.ns@gmail.com>
This commit is contained in:
co-authored by
Christopher Di Bella
parent
3ef128ac91
commit
8a59f2a76b
+12
-12
@@ -144,7 +144,7 @@ fn GetRefs() {
|
||||
// CHECK:STDOUT: %_.var.2 = alloca i32, align 4, !dbg !17
|
||||
// CHECK:STDOUT: %.loc25_23.2.temp = alloca i32, align 4, !dbg !18
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %c.var), !dbg !14
|
||||
// CHECK:STDOUT: call void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2603c91dd66a1dca"(ptr %c.var), !dbg !14
|
||||
// CHECK:STDOUT: call void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.4fdc745d4b6d0e3c"(ptr %c.var), !dbg !14
|
||||
// CHECK:STDOUT: call void @_Z8TakeCRefR1C(ptr %c.var), !dbg !19
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %_.var.1), !dbg !15
|
||||
// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %_.var.1, ptr align 1 @C.val.loc19_20, i64 0, i1 false), !dbg !15
|
||||
@@ -176,7 +176,7 @@ fn GetRefs() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Default.5648bcc2d6c775b7.Core:C.Cpp"(ptr sret({}) %return) #2 !dbg !29 {
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Default.08e786f435a99766.Core:C.Cpp"(ptr sret({}) %return) #2 !dbg !29 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: call void @_ZN1CC1Ev.carbon_thunk.(ptr %return), !dbg !33
|
||||
// CHECK:STDOUT: ret void, !dbg !33
|
||||
@@ -236,8 +236,8 @@ fn GetRefs() {
|
||||
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #5
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2603c91dd66a1dca"(ptr sret({}) %return) #0 !dbg !43 {
|
||||
// CHECK:STDOUT: call void @"_COp:thunk:Default.5648bcc2d6c775b7.Core:C.Cpp"(ptr %return), !dbg !45
|
||||
// CHECK:STDOUT: define linkonce_odr void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.4fdc745d4b6d0e3c"(ptr sret({}) %return) #0 !dbg !43 {
|
||||
// CHECK:STDOUT: call void @"_COp:thunk:Default.08e786f435a99766.Core:C.Cpp"(ptr %return), !dbg !45
|
||||
// CHECK:STDOUT: ret void, !dbg !46
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -296,7 +296,7 @@ fn GetRefs() {
|
||||
// CHECK:STDOUT: !26 = !{!27, !27, i64 0}
|
||||
// CHECK:STDOUT: !27 = !{!"p1 _ZTS1C", !28, i64 0}
|
||||
// CHECK:STDOUT: !28 = !{!"any pointer", !9, i64 0}
|
||||
// CHECK:STDOUT: !29 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Default.5648bcc2d6c775b7.Core:C.Cpp", scope: null, file: !6, line: 5, type: !30, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !29 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Default.08e786f435a99766.Core:C.Cpp", scope: null, file: !6, line: 5, type: !30, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !30 = !DISubroutineType(types: !31)
|
||||
// CHECK:STDOUT: !31 = !{!32}
|
||||
// CHECK:STDOUT: !32 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
|
||||
@@ -310,7 +310,7 @@ fn GetRefs() {
|
||||
// CHECK:STDOUT: !40 = !{!41}
|
||||
// CHECK:STDOUT: !41 = !DILocalVariable(arg: 1, scope: !36, type: !39)
|
||||
// CHECK:STDOUT: !42 = !DILocation(line: 25, column: 23, scope: !36)
|
||||
// CHECK:STDOUT: !43 = distinct !DISubprogram(name: "Op", linkageName: "_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2603c91dd66a1dca", scope: null, file: !44, line: 9, type: !30, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !43 = distinct !DISubprogram(name: "Op", linkageName: "_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.4fdc745d4b6d0e3c", scope: null, file: !44, line: 9, type: !30, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !44 = !DIFile(filename: "min_prelude/parts/default.carbon", directory: "")
|
||||
// CHECK:STDOUT: !45 = !DILocation(line: 9, column: 28, scope: !43)
|
||||
// CHECK:STDOUT: !46 = !DILocation(line: 9, column: 21, scope: !43)
|
||||
@@ -333,7 +333,7 @@ fn GetRefs() {
|
||||
// CHECK:STDOUT: %_.var = alloca i32, align 4, !dbg !17
|
||||
// CHECK:STDOUT: %.loc26_23.2.temp = alloca i32, align 4, !dbg !18
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %c.var), !dbg !14
|
||||
// CHECK:STDOUT: call void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2603c91dd66a1dca"(ptr %c.var), !dbg !14
|
||||
// CHECK:STDOUT: call void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.4fdc745d4b6d0e3c"(ptr %c.var), !dbg !14
|
||||
// CHECK:STDOUT: call void @_Z8TakeCRefR1C10ForceThunk.carbon_thunk.r(ptr %c.var), !dbg !19
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_18.2.temp), !dbg !15
|
||||
// CHECK:STDOUT: call void @_Z9TakeCRRefRK1C10ForceThunk.carbon_thunk._(ptr @C.val.loc20_20.3), !dbg !20
|
||||
@@ -364,7 +364,7 @@ fn GetRefs() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Default.5648bcc2d6c775b7.Core:C.Cpp"(ptr sret({}) %return) #2 !dbg !29 {
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Default.08e786f435a99766.Core:C.Cpp"(ptr sret({}) %return) #2 !dbg !29 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: call void @_ZN1CC1Ev.carbon_thunk.(ptr %return), !dbg !33
|
||||
// CHECK:STDOUT: ret void, !dbg !33
|
||||
@@ -446,8 +446,8 @@ fn GetRefs() {
|
||||
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #4
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2603c91dd66a1dca"(ptr sret({}) %return) #0 !dbg !45 {
|
||||
// CHECK:STDOUT: call void @"_COp:thunk:Default.5648bcc2d6c775b7.Core:C.Cpp"(ptr %return), !dbg !47
|
||||
// CHECK:STDOUT: define linkonce_odr void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.4fdc745d4b6d0e3c"(ptr sret({}) %return) #0 !dbg !45 {
|
||||
// CHECK:STDOUT: call void @"_COp:thunk:Default.08e786f435a99766.Core:C.Cpp"(ptr %return), !dbg !47
|
||||
// CHECK:STDOUT: ret void, !dbg !48
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -507,7 +507,7 @@ fn GetRefs() {
|
||||
// CHECK:STDOUT: !26 = !{!27, !27, i64 0}
|
||||
// CHECK:STDOUT: !27 = !{!"p1 _ZTS1C", !28, i64 0}
|
||||
// CHECK:STDOUT: !28 = !{!"any pointer", !9, i64 0}
|
||||
// CHECK:STDOUT: !29 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Default.5648bcc2d6c775b7.Core:C.Cpp", scope: null, file: !6, line: 5, type: !30, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !29 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Default.08e786f435a99766.Core:C.Cpp", scope: null, file: !6, line: 5, type: !30, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !30 = !DISubroutineType(types: !31)
|
||||
// CHECK:STDOUT: !31 = !{!32}
|
||||
// CHECK:STDOUT: !32 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
|
||||
@@ -523,7 +523,7 @@ fn GetRefs() {
|
||||
// CHECK:STDOUT: !42 = !{!43}
|
||||
// CHECK:STDOUT: !43 = !DILocalVariable(arg: 1, scope: !38, type: !41)
|
||||
// CHECK:STDOUT: !44 = !DILocation(line: 26, column: 23, scope: !38)
|
||||
// CHECK:STDOUT: !45 = distinct !DISubprogram(name: "Op", linkageName: "_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2603c91dd66a1dca", scope: null, file: !46, line: 9, type: !30, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !45 = distinct !DISubprogram(name: "Op", linkageName: "_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.4fdc745d4b6d0e3c", scope: null, file: !46, line: 9, type: !30, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !46 = !DIFile(filename: "min_prelude/parts/default.carbon", directory: "")
|
||||
// CHECK:STDOUT: !47 = !DILocation(line: 9, column: 28, scope: !45)
|
||||
// CHECK:STDOUT: !48 = !DILocation(line: 9, column: 21, scope: !45)
|
||||
|
||||
Reference in New Issue
Block a user