diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2014-10-09 08:45:04 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2014-10-09 08:45:04 +0000 |
commit | ec4747802ae99edea83b3199df52be5c1f43f048 (patch) | |
tree | 0ab9f13bad64139844298485d5f2e3a62559720d /clang/lib/CodeGen | |
parent | a9ee5c06f4c7d6e03aafe2b730f505f901694987 (diff) | |
download | bcm5719-llvm-ec4747802ae99edea83b3199df52be5c1f43f048.tar.gz bcm5719-llvm-ec4747802ae99edea83b3199df52be5c1f43f048.zip |
Fix for bug http://llvm.org/PR17427.
Assertion failed: "Computed __func__ length differs from type!"
Reworked PredefinedExpr representation with internal StringLiteral field for function declaration.
Differential Revision: http://reviews.llvm.org/D5365
llvm-svn: 219393
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 91 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 3 |
3 files changed, 17 insertions, 82 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 518d81bd361..19f6e949990 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -24,6 +24,7 @@ #include "clang/AST/Attr.h" #include "clang/Frontend/CodeGenOptions.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" @@ -2069,86 +2070,18 @@ LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) { E->getType()); } -static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source, - SmallString<32>& Target) { - Target.resize(CharByteWidth * (Source.size() + 1)); - char *ResultPtr = &Target[0]; - const UTF8 *ErrorPtr; - bool success = ConvertUTF8toWide(CharByteWidth, Source, ResultPtr, ErrorPtr); - (void)success; - assert(success); - Target.resize(ResultPtr - &Target[0]); -} - LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) { - switch (E->getIdentType()) { - default: - return EmitUnsupportedLValue(E, "predefined expression"); - - case PredefinedExpr::Func: - case PredefinedExpr::Function: - case PredefinedExpr::LFunction: - case PredefinedExpr::FuncDName: - case PredefinedExpr::FuncSig: - case PredefinedExpr::PrettyFunction: { - PredefinedExpr::IdentType IdentType = E->getIdentType(); - std::string GVName; - - // FIXME: We should use the string literal mangling for the Microsoft C++ - // ABI so that strings get merged. - switch (IdentType) { - default: llvm_unreachable("Invalid type"); - case PredefinedExpr::Func: GVName = "__func__."; break; - case PredefinedExpr::Function: GVName = "__FUNCTION__."; break; - case PredefinedExpr::FuncDName: GVName = "__FUNCDNAME__."; break; - case PredefinedExpr::FuncSig: GVName = "__FUNCSIG__."; break; - case PredefinedExpr::LFunction: GVName = "L__FUNCTION__."; break; - case PredefinedExpr::PrettyFunction: GVName = "__PRETTY_FUNCTION__."; break; - } - - StringRef FnName = CurFn->getName(); - if (FnName.startswith("\01")) - FnName = FnName.substr(1); - GVName += FnName; - - // If this is outside of a function use the top level decl. - const Decl *CurDecl = CurCodeDecl; - if (!CurDecl || isa<VarDecl>(CurDecl)) - CurDecl = getContext().getTranslationUnitDecl(); - - const Type *ElemType = E->getType()->getArrayElementTypeNoTypeQual(); - std::string FunctionName; - if (isa<BlockDecl>(CurDecl)) { - // Blocks use the mangled function name. - // FIXME: ComputeName should handle blocks. - FunctionName = FnName.str(); - } else if (isa<CapturedDecl>(CurDecl)) { - // For a captured statement, the function name is its enclosing - // function name not the one compiler generated. - FunctionName = PredefinedExpr::ComputeName(IdentType, CurDecl); - } else { - FunctionName = PredefinedExpr::ComputeName(IdentType, CurDecl); - assert(cast<ConstantArrayType>(E->getType())->getSize() - 1 == - FunctionName.size() && - "Computed __func__ length differs from type!"); - } - - llvm::Constant *C; - if (ElemType->isWideCharType()) { - SmallString<32> RawChars; - ConvertUTF8ToWideString( - getContext().getTypeSizeInChars(ElemType).getQuantity(), FunctionName, - RawChars); - StringLiteral *SL = StringLiteral::Create( - getContext(), RawChars, StringLiteral::Wide, - /*Pascal = */ false, E->getType(), E->getLocation()); - C = CGM.GetAddrOfConstantStringFromLiteral(SL); - } else { - C = CGM.GetAddrOfConstantCString(FunctionName, GVName.c_str(), 1); - } - return MakeAddrLValue(C, E->getType()); - } - } + auto SL = E->getFunctionName(); + assert(SL != nullptr && "No StringLiteral name in PredefinedExpr"); + StringRef FnName = CurFn->getName(); + if (FnName.startswith("\01")) + FnName = FnName.substr(1); + StringRef NameItems[] = { + PredefinedExpr::getIdentTypeName(E->getIdentType()), FnName}; + std::string GVName = llvm::join(NameItems, NameItems + 2, "."); + + auto C = CGM.GetAddrOfConstantStringFromLiteral(SL, GVName); + return MakeAddrLValue(C, E->getType()); } /// Emit a type description suitable for use by a runtime sanitizer library. The diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index a7a65b88c91..5d314f525cd 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2729,7 +2729,8 @@ GenerateStringLiteral(llvm::Constant *C, llvm::GlobalValue::LinkageTypes LT, /// GetAddrOfConstantStringFromLiteral - Return a pointer to a /// constant array for the given string literal. llvm::GlobalVariable * -CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) { +CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S, + StringRef Name) { auto Alignment = getContext().getAlignOfGlobalVarInChars(S->getType()).getQuantity(); @@ -2761,7 +2762,7 @@ CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) { GlobalVariableName = MangledNameBuffer; } else { LT = llvm::GlobalValue::PrivateLinkage; - GlobalVariableName = ".str"; + GlobalVariableName = Name; } auto GV = GenerateStringLiteral(C, LT, *this, GlobalVariableName, Alignment); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 955f665f86c..665a7a589f8 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -785,7 +785,8 @@ public: /// Return a pointer to a constant array for the given string literal. llvm::GlobalVariable * - GetAddrOfConstantStringFromLiteral(const StringLiteral *S); + GetAddrOfConstantStringFromLiteral(const StringLiteral *S, + StringRef Name = ".str"); /// Return a pointer to a constant array for the given ObjCEncodeExpr node. llvm::GlobalVariable * |