Bug 30361

Summary: Documentation: Example usage of __attribute__((visibility("hidden"))) misleading
Product: gcc Reporter: Richard Dawe <rich>
Component: cAssignee: Not yet assigned to anyone <unassigned>
Status: UNCONFIRMED ---    
Severity: normal CC: gcc-bugs
Priority: P3 Keywords: documentation
Version: unknown   
Target Milestone: ---   
Host: Not applicable Target: Not applicable
Build: Not applicable Known to work:
Known to fail: Last reconfirmed:
Attachments: A test case

Description Richard Dawe 2007-01-03 21:40:53 UTC
The documentation for the visibility attribute shown by the "info gcc 'c extension' function" command is misleading. It says:

"`visibility ("VISIBILITY_TYPE")'
     The `visibility' attribute on ELF targets causes the declaration
     to be emitted with default, hidden, protected or internal
     visibility.

          void __attribute__ ((visibility ("protected")))
          f () { /* Do something. */; }
          int i __attribute__ ((visibility ("hidden")));"

Note that the attribute is attached to the return type of the function "f", not the function declaration itself. I think this means that the hidden visibility is applied to the type, not the function, which is strange.

I'm looking at the documentation from gcc trunk.
Comment 1 Andrew Pinski 2007-01-03 21:43:58 UTC
> Note that the attribute is attached to the return type of the function "f", not
> the function declaration itself. I think this means that the hidden visibility
> is applied to the type, not the function, which is strange.

That is because that is how attributes on function definitions work.  this is really unrelated to visibility in general but attributes.
Comment 2 Richard Dawe 2007-01-03 21:45:20 UTC
Created attachment 12853 [details]
A test case

When I compile the attached test case, I get:

[rich@katrina test-cases]$ make
g++ -W -Wall -g    hidden.cpp   -o hidden
hidden.cpp:5: warning: 'visibility' attribute ignored on non-class types

Line 5 refers to the declaration with the attribute attached to the return type.

Looking at the generated ELF file, I see that "func" is not hidden, but "func2" is:

[rich@katrina test-cases]$ readelf -s hidden | c++filt  | grep func
    51: 080487f2    23 FUNC    LOCAL  DEFAULT   12 global constructors keyed to _Z4funcv
    53: 08049e80     4 OBJECT  LOCAL  DEFAULT   25 func2()::foo2
    55: 08049e90     4 OBJECT  LOCAL  DEFAULT   25 func()::foo
    59: 08049e78     8 OBJECT  LOCAL  DEFAULT   25 guard variable for func2()::foo2
    60: 08049e88     8 OBJECT  LOCAL  DEFAULT   25 guard variable for func()::foo
    89: 080488fa   220 FUNC    GLOBAL DEFAULT   12 func()
    99: 0804881e   220 FUNC    GLOBAL HIDDEN   12 func2()

Version information:

[rich@katrina test-cases]$ gcc --version  
gcc (GCC) 4.1.1 20061011 (Red Hat 4.1.1-30)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[rich@katrina test-cases]$ ld --version
GNU ld version 2.17.50.0.3-6 20060715
Copyright 2005 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License.  This program has absolutely no warranty.
[rich@katrina test-cases]$ cat /etc/redhat-release 
Fedora Core release 6 (Zod)
[rich@katrina test-cases]$ rpm -q gcc
gcc-4.1.1-30
[rich@katrina test-cases]$ rpm -q binutils
binutils-2.17.50.0.3-6
Comment 3 Andrew Pinski 2007-01-03 21:45:41 UTC
Read:
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Attribute-Syntax.html

Which describes the syntax.
Comment 4 Andrew Pinski 2007-01-03 21:46:48 UTC
gcc (GCC) 4.1.1 20061011 (Red Hat 4.1.1-30)

This should also tell you, that you are using a modified version of the compiler and the bug report should have been filed up with redhat first.
Comment 5 Richard Dawe 2007-01-03 21:55:19 UTC
Thanks for the quick response and the reference to the attribute documentation.

I agree my comment about the documentation being incorrect is wrong. But it doesn't look to me like the visibility is correct for my test program. I'll try to reproduce this with vanilla trunk gcc & binutils.
Comment 6 Richard Dawe 2007-01-06 14:54:28 UTC
I've repeated my testing with binutils 070103 (from snapshot from web page) and gcc 4.3.0 20070104 from svn trunk (svn revision 120449).

Using hidden visibility with the attribute before the function name in the declaration is still broken. It works if I use the attribute after the function name in the declaration.

Those symptoms are what caused me to think the documentation was wrong in the first place.

[rich@katrina test-cases]$ ld --version
GNU ld version 070103 20070103
Copyright 2005 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License.  This program has absolutely no warranty.

[rich@katrina test-cases]$ gcc --version
gcc (GCC) 4.3.0 20070104 (experimental)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[rich@katrina test-cases]$ rm -f hidden && make
g++ -W -Wall -g    hidden.cpp   -o hidden
hidden.cpp:5: warning: 'visibility' attribute ignored on non-class types

[rich@katrina test-cases]$ readelf -s hidden | c++filt  | grep func
    51: 080489d8    28 FUNC    LOCAL  DEFAULT   12 global constructors keyed to _Z4funcv
    54: 080491f8     4 OBJECT  LOCAL  DEFAULT   25 func2()::foo2
    56: 08049208     4 OBJECT  LOCAL  DEFAULT   25 func()::foo
    60: 080491f0     8 OBJECT  LOCAL  DEFAULT   25 guard variable for func2()::foo2
    61: 08049200     8 OBJECT  LOCAL  DEFAULT   25 guard variable for func()::foo
    93: 08048ae4   220 FUNC    GLOBAL DEFAULT   12 func()
   103: 08048a08   220 FUNC    GLOBAL HIDDEN   12 func2()

[rich@katrina test-cases]$ readelf --version
GNU readelf 070103 20070103
Copyright 2005 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License.  This program has absolutely no warranty.