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.

llvm-svn: 199688
This commit is contained in:
Rafael Espindola
2014-01-20 20:33:18 +00:00
parent 8a63b15b3c
commit d19f80a0b4
7 changed files with 16 additions and 11 deletions

View File

@@ -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.