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
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index fc7cc02..29d77b6 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -48,23 +48,8 @@
       
   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 50f0d12..69abbcc 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -617,6 +617,24 @@
         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 125d91c..1b6ff87 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -872,13 +872,21 @@
     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 ef42d06..7d7edec 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");
+
+