ahatanak created this revision. ahatanak added reviewers: rjmccall, theraven. ahatanak added a project: clang. Herald added subscribers: dexonsmith, jkorous.
clang currently emits different strings for `s0` and `s1` in the following code because pointers to typedefs are encoded as "^{PointeeClassName=#}" while ObjC pointer types that aren't pointers to typedefs are encoded as "@". @class Class1; typedef NSArray<Class1 *> MyArray; void foo1(void) { const char *s0 = @encode(MyArray *); // "^{NSArray=#}" const char *s1 = @encode(NSArray<Class1 *> *); // "@" } It seems that this was a deliberate choice made in r61387 to make clang compatible with gcc (see http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20081222/010465.html), but it causes apple's runtime to crash. This patch fixes the bug by checking whether the runtime is one of the GNU runtimes before using the special encoding for typedefs. rdar://problem/50563529 Repository: rC Clang https://reviews.llvm.org/D61974 Files: lib/AST/ASTContext.cpp test/CodeGenObjC/encode-test-6.m test/CodeGenObjC/encode-test.m test/CodeGenObjCXX/encode.mm
Index: test/CodeGenObjCXX/encode.mm =================================================================== --- test/CodeGenObjCXX/encode.mm +++ test/CodeGenObjCXX/encode.mm @@ -242,6 +242,6 @@ @end const char *expand_struct() { - // CHECK: @{{.*}} = private unnamed_addr constant [16 x i8] c"{N={S<N>=^{N}}}\00" + // CHECK: @{{.*}} = private unnamed_addr constant [13 x i8] c"{N={S<N>=@}}\00" return @encode(N); } Index: test/CodeGenObjC/encode-test.m =================================================================== --- test/CodeGenObjC/encode-test.m +++ test/CodeGenObjC/encode-test.m @@ -1,7 +1,8 @@ -// RUN: %clang_cc1 -triple i686-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o %t %s -// RUN: FileCheck < %t %s +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck -check-prefix=MACOSX -check-prefix=CHECK %s +// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -fobjc-runtime=gnustep-1.7 -emit-llvm -o - %s | FileCheck -check-prefix=GNUSTEP -check-prefix=CHECK %s + // -// CHECK: @OBJC_METH_VAR_TYPE_{{.*}} = private unnamed_addr constant [16 x i8] c"v12@0:4[3[4@]]8\00" +// MACOSX: @OBJC_METH_VAR_TYPE_{{.*}} = private unnamed_addr constant [16 x i8] c"v12@0:4[3[4@]]8\00" @class Int1; @@ -95,7 +96,8 @@ // CHECK: @g0 = constant [15 x i8] c"{Innermost=CC}\00" const char g0[] = @encode(struct Innermost); -// CHECK: @g1 = constant [38 x i8] c"{Derived=#ib32b8b3b8sb16b8b8b2b8ccb6}\00" +// MACOSX: @g1 = constant [38 x i8] c"{Derived=#ib32b8b3b8sb16b8b8b2b8ccb6}\00" +// GNUSTEP: @g1 = constant [83 x i8] c"{Derived=#ib96i32b128i8b136i3b139I8sb176I16b192i8b200i8b208i2b210i8ccb240i6b248c0}\00" const char g1[] = @encode(Derived); // CHECK: @g2 = constant [9 x i8] c"{B1=#@c}\00" @@ -107,7 +109,8 @@ // CHECK: @g4 = constant [6 x i8] c"{S=i}\00" const char g4[] = @encode(const struct S); -// CHECK: @g5 = constant [12 x i8] c"^{Object=#}\00" +// MACOSX: @g5 = constant [2 x i8] c"@\00" +// GNUSTEP: @g5 = constant [12 x i8] c"^{Object=#}\00" const char g5[] = @encode(MyObj * const); //// @@ -133,10 +136,12 @@ @implementation Derived1X @end -// CHECK: @g6 = constant [18 x i8] c"{Base1X=b2b3b4b5}\00" +// MACOSX: @g6 = constant [18 x i8] c"{Base1X=b2b3b4b5}\00" +// GNUSTEP: @g6 = constant [31 x i8] c"{Base1X=b0I2b2i3b5i4b9I5b16c0}\00" const char g6[] = @encode(Base1X); -// CHECK: @g7 = constant [27 x i8] c"{Derived1X=b2b3b4b5b5b4b3}\00" +// MACOSX: @g7 = constant [27 x i8] c"{Derived1X=b2b3b4b5b5b4b3}\00" +// GNUSTEP: @g7 = constant [54 x i8] c"{Derived1X=b0I2b2i3b5i4b9I5b16c0b16i5b21i4b25i3b32c0}\00" const char g7[] = @encode(Derived1X); // CHECK: @g8 = constant [7 x i8] c"{s8=D}\00" @@ -184,10 +189,10 @@ typedef typeof(sizeof(int)) size_t; size_t strlen(const char *s); -// CHECK-LABEL: @test_strlen( -// CHECK: %[[i:.*]] = alloca i32 -// CHECK: %[[call:.*]] = call i32 @strlen -// CHECK: store i32 %[[call]], i32* %[[i]] +// MACOSX-LABEL: @test_strlen( +// MACOSX: %[[i:.*]] = alloca i32 +// MACOSX: %[[call:.*]] = call i32 @strlen +// MACOSX: store i32 %[[call]], i32* %[[i]] void test_strlen() { const char array[] = @encode(int); int i = strlen(array); Index: test/CodeGenObjC/encode-test-6.m =================================================================== --- test/CodeGenObjC/encode-test-6.m +++ test/CodeGenObjC/encode-test-6.m @@ -34,7 +34,7 @@ @synthesize property = _property; @end -// CHECK: private unnamed_addr constant [24 x i8] c"^{BABugExample=@}16 +// CHECK: private unnamed_addr constant [8 x i8] c"@16 // rdar://14408244 @class SCNCamera; @@ -52,7 +52,7 @@ C3DCameraStorage _storage; } @end -// CHECK: private unnamed_addr constant [39 x i8] c"{?=\22presentationInstance\22^{SCNCamera}}\00" +// CHECK: private unnamed_addr constant [39 x i8] c"{?=\22presentationInstance\22@\22SCNCamera\22}\00" // rdar://16655340 int i; Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -6970,11 +6970,12 @@ } QualType PointeeTy = OPT->getPointeeType(); - if (!Options.EncodingProperty() && + if (getLangOpts().ObjCRuntime.isGNUFamily() && + !Options.EncodingProperty() && isa<TypedefType>(PointeeTy.getTypePtr()) && !Options.EncodePointerToObjCTypedef()) { - // Another historical/compatibility reason. - // We encode the underlying type which comes out as + // If the runtime is one of the GNU family runtimes, encode the underlying + // type which comes out as // {...}; S += '^'; if (FD && OPT->getInterfaceDecl()) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits