From 506ff88f44562df267b6a06608ab841b76df2a2b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 6 Oct 2008 07:26:43 +0000 Subject: [PATCH] Make sema and codegen allow __builtin___CFStringMakeConstantString as a valid constant lvalue. Implement this in codegen by moving the code out of CGBuiltin into EmitConstantExpr. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57163 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBuiltin.cpp | 19 ++----------------- lib/CodeGen/CGExprConstant.cpp | 18 ++++++++++++++++++ lib/Sema/SemaDecl.cpp | 16 ++++++++++++---- test/CodeGen/cfstring.c | 5 +++++ 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index fc7cc02710..29d77b6e82 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -48,23 +48,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { switch (BuiltinID) { default: break; // Handle intrinsics and libm functions below. - case Builtin::BI__builtin___CFStringMakeConstantString: { - const Expr *Arg = E->getArg(0); - - while (1) { - if (const ParenExpr *PE = dyn_cast(Arg)) - Arg = PE->getSubExpr(); - else if (const ImplicitCastExpr *CE = dyn_cast(Arg)) - Arg = CE->getSubExpr(); - else - break; - } - - const StringLiteral *Literal = cast(Arg); - std::string S(Literal->getStrData(), Literal->getByteLength()); - - return RValue::get(CGM.GetAddrOfConstantCFString(S)); - } + case Builtin::BI__builtin___CFStringMakeConstantString: + return RValue::get(CGM.EmitConstantExpr(E, 0)); case Builtin::BI__builtin_stdarg_start: case Builtin::BI__builtin_va_start: case Builtin::BI__builtin_va_end: { diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 50f0d12240..69abbcc984 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -617,6 +617,24 @@ public: return llvm::ConstantFP::get(Result.getFloat()); } + // Handle __builtin___CFStringMakeConstantString. + if (E->isBuiltinCall() ==Builtin::BI__builtin___CFStringMakeConstantString){ + const Expr *Arg = E->getArg(0); + + while (1) { + if (const ParenExpr *PE = dyn_cast(Arg)) + Arg = PE->getSubExpr(); + else if (const ImplicitCastExpr *CE = dyn_cast(Arg)) + Arg = CE->getSubExpr(); + else + break; + } + + const StringLiteral *Literal = cast(Arg); + std::string S(Literal->getStrData(), Literal->getByteLength()); + return CGM.GetAddrOfConstantCFString(S); + } + CGM.ErrorUnsupported(E, "constant call expression"); return llvm::Constant::getNullValue(ConvertType(E->getType())); } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 125d91cdba..1b6ff878f5 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -872,13 +872,21 @@ bool Sema::CheckAddressConstantExpression(const Expr* Init) { Diag(Init->getExprLoc(), diag::err_init_element_not_constant, Init->getSourceRange()); return true; - case Expr::ParenExprClass: { - const ParenExpr* PE = cast(Init); - return CheckAddressConstantExpression(PE->getSubExpr()); - } + case Expr::ParenExprClass: + return CheckAddressConstantExpression(cast(Init)->getSubExpr()); case Expr::StringLiteralClass: case Expr::ObjCStringLiteralClass: return false; + case Expr::CallExprClass: + // __builtin___CFStringMakeConstantString is a valid constant l-value. + if (cast(Init)->isBuiltinCall() == + Builtin::BI__builtin___CFStringMakeConstantString) + return false; + + Diag(Init->getExprLoc(), + diag::err_init_element_not_constant, Init->getSourceRange()); + return true; + case Expr::UnaryOperatorClass: { const UnaryOperator *Exp = cast(Init); diff --git a/test/CodeGen/cfstring.c b/test/CodeGen/cfstring.c index ef42d06283..7d7edeca3c 100644 --- a/test/CodeGen/cfstring.c +++ b/test/CodeGen/cfstring.c @@ -4,3 +4,8 @@ void f() { CFSTR("Hello, World!"); } + +// rdar://6248329 +void *G = CFSTR("yo joe"); + + -- 2.40.0