Bug 9040 – Assertion `precedence[e->op] != PREC_zero' failed instantiating anonymous class at compile time
Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2012-11-17T08:03:00Z
Last change time
2013-11-22T06:07:27Z
Assigned to
nobody
Creator
ogondza
Comments
Comment #0 by ogondza — 2012-11-17T08:03:45Z
An assertion seems to fail when instantiating anonymous class at compile time.
Instantiating non-anonymous class gives meaningful error message.
class BaseClass {}
void main() {
// OK
BaseClass instance = new class BaseClass {};
// Error: cannot evaluate new BaseClass at compile time
static BaseClass staticInstance = new BaseClass();
//dmd: expression.c:1276: void expToCBuffer(OutBuffer*, HdrGenState*, Expression*, PREC): Assertion `precedence[e->op] != PREC_zero' failed.
//Aborted
static BaseClass staticAnonInstance = new class BaseClass {};
}
Comment #1 by bearophile_hugs — 2012-11-17T08:32:33Z
On the latest dmd 2.061head this program:
class BaseClass {}
void main() {
BaseClass instance = new class BaseClass {};
static BaseClass staticAnonInstance = new class BaseClass {};
}
Gives me (32 bit, Windows):
test.d(4): Error: non-constant expression cast(BaseClass)ยจ6U
The error message doesn't look good.
Comment #2 by andrej.mitrovich — 2013-09-26T06:03:54Z
In 2.063.2 this now prints:
test.d(9): Error: variable test.main.staticInstance is mutable. Only const or immutable class thread local variable are allowed, not test.BaseClass
Unfortunately there's a new issue:
-----
class BaseClass {}
void main()
{
static BaseClass staticAnonInstance = new class BaseClass {};
}
-----
However this is a separate issue, so I'll file it as a new bug.
Comment #3 by andrej.mitrovich — 2013-09-26T06:08:18Z
Argh, I just saw it's labeled as Posix and x64. Is there still a linker failure for you on that platform? I've reopened the issue, if it's fixed please mark it as WORKSFORME. Thanks.
Comment #4 by andrej.mitrovich — 2013-09-26T06:08:54Z
(In reply to comment #2)
> Unfortunately there's a new issue:
>
> -----
> class BaseClass {}
>
> void main()
> {
> static BaseClass staticAnonInstance = new class BaseClass {};
> }
> -----
>
> However this is a separate issue, so I'll file it as a new bug.
W.r.t. this it's a linker failure, and I've filed Issue 11126 for it.
Comment #5 by andrej.mitrovich — 2013-09-26T06:09:40Z
(In reply to comment #3)
> Argh, I just saw it's labeled as Posix and x64. Is there still a linker failure
> for you on that platform? I've reopened the issue, if it's fixed please mark it
> as WORKSFORME. Thanks.
I meant to ask if the compiler is still crashing, the linker issue is separate (Issue 11126).
Comment #6 by ogondza — 2013-09-28T03:31:11Z
(In reply to comment #5)
I do not longer observe the compiler failure. In v2.063.2, I am hitting Issue 11126 instead when running:
-----
class BaseClass {}
void main()
{
static BaseClass staticAnonInstance = new class BaseClass {};
}
-----
Comment #7 by k.hara.pg — 2013-11-21T22:42:18Z
(In reply to comment #6)
> (In reply to comment #5)
> I do not longer observe the compiler failure. In v2.063.2, I am hitting Issue
> 11126 instead when running:
> -----
> class BaseClass {}
>
> void main()
> {
> static BaseClass staticAnonInstance = new class BaseClass {};
> }
> -----
From 2.064, the code prints following error.
test.d(5): Error: variable test.main.staticAnonInstance is mutable. Only const or immutable class thread local variable are allowed, not test.BaseClass
Comment #8 by andrej.mitrovich — 2013-11-22T00:47:11Z
(In reply to comment #7)
> test.d(5): Error: variable test.main.staticAnonInstance is mutable. Only const
> or immutable class thread local variable are allowed, not test.BaseClass
Btw, can we do something about this diagnostic? It makes absolutely no sense at all. Here's a mutable class thread-local variable:
auto a = new Class();
So the diagnostic makes no sense..
Comment #9 by yebblies — 2013-11-22T04:47:07Z
(In reply to comment #8)
> (In reply to comment #7)
> > test.d(5): Error: variable test.main.staticAnonInstance is mutable. Only const
> > or immutable class thread local variable are allowed, not test.BaseClass
>
> Btw, can we do something about this diagnostic? It makes absolutely no sense at
> all. Here's a mutable class thread-local variable:
>
> auto a = new Class();
>
> So the diagnostic makes no sense..
class Class {}
auto a = new Class();
testx.d(136): Error: variable testx.a is mutable. Only const or immutable class thread local variable are allowed, not testx.Class
Why doesn't it make sense?
Comment #10 by andrej.mitrovich — 2013-11-22T05:15:35Z
(In reply to comment #9)
> (In reply to comment #8)
> > (In reply to comment #7)
> > > test.d(5): Error: variable test.main.staticAnonInstance is mutable. Only const
> > > or immutable class thread local variable are allowed, not test.BaseClass
> >
> > Btw, can we do something about this diagnostic? It makes absolutely no sense at
> > all. Here's a mutable class thread-local variable:
> >
> > auto a = new Class();
> >
> > So the diagnostic makes no sense..
>
> class Class {}
> auto a = new Class();
>
> testx.d(136): Error: variable testx.a is mutable. Only const or immutable class
> thread local variable are allowed, not testx.Class
>
> Why doesn't it make sense?
I thought this had something to do with not allowing 'new'ing a class at compile-time. I don't quite understand where the limitation for TLS specifically came from, e.g.:
-----
class Class { }
static tls = new Class(); // NG
__gshared glob = new Class(); // ok
void main() { }
-----
Why is one allowed but not the other? And is this documented somewhere?
Comment #11 by yebblies — 2013-11-22T06:07:27Z
(In reply to comment #10)
>
> I thought this had something to do with not allowing 'new'ing a class at
> compile-time. I don't quite understand where the limitation for TLS
> specifically came from, e.g.:
>
> -----
> class Class { }
> static tls = new Class(); // NG
> __gshared glob = new Class(); // ok
>
> void main() { }
> -----
>
> Why is one allowed but not the other? And is this documented somewhere?
IIRC because all threads get the same tls init data, and end up referencing the same class. This could be fixed, but it doesn't currently work.