Modified to generalize the patch to handle explicit initialization of array
of any dimensions successfully. The assertion failure mentioned before is
resolved with this patch and regression is verified to be successful without
any additional failures.
Please let me know of this patch is good to commit ?
Hi rsmith, eli.friedman, dblaikie,
http://llvm-reviews.chandlerc.com/D1986
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1986?vs=5056&id=5574#toc
Files:
llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp
llvm/tools/clang/test/CodeGenCXX/cxx0x-initializer-placement-new-array.cpp
Index: llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
+++ llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
@@ -1566,6 +1566,14 @@
/// to ItaniumCXXABI.cpp together with all the references to VTT.
llvm::Value *GetVTTParameter(GlobalDecl GD, bool ForVirtualBase,
bool Delegating);
+ void CheckArrayInitializer(CodeGenFunction* CGF, const InitListExpr* Init,
+ QualType ElemType, llvm::Value *NewPtr, llvm::AllocaInst* endOfInit,
+ unsigned &Index);
+ void CheckSubExprInitializer(CodeGenFunction* CGF, const Expr* expr,
+ QualType ElemType, llvm::Value *NewPtr, llvm::AllocaInst* endOfInit,
+ unsigned &Index);
+ void CheckExplicitInitializer(CodeGenFunction* CGF, const InitListExpr*
Init,
+ QualType ElemType, llvm::Value *NewPtr, llvm::AllocaInst* endOfInit);
void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
CXXCtorType CtorType,
Index: llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp
===================================================================
--- llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp
+++ llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp
@@ -783,14 +783,7 @@
cleanup = EHStack.stable_begin();
}
- for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) {
- // Tell the cleanup that it needs to destroy up to this
- // element. TODO: some of these stores can be trivially
- // observed to be unnecessary.
- if (endOfInit) Builder.CreateStore(explicitPtr, endOfInit);
- StoreAnyExprIntoOneUnit(*this, ILE->getInit(i), elementType,
explicitPtr);
- explicitPtr =Builder.CreateConstGEP1_32(explicitPtr, 1,
"array.exp.next");
- }
+ CheckExplicitInitializer(this, ILE, elementType, explicitPtr, endOfInit);
// The remaining elements are filled with the array filler expression.
Init = ILE->getArrayFiller();
@@ -1857,3 +1850,48 @@
EmitInitializerForField(*CurField, LV, *i, ArrayIndexes);
}
}
+
+void CodeGenFunction::CheckArrayInitializer(CodeGenFunction* CGF,
+ const InitListExpr* ILE, QualType ElemType,
+ llvm::Value *NewPtr,
+ llvm::AllocaInst* endOfInit,
+ unsigned &Index) {
+ while(Index < ILE->getNumInits()) {
+ CheckSubExprInitializer(CGF, ILE->getInit(Index), ElemType, NewPtr,
endOfInit, Index);
+ }
+}
+
+void CodeGenFunction::CheckSubExprInitializer(CodeGenFunction* CGF,
+ const Expr* expr, QualType ElemType,
+ llvm::Value *NewPtr,
+ llvm::AllocaInst* endOfInit,
+ unsigned &Index) {
+ if (const InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
+ if (!ElemType->isRecordType() || ElemType->isAggregateType()) {
+ CheckExplicitInitializer(CGF, SubInitList, ElemType, NewPtr, endOfInit);
+ ++Index; ///ROW increment
+ return;
+ }
+ }
+
+ if(ElemType->isLiteralType(getContext())
+ || ElemType->isObjectType()
+ || ElemType->isComplexType()
+ || ElemType->isScalarType()
+ || ElemType->isAggregateType() ) {
+ if (endOfInit != 0) Builder.CreateStore(NewPtr, endOfInit);
+ StoreAnyExprIntoOneUnit(*CGF, expr, ElemType, NewPtr);
+ NewPtr =Builder.CreateConstGEP1_32(NewPtr, 1, "array.exp.next");
+ Index++;
+ return;
+ }
+
+}
+
+void CodeGenFunction::CheckExplicitInitializer(CodeGenFunction* CGF,
+ const InitListExpr* Init, QualType ElemType,
+ llvm::Value *NewPtr, llvm::AllocaInst* endOfInit) {
+ unsigned Index = 0;
+ CheckArrayInitializer(CGF, Init, ElemType, NewPtr, endOfInit, Index);
+
+}
Index:
llvm/tools/clang/test/CodeGenCXX/cxx0x-initializer-placement-new-array.cpp
===================================================================
--- llvm/tools/clang/test/CodeGenCXX/cxx0x-initializer-placement-new-array.cpp
+++ llvm/tools/clang/test/CodeGenCXX/cxx0x-initializer-placement-new-array.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -emit-llvm -o - %s |
FileCheck %s
+
+typedef __SIZE_TYPE__ size_t;
+void* operator new[](size_t, void *p) { return p; }
+template <typename T = size_t>
+void f ()
+{
+ size_t coord [2][2];
+ new (&coord) size_t [2][2]
+ {
+ {0,0},
+ {0,0},
+ };
+ // CHECK: %coord = alloca [2 x [2 x i32]], align 4
+ // CHECK: %0 = bitcast [2 x [2 x i32]]* %coord to i8*
+ // CHECK: %1 = bitcast i8* %0 to i32*
+ // CHECK: %array.end = getelementptr inbounds i32* %1, i32 4
+ // CHECK-NEXT: store i32 0, i32* %1, align 4
+ // CHECK-NEXT: %array.exp.next = getelementptr i32* %1, i32 1
+ // CHECK-NEXT: store i32 0, i32* %1, align 4
+ // CHECK-NEXT: %array.exp.next1 = getelementptr i32* %1, i32 1
+ // CHECK-NEXT: store i32 0, i32* %1, align 4
+ // CHECK-NEXT: %array.exp.next2 = getelementptr i32* %1, i32 1
+ // CHECK-NEXT: store i32 0, i32* %1, align 4
+ // CHECK-NEXT: %array.exp.next3 = getelementptr i32* %1, i32 1
+
+}
+
+int main ()
+{
+ f<>();
+}
Index: llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
+++ llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
@@ -1566,6 +1566,14 @@
/// to ItaniumCXXABI.cpp together with all the references to VTT.
llvm::Value *GetVTTParameter(GlobalDecl GD, bool ForVirtualBase,
bool Delegating);
+ void CheckArrayInitializer(CodeGenFunction* CGF, const InitListExpr* Init,
+ QualType ElemType, llvm::Value *NewPtr, llvm::AllocaInst* endOfInit,
+ unsigned &Index);
+ void CheckSubExprInitializer(CodeGenFunction* CGF, const Expr* expr,
+ QualType ElemType, llvm::Value *NewPtr, llvm::AllocaInst* endOfInit,
+ unsigned &Index);
+ void CheckExplicitInitializer(CodeGenFunction* CGF, const InitListExpr* Init,
+ QualType ElemType, llvm::Value *NewPtr, llvm::AllocaInst* endOfInit);
void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
CXXCtorType CtorType,
Index: llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp
===================================================================
--- llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp
+++ llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp
@@ -783,14 +783,7 @@
cleanup = EHStack.stable_begin();
}
- for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) {
- // Tell the cleanup that it needs to destroy up to this
- // element. TODO: some of these stores can be trivially
- // observed to be unnecessary.
- if (endOfInit) Builder.CreateStore(explicitPtr, endOfInit);
- StoreAnyExprIntoOneUnit(*this, ILE->getInit(i), elementType, explicitPtr);
- explicitPtr =Builder.CreateConstGEP1_32(explicitPtr, 1, "array.exp.next");
- }
+ CheckExplicitInitializer(this, ILE, elementType, explicitPtr, endOfInit);
// The remaining elements are filled with the array filler expression.
Init = ILE->getArrayFiller();
@@ -1857,3 +1850,48 @@
EmitInitializerForField(*CurField, LV, *i, ArrayIndexes);
}
}
+
+void CodeGenFunction::CheckArrayInitializer(CodeGenFunction* CGF,
+ const InitListExpr* ILE, QualType ElemType,
+ llvm::Value *NewPtr,
+ llvm::AllocaInst* endOfInit,
+ unsigned &Index) {
+ while(Index < ILE->getNumInits()) {
+ CheckSubExprInitializer(CGF, ILE->getInit(Index), ElemType, NewPtr, endOfInit, Index);
+ }
+}
+
+void CodeGenFunction::CheckSubExprInitializer(CodeGenFunction* CGF,
+ const Expr* expr, QualType ElemType,
+ llvm::Value *NewPtr,
+ llvm::AllocaInst* endOfInit,
+ unsigned &Index) {
+ if (const InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
+ if (!ElemType->isRecordType() || ElemType->isAggregateType()) {
+ CheckExplicitInitializer(CGF, SubInitList, ElemType, NewPtr, endOfInit);
+ ++Index; ///ROW increment
+ return;
+ }
+ }
+
+ if(ElemType->isLiteralType(getContext())
+ || ElemType->isObjectType()
+ || ElemType->isComplexType()
+ || ElemType->isScalarType()
+ || ElemType->isAggregateType() ) {
+ if (endOfInit != 0) Builder.CreateStore(NewPtr, endOfInit);
+ StoreAnyExprIntoOneUnit(*CGF, expr, ElemType, NewPtr);
+ NewPtr =Builder.CreateConstGEP1_32(NewPtr, 1, "array.exp.next");
+ Index++;
+ return;
+ }
+
+}
+
+void CodeGenFunction::CheckExplicitInitializer(CodeGenFunction* CGF,
+ const InitListExpr* Init, QualType ElemType,
+ llvm::Value *NewPtr, llvm::AllocaInst* endOfInit) {
+ unsigned Index = 0;
+ CheckArrayInitializer(CGF, Init, ElemType, NewPtr, endOfInit, Index);
+
+}
Index: llvm/tools/clang/test/CodeGenCXX/cxx0x-initializer-placement-new-array.cpp
===================================================================
--- llvm/tools/clang/test/CodeGenCXX/cxx0x-initializer-placement-new-array.cpp
+++ llvm/tools/clang/test/CodeGenCXX/cxx0x-initializer-placement-new-array.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s
+
+typedef __SIZE_TYPE__ size_t;
+void* operator new[](size_t, void *p) { return p; }
+template <typename T = size_t>
+void f ()
+{
+ size_t coord [2][2];
+ new (&coord) size_t [2][2]
+ {
+ {0,0},
+ {0,0},
+ };
+ // CHECK: %coord = alloca [2 x [2 x i32]], align 4
+ // CHECK: %0 = bitcast [2 x [2 x i32]]* %coord to i8*
+ // CHECK: %1 = bitcast i8* %0 to i32*
+ // CHECK: %array.end = getelementptr inbounds i32* %1, i32 4
+ // CHECK-NEXT: store i32 0, i32* %1, align 4
+ // CHECK-NEXT: %array.exp.next = getelementptr i32* %1, i32 1
+ // CHECK-NEXT: store i32 0, i32* %1, align 4
+ // CHECK-NEXT: %array.exp.next1 = getelementptr i32* %1, i32 1
+ // CHECK-NEXT: store i32 0, i32* %1, align 4
+ // CHECK-NEXT: %array.exp.next2 = getelementptr i32* %1, i32 1
+ // CHECK-NEXT: store i32 0, i32* %1, align 4
+ // CHECK-NEXT: %array.exp.next3 = getelementptr i32* %1, i32 1
+
+}
+
+int main ()
+{
+ f<>();
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits