[PATCH] When an array is created that is too large, lower its size to the maximum allowable size.
Richard Trieu
rtrieu at google.com
Wed May 15 16:58:25 PDT 2013
After an "array is too large" error, set the array size to the maximum allowable size. This prevents an overflow in size calculation later.
http://llvm-reviews.chandlerc.com/D800
Files:
lib/Sema/SemaType.cpp
test/Sema/offsetof-64.c
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);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D800.1.patch
Type: text/x-patch
Size: 2260 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130515/1c50356d/attachment.bin>
More information about the cfe-commits
mailing list