diff --git a/ir/irstruct.cpp b/ir/irstruct.cpp index cfac2b6e..21ef927f 100644 --- a/ir/irstruct.cpp +++ b/ir/irstruct.cpp @@ -256,9 +256,11 @@ LLConstant * IrStruct::createStructInitializer(StructInitializer * si) { VarDeclaration* vd = (VarDeclaration*)si->vars.data[i]; Initializer* ini = (Initializer*)si->value.data[i]; + Loc loc = ini ? ini->loc : si->loc; size_t idx = datamap[i]; + // check for duplicate initialization if (data[idx].first != NULL) { Loc l = ini ? ini->loc : si->loc; @@ -266,6 +268,23 @@ LLConstant * IrStruct::createStructInitializer(StructInitializer * si) continue; } + // check for overlapping initialization + for (size_t j = 0; j < i; j++) + { + size_t idx2 = datamap[j]; + assert(data[idx2].first); + + VarDeclarationIter it(aggrdecl->fields, idx2); + + unsigned f_begin = it->offset; + unsigned f_end = f_begin + it->type->size(); + + if (vd->offset >= f_end || (vd->offset + vd->type->size()) <= f_begin) + continue; + + error(loc, "initializer for %s overlaps previous initialization of %s", vd->toChars(), it->toChars()); + } + IF_LOG Logger::println("Explicit initializer: %s @+%u", vd->toChars(), vd->offset); LOG_SCOPE; diff --git a/tests/mini/nocompile_initoverlap1.d b/tests/mini/nocompile_initoverlap1.d new file mode 100644 index 00000000..26b9d2c4 --- /dev/null +++ b/tests/mini/nocompile_initoverlap1.d @@ -0,0 +1,8 @@ +struct Vector { + union { float x; float y; } + const static Vector zero = { x : 0, y : 0 }; +} + +struct HBoxLayout { + Vector padding = Vector.zero; +}