public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug d/95198] New: [D] extern(C) private final functions should use 'local' linker attribute
@ 2020-05-19  1:12 witold.baryluk+gcc at gmail dot com
  2020-05-19  1:15 ` [Bug d/95198] " witold.baryluk+gcc at gmail dot com
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: witold.baryluk+gcc at gmail dot com @ 2020-05-19  1:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95198

            Bug ID: 95198
           Summary: [D] extern(C) private final functions should use
                    'local' linker attribute
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: d
          Assignee: ibuclaw at gdcproject dot org
          Reporter: witold.baryluk+gcc at gmail dot com
  Target Milestone: ---

```
module t1;

extern(C)
private final int f() {
  return 5;
}
pragma(msg, f.mangleof);

```

`gdc -c t1.d -o t1.o` results in object with this symbols:

0000000000000000 D _D2t111__moduleRefZ
0000000000000000 D _D2t112__ModuleInfoZ
                 U _d_dso_registry
0000000000000000 T f
0000000000000000 W gdc.dso_ctor
0000000000000000 W gdc.dso_dtor
0000000000000000 u gdc.dso_initialized
0000000000000000 u gdc.dso_slot
0000000000000016 t _GLOBAL__D_2t1
000000000000000b t _GLOBAL__I_2t1
                 U _GLOBAL_OFFSET_TABLE_
                 U __start_minfo
                 U __stop_minfo



Symbol, '0000000000000000 T f' should instead be '0000000000000000 t f'

Additional when using optimizations, I would expect the f to not be emitted at
all, but it is still there (unless compiler decides not to inline it or its
address is not taken and passed around), even with `gdc -O3`.

gcc for C does use LOCAL for static functions and variables in translation
unit. Similarly probably for C++ symbols in anonymous namespaces.



Example of linking issues:

t1.d:
```
module t1;

extern(C)
private final int f() {
  return 5;
}
```

t2.d:
```
module t2;

extern(C)
private final int f() {
  return 10;
}
```

tm.d:
```
module tm;

void main() {
}
```

$ gdc -O0 -c t1.d -o t1.o
$ gdc -O0 -c t2.d -o t2.o
$ gdc t1.o t2.o tm.d -o t12
/usr/bin/ld: t2.o: in function `f':
t2.d:(.text+0x0): multiple definition of `f'; t1.o:t1.d:(.text+0x0): first
defined here
collect2: error: ld returned 1 exit status
$


This code should link, similar to equivalent code in C. The use case is local
function that is passed in some other module function or method (or static
module constructor for example), to C libraries or other modules as a callback
or for variables a return value.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug d/95198] [D] extern(C) private final functions should use 'local' linker attribute
  2020-05-19  1:12 [Bug d/95198] New: [D] extern(C) private final functions should use 'local' linker attribute witold.baryluk+gcc at gmail dot com
@ 2020-05-19  1:15 ` witold.baryluk+gcc at gmail dot com
  2020-05-19  6:58 ` ibuclaw at gdcproject dot org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: witold.baryluk+gcc at gmail dot com @ 2020-05-19  1:15 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95198

--- Comment #1 from Witold Baryluk <witold.baryluk+gcc at gmail dot com> ---
BTW.

Using:

```
extern(C) private final static int f() { ... }
```


doesn't change anything.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug d/95198] [D] extern(C) private final functions should use 'local' linker attribute
  2020-05-19  1:12 [Bug d/95198] New: [D] extern(C) private final functions should use 'local' linker attribute witold.baryluk+gcc at gmail dot com
  2020-05-19  1:15 ` [Bug d/95198] " witold.baryluk+gcc at gmail dot com
@ 2020-05-19  6:58 ` ibuclaw at gdcproject dot org
  2020-05-20 23:08 ` witold.baryluk+gcc at gmail dot com
  2020-06-22 20:24 ` ibuclaw at gdcproject dot org
  3 siblings, 0 replies; 5+ messages in thread
From: ibuclaw at gdcproject dot org @ 2020-05-19  6:58 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95198

--- Comment #2 from Iain Buclaw <ibuclaw at gdcproject dot org> ---
(In reply to Witold Baryluk from comment #0)
> ```
> module t1;
> 
> extern(C)
> private final int f() {
>   return 5;
> }
> pragma(msg, f.mangleof);
> 
> ```
> 
> `gdc -c t1.d -o t1.o` results in object with this symbols:
> 
> 0000000000000000 D _D2t111__moduleRefZ
> 0000000000000000 D _D2t112__ModuleInfoZ
>                  U _d_dso_registry
> 0000000000000000 T f
> 0000000000000000 W gdc.dso_ctor
> 0000000000000000 W gdc.dso_dtor
> 0000000000000000 u gdc.dso_initialized
> 0000000000000000 u gdc.dso_slot
> 0000000000000016 t _GLOBAL__D_2t1
> 000000000000000b t _GLOBAL__I_2t1
>                  U _GLOBAL_OFFSET_TABLE_
>                  U __start_minfo
>                  U __stop_minfo
> 
> 
> 
> Symbol, '0000000000000000 T f' should instead be '0000000000000000 t f'
> 
> Additional when using optimizations, I would expect the f to not be emitted
> at all, but it is still there (unless compiler decides not to inline it or
> its address is not taken and passed around), even with `gdc -O3`.
> 
> gcc for C does use LOCAL for static functions and variables in translation
> unit. Similarly probably for C++ symbols in anonymous namespaces.
> 

There isn't really a notion of a translation unit in D, the minimal
encapsulation unit is a module.

There are a number of reasons why static in the C sense doesn't exist though.

The main example to demonstrate the current behaviour is correct would be the
following:
```
extern(C)
private final int f() {
  return 5;
}

