mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +03:00
fix bugzilla 21995 Struct with size uint.max or greater causes ICE
This commit is contained in:
parent
ef02f08456
commit
c2fb0d4273
4 changed files with 23 additions and 21 deletions
|
@ -793,6 +793,7 @@ public uint alignmember(structalign_t alignment, uint memalignsize, uint offset)
|
||||||
/****************************************
|
/****************************************
|
||||||
* Place a field (mem) into an aggregate (agg), which can be a struct, union or class
|
* Place a field (mem) into an aggregate (agg), which can be a struct, union or class
|
||||||
* Params:
|
* Params:
|
||||||
|
* loc = source location for error messages
|
||||||
* nextoffset = location just past the end of the previous field in the aggregate.
|
* nextoffset = location just past the end of the previous field in the aggregate.
|
||||||
* Updated to be just past the end of this field to be placed, i.e. the future nextoffset
|
* Updated to be just past the end of this field to be placed, i.e. the future nextoffset
|
||||||
* memsize = size of field
|
* memsize = size of field
|
||||||
|
@ -805,8 +806,8 @@ public uint alignmember(structalign_t alignment, uint memalignsize, uint offset)
|
||||||
* aligned offset to place field at
|
* aligned offset to place field at
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public uint placeField(ref uint nextoffset, uint memsize, uint memalignsize,
|
public uint placeField(Loc loc, ref uint nextoffset, uint memsize, uint memalignsize,
|
||||||
structalign_t alignment, ref uint aggsize, ref uint aggalignsize, bool isunion) @safe pure nothrow
|
structalign_t alignment, ref uint aggsize, ref uint aggalignsize, bool isunion) @trusted nothrow
|
||||||
{
|
{
|
||||||
static if (0)
|
static if (0)
|
||||||
{
|
{
|
||||||
|
@ -829,7 +830,12 @@ public uint placeField(ref uint nextoffset, uint memsize, uint memalignsize,
|
||||||
bool overflow;
|
bool overflow;
|
||||||
const sz = addu(memsize, actualAlignment, overflow);
|
const sz = addu(memsize, actualAlignment, overflow);
|
||||||
addu(ofs, sz, overflow);
|
addu(ofs, sz, overflow);
|
||||||
if (overflow) assert(0);
|
if (overflow)
|
||||||
|
{
|
||||||
|
error(loc, "max object size %u exceeded from adding field size %u + alignment adjustment %u + field offset %u when placing field in aggregate",
|
||||||
|
uint.max, memsize, actualAlignment, ofs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Skip no-op for noreturn without custom aligment
|
// Skip no-op for noreturn without custom aligment
|
||||||
if (memalignsize != 0 || !alignment.isDefault())
|
if (memalignsize != 0 || !alignment.isDefault())
|
||||||
|
|
|
@ -7126,7 +7126,7 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
|
||||||
assert(sz != SIZE_INVALID && sz < uint.max);
|
assert(sz != SIZE_INVALID && sz < uint.max);
|
||||||
uint memsize = cast(uint)sz; // size of member
|
uint memsize = cast(uint)sz; // size of member
|
||||||
uint memalignsize = target.fieldalign(t); // size of member for alignment purposes
|
uint memalignsize = target.fieldalign(t); // size of member for alignment purposes
|
||||||
vd.offset = placeField(
|
vd.offset = placeField(vd.loc,
|
||||||
fieldState.offset,
|
fieldState.offset,
|
||||||
memsize, memalignsize, vd.alignment,
|
memsize, memalignsize, vd.alignment,
|
||||||
ad.structsize, ad.alignsize,
|
ad.structsize, ad.alignsize,
|
||||||
|
@ -7193,7 +7193,7 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
|
||||||
alignsize = memsize; // not memalignsize
|
alignsize = memsize; // not memalignsize
|
||||||
|
|
||||||
uint dummy;
|
uint dummy;
|
||||||
bfd.offset = placeField(
|
bfd.offset = placeField(bfd.loc,
|
||||||
fieldState.offset,
|
fieldState.offset,
|
||||||
memsize, alignsize, bfd.alignment,
|
memsize, alignsize, bfd.alignment,
|
||||||
ad.structsize,
|
ad.structsize,
|
||||||
|
@ -7395,7 +7395,7 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
|
||||||
/* Given the anon 'member's size and alignment,
|
/* Given the anon 'member's size and alignment,
|
||||||
* go ahead and place it.
|
* go ahead and place it.
|
||||||
*/
|
*/
|
||||||
anond.anonoffset = placeField(
|
anond.anonoffset = placeField(anond.loc,
|
||||||
fieldState.offset,
|
fieldState.offset,
|
||||||
anond.anonstructsize, anond.anonalignsize, alignment,
|
anond.anonstructsize, anond.anonalignsize, alignment,
|
||||||
ad.structsize, ad.alignsize,
|
ad.structsize, ad.alignsize,
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
/*
|
|
||||||
TEST_OUTPUT:
|
|
||||||
---
|
|
||||||
fail_compilation/failCopyCtor.d(10): Error: `struct A` may not define both a rvalue constructor and a copy constructor
|
|
||||||
fail_compilation/failCopyCtor.d(12): rvalue constructor defined here
|
|
||||||
fail_compilation/failCopyCtor.d(13): copy constructor defined here
|
|
||||||
---
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct A
|
|
||||||
{
|
|
||||||
this(immutable A a) {}
|
|
||||||
this(ref shared A a) immutable {}
|
|
||||||
this(ref A a) {}
|
|
||||||
}
|
|
11
compiler/test/fail_compilation/test21995.d
Normal file
11
compiler/test/fail_compilation/test21995.d
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/* TEST_OUTPUT:
|
||||||
|
---
|
||||||
|
fail_compilation/test21995.d(10): Error: max object size 4294967295 exceeded from adding field size 3 + alignment adjustment 1 + field offset 4294967292 when placing field in aggregate
|
||||||
|
---
|
||||||
|
*/
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
ubyte[0x7ffffffe] a;
|
||||||
|
ubyte[0x7ffffffe] b;
|
||||||
|
ubyte[3] c;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue