]> granicus.if.org Git - clang/commitdiff
Fix the emission of expressions like char a[10] = "asdf"; previously,
authorEli Friedman <eli.friedman@gmail.com>
Mon, 19 May 2008 17:51:16 +0000 (17:51 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Mon, 19 May 2008 17:51:16 +0000 (17:51 +0000)
they were causing bad code to be emitted.  There are two fixes here: one
makes sure we emit a string that is long enough, and one makes sure we
properly handle string initialization in init lists.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51259 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
test/CodeGen/string-init.c [new file with mode: 0644]

index 840ed4314f6d1f091bd5271ff585a1493acc8cbd..8d36c8e26d30be1ca475fe384f660491f353936e 100644 (file)
@@ -395,9 +395,16 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
 
 LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
   assert(!E->isWide() && "FIXME: Wide strings not supported yet!");
+  // Get the string data
   const char *StrData = E->getStrData();
   unsigned Len = E->getByteLength();
   std::string StringLiteral(StrData, StrData+Len);
+
+  // Resize the string to the right size
+  const ConstantArrayType *CAT = E->getType()->getAsConstantArrayType();
+  uint64_t RealLen = CAT->getSize().getZExtValue();
+  StringLiteral.resize(RealLen, '\0');
+
   return LValue::MakeAddr(CGM.GetAddrOfConstantString(StringLiteral));
 }
 
index 6b68705af7329d99516a078f021a2d3920743034..c7c250ee7beb8e1ce060c5618d2f38c7faa36008 100644 (file)
@@ -53,7 +53,7 @@ public:
   void EmitAggregateClear(llvm::Value *DestPtr, QualType Ty);
 
   void EmitNonConstInit(InitListExpr *E);
-  
+
   //===--------------------------------------------------------------------===//
   //                            Visitor Methods
   //===--------------------------------------------------------------------===//
@@ -336,7 +336,6 @@ void AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) {
   }
 }
 
-
 void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
   if (E->isConstantExpr(CGF.getContext(), 0)) {
     // FIXME: call into const expr emitter so that we can emit
@@ -355,6 +354,14 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
       cast<llvm::ArrayType>(APType->getElementType());
     
     uint64_t NumInitElements = E->getNumInits();
+
+    if (E->getNumInits() > 0 &&
+        E->getType().getCanonicalType().getUnqualifiedType() == 
+          E->getInit(0)->getType().getCanonicalType().getUnqualifiedType()) {
+      EmitAggLoadOfLValue(E->getInit(0));
+      return;
+    }
+
     uint64_t NumArrayElements = AType->getNumElements();
     QualType ElementType = E->getType()->getAsArrayType()->getElementType();
     
diff --git a/test/CodeGen/string-init.c b/test/CodeGen/string-init.c
new file mode 100644 (file)
index 0000000..1d1a740
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: clang -emit-llvm %s -o - | not grep "[5 x i8]"
+// RUN: clang -emit-llvm %s -o - | not grep "store"
+
+void test(void) {
+  char a[10] = "asdf";
+  char b[10] = { "asdf" };
+}
+