kristina updated this revision to Diff 166576. kristina added a comment. Does this look about right? I'm not sure what's up with DSO local attribute, it doesn't seem to apply, I think this test makes sense though. `ninja check-clang-codegen` succeeded this time:
Testing Time: 12.77s Expected Passes : 1242 Expected Failures : 2 Unsupported Tests : 120 Bitcode looks like this (for the 3rd case, which is a fairly odd one since it's a variable sized array without extern): /q/org.llvm.caches/llvm-8.0/4132/bin/clang -cc1 -internal-isystem /q/org.llvm.caches/llvm-8.0/4132/lib/clang/8.0.4132/include -nostdsysteminc -triple x86_64-elf -S -emit-llvm /SourceCache/llvm-trunk-8.0.4132/tools/clang/test/CodeGen/cfstring-elf.c -o - ; ModuleID = '/SourceCache/llvm-trunk-8.0.4132/tools/clang/test/CodeGen/cfstring-elf.c' source_filename = "/SourceCache/llvm-trunk-8.0.4132/tools/clang/test/CodeGen/cfstring-elf.c" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-unknown-elf" %struct.__NSConstantString_tag = type { i32*, i32, i8*, i64 } %struct.__CFString = type opaque @.str = private unnamed_addr constant [7 x i8] c"string\00", section ".rodata", align 1 @_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x i32]* bitcast ([1 x i64]* @__CFConstantStringClassReference to [0 x i32]*), i32 0, i32 0), i32 1992, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i64 6 }, section "cfstring", align 8 @string = constant %struct.__CFString* bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_ to %struct.__CFString*), align 8 @__CFConstantStringClassReference = common global [1 x i64] zeroinitializer, align 8 !llvm.module.flags = !{!0} !llvm.ident = !{!1} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{!"Kristina's toolchain (8.0.4132+assert+modules+thinlto+tests+debug) clang version 8.0.4132 (https://llvm.googlesource.com/clang 8c1a8e6be4042ef6e930f19162f5e308ac56a38e) (https://llvm.googlesource.com/llvm bf40f1cb4e37e0046f94428f6332255ccf00e440) (based on LLVM 8.0.4132svn)"} Repository: rC Clang https://reviews.llvm.org/D52344 Files: lib/CodeGen/CodeGenModule.cpp test/CodeGen/cfstring-elf.c
Index: test/CodeGen/cfstring-elf.c =================================================================== --- test/CodeGen/cfstring-elf.c +++ test/CodeGen/cfstring-elf.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple x86_64-elf -DCF_BUILDING_CF -DDECL -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-CF-IN-CF-DECL +// RUN: %clang_cc1 -triple x86_64-elf -DCF_BUILDING_CF -DDEFN -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-CF-IN-CF-DEFN +// RUN: %clang_cc1 -triple x86_64-elf -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-CF +// RUN: %clang_cc1 -triple x86_64-elf -DEXTERN -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-CF-EXTERN + +// RUN: %clang_cc1 -Os -triple x86_64-elf -DCF_BUILDING_CF -DDECL -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-CF-IN-CF-DECL +// RUN: %clang_cc1 -Os -triple x86_64-elf -DCF_BUILDING_CF -DDEFN -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-CF-IN-CF-DEFN +// RUN: %clang_cc1 -Os -triple x86_64-elf -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-CF +// RUN: %clang_cc1 -Os -triple x86_64-elf -DEXTERN -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-CF-EXTERN + + +#if defined(CF_BUILDING_CF) +#if defined(DECL) +extern long __CFConstantStringClassReference[]; +#elif defined(DEFN) +long __CFConstantStringClassReference[32]; +#endif +#else +#if defined(EXTERN) +extern long __CFConstantStringClassReference[]; +#else +long __CFConstantStringClassReference[]; +#endif +#endif + +typedef struct __CFString *CFStringRef; +const CFStringRef string = (CFStringRef)__builtin___CFStringMakeConstantString("string"); + + +// CHECK-CF-IN-CF-DECL: @__CFConstantStringClassReference = external global [0 x i32] +// CHECK-CF-IN-CF-DEFN: @__CFConstantStringClassReference = common global [32 x i64] zeroinitializer, align 16 +// CHECK-CF: @__CFConstantStringClassReference = common global [1 x i64] zeroinitializer, align 8 +// CHECK-CF-EXTERN: @__CFConstantStringClassReference = external global [0 x i32] +// CHECK-CF-EXTERN: @.str = private unnamed_addr constant [7 x i8] c"string\00", section ".rodata", align 1 Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -4109,37 +4109,48 @@ llvm::Constant *Zero = llvm::Constant::getNullValue(Int32Ty); llvm::Constant *Zeros[] = { Zero, Zero }; - + // If we don't already have it, get __CFConstantStringClassReference. if (!CFConstantStringClassRef) { llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); Ty = llvm::ArrayType::get(Ty, 0); - llvm::GlobalValue *GV = cast<llvm::GlobalValue>( - CreateRuntimeVariable(Ty, "__CFConstantStringClassReference")); - - if (getTriple().isOSBinFormatCOFF()) { - IdentifierInfo &II = getContext().Idents.get(GV->getName()); - TranslationUnitDecl *TUDecl = getContext().getTranslationUnitDecl(); - DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); - - const VarDecl *VD = nullptr; - for (const auto &Result : DC->lookup(&II)) - if ((VD = dyn_cast<VarDecl>(Result))) - break; - - if (!VD || !VD->hasAttr<DLLExportAttr>()) { - GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); - GV->setLinkage(llvm::GlobalValue::ExternalLinkage); - } else { - GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); - GV->setLinkage(llvm::GlobalValue::ExternalLinkage); + llvm::Constant *C = + CreateRuntimeVariable(Ty, "__CFConstantStringClassReference"); + + if (getTriple().isOSBinFormatELF() || getTriple().isOSBinFormatCOFF()) { + llvm::GlobalValue *GV = nullptr; + + if ((GV = dyn_cast<llvm::GlobalValue>(C))) { + IdentifierInfo &II = getContext().Idents.get(GV->getName()); + TranslationUnitDecl *TUDecl = getContext().getTranslationUnitDecl(); + DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); + + const VarDecl *VD = nullptr; + for (const auto &Result : DC->lookup(&II)) + if ((VD = dyn_cast<VarDecl>(Result))) + break; + + if (getTriple().isOSBinFormatELF()) { + if (!VD) + GV->setLinkage(llvm::GlobalValue::ExternalLinkage); + } + else { + if (!VD || !VD->hasAttr<DLLExportAttr>()) { + GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + GV->setLinkage(llvm::GlobalValue::ExternalLinkage); + } else { + GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + GV->setLinkage(llvm::GlobalValue::ExternalLinkage); + } + } + + setDSOLocal(GV); } } - setDSOLocal(GV); - + // Decay array -> ptr CFConstantStringClassRef = - llvm::ConstantExpr::getGetElementPtr(Ty, GV, Zeros); + llvm::ConstantExpr::getGetElementPtr(Ty, C, Zeros); } QualType CFTy = getContext().getCFConstantStringType(); @@ -4185,7 +4196,11 @@ if (getTriple().isOSBinFormatMachO()) GV->setSection(isUTF16 ? "__TEXT,__ustring" : "__TEXT,__cstring,cstring_literals"); - + // Make sure the literal ends up in .rodata to allow for safe ICF and for + // the static linker to adjust permissions to read-only later on. + else if (getTriple().isOSBinFormatELF()) + GV->setSection(".rodata"); + // String. llvm::Constant *Str = llvm::ConstantExpr::getGetElementPtr(GV->getValueType(), GV, Zeros);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits