From f6c717c3dca839dcd189b4a6fa46c8fe7a8bec1d Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 23 Jan 2009 16:54:12 +0000 Subject: [PATCH] Properly manage the bit-widths of APInts/APSInts in array initialization. Fixes PR clang/3377 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62851 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaInit.cpp | 19 ++++++++++++------- test/Sema/designated-initializers.c | 3 +++ test/Sema/init.c | 4 +++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index e855840ea5..ba8312b7b5 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -142,8 +142,9 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList, CheckStructUnionTypes(IList, DeclType, RD->field_begin(), SubobjectIsDesignatorContext, Index); } else if (DeclType->isArrayType()) { - // FIXME: Is 32 always large enough for array indices? - llvm::APSInt Zero(32, false); + llvm::APSInt Zero( + SemaRef->Context.getTypeSize(SemaRef->Context.getSizeType()), + false); CheckArrayType(IList, DeclType, Zero, SubobjectIsDesignatorContext, Index); } else @@ -269,15 +270,13 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, return; } - // FIXME: Will 32 bits always be enough? I hope so. - const unsigned ArraySizeBits = 32; - // We might know the maximum number of elements in advance. - llvm::APSInt maxElements(ArraySizeBits, 0); + llvm::APSInt maxElements(elementIndex.getBitWidth(), 0); bool maxElementsKnown = false; if (const ConstantArrayType *CAT = SemaRef->Context.getAsConstantArrayType(DeclType)) { maxElements = CAT->getSize(); + elementIndex.extOrTrunc(maxElements.getBitWidth()); maxElementsKnown = true; } @@ -300,6 +299,11 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, continue; } + if (elementIndex.getBitWidth() > maxElements.getBitWidth()) + maxElements.extend(elementIndex.getBitWidth()); + else if (elementIndex.getBitWidth() < maxElements.getBitWidth()) + elementIndex.extend(maxElements.getBitWidth()); + // If the array is of incomplete type, keep track of the number of // elements in the initializer. if (!maxElementsKnown && elementIndex > maxElements) @@ -325,7 +329,7 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, if (DeclType->isIncompleteArrayType()) { // If this is an incomplete array type, the actual type needs to // be calculated here. - llvm::APInt Zero(ArraySizeBits, 0); + llvm::APInt Zero(maxElements.getBitWidth(), 0); if (maxElements == Zero) { // Sizing an array implicitly to zero is not allowed by ISO C, // but is supported by GNU. @@ -563,6 +567,7 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList, if (isa(AT)) { llvm::APSInt MaxElements(cast(AT)->getSize(), false); + DesignatedIndex.extOrTrunc(MaxElements.getBitWidth()); if (DesignatedIndex >= MaxElements) { SemaRef->Diag(IndexExpr->getSourceRange().getBegin(), diag::err_array_designator_too_large) diff --git a/test/Sema/designated-initializers.c b/test/Sema/designated-initializers.c index cc2c3468ed..8e5bd43b6c 100644 --- a/test/Sema/designated-initializers.c +++ b/test/Sema/designated-initializers.c @@ -112,3 +112,6 @@ struct disklabel_ops { struct disklabel_ops disklabel64_ops = { .labelsize = sizeof(struct disklabel_ops) }; + +// PR clang/3377 +int bitwidth[] = { [(long long int)1] = 5, [(short int)2] = 2 }; diff --git a/test/Sema/init.c b/test/Sema/init.c index abfab37b43..edaaf64b8b 100644 --- a/test/Sema/init.c +++ b/test/Sema/init.c @@ -2,7 +2,9 @@ typedef void (* fp)(void); void foo(void); -fp a[1] = { foo }; + +// PR clang/3377 +fp a[(short int)1] = { foo }; int myArray[5] = {1, 2, 3, 4, 5}; int *myPointer2 = myArray; -- 2.40.0