From 68aa3e10547409a98d865dc56fec9af8243a192f Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 20 Jan 2014 20:33:18 +0000 Subject: [PATCH] Give explicit sections for string constants used in NSStrings. Without them they can be merged with non unnamed_addr constants during LTO. The resulting constant is not unnamed_addr and goes in a different section, which causes ld64 to crash. A testcase that would crash before: * file1.mm: void g(id notification) { [notification valueForKey:@"name"]; } * file2.cpp: extern const char js_name_str[] = "name"; * file3.cpp extern bool JS_GetProperty(const char *name); extern const char js_name_str[]; bool js_ReportUncaughtException() { JS_GetProperty(js_name_str); } run clang file1.mm -o file1.o -c -w -emit-llvm clang file2.cpp -o file2.o -c -w -emit-llvm clang file3.cpp -o file3.o -c -w ld -dylib -o XUL file1.o file2.o file3.o -undefined dynamic_lookup. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@199688 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenModule.cpp | 5 +++++ test/CodeGen/cfstring.c | 6 +++--- test/CodeGen/darwin-string-literals.c | 8 ++++---- test/CodeGen/utf16-cfstrings.c | 2 +- test/CodeGenObjC/2009-08-05-utf16.m | 2 +- test/CodeGenObjC/2010-02-01-utf16-with-null.m | 2 +- test/CodeGenObjC/constant-strings.m | 2 +- 7 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 88e6e66f9c..12edab7cd6 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -2396,12 +2396,17 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { GV->setUnnamedAddr(true); // Don't enforce the target's minimum global alignment, since the only use // of the string is via this class initializer. + // FIXME: We set the section explicitly to avoid a bug in ld64 224.1. Without + // it LLVM can merge the string with a non unnamed_addr one during LTO. Doing + // that changes the section it ends in, which surprises ld64. if (isUTF16) { CharUnits Align = getContext().getTypeAlignInChars(getContext().ShortTy); GV->setAlignment(Align.getQuantity()); + GV->setSection("__TEXT,__ustring"); } else { CharUnits Align = getContext().getTypeAlignInChars(getContext().CharTy); GV->setAlignment(Align.getQuantity()); + GV->setSection("__TEXT,__cstring,cstring_literals"); } // String. diff --git a/test/CodeGen/cfstring.c b/test/CodeGen/cfstring.c index 9d98b56e6b..f73ffc6082 100644 --- a/test/CodeGen/cfstring.c +++ b/test/CodeGen/cfstring.c @@ -5,9 +5,9 @@ // // RUN: %clang_cc1 -fwritable-strings -emit-llvm %s -o - | FileCheck %s // -// CHECK: @.str = linker_private unnamed_addr constant [14 x i8] c"Hello, World!\00", align 1 -// CHECK: @.str1 = linker_private unnamed_addr constant [7 x i8] c"yo joe\00", align 1 -// CHECK: @.str3 = linker_private unnamed_addr constant [16 x i8] c"Goodbye, World!\00", align 1 +// CHECK: @.str = linker_private unnamed_addr constant [14 x i8] c"Hello, World!\00", section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @.str1 = linker_private unnamed_addr constant [7 x i8] c"yo joe\00", section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @.str3 = linker_private unnamed_addr constant [16 x i8] c"Goodbye, World!\00", section "__TEXT,__cstring,cstring_literals", align 1 #define CFSTR __builtin___CFStringMakeConstantString diff --git a/test/CodeGen/darwin-string-literals.c b/test/CodeGen/darwin-string-literals.c index c7d9ff9160..621a46eb36 100644 --- a/test/CodeGen/darwin-string-literals.c +++ b/test/CodeGen/darwin-string-literals.c @@ -2,16 +2,16 @@ // CHECK-LSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00" // CHECK-LSB: @.str1 = linker_private unnamed_addr constant [8 x i8] c"string1\00" -// CHECK-LSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], align 2 -// CHECK-LSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], align 2 +// CHECK-LSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], section "__TEXT,__ustring", align 2 +// CHECK-LSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], section "__TEXT,__ustring", align 2 // RUN: %clang_cc1 -triple powerpc-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix CHECK-MSB %s // CHECK-MSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00" // CHECK-MSB: @.str1 = linker_private unnamed_addr constant [8 x i8] c"string1\00" -// CHECK-MSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], align 2 -// CHECK-MSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], align 2 +// CHECK-MSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], section "__TEXT,__ustring", align 2 +// CHECK-MSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], section "__TEXT,__ustring", align 2 const char *g0 = "string0"; const void *g1 = __builtin___CFStringMakeConstantString("string1"); diff --git a/test/CodeGen/utf16-cfstrings.c b/test/CodeGen/utf16-cfstrings.c index d4f214b0d6..3ac84b3537 100644 --- a/test/CodeGen/utf16-cfstrings.c +++ b/test/CodeGen/utf16-cfstrings.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s // -// CHECK: @.str = internal unnamed_addr constant [9 x i16] [i16 252, i16 98, i16 101, i16 114, i16 104, i16 117, i16 110, i16 100, i16 0], align 2 +// CHECK: @.str = internal unnamed_addr constant [9 x i16] [i16 252, i16 98, i16 101, i16 114, i16 104, i16 117, i16 110, i16 100, i16 0], section "__TEXT,__ustring", align 2 #define CFSTR __builtin___CFStringMakeConstantString diff --git a/test/CodeGenObjC/2009-08-05-utf16.m b/test/CodeGenObjC/2009-08-05-utf16.m index 06458e730a..76927c08e2 100644 --- a/test/CodeGenObjC/2009-08-05-utf16.m +++ b/test/CodeGenObjC/2009-08-05-utf16.m @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -emit-llvm -w -x objective-c %s -o - | FileCheck %s // rdar://7095855 rdar://7115749 -// CHECK: internal unnamed_addr constant [6 x i16] [i16 105, i16 80, i16 111, i16 100, i16 8482, i16 0], align 2 +// CHECK: internal unnamed_addr constant [6 x i16] [i16 105, i16 80, i16 111, i16 100, i16 8482, i16 0], section "__TEXT,__ustring", align 2 void *P = @"iPod™"; diff --git a/test/CodeGenObjC/2010-02-01-utf16-with-null.m b/test/CodeGenObjC/2010-02-01-utf16-with-null.m index 2845480007..f40552a8ad 100644 --- a/test/CodeGenObjC/2010-02-01-utf16-with-null.m +++ b/test/CodeGenObjC/2010-02-01-utf16-with-null.m @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple i686-apple-darwin -emit-llvm %s -o - | FileCheck %s // rdar://7589850 -// CHECK: @.str = internal unnamed_addr constant [9 x i16] [i16 103, i16 111, i16 111, i16 100, i16 0, i16 98, i16 121, i16 101, i16 0], align 2 +// CHECK: @.str = internal unnamed_addr constant [9 x i16] [i16 103, i16 111, i16 111, i16 100, i16 0, i16 98, i16 121, i16 101, i16 0], section "__TEXT,__ustring", align 2 // CHECK: @_unnamed_cfstring_ = private constant %struct.NSConstantString { i32* getelementptr inbounds ([0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast ([9 x i16]* @.str to i8*), i32 8 }, section "__DATA,__cfstring" // CHECK: @P = global i8* bitcast (%struct.NSConstantString* @_unnamed_cfstring_ to i8*), align 4 void *P = @"good\0bye"; diff --git a/test/CodeGenObjC/constant-strings.m b/test/CodeGenObjC/constant-strings.m index cad634a4b1..0a65496373 100644 --- a/test/CodeGenObjC/constant-strings.m +++ b/test/CodeGenObjC/constant-strings.m @@ -3,7 +3,7 @@ // Check that we set alignment 1 on the string. // -// CHECK-NEXT: @.str = {{.*}}constant [13 x i8] c"Hello World!\00", align 1 +// CHECK-NEXT: @.str = {{.*}}constant [13 x i8] c"Hello World!\00", section "__TEXT,__cstring,cstring_literals", align 1 // RUN: %clang_cc1 -fobjc-runtime=gcc -emit-llvm -o %t %s // RUN: FileCheck --check-prefix=CHECK-GNU < %t %s -- 2.40.0