D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 4940 - ICE(symbol.c): Accessing tuple-typed field of struct literal with user-defined constructor
Summary: ICE(symbol.c): Accessing tuple-typed field of struct literal with user-define...
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: ice-on-valid-code, patch
: 6530 6729 7233 (view as issue list)
Depends on:
Blocks:
 
Reported: 2010-09-25 18:39 UTC by Kasumi Hanazuki
Modified: 2012-01-17 11:05 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Kasumi Hanazuki 2010-09-25 18:39:51 UTC
DMD v2.049 on Windows crashes with the message:

  Internal error: ..\ztc\symbol.c 1043

This only occurs when accessing a tuple-typed field on a struct literal directly and using an user-defined constructor.

----

void main() {
  auto w = S(0).x;
}

template Tuple(T...) {
  alias T Tuple;
}

struct S {
  Tuple!(int, int) x;
  this(int) { }
}
Comment 1 yebblies 2011-08-29 22:13:26 UTC
*** Issue 6530 has been marked as a duplicate of this issue. ***
Comment 2 yebblies 2011-08-29 22:13:59 UTC
Test case from 6530:

struct S {
    int a, b, c;
}

struct HasPostblit {
    this(this) {}  // Bug goes away without this.
}

auto toRandomAccessTuple(T...)(T input, HasPostblit hasPostblit) {
    return S(1, 2, 3);
}

void doStuff(T...)(T args) {
    HasPostblit hasPostblit;

    // Bug goes away without the .tupleof.
    auto foo = toRandomAccessTuple(args, hasPostblit).tupleof;
}

void main() {
    doStuff(1, 2, 3);
}
Comment 3 Kenji Hara 2012-01-06 01:34:59 UTC
In the expression e1.tupleof, if e1 has some side effect, this problem occurs.

The explanation of bug mechanism:

1. e1.tupleof is translated to e1.field0, e1.field1, ..., e1.fieldN
(e1.tupleof.length == N).
But if e1 has some side effect (e.g. e1 is function call), e1 is simply duplicated.

  funcall().tupleof -> (funcall().field0, funcall, field1, ..., funcall.fieldN)

2. Postblit call on function argument creates hidden temporary variable.

  toRandomAccessTuple(args, hasPostblit)
  ->
  toRandomAccessTuple(args, (auto __cpcttmp = hasPostblit, __cpcttmp))

The combination of #1 and #2 causes duplication of hidden variable like follows:

  toRandomAccessTuple(args, hasPostblit).tupleof
  ->
  (toRandomAccessTuple(args, (auto __cpcttmp = hasPostblit, __cpcttmp)).a,
   toRandomAccessTuple(args, (auto __cpcttmp = hasPostblit, __cpcttmp)).b,
   toRandomAccessTuple(args, (auto __cpcttmp = hasPostblit, __cpcttmp)).c)

Finally the repetation of __cpcttmp cause ICE in backend.
Comment 4 Kenji Hara 2012-01-06 01:36:27 UTC
*** Issue 6729 has been marked as a duplicate of this issue. ***
Comment 5 Kenji Hara 2012-01-06 01:36:43 UTC
*** Issue 7233 has been marked as a duplicate of this issue. ***