diff options
| author | Shoaib Meenai <smeenai@fb.com> | 2019-03-28 17:01:20 +0000 |
|---|---|---|
| committer | Shoaib Meenai <smeenai@fb.com> | 2019-03-28 17:01:20 +0000 |
| commit | 155e26f0f43c92131d624fe5e0db4b3cb010cf96 (patch) | |
| tree | 44e5134b3bcb0b4e61381973fd520b6a4f9b09d4 | |
| parent | 1af05df3de60802c523661385b04229106a0c2c3 (diff) | |
| download | bcm5719-llvm-155e26f0f43c92131d624fe5e0db4b3cb010cf96.tar.gz bcm5719-llvm-155e26f0f43c92131d624fe5e0db4b3cb010cf96.zip | |
[CodeGen] Add additional mangling for struct members of non trivial structs
In https://bugs.llvm.org/show_bug.cgi?id=41206 we observe bad codegen
when embedding a non-trivial C struct within a C struct. This is due to
the fact that name mangling for non-trivial structs marks the two
structs as identical. This diff contains a fix for this issue.
Patch by Dan Zimmerman <daniel.zimmerman@me.com>.
Differential Revision: https://reviews.llvm.org/D59873
llvm-svn: 357184
| -rw-r--r-- | clang/lib/CodeGen/CGNonTrivialStruct.cpp | 5 | ||||
| -rw-r--r-- | clang/test/CodeGenObjC/nontrivial-c-struct-within-struct-name.m | 44 | ||||
| -rw-r--r-- | clang/test/CodeGenObjC/strong-in-c-struct.m | 32 |
3 files changed, 63 insertions, 18 deletions
diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp index a1649e4fb7b..f2b59f8bc50 100644 --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -139,8 +139,8 @@ struct CopyStructVisitor : StructVisitor<Derived>, // <alignment-info> ::= <dst-alignment> ["_" <src-alignment>] // <struct-field-info> ::= <field-info>+ // <field-info> ::= <struct-or-scalar-field-info> | <array-field-info> -// <struct-or-scalar-field-info> ::= <struct-field-info> | <strong-field-info> | -// <trivial-field-info> +// <struct-or-scalar-field-info> ::= "_S" <struct-field-info> | +// <strong-field-info> | <trivial-field-info> // <array-field-info> ::= "_AB" <array-offset> "s" <element-size> "n" // <num-elements> <innermost-element-info> "_AE" // <innermost-element-info> ::= <struct-or-scalar-field-info> @@ -175,6 +175,7 @@ template <class Derived> struct GenFuncNameBase { void visitStruct(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset) { CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD); + appendStr("_S"); asDerived().visitStructFields(QT, FieldOffset); } diff --git a/clang/test/CodeGenObjC/nontrivial-c-struct-within-struct-name.m b/clang/test/CodeGenObjC/nontrivial-c-struct-within-struct-name.m new file mode 100644 index 00000000000..854c097c0ea --- /dev/null +++ b/clang/test/CodeGenObjC/nontrivial-c-struct-within-struct-name.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s + +@class I; + +typedef struct { + I *name; +} Foo; + +typedef struct { + Foo foo; +} Bar; + +typedef struct { + Bar bar; +} Baz; + +I *getI(); + +void f() { + Foo foo = {getI()}; + Bar bar = {foo}; + Baz baz = {bar}; +} + +// CHECK: define linkonce_odr hidden void @__destructor_8_S_S_s0(i8** %[[DST:.*]]) +// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 +// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 +// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 +// CHECK: call void @__destructor_8_S_s0(i8** %[[V0]]) +// CHECK: ret void + +// CHECK: define linkonce_odr hidden void @__destructor_8_S_s0(i8** %[[DST:.*]]) +// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 +// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 +// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 +// CHECK: call void @__destructor_8_s0(i8** %[[V0]]) +// CHECK: ret void + +// CHECK: define linkonce_odr hidden void @__destructor_8_s0(i8** %dst) +// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 +// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 +// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 +// CHECK: call void @llvm.objc.storeStrong(i8** %[[V0]], i8* null) +// CHECK: ret void diff --git a/clang/test/CodeGenObjC/strong-in-c-struct.m b/clang/test/CodeGenObjC/strong-in-c-struct.m index 999b89dd60f..17587f7d62d 100644 --- a/clang/test/CodeGenObjC/strong-in-c-struct.m +++ b/clang/test/CodeGenObjC/strong-in-c-struct.m @@ -89,12 +89,12 @@ void func(Strong *); // CHECK: define void @test_constructor_destructor_StrongOuter() // CHECK: %[[T:.*]] = alloca %[[STRUCT_STRONGOUTER:.*]], align 8 // CHECK: %[[V0:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8** -// CHECK: call void @__default_constructor_8_s16_s24(i8** %[[V0]]) +// CHECK: call void @__default_constructor_8_S_s16_s24(i8** %[[V0]]) // CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8** -// CHECK: call void @__destructor_8_s16_s24(i8** %[[V1]]) +// CHECK: call void @__destructor_8_S_s16_s24(i8** %[[V1]]) // CHECK: ret void -// CHECK: define linkonce_odr hidden void @__default_constructor_8_s16_s24(i8** %[[DST:.*]]) +// CHECK: define linkonce_odr hidden void @__default_constructor_8_S_s16_s24(i8** %[[DST:.*]]) // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 @@ -117,7 +117,7 @@ void func(Strong *); // CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 %[[V4]], i8 0, i64 8, i1 false) // CHECK: ret void -// CHECK: define linkonce_odr hidden void @__destructor_8_s16_s24(i8** %[[DST:.*]]) +// CHECK: define linkonce_odr hidden void @__destructor_8_S_s16_s24(i8** %[[DST:.*]]) // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 @@ -149,12 +149,12 @@ void test_constructor_destructor_StrongOuter(void) { // CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGOUTER]]*, %[[STRUCT_STRONGOUTER]]** %[[S_ADDR]], align 8 // CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8** // CHECK: %[[V2:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[V0]] to i8** -// CHECK: call void @__copy_constructor_8_8_t0w16_s16_s24_t32w8(i8** %[[V1]], i8** %[[V2]]) +// CHECK: call void @__copy_constructor_8_8_S_t0w16_s16_s24_t32w8(i8** %[[V1]], i8** %[[V2]]) // CHECK: %[[V3:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8** -// CHECK: call void @__destructor_8_s16_s24(i8** %[[V3]]) +// CHECK: call void @__destructor_8_S_s16_s24(i8** %[[V3]]) // CHECK: ret void -// CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) +// CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 @@ -208,7 +208,7 @@ void test_copy_constructor_StrongOuter(StrongOuter *s) { StrongOuter t = *s; } -/// CHECK: define linkonce_odr hidden void @__copy_assignment_8_8_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) +/// CHECK: define linkonce_odr hidden void @__copy_assignment_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 @@ -231,15 +231,15 @@ void test_copy_assignment_StrongOuter(StrongOuter *d, StrongOuter *s) { // CHECK: define void @test_move_constructor_StrongOuter() // CHECK: %[[T1:.*]] = getelementptr inbounds %[[STRUCT_BLOCK_BYREF_T:.*]], %[[STRUCT_BLOCK_BYREF_T]]* %{{.*}}, i32 0, i32 7 // CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T1]] to i8** -// CHECK: call void @__default_constructor_8_s16_s24(i8** %[[V1]]) +// CHECK: call void @__default_constructor_8_S_s16_s24(i8** %[[V1]]) // CHECK: %[[T2:.*]] = getelementptr inbounds %[[STRUCT_BLOCK_BYREF_T]], %[[STRUCT_BLOCK_BYREF_T]]* %{{.*}}, i32 0, i32 7 // CHECK: %[[V9:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T2]] to i8** -// CHECK: call void @__destructor_8_s16_s24(i8** %[[V9]]) +// CHECK: call void @__destructor_8_S_s16_s24(i8** %[[V9]]) // CHECK: define internal void @__Block_byref_object_copy_(i8*, i8*) -// CHECK: call void @__move_constructor_8_8_t0w16_s16_s24_t32w8( +// CHECK: call void @__move_constructor_8_8_S_t0w16_s16_s24_t32w8( -// CHECK: define linkonce_odr hidden void @__move_constructor_8_8_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) +// CHECK: define linkonce_odr hidden void @__move_constructor_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 @@ -258,14 +258,14 @@ void test_copy_assignment_StrongOuter(StrongOuter *d, StrongOuter *s) { // CHECK: store i8* %[[V8]], i8** %[[V4]], align 8 // CHECK: define internal void @__Block_byref_object_dispose_(i8*) -// CHECK: call void @__destructor_8_s16_s24( +// CHECK: call void @__destructor_8_S_s16_s24( void test_move_constructor_StrongOuter(void) { __block StrongOuter t; BlockTy b = ^{ (void)t; }; } -// CHECK: define linkonce_odr hidden void @__move_assignment_8_8_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) +// CHECK: define linkonce_odr hidden void @__move_assignment_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 @@ -480,14 +480,14 @@ void test_constructor_destructor_IDArray(void) { IDArray t; } -// CHECK: define linkonce_odr hidden void @__default_constructor_8_AB8s24n4_s24_AE( +// CHECK: define linkonce_odr hidden void @__default_constructor_8_AB8s24n4_S_s24_AE( void test_constructor_destructor_StructArray(void) { StructArray t; } // Test that StructArray's field 'd' is copied before entering the loop. -// CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_t0w8_AB8s24n4_t8w16_s24_AE(i8** %[[DST:.*]], i8** %[[SRC:.*]]) +// CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_t0w8_AB8s24n4_S_t8w16_s24_AE(i8** %[[DST:.*]], i8** %[[SRC:.*]]) // CHECK: entry: // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 |

