www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3863] New: Various errors and ICEs for struct constructors with ellipses

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3863

           Summary: Various errors and ICEs for struct constructors with
                    ellipses
           Product: D
           Version: 2.041
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: ice-on-valid-code, rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: ludwig informatik.uni-luebeck.de


--- Comment #0 from Sönke Ludwig <ludwig informatik.uni-luebeck.de> 2010-02-28
02:41:00 PST ---
The following code snipped lists a number of ways to define a struct constant
which fail compilation in one way or another. This happens only 

---
struct Vec(int N){
    //static immutable constant = Vec(1, 2); // error more initializers than
fields
    //static immutable Vec constant = Vec(1, 2); // compiles
    //enum constant = Vec(1, 2); // error more initializers than fields
    enum Vec constant = Vec(1, 2); // compiles

    this(const float[N] args...) {}
    //this(float a, float b) {} // all cases compile
}

struct Test {
    alias Vec!2 Vec2;

    Vec2 member;

    //static immutable constant = Test(Vec!2(1, 2)); // compiler crash
    //static immutable Test constant = Test(Vec!2(1, 2)); // assertion failure
on todt.c:688
    //static immutable constant = Test(Vec!(2).constant); // assertion failure
on todt.c:688
    //enum constant = Test(Vec!(2).constant); // compiles
    enum Test constant = Test(Vec2.constant); // compiles
    //enum Test constant = Test(Vec2(1, 2)); // error void initializer has no
value

    this(Vec2 x){
        member = x;
    }
}
---



When the first sturct is not templated, the situation changes:

---
struct Vec {
    static immutable Vec constant = Vec(1, 2);

    this(const float[2] args...) {}
}

struct Test {
    alias Vec Vec2;

    Vec2 member;

    static immutable constant = Test(Vec2(1, 2)); // compiler crash
    //static immutable Test constant = Test(Vec2(1, 2)); // compiles
    //static immutable constant = Test(Vec2.constant); // compiles
    //enum constant = Test(Vec2.constant); // compiles
    //enum Test constant = Test(Vec2.constant); // compiles
    //enum Test constant = Test(Vec2(1, 2)); // error void initializer has no
value

    this(Vec2 x){
        member = x;
    }
}
---



Using an enum in the first struct makes things worse:

---
struct Vec {
    enum Vec constant = Vec(1, 2);

    this(const float[2] args...) {}
}

struct Test {
    alias Vec Vec2;

    Vec2 member;

    static immutable constant = Test(Vec2(1, 2)); // compiler crash
    //static immutable Test constant = Test(Vec2(1, 2)); // compiles
    //static immutable constant = Test(Vec2.constant); // compiler crash
    //enum constant = Test(Vec2.constant); // compiler crash
    //enum Test constant = Test(Vec2.constant); // error void initializer has
no value
    //enum Test constant = Test(Vec2(1, 2)); // error void initializer has no
value

    this(Vec2 x){
        member = x;
    }
}
---

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 28 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3863



--- Comment #1 from Sönke Ludwig <ludwig informatik.uni-luebeck.de> 2010-02-28
03:29:17 PST ---
(In reply to comment #0)
 The following code snipped lists a number of ways to define a struct constant
 which fail compilation in one way or another. This happens only 
... if ellipses are used for the constructor arguments. However, the "more fields than initializers" case remains even without them: --- struct Vec{ //static immutable constant = Vec(1, 2); // error more initializers than fields //static immutable Vec constant = Vec(1, 2); // compiles //enum constant = Vec(1, 2); // error more initializers than fields //enum Vec constant = Vec(1, 2); // compiles this(float a, float b) {} } --- -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 28 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3863


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au


--- Comment #2 from Don <clugdbug yahoo.com.au> 2010-04-10 13:55:43 PDT ---
The first step is to turn the segfaults into an ICE:
todt.c, line 59.

dt_t *VoidInitializer::toDt()
{   /* Void initializers are set to 0, just because we need something
     * to set them to in the static data segment.
     */
    dt_t *dt = NULL;
+    assert(type);
    dtnzeros(&dt, type->size());
    return dt;
}

I haven't been able to reproduce the other ICE (todt.c 688) on either 2.043,
2.040, or 2.041.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 10 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3863



--- Comment #3 from Sönke Ludwig <ludwig informatik.uni-luebeck.de> 2010-04-11
07:53:32 PDT ---
I looked again at the assertion failure and it seems as it has had nothing to
do with the ellipses. Also does not occur on 2.043 anymore (but does on 2.041).
Reduced repro case:

---
struct Vec{
    float member[2];
    enum Vec constant = Vec(1, 2);
    this(float a, float b){}
}

struct Test {
    Vec member;
    static immutable Test constant1 = Test(Vec(1, 2));
}
---

I could not find an existing bug report for the error messages "more
initializers than fields" or "void initializer has no value". It seems that
when using type inference for the enum constant, the order of declarations of
the member variable, the enum constant and the constructor determines what
"Vec(1, 2)" means (struct literal or constructor call) or "sees". But maybe it
would be better to make a seperate bug report and consider only the compiler
crash here?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 11 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3863



--- Comment #4 from Don <clugdbug yahoo.com.au> 2010-04-11 11:32:54 PDT ---
(In reply to comment #3)
 I looked again at the assertion failure and it seems as it has had nothing to
 do with the ellipses. Also does not occur on 2.043 anymore (but does on 2.041).
Great! I can reproduce that, too.
 I could not find an existing bug report for the error messages "more
 initializers than fields" or "void initializer has no value". It seems that
 when using type inference for the enum constant, the order of declarations of
 the member variable, the enum constant and the constructor determines what
 "Vec(1, 2)" means (struct literal or constructor call) or "sees". But maybe it
 would be better to make a seperate bug report and consider only the compiler
 crash here?
Yes, please make a separate bug. I'm pretty sure that the crash has a cause which is different from the rest. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 11 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3863


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|rejects-valid               |patch, wrong-code


--- Comment #5 from Don <clugdbug yahoo.com.au> 2010-04-11 14:51:25 PDT ---
Actually this is a rare case where the ICE bug is the same as the others.
I don't think it has anything to do with constructor varargs, actually.
It involves using a struct constructor to perform type inference of a member of
that struct.

Here's an example of a situation where the current behaviour leads to wrong
code:

struct Vec {
   int w;
   this(int x) { w = 2; }

   enum KK = Vec(100);
   enum Vec KK2 = Vec(100);
}

static assert(Vec.KK == Vec.KK2);
// Error: static assert  ((Vec(100)) == (Vec(2))) is false
=========


PATCH. Issue an error message in these potentially recursive situations.
Although in this specific case, it could be made to compile by running semantic
on the constructors first, that won't work in general (the constructor may make
use of the enum, for example).
I've tested this on the DMD test suite, and it passes.


expression.c CallExp::semantic(), line 6790.
==========

#if !STRUCTTHISREF
                /* Constructors return a pointer to the instance
                 */
                e = new PtrExp(loc, e);
#endif
                e = e->semantic(sc);
                return e;
            }
+            // Check for a forward reference to a struct constructor.
+            else if (arguments && arguments->dim && !ad->ctor && ad->sizeok !=
1)
+            {
+                // The semantic pass of the struct isn't yet complete.
+                // Check for attempt to use a constructor.
+                Dsymbol *ctor = ad->search(0, Id::ctor, 0);
+                if (ctor)
+                {
+                    error("Forward reference to struct constructor");
+                    return new ErrorExp();
+                }
+            }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 11 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3863



--- Comment #6 from Sönke Ludwig <ludwig informatik.uni-luebeck.de> 2010-04-27
14:13:23 PDT ---
Just wanted to note that this bug actually provides the only way to work around
issue 3801. So please, do not fix or change this into an error message before
implementing "struct.member[] = x;" or "struct.member[i] = x;" for CTFE.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 27 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3863


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |DUPLICATE


--- Comment #7 from Don <clugdbug yahoo.com.au> 2013-01-16 03:07:00 PST ---
Fixed when bug 8741 was fixed. the wrong-code and ICE test cases now generate
error messages.

*** This issue has been marked as a duplicate of issue 8741 ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 16 2013