зеркало из https://github.com/microsoft/clang.git
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
This commit is contained in:
Родитель
be109b3e76
Коммит
f6c717c3dc
|
@ -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<ConstantArrayType>(AT)) {
|
||||
llvm::APSInt MaxElements(cast<ConstantArrayType>(AT)->getSize(), false);
|
||||
DesignatedIndex.extOrTrunc(MaxElements.getBitWidth());
|
||||
if (DesignatedIndex >= MaxElements) {
|
||||
SemaRef->Diag(IndexExpr->getSourceRange().getBegin(),
|
||||
diag::err_array_designator_too_large)
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче