Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
March 03, 2006 Invalid method called - reduced test case | ||||
---|---|---|---|---|
| ||||
Attachments: | DMD seems to be picky about the order of files passed to it. The
attached program is a reduced version of what Ant encountered while
working on Duit. I believe this is the same bug that Tyler reported
regarding DWT.
The .zip archive contains 3 D modules: a.d, b.d and main.d
When compiled using:
dmd b.d a.d main.d
...the resulting executable will be buggy. More specifically, an assertion (that I put in a function which should never be called) will fail :)
The behavior is the same if one builds a .lib or .a file using dmd -c b.d a.d
...and then links to main.d
Tested on Windows and Linux using the #D compiler farm ;)
--
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d-pu s+: a-->----- C+++$>++++ UL P+ L+ E--- W++ N++ o? K? w++ !O
!M V? PS- PE- Y PGP t 5 X? R tv-- b DI- D+ G e>+++ h>++ !r !y
------END GEEK CODE BLOCK------
Tomasz Stachowiak /+ a.k.a. h3r3tic +/
|
March 06, 2006 Re: Invalid method called - reduced test case | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S Attachments: | Tom S schrieb am 2006-03-03:
>
> DMD seems to be picky about the order of files passed to it. The
> attached program is a reduced version of what Ant encountered while
> working on Duit. I believe this is the same bug that Tyler reported
> regarding DWT.
> The .zip archive contains 3 D modules: a.d, b.d and main.d
>
> When compiled using:
> dmd b.d a.d main.d
>
> ...the resulting executable will be buggy. More specifically, an assertion (that I put in a function which should never be called) will fail :)
>
> The behavior is the same if one builds a .lib or .a file using dmd -c b.d a.d
>
> ...and then links to main.d
>
> Tested on Windows and Linux using the #D compiler farm ;)
Your test case seems to be broken:
=== a.d ===
private import b;
class Foo : Bar {
void foo() {
assert(false); // this should never be called !
}
}
=== b.d ===
class Bar {
private import a;
void bar() {
printf("Bar.bar()\n");
}
}
=== main.d ===
private import a;
void main() {
(new Foo()).bar();
}
You call Foo.bar in main - that's exactly the function you didn't expect to execute.
The real bug is: the private of "private import a;" isn't enforced and thus interpreted as "import a;" - the protection attributes are known not to work properly in many situations.
Thomas
|
March 06, 2006 Re: Invalid method called - reduced test case | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas Kuehne | Thomas Kuehne wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Tom S schrieb am 2006-03-03:
>> DMD seems to be picky about the order of files passed to it. The attached program is a reduced version of what Ant encountered while working on Duit. I believe this is the same bug that Tyler reported regarding DWT.
>> The .zip archive contains 3 D modules: a.d, b.d and main.d
>>
>> When compiled using:
>> dmd b.d a.d main.d
>>
>> ...the resulting executable will be buggy. More specifically, an assertion (that I put in a function which should never be called) will fail :)
>>
>> The behavior is the same if one builds a .lib or .a file using
>> dmd -c b.d a.d
>>
>> ...and then links to main.d
>>
>> Tested on Windows and Linux using the #D compiler farm ;)
>
> Your test case seems to be broken:
>
> === a.d ===
> private import b;
>
> class Foo : Bar {
> void foo() {
> assert(false); // this should never be called !
> }
> }
>
> === b.d ===
> class Bar {
> private import a;
>
> void bar() {
> printf("Bar.bar()\n");
> }
> }
>
> === main.d ===
> private import a;
>
> void main() {
> (new Foo()).bar();
> }
>
>
> You call Foo.bar in main - that's exactly the function you didn't expect
> to execute.
>
> The real bug is: the private of "private import a;" isn't enforced and thus
> interpreted as "import a;" - the protection attributes are known not to
> work properly in many situations.
>
> Thomas
>
>
> -----BEGIN PGP SIGNATURE-----
>
> iD8DBQFEDASk3w+/yD4P9tIRAljXAKDCRA+aN1NNiC4cgMyX8WNyXjYjkQCgwViR
> rw5WgcU4IBE4e64MtO1zzUA=
> =NlAj
> -----END PGP SIGNATURE-----
How is it broken?
I fail to understand, then, why Foo.foo() is called when a call to Foo.bar() is made? Their function signatures are quite different, no? Are the vtables getting reassigned from the compile/link order?
Change the compile order with this:
dmd main.d a.d b.d
and Foo.bar() is called as expected. This seems to be a compile order-related issue. Why does this work just because the objects are built in a different order?
In what situation would we see main.d /not/ put first in the build list?
This does appear to be a dangerous problem, nonetheless...
-JJR
|
March 06, 2006 Re: Invalid method called - reduced test case | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas Kuehne | Thomas Kuehne wrote: > Your test case seems to be broken: > > === a.d === > private import b; > > class Foo : Bar { > void foo() { > assert(false); // this should never be called ! > } > } > > === b.d === > class Bar { > private import a; > > void bar() { > printf("Bar.bar()\n"); > } > } > > === main.d === > private import a; > > void main() { > (new Foo()).bar(); > } > > > You call Foo.bar in main - that's exactly the function you didn't expect > to execute. Wrong. I tell it to call Foo.bar but Foo.foo gets called (the function that contains the assert) :) The order in which these modules are passed to the compiler is important. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d-pu s+: a-->----- C+++$>++++ UL P+ L+ E--- W++ N++ o? K? w++ !O !M V? PS- PE- Y PGP t 5 X? R tv-- b DI- D+ G e>+++ h>++ !r !y ------END GEEK CODE BLOCK------ Tomasz Stachowiak /+ a.k.a. h3r3tic +/ |
Copyright © 1999-2021 by the D Language Foundation