Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -1396,6 +1396,14 @@ S.LangOpts.GNUMode).isInvalid(); } +/// Set NumElements to the max size that an array of ElementType can be, +/// using MaxBits addressing. +static void getMaxArraySize(ASTContext &Context, QualType ElementType, + unsigned MaxBits, llvm::APSInt &NumElements) { + uint64_t ElementSize = Context.getTypeSizeInChars(ElementType).getQuantity(); + llvm::APInt ElementSizeInt(MaxBits, ElementSize); + NumElements = llvm::APInt::getAllOnesValue(MaxBits).udiv(ElementSizeInt); +} /// \brief Build an array type. /// @@ -1549,10 +1557,14 @@ // Is the array too large? unsigned ActiveSizeBits = ConstantArrayType::getNumAddressingBits(Context, T, ConstVal); - if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) + if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) { Diag(ArraySize->getLocStart(), diag::err_array_too_large) << ConstVal.toString(10) << ArraySize->getSourceRange(); + // Set array size to largest allowable size. + getMaxArraySize(Context, T, ConstantArrayType::getMaxSizeBits(Context), + ConstVal); + } } T = Context.getConstantArrayType(T, ConstVal, ASM, Quals); Index: test/Sema/offsetof-64.c =================================================================== --- test/Sema/offsetof-64.c +++ test/Sema/offsetof-64.c @@ -1,15 +1,20 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -// expected-no-diagnostics // PR15216 // Don't crash when taking computing the offset of structs with large arrays. const unsigned long Size = (1l << 62); -struct Chunk { +struct Chunk1 { char padding[Size]; char more_padding[1][Size]; char data; }; -int test1 = __builtin_offsetof(struct Chunk, data); +int test1 = __builtin_offsetof(struct Chunk1, data); +struct Chunk2 { + char padding[Size][Size][Size]; // expected-error 2{{array is too large}} + char data; +}; + +int test2 = __builtin_offsetof(struct Chunk2, data);