diff options
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 19 | ||||
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 16 | ||||
-rw-r--r-- | 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<ParenExpr>(Arg)) - Arg = PE->getSubExpr(); - else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg)) - Arg = CE->getSubExpr(); - else - break; - } - - const StringLiteral *Literal = cast<StringLiteral>(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<ParenExpr>(Arg)) + Arg = PE->getSubExpr(); + else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg)) + Arg = CE->getSubExpr(); + else + break; + } + + const StringLiteral *Literal = cast<StringLiteral>(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<ParenExpr>(Init); - return CheckAddressConstantExpression(PE->getSubExpr()); - } + case Expr::ParenExprClass: + return CheckAddressConstantExpression(cast<ParenExpr>(Init)->getSubExpr()); case Expr::StringLiteralClass: case Expr::ObjCStringLiteralClass: return false; + case Expr::CallExprClass: + // __builtin___CFStringMakeConstantString is a valid constant l-value. + if (cast<CallExpr>(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<UnaryOperator>(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"); + + |