changeset 1254:747fdd9245d7

Added checks for overlapping union initializers, as shown in bug #259 .
author Tomas Lindquist Olsen <tomas.l.olsen gmail com>
date Wed, 22 Apr 2009 01:18:21 +0200
parents 752bed475b75
children 9014d7f0433f
files ir/irstruct.cpp tests/mini/nocompile_initoverlap1.d
diffstat 2 files changed, 27 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ir/irstruct.cpp	Tue Apr 21 20:19:53 2009 +0200
+++ b/ir/irstruct.cpp	Wed Apr 22 01:18:21 2009 +0200
@@ -256,9 +256,11 @@
     {
         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 @@
             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;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mini/nocompile_initoverlap1.d	Wed Apr 22 01:18:21 2009 +0200
@@ -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;
+}