auto pubf()() {
  return f();
}
```
In this module, 'f' is unused, but it can neither be local or discarded because
if another module instantiates 'pubf', you'll run into linker errors.


(In reply to Witold Baryluk from comment #1)
> BTW.
> 
> Using:
> 
> ```
> extern(C) private final static int f() { ... }
> ```
> 
> 
> doesn't change anything.


static has no effect on module-level declarations
(https://dlang.org/spec/attribute.html#static)

final has no effect on anything that isn't a virtual member function (and I'm
not sure it even makes sense to allow it otherwise).

private is a visibility/access attribute that only affects symbol name lookup
resolution (https://dlang.org/spec/attribute.html#visibility_attributes). 
DECL_VISIBILITY could be set as a further hint for 'private', but that won't
remove the fact you'll still get multiple definition errors.

Note: dmd marks top-level functions as weak, a behaviour I have no intention of
replicating.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug d/95198] [D] extern(C) private final functions should use 'local' linker attribute
  2020-05-19  1:12 [Bug d/95198] New: [D] extern(C) private final functions should use 'local' linker attribute witold.baryluk+gcc at gmail dot com
  2020-05-19  1:15 ` [Bug d/95198] " witold.baryluk+gcc at gmail dot com
  2020-05-19  6:58 ` ibuclaw at gdcproject dot org
@ 2020-05-20 23:08 ` witold.baryluk+gcc at gmail dot com
  2020-06-22 20:24 ` ibuclaw at gdcproject dot org
  3 siblings, 0 replies; 5+ messages in thread
From: witold.baryluk+gcc at gmail dot com @ 2020-05-20 23:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95198

--- Comment #3 from Witold Baryluk <witold.baryluk+gcc at gmail dot com> ---
> The main example to demonstrate the current behaviour is correct would be the following:

```
extern(C)
private final int f() {
  return 5;
}

auto pubf()() {
  return f();
}
```

I see, I guess you are right. I don't know how would one go to fix this to work
correctly with existing linkers and not break other code.

Thanks for clarifications.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug d/95198] [D] extern(C) private final functions should use 'local' linker attribute
  2020-05-19  1:12 [Bug d/95198] New: [D] extern(C) private final functions should use 'local' linker attribute witold.baryluk+gcc at gmail dot com
                   ` (2 preceding siblings ...)
  2020-05-20 23:08 ` witold.baryluk+gcc at gmail dot com
@ 2020-06-22 20:24 ` ibuclaw at gdcproject dot org
  3 siblings, 0 replies; 5+ messages in thread
From: ibuclaw at gdcproject dot org @ 2020-06-22 20:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95198

Iain Buclaw <ibuclaw at gdcproject dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #4 from Iain Buclaw <ibuclaw at gdcproject dot org> ---
(In reply to Witold Baryluk from comment #3)
> > The main example to demonstrate the current behaviour is correct would be the following:
> 
> ```
> extern(C)
> private final int f() {
>   return 5;
> }
> 
> auto pubf()() {
>   return f();
> }
> ```
> 
> I see, I guess you are right. I don't know how would one go to fix this to
> work correctly with existing linkers and not break other code.
> 
> Thanks for clarifications.

To close this issue, I'll leave my thoughts on a similar topic that was touched
on the D ML (this time, regarding the linkage of inline functions).

I'm of the opinion that there is no concept of external (global) or internal
(local) linkage in D.  Rather there's language linkage and module linkage.

Language linkage as in `extern(C++)`, `extern(C)`, `extern(Objective-C)`...

Module linkage as in for a given declaration resolves to the same symbol across
all TUs that import its residing module, but otherwise not strictly visible
outside of that.

It might do well to familiarize yourself with C++2a modules as a primer.  But
even then, you'll have to unlearn a lot of things.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-06-22 20:24 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-19  1:12 [Bug d/95198] New: [D] extern(C) private final functions should use 'local' linker attribute witold.baryluk+gcc at gmail dot com
2020-05-19  1:15 ` [Bug d/95198] " witold.baryluk+gcc at gmail dot com
2020-05-19  6:58 ` ibuclaw at gdcproject dot org
2020-05-20 23:08 ` witold.baryluk+gcc at gmail dot com
2020-06-22 20:24 ` ibuclaw at gdcproject dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).