Fix PR1992 by computing the right type for string literals, which
is an array type not a pointer type.  This requires updating some
diags that change and updating the code generator to handle the
proper form of strings.




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46941 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CGExprConstant.cpp b/CodeGen/CGExprConstant.cpp
index 8c319a0..5695475 100644
--- a/CodeGen/CGExprConstant.cpp
+++ b/CodeGen/CGExprConstant.cpp
@@ -205,9 +205,7 @@
       // Note that VLAs can't exist for global variables.
       // The only thing that can have array type like this is a
       // DeclRefExpr(FileVarDecl)?
-      const DeclRefExpr *DRE = cast<DeclRefExpr>(ICExpr->getSubExpr());
-      const VarDecl *VD = cast<VarDecl>(DRE->getDecl());
-      llvm::Constant *C = CGM.GetAddrOfGlobalVar(VD, false);
+      llvm::Constant *C = EmitLValue(ICExpr->getSubExpr());
       assert(isa<llvm::PointerType>(C->getType()) &&
              isa<llvm::ArrayType>(cast<llvm::PointerType>(C->getType())
                                   ->getElementType()));
@@ -232,11 +230,7 @@
   llvm::Constant *VisitStringLiteral(StringLiteral *E) {
     const char *StrData = E->getStrData();
     unsigned Len = E->getByteLength();
-    
-    // If the string has a pointer type, emit it as a global and use the pointer
-    // to the global as its value.
-    if (E->getType()->isPointerType()) 
-      return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len));
+    assert(!E->getType()->isPointerType() && "Strings are always arrays");
     
     // Otherwise this must be a string initializing an array in a static
     // initializer.  Don't emit it as the address of the string, emit the string
@@ -532,7 +526,7 @@
       // to be the only use of the variable, so we just generate it here.
       CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
       llvm::Constant* C = Visit(CLE->getInitializer());
-      C = new llvm::GlobalVariable(C->getType(), E->getType().isConstQualified(), 
+      C = new llvm::GlobalVariable(C->getType(),E->getType().isConstQualified(), 
                                    llvm::GlobalValue::InternalLinkage,
                                    C, ".compoundliteral", &CGM.getModule());
       return C;
@@ -541,8 +535,8 @@
       ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
       if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
         return CGM.GetAddrOfFunctionDecl(FD, false);
-      if (const FileVarDecl* FVD = dyn_cast<FileVarDecl>(Decl))
-        return CGM.GetAddrOfGlobalVar(FVD, false);
+      if (const VarDecl* VD = dyn_cast<VarDecl>(Decl))
+        return CGM.GetAddrOfGlobalVar(VD, false);
       // We can end up here with static block-scope variables (and others?)
       // FIXME: How do we implement block-scope variables?!
       assert(0 && "Unimplemented Decl type");
diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp
index e1aec69..ef05586 100644
--- a/CodeGen/CodeGenModule.cpp
+++ b/CodeGen/CodeGenModule.cpp
@@ -384,7 +384,7 @@
   return GV;
 }
 
-/// GenerateWritableString -- Creates storage for a string literal
+/// GenerateWritableString -- Creates storage for a string literal.
 static llvm::Constant *GenerateStringLiteral(const std::string &str, 
                                              bool constant,
                                              CodeGenModule &CGM) {
@@ -395,14 +395,11 @@
   C = new llvm::GlobalVariable(C->getType(), constant, 
                                llvm::GlobalValue::InternalLinkage,
                                C, ".str", &CGM.getModule());
-  llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
-  llvm::Constant *Zeros[] = { Zero, Zero };
-  C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
   return C;
 }
 
-/// CodeGenModule::GetAddrOfConstantString -- returns a pointer to the first 
-/// element of a character array containing the literal.
+/// CodeGenModule::GetAddrOfConstantString -- returns a pointer to the character
+/// array containing the literal.  The result is pointer to array type.
 llvm::Constant *CodeGenModule::GetAddrOfConstantString(const std::string &str) {
   // Don't share any string literals if writable-strings is turned on.
   if (Features.WritableStrings)
diff --git a/CodeGen/CodeGenModule.h b/CodeGen/CodeGenModule.h
index 7c236e0..9206088 100644
--- a/CodeGen/CodeGenModule.h
+++ b/CodeGen/CodeGenModule.h
@@ -80,6 +80,9 @@
   ///
   llvm::Function *getBuiltinLibFunction(unsigned BuiltinID);
   llvm::Constant *GetAddrOfConstantCFString(const std::string& str);
+
+  /// GetAddrOfConstantString -- returns a pointer to the character
+  /// array containing the literal.  The result is pointer to array type.
   llvm::Constant *GetAddrOfConstantString(const std::string& str);
   llvm::Function *getMemCpyFn();
   llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0,