[Issue 23722] New: Lambdas are mangled incorrectly when using multiple compilation units, resulting in incorrect code
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Thu Feb 16 01:46:54 UTC 2023
https://issues.dlang.org/show_bug.cgi?id=23722
Issue ID: 23722
Summary: Lambdas are mangled incorrectly when using multiple
compilation units, resulting in incorrect code
Product: D
Version: D2
Hardware: x86_64
OS: Linux
Status: NEW
Severity: normal
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: zach-dmd at cs.stanford.edu
I have two files, foo.d and bar.d:
bar.d:
```
module bar;
struct A {
import core.stdc.stdio;
alias x = () {
printf("x\n");
};
alias y = () {
printf("y\n");
};
}
// do_x should call A.x (and print "x")
void do_x() {
A.x();
}
```
and foo.d:
```
module foo;
import bar;
// do_y should call A.y (and print "y")
void do_y() {
A.y();
}
extern (C) void main() {
do_y(); // should print y
do_x(); // should print x
}
```
This program should print `y` and then `x`. If I compile as one compilation
unit then it works fine:
```
$ dmd -betterC foo.d bar.d
$ ./foo
y
x
```
But if I compile with separate compilation units then it has incorrect
behavior:
```
$ dmd -betterC -c foo.d
$ dmd -betterC -c bar.d
$ gcc foo.o bar.o -o foo
$ ./foo
x
x
```
This is because in foo.d `A.y` is mangled as `_D3bar1A9__lambda4FNbNiZv`, but
and in bar.d `A.x` is mangled as `_D3bar1A9__lambda4FNbNiZv`. They both have
the same mangled value but they are different lambdas that do different things.
Thus the call to `A.y` ends up being a call to `A.x` once the linker has
resolved the symbols. The mangled name seems to use a count of instantiated
lambdas for uniqueness, but it should instead to depend on something that is
unique across compilation units, such as a counter for the total number of
lambdas (this appears to be the approach C++ takes to solve this).
Thanks.
--
More information about the Digitalmars-d-bugs
mailing list