Hi rsmith,
clang still doesn't emit the right llvm code when initializing multi-D arrays
it seems.
For e.g. the following code would still crash for me on Windows 7, 64 bit:
auto f4 = new int[100][200][300]{{{1,2,3}, {4, 5, 6}}, {{10, 20, 30}}};
It seems that the final new loop that iterates through each outermost array and
memsets it to zero gets confused with its final ptr arithmetic.
This patch ensures that it converts the pointer to the allocated type (int
[200][300]) before incrementing it (instead of using the base type: 'int').
Thoughts?
http://llvm-reviews.chandlerc.com/D2398
Files:
lib/CodeGen/CGExprCXX.cpp
Index: lib/CodeGen/CGExprCXX.cpp
===================================================================
--- lib/CodeGen/CGExprCXX.cpp
+++ lib/CodeGen/CGExprCXX.cpp
@@ -864,9 +864,18 @@
cleanupDominator->eraseFromParent();
}
- // Advance to the next element.
- llvm::Value *nextPtr = Builder.CreateConstGEP1_32(curPtr, 1, "array.next");
+ // Advance to the next element by adjusting the pointer type as necessary.
+ // For new int[10][20][30], alloc type is int[20][30], base type is 'int'.
+ QualType AllocType = E->getAllocatedType();
+ llvm::Type *AllocPtrTy = ConvertTypeForMem(AllocType)->getPointerTo(
+ curPtr->getType()->getPointerAddressSpace());
+ llvm::Value *curPtrAllocTy = Builder.CreateBitCast(curPtr, AllocPtrTy);
+ llvm::Value *nextPtrAllocTy =
+ Builder.CreateConstGEP1_32(curPtrAllocTy, 1, "array.next");
+ // Cast it back to the base type so that we can compare it to the endPtr.
+ llvm::Value *nextPtr =
+ Builder.CreateBitCast(nextPtrAllocTy, endPtr->getType());
// Check whether we've gotten to the end of the array and, if so,
// exit the loop.
llvm::Value *isEnd = Builder.CreateICmpEQ(nextPtr, endPtr, "array.atend");
Index: lib/CodeGen/CGExprCXX.cpp
===================================================================
--- lib/CodeGen/CGExprCXX.cpp
+++ lib/CodeGen/CGExprCXX.cpp
@@ -864,9 +864,18 @@
cleanupDominator->eraseFromParent();
}
- // Advance to the next element.
- llvm::Value *nextPtr = Builder.CreateConstGEP1_32(curPtr, 1, "array.next");
+ // Advance to the next element by adjusting the pointer type as necessary.
+ // For new int[10][20][30], alloc type is int[20][30], base type is 'int'.
+ QualType AllocType = E->getAllocatedType();
+ llvm::Type *AllocPtrTy = ConvertTypeForMem(AllocType)->getPointerTo(
+ curPtr->getType()->getPointerAddressSpace());
+ llvm::Value *curPtrAllocTy = Builder.CreateBitCast(curPtr, AllocPtrTy);
+ llvm::Value *nextPtrAllocTy =
+ Builder.CreateConstGEP1_32(curPtrAllocTy, 1, "array.next");
+ // Cast it back to the base type so that we can compare it to the endPtr.
+ llvm::Value *nextPtr =
+ Builder.CreateBitCast(nextPtrAllocTy, endPtr->getType());
// Check whether we've gotten to the end of the array and, if so,
// exit the loop.
llvm::Value *isEnd = Builder.CreateICmpEQ(nextPtr, endPtr, "array.atend");
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits