[Issue 23806] [REG 2.099.0] Link error with -betterC

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri Mar 24 09:58:02 UTC 2023


https://issues.dlang.org/show_bug.cgi?id=23806

RazvanN <razvan.nitu1305 at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |razvan.nitu1305 at gmail.com

--- Comment #2 from RazvanN <razvan.nitu1305 at gmail.com> ---
(In reply to SHOO from comment #0)
> After the dmd-2.099.0, the following code causes a link error when built
> with the -betterC compile option:
> ------------------
> struct Foo
> {
> 	~this(){}
> }
> struct Bar
> {
> 	this(ref Bar){}
> }
> struct Data
> {
> 	Foo[2] _foo;
> 	Bar    _bar;
> }
> extern (C) void main()
> {
> 	Data pool;
> }
> ------------------
> 
> (dmd-2.099.0)dev at cc4fa74d49d1:~/work$ dmd -betterC main.d
> main.o:main.d:function
> _D4core8internal5array12construction__T12_d_arrayctorHTANgS4main3FooTNgQnZQBj
> FNeNkMQBcMQBgPaZ27enforceRawArraysConformableMFNaNbNiNexAaxmxAvxQdZv: error:
> undefined reference to
> '_D4core8internal4util5array31enforceRawArraysConformableNogcFNbNfxAaxmxAvxQd
> xbZv'
> collect2: error: ld returned 1 exit status
> Error: linker exited with status 1
> 
> This error does not occur before dmd-2.098.1 and in ldc-1.32.0

Unfortunately, this is an annoying issue. Here's what happens:

The copy constructor of Bar triggers the generation of a copy constructor in
Data with the signature `this(ref inout Data src) inout`. The body of the copy
constructor is:

this._foo = src._foo;
this._bar = src._bar;

The first statement is lowered to _d_arrayctor(this._foo, src._foo) which calls
the druntime template, which in turn calls some druntime internal functions
(not templates). This is the fundamental issue, the hook should only call other
templates otherwise it is not usable in betterC.

However, what happens next is that the second statement is lowered to a copy
constructor call: _bar.__ctor(src._bar). Note that src is `inout` whereas the
parameter of Bar's copy constructor is mutable. This issues an error, but since
we're in a generated method, it gets gagged and the generated copy constructor
is disabled. However, the body of _d_arrayctor has already been attached to AST
and therefore it will get codegened (even if it's not used). That will cause
the linker error.

I think the only way to fix this is to somehow mark the template instances that
are instantiated from a disabled context so that they are not codegened.
Although it's not really obvious how to do that.

--


More information about the Digitalmars-d-bugs mailing list