Bug 20274 - -fvisibility=hidden has no effect on calling undefined function
Summary: -fvisibility=hidden has no effect on calling undefined function
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.0.0
: P2 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: visibility
Depends on:
Blocks:
 
Reported: 2005-03-02 05:11 UTC by H.J. Lu
Modified: 2006-06-23 05:25 UTC (History)
2 users (show)

See Also:
Host:
Target: x86_64-unknown-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2005-03-02 05:11:35 UTC
bash-3.00$ cat x.c
#if 1
extern void foo ();
#else
extern void foo () __attribute__((visibility ("hidden")));
#endif

void
bar ()
{
  foo ();
}
bash-3.00$ ./xgcc -B./ -fPIC -O2 x.c -S -fvisibility=hidden
bash-3.00$ more x.s
        .file   "x.c"
        .text
        .p2align 4,,15
.globl bar
        .hidden bar
        .type   bar, @function
bar:
.LFB2:
        xorl    %eax, %eax
        jmp     foo@PLT
.LFE2:
        .size   bar, .-bar

foo is defined in a different file. Why doesn't gcc use "jmp foo" instead of
"jmp foo@PLT"? Use

extern void foo () __attribute__((visibility ("hidden")));

works.
Comment 1 Andrew Pinski 2005-03-02 05:18:47 UTC
Seems like someone forgot to apply the visibility to the undefined functions, though that might be on 
purpose.
Comment 2 H.J. Lu 2005-03-02 06:46:50 UTC
If it is on purpose, it should be documented, something like
-fvisibility=hidden can be used to access the global data/function
defined in the same file as if they are local. It may make
-fvisibility=hidden less useful.
Comment 3 H.J. Lu 2005-03-02 17:19:52 UTC
default_binds_local_p_1 has

  /* A variable is local if the user explicitly tells us so.  */
  else if (DECL_VISIBILITY_SPECIFIED (exp) && DECL_VISIBILITY (exp) !=
VISIBILITY_DEFAULT)
    local_p = true;
  /* Otherwise, variables defined outside this object may not be local.  */  
else if (DECL_EXTERNAL (exp))
    local_p = false;
  /* Linkonce and weak data are never local.  */
  else if (DECL_ONE_ONLY (exp) || DECL_WEAK (exp))
    local_p = false;
  /* If none of the above and visibility is not default, make local.  */
  else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
    local_p = true;

If a symbol is undefined and its visibility isn't specified by the user,
it won't be treated as local. So it is done on purpose. The document should
be updated to reflect this. It can say something like "-fvisibility has
no effect on undefined symbols."
Comment 4 Jason Merrill 2006-06-23 05:25:06 UTC
This is the intended behavior of -fvisibility; see the discussion of PR 15000 for the rationale.