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
+20
-20
@@ -281,7 +281,7 @@ fn Four() {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %_.var = alloca [8 x i8], align 1, !dbg !14
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %_.var), !dbg !14
|
||||
// CHECK:STDOUT: call void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2603c91dd66a1dca"(ptr %_.var), !dbg !14
|
||||
// CHECK:STDOUT: call void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.4fdc745d4b6d0e3c"(ptr %_.var), !dbg !14
|
||||
// CHECK:STDOUT: ret void, !dbg !15
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -296,7 +296,7 @@ fn Four() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Default.5648bcc2d6c775b7.Core:C.Cpp"(ptr sret([8 x i8]) %return) #2 !dbg !19 {
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Default.08e786f435a99766.Core:C.Cpp"(ptr sret([8 x i8]) %return) #2 !dbg !19 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: call void @_ZN1CC1Ev.carbon_thunk.(ptr %return), !dbg !24
|
||||
// CHECK:STDOUT: ret void, !dbg !24
|
||||
@@ -306,8 +306,8 @@ fn Four() {
|
||||
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #3
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2603c91dd66a1dca"(ptr sret([8 x i8]) %return) #0 !dbg !25 {
|
||||
// CHECK:STDOUT: call void @"_COp:thunk:Default.5648bcc2d6c775b7.Core:C.Cpp"(ptr %return), !dbg !27
|
||||
// CHECK:STDOUT: define linkonce_odr void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.4fdc745d4b6d0e3c"(ptr sret([8 x i8]) %return) #0 !dbg !25 {
|
||||
// CHECK:STDOUT: call void @"_COp:thunk:Default.08e786f435a99766.Core:C.Cpp"(ptr %return), !dbg !27
|
||||
// CHECK:STDOUT: ret void, !dbg !28
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -353,13 +353,13 @@ fn Four() {
|
||||
// CHECK:STDOUT: !16 = !{!17, !17, i64 0}
|
||||
// CHECK:STDOUT: !17 = !{!"p1 _ZTS1C", !18, i64 0}
|
||||
// CHECK:STDOUT: !18 = !{!"any pointer", !9, i64 0}
|
||||
// CHECK:STDOUT: !19 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Default.5648bcc2d6c775b7.Core:C.Cpp", scope: null, file: !20, line: 4, type: !21, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !19 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Default.08e786f435a99766.Core:C.Cpp", scope: null, file: !20, line: 4, type: !21, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !20 = !DIFile(filename: "./default.h", directory: "")
|
||||
// CHECK:STDOUT: !21 = !DISubroutineType(types: !22)
|
||||
// CHECK:STDOUT: !22 = !{!23}
|
||||
// CHECK:STDOUT: !23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
|
||||
// CHECK:STDOUT: !24 = !DILocation(line: 4, column: 3, scope: !19)
|
||||
// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "Op", linkageName: "_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2603c91dd66a1dca", scope: null, file: !26, line: 9, type: !21, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "Op", linkageName: "_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.4fdc745d4b6d0e3c", scope: null, file: !26, line: 9, type: !21, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !26 = !DIFile(filename: "min_prelude/parts/default.carbon", directory: "")
|
||||
// CHECK:STDOUT: !27 = !DILocation(line: 9, column: 28, scope: !25)
|
||||
// CHECK:STDOUT: !28 = !DILocation(line: 9, column: 21, scope: !25)
|
||||
@@ -388,11 +388,11 @@ fn Four() {
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_65.1.temp), !dbg !14
|
||||
// CHECK:STDOUT: call void @_ZN26ImplicitlyDefaultedDefaultC1Ev.carbon_thunk.(ptr %.loc8_65.1.temp), !dbg !14
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %_.var.loc9), !dbg !15
|
||||
// CHECK:STDOUT: call void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2db09a503899761f"(ptr %_.var.loc9), !dbg !15
|
||||
// CHECK:STDOUT: call void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.dc183edbabc24d2f"(ptr %_.var.loc9), !dbg !15
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc12_65.1.temp), !dbg !16
|
||||
// CHECK:STDOUT: call void @_ZN26ExplicitlyDefaultedDefaultC1Ev.carbon_thunk.(ptr %.loc12_65.1.temp), !dbg !16
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %_.var.loc13), !dbg !17
|
||||
// CHECK:STDOUT: call void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.0dfbcd9a7c1791ba"(ptr %_.var.loc13), !dbg !17
|
||||
// CHECK:STDOUT: call void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.44ad2ae60410d16d"(ptr %_.var.loc13), !dbg !17
|
||||
// CHECK:STDOUT: ret void, !dbg !18
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -407,7 +407,7 @@ fn Four() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Default.40902cf3dea87d9c.Core:ImplicitlyDefaultedDefault.Cpp"(ptr sret([4 x i8]) %return) #2 !dbg !22 {
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Default.1458cb9e3f45d9d7.Core:ImplicitlyDefaultedDefault.Cpp"(ptr sret([4 x i8]) %return) #2 !dbg !22 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: call void @_ZN26ImplicitlyDefaultedDefaultC1Ev.carbon_thunk.(ptr %return), !dbg !27
|
||||
// CHECK:STDOUT: ret void, !dbg !27
|
||||
@@ -424,7 +424,7 @@ fn Four() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Default.f7ced4a20f885cf5.Core:ExplicitlyDefaultedDefault.Cpp"(ptr sret([4 x i8]) %return) #2 !dbg !30 {
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Default.16c8d515df1b6c01.Core:ExplicitlyDefaultedDefault.Cpp"(ptr sret([4 x i8]) %return) #2 !dbg !30 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: call void @_ZN26ExplicitlyDefaultedDefaultC1Ev.carbon_thunk.(ptr %return), !dbg !31
|
||||
// CHECK:STDOUT: ret void, !dbg !31
|
||||
@@ -434,14 +434,14 @@ fn Four() {
|
||||
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #3
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2db09a503899761f"(ptr sret([4 x i8]) %return) #0 !dbg !32 {
|
||||
// CHECK:STDOUT: call void @"_COp:thunk:Default.40902cf3dea87d9c.Core:ImplicitlyDefaultedDefault.Cpp"(ptr %return), !dbg !34
|
||||
// CHECK:STDOUT: define linkonce_odr void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.dc183edbabc24d2f"(ptr sret([4 x i8]) %return) #0 !dbg !32 {
|
||||
// CHECK:STDOUT: call void @"_COp:thunk:Default.1458cb9e3f45d9d7.Core:ImplicitlyDefaultedDefault.Cpp"(ptr %return), !dbg !34
|
||||
// CHECK:STDOUT: ret void, !dbg !35
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.0dfbcd9a7c1791ba"(ptr sret([4 x i8]) %return) #0 !dbg !36 {
|
||||
// CHECK:STDOUT: call void @"_COp:thunk:Default.f7ced4a20f885cf5.Core:ExplicitlyDefaultedDefault.Cpp"(ptr %return), !dbg !37
|
||||
// CHECK:STDOUT: define linkonce_odr void @"_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.44ad2ae60410d16d"(ptr sret([4 x i8]) %return) #0 !dbg !36 {
|
||||
// CHECK:STDOUT: call void @"_COp:thunk:Default.16c8d515df1b6c01.Core:ExplicitlyDefaultedDefault.Cpp"(ptr %return), !dbg !37
|
||||
// CHECK:STDOUT: ret void, !dbg !38
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -503,7 +503,7 @@ fn Four() {
|
||||
// CHECK:STDOUT: !19 = !{!20, !20, i64 0}
|
||||
// CHECK:STDOUT: !20 = !{!"p1 _ZTS26ImplicitlyDefaultedDefault", !21, i64 0}
|
||||
// CHECK:STDOUT: !21 = !{!"any pointer", !9, i64 0}
|
||||
// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Default.40902cf3dea87d9c.Core:ImplicitlyDefaultedDefault.Cpp", scope: null, file: !23, line: 2, type: !24, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Default.1458cb9e3f45d9d7.Core:ImplicitlyDefaultedDefault.Cpp", scope: null, file: !23, line: 2, type: !24, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !23 = !DIFile(filename: "./defaulted_default.h", directory: "")
|
||||
// CHECK:STDOUT: !24 = !DISubroutineType(types: !25)
|
||||
// CHECK:STDOUT: !25 = !{!26}
|
||||
@@ -511,13 +511,13 @@ fn Four() {
|
||||
// CHECK:STDOUT: !27 = !DILocation(line: 2, column: 8, scope: !22)
|
||||
// CHECK:STDOUT: !28 = !{!29, !29, i64 0}
|
||||
// CHECK:STDOUT: !29 = !{!"p1 _ZTS26ExplicitlyDefaultedDefault", !21, i64 0}
|
||||
// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Default.f7ced4a20f885cf5.Core:ExplicitlyDefaultedDefault.Cpp", scope: null, file: !23, line: 7, type: !24, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Default.16c8d515df1b6c01.Core:ExplicitlyDefaultedDefault.Cpp", scope: null, file: !23, line: 7, type: !24, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !31 = !DILocation(line: 7, column: 3, scope: !30)
|
||||
// CHECK:STDOUT: !32 = distinct !DISubprogram(name: "Op", linkageName: "_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.2db09a503899761f", scope: null, file: !33, line: 9, type: !24, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !32 = distinct !DISubprogram(name: "Op", linkageName: "_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.dc183edbabc24d2f", scope: null, file: !33, line: 9, type: !24, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !33 = !DIFile(filename: "min_prelude/parts/default.carbon", directory: "")
|
||||
// CHECK:STDOUT: !34 = !DILocation(line: 9, column: 28, scope: !32)
|
||||
// CHECK:STDOUT: !35 = !DILocation(line: 9, column: 21, scope: !32)
|
||||
// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "Op", linkageName: "_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.0dfbcd9a7c1791ba", scope: null, file: !33, line: 9, type: !24, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "Op", linkageName: "_COp.cbe5dd53b28eb3d1:DefaultOrUnformed.Core.44ad2ae60410d16d", scope: null, file: !33, line: 9, type: !24, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !37 = !DILocation(line: 9, column: 28, scope: !36)
|
||||
// CHECK:STDOUT: !38 = !DILocation(line: 9, column: 21, scope: !36)
|
||||
// CHECK:STDOUT: !39 = !{!40, !8, i64 0}
|
||||
@@ -552,7 +552,7 @@ fn Four() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Copy.83073f2d17ed2f9e.Core:Copy.Cpp"(ptr sret([4 x i8]) %return, ptr %self) #2 !dbg !22 {
|
||||
// CHECK:STDOUT: define void @"_COp:thunk:Copy.0459c72f2d146eb1.Core:Copy.Cpp"(ptr sret([4 x i8]) %return, ptr %self) #2 !dbg !22 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: call void @_ZN4CopyC1ERKS_.carbon_thunk._(ptr %self, ptr %return), !dbg !26
|
||||
// CHECK:STDOUT: ret void, !dbg !26
|
||||
@@ -595,7 +595,7 @@ fn Four() {
|
||||
// CHECK:STDOUT: !19 = !{!20, !20, i64 0}
|
||||
// CHECK:STDOUT: !20 = !{!"p1 _ZTS4Copy", !21, i64 0}
|
||||
// CHECK:STDOUT: !21 = !{!"any pointer", !9, i64 0}
|
||||
// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Copy.83073f2d17ed2f9e.Core:Copy.Cpp", scope: null, file: !23, line: 5, type: !12, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !24)
|
||||
// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk:Copy.0459c72f2d146eb1.Core:Copy.Cpp", scope: null, file: !23, line: 5, type: !12, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !24)
|
||||
// CHECK:STDOUT: !23 = !DIFile(filename: "./copy.h", directory: "")
|
||||
// CHECK:STDOUT: !24 = !{!25}
|
||||
// CHECK:STDOUT: !25 = !DILocalVariable(arg: 1, scope: !22, type: !14)
|
||||
|
||||
Reference in New Issue
Block a user