Thread overview
Problem with extern function declarations
Apr 07, 2015
Johannes Pfau
Apr 21, 2015
Jens Bauer
Apr 21, 2015
Johannes Pfau
Apr 21, 2015
Jens Bauer
Apr 22, 2015
Jens Bauer
April 07, 2015
The recently added weak attribute shows a small difference in behavior compared to c:

------------------------
#include <stdio.h>
__attribute__((weak)) int test();
int main()
{
    printf("%p %d\n", &test, (int)&test);
    return 0;
}
------------------------
(nil) 0
------------------------
import core.stdc.stdio, gcc.attribute;
@attribute("weak") void test();
int main()
{
    printf("%p %d\n", &test, cast(int)&test);
    return 0;
}
------------------------
=> unresolved symbol test

The problem is that we mark the function decl as TREE_STATIC. The C compiler marks it as DECL_EXTERNAL instead. Interestingly for variables things work as 'expected':

---------------------------------------------
__gshared @attribute("weak") extern int test; => address (nil) / 0
__gshared @attribute("weak") int test; => real address
---------------------------------------------


So:
1) Can we mark int test(); as DECL_EXTERNAL or am I missing something?
2) Is this change correct or is there a better way:

@@ -1717,7 +1717,7 @@ setup_symbol_storage (Dsymbol *dsym, tree decl,
bool public_p) }

       VarDeclaration *vd = rd ? rd->isVarDeclaration() : NULL;
-      if (!local_p || (vd && vd->storage_class & STCextern))
+      if (!local_p || (vd && vd->storage_class & STCextern) || (rd &&
rd->isFuncDeclaration() && !rd->isFuncDeclaration()->fbody)) {
 	  DECL_EXTERNAL (decl) = 1;
 	  TREE_STATIC (decl) = 0;
April 21, 2015
On Tuesday, 7 April 2015 at 19:31:25 UTC, Johannes Pfau wrote:
> The recently added weak attribute shows a small difference in behavior compared to c {snip}
>
> __attribute__((weak)) int test();
>
> (nil) 0
> ------------------------
> @attribute("weak") void test();
>
> => unresolved symbol test
>
> The problem is that we mark the function decl as TREE_STATIC. The C compiler marks it as DECL_EXTERNAL instead. Interestingly for variables things work as 'expected' {snip}

I'm still hoping for a solution to this. Should I file a bug-report ?
April 21, 2015
Am Tue, 21 Apr 2015 11:42:40 +0000
schrieb "Jens Bauer" <doctor@who.no>:

> On Tuesday, 7 April 2015 at 19:31:25 UTC, Johannes Pfau wrote:
> > The recently added weak attribute shows a small difference in behavior compared to c {snip}
> >
> > __attribute__((weak)) int test();
> >
> > (nil) 0
> > ------------------------
> > @attribute("weak") void test();
> >
> > => unresolved symbol test
> >
> > The problem is that we mark the function decl as TREE_STATIC. The C compiler marks it as DECL_EXTERNAL instead. Interestingly for variables things work as 'expected' {snip}
> 
> I'm still hoping for a solution to this. Should I file a bug-report ?

Didn't this[1] commit fix the problem?

[1] https://github.com/D-Programming-GDC/GDC/commit/85c65ea7304700c69fcffd51db9589d2cbc1fe03
April 21, 2015
On Tuesday, 21 April 2015 at 14:10:36 UTC, Johannes Pfau wrote:
> Am Tue, 21 Apr 2015 11:42:40 +0000 schrieb "Jens Bauer" <doctor@who.no>:
>> 
>> I'm still hoping for a solution to this. Should I file a bug-report ?
>
> Didn't this[1] commit fix the problem?

My mistake. I had my git repository stuck on a 2 week old version, so running my update script didn't do anything useful.
I'm building GDC now and will test tomorrow; sorry for the noise.
April 22, 2015
On Tuesday, 21 April 2015 at 14:10:36 UTC, Johannes Pfau wrote:
> Am Tue, 21 Apr 2015 11:42:40 +0000
> schrieb "Jens Bauer" <doctor@who.no>:
>
>> I'm still hoping for a solution to this. Should I file a bug-report ?
>
> Didn't this[1] commit fix the problem?

I can confirm that the problem is fixed.
-And the code generation is quite impressive.

In C I had ...

if(LowLevelInit) LowLevelInit();  /* generates a lot of redundant code: load register, compare, branch, branch+link */

In D, I only need:

LowLevelInit;

This generates a nop.w instruction if the LowLevelInit does not exist (this is definitely the desired behaviour, if the BL instruction can not be removed completely; but I believe we're speaking about code that's already generated, thus the optimizer is doing quite well).

I can now conclude my startup.d; which will be a "production ready" startup file, that can replace both startup.s and startup.c completely.
Thank you for making this possible!