You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Encountered this during my android/jni stuff. Easier to describe with code than with words:
----
mixin template Impl(T, string name){
alias a = __traits(getMember, T, name); // comment this and it works
static void impl() {
auto t = new T();
__traits(getMember, t, name)();
}
}
class A(CRTP) {
static foreach(memberName; __traits(derivedMembers, CRTP))
mixin Impl!(CRTP, memberName);
}
class Foo : A!Foo {
void test() {
import core.stdc.stdio;
printf("Success
");
}
}
void main() {
Foo.impl();
}
----
Compiles successfully. Running it leads to crash.
Make `class Foo` into `final class Foo` and it works.
Put `final` on `void test` instead and it works here, but adding more members can result in the wrong method being called. Leads me to believe the virtual function slot gets confused.
Comment that `alias a = ....` line in there and it works. So the fundamental problem is related to the alias being present in the mixin template, even if never used.
So the alias of the virtual derived member appearing in the base class. However, I believe the use of the curiously-recurring template pattern is necessary to trigger the bug though since I've been unable to reproduce the crash without that.
This is the most I have been able to minimize it... the original version is:
---
mixin template Impl(T, alias a) {
static void impl() {
auto t = new T();
__traits(getMember, t, __traits(identifier, a))();
}
}
class A(CRTP) {
static foreach(memberName; __traits(derivedMembers, CRTP))
mixin Impl!(CRTP, __traits(getMember, CRTP, memberName));
}
class Foo : A!Foo {
void test() {
import core.stdc.stdio;
printf("Success
");
}
}
void main() {
Foo.impl();
}
---
And I think it is worth noting that one too: just *passing* the alias to the mixin template also results in the same behavior. It doesn't have to explicitly mixin the alias, as long as it is present there.
The text was updated successfully, but these errors were encountered:
With assertions built in DMD your code triggers this :
https://github.com/dlang/dmd/blob/498822ec8efb8e2b68e257b01fa1e097ec6e3a88/compiler/src/dmd/dsymbolsem.d#L5261, so the vtbl seems to be started already, probably with "test" but then is rebuild again, without
reduced further
```mixin template Impl(T){ alias a = __traits(getMember, T, "test"); //alias a = T.test; // no vtbl corruption with this alias}class A(T) { mixin Impl!T;}class Foo : A!Foo { void test() {}}void main() { (new Foo).test();} ```
The same corruption without the getMember trait:
```mixin template Impl(T){ alias a = T.test; pragma(msg, typeof(a)); // launch dsymbolsema and corrupt vtbl}class A(T) { mixin Impl!T;}class Foo : A!Foo { void test() {}}void main() { (new Foo).test();} ```
Adam D. Ruppe (@adamdruppe) reported this on 2019-12-19T19:18:35Z
Transferred from https://issues.dlang.org/show_bug.cgi?id=20458
CC List
Description
The text was updated successfully, but these errors were encountered: