diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -391,7 +391,7 @@ static llvm::Constant * EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType, - llvm::Type *CommonElementType, unsigned ArrayBound, + llvm::Type *CommonElementType, uint64_t ArrayBound, SmallVectorImpl &Elements, llvm::Constant *Filler); @@ -945,11 +945,11 @@ static llvm::Constant * EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType, - llvm::Type *CommonElementType, unsigned ArrayBound, + llvm::Type *CommonElementType, uint64_t ArrayBound, SmallVectorImpl &Elements, llvm::Constant *Filler) { // Figure out how long the initial prefix of non-zero elements is. - unsigned NonzeroLength = ArrayBound; + uint64_t NonzeroLength = ArrayBound; if (Elements.size() < NonzeroLength && Filler->isNullValue()) NonzeroLength = Elements.size(); if (NonzeroLength == Elements.size()) { @@ -1223,11 +1223,11 @@ auto *CAT = CGM.getContext().getAsConstantArrayType(ILE->getType()); assert(CAT && "can't emit array init for non-constant-bound array"); unsigned NumInitElements = ILE->getNumInits(); - unsigned NumElements = CAT->getSize().getZExtValue(); + uint64_t NumElements = CAT->getSize().getZExtValue(); // Initialising an array requires us to automatically // initialise any elements that have not been initialised explicitly - unsigned NumInitableElts = std::min(NumInitElements, NumElements); + uint64_t NumInitableElts = std::min((uint64_t)NumInitElements, NumElements); QualType EltType = CAT->getElementType(); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -836,8 +836,8 @@ QualType ElementType; InitializedEntity ElementEntity = Entity; - unsigned NumInits = ILE->getNumInits(); - unsigned NumElements = NumInits; + uint64_t NumInits = ILE->getNumInits(); + uint64_t NumElements = NumInits; if (const ArrayType *AType = SemaRef.Context.getAsArrayType(ILE->getType())) { ElementType = AType->getElementType(); if (const auto *CAType = dyn_cast(AType)) @@ -857,7 +857,7 @@ ElementType = ILE->getType(); bool SkipEmptyInitChecks = false; - for (unsigned Init = 0; Init != NumElements; ++Init) { + for (uint64_t Init = 0; Init != NumElements; ++Init) { if (hadError) return; diff --git a/clang/test/CodeGen/big-array-init.c b/clang/test/CodeGen/big-array-init.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/big-array-init.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -O0 -triple x86_64-unknown-linux-gnu -S -emit-llvm -o - | FileCheck %s +/* checks for #57353, arrays that are larger than 2^32 were emitting wrongly. */ + +// CHECK: @bad_char = global <{ i8, [4294967295 x i8] }> <{ i8 1, [4294967295 x i8] zeroinitializer }>, align 16 +char bad_char[4294967296] = {1}; +// CHECK: @bad_int = global <{ i32, [1073741823 x i32] }> <{ i32 1, [1073741823 x i32] zeroinitializer }>, align 16 +int bad_int[1073741824] = {1}; diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -3164,7 +3164,7 @@ const Constant *BaseCV, uint64_t Offset, AsmPrinter::AliasMapTy *AliasList) { // Print the fields in successive locations. Pad to align if needed! - unsigned Size = DL.getTypeAllocSize(CS->getType()); + uint64_t Size = DL.getTypeAllocSize(CS->getType()); const StructLayout *Layout = DL.getStructLayout(CS->getType()); uint64_t SizeSoFar = 0; for (unsigned I = 0, E = CS->getNumOperands(); I != E; ++I) { @@ -3391,7 +3391,7 @@ uint64_t Offset, AsmPrinter::AliasMapTy *AliasList) { emitGlobalAliasInline(AP, Offset, AliasList); - uint64_t Size = DL.getTypeAllocSize(CV->getType()); + unsigned Size = DL.getTypeAllocSize(CV->getType()); // Globals with sub-elements such as combinations of arrays and structs // are handled recursively by emitGlobalConstantImpl. Keep track of the