Bug 97543 - compile error involving -fvisibility
Summary: compile error involving -fvisibility
Status: RESOLVED INVALID
Alias: None
Product: SUSE LINUX 10.0
Classification: openSUSE
Component: Development (show other bugs)
Version: Preview 2
Hardware: x86-64 All
: P5 - None : Normal
Target Milestone: ---
Assignee: Michael Matz
QA Contact: E-mail List
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-07-21 02:07 UTC by Dirk Mueller
Modified: 2006-10-05 11:01 UTC (History)
1 user (show)

See Also:
Found By: Other
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dirk Mueller 2005-07-21 02:07:32 UTC
appears to be suse specific.  
 
testcase:  
 
=== Cut === 
#include <qdir.h> 
 
void breakme(const QString& newPath) 
{ 
                                QDir(newPath) != QDir(QDir::homeDirPath ()); 
} 
=== Cut === 
 
g++ -v -fPIC -DPIC -I/usr/lib/qt3/include -fvisibility=hidden 
-fvisibility-inlines-hidden -Wall -O2 -o libtest.so -shared testcase.cpp 
 
... 
GNU C++ version 4.0.2 20050714 (prerelease) (SUSE Linux) (x86_64-suse-linux) 
... 
 
removing -fvisibility-inlines-hidden fixes it.
Comment 1 Dirk Mueller 2005-07-21 02:11:04 UTC
breaks digikam and a few other KDE packages.  
 
 
Comment 2 Dirk Mueller 2005-07-21 02:11:46 UTC
ok, I suck.. the error message is: 
 
/usr/lib64/gcc/x86_64-suse-linux/4.0.2/../../../../x86_64-suse-linux/bin/ld: /tmp/ccY9bnzi.o: 
relocation R_X86_64_32 against `QString::null' can not be used when making a 
shared object; recompile with -fPIC 
Comment 3 Michael Matz 2005-07-21 13:43:14 UTC
Hmm, wasn't visibility switched off for such reasons in KDE on x86-64? 
OTOH we have some additional patches on top (from HJ Lu), which were supposed 
to make this visibility stuff work on more platforms than x86, and perhaps 
that breaks other things, or is not complete enough. 
Comment 4 Dirk Mueller 2005-07-21 14:51:14 UTC
not upstream.. can't find such a change in the suse packages, but could be 
that I'm missing something. strangely it works for most packages though.  
Comment 5 Michael Matz 2005-07-21 15:00:31 UTC
Hmm, it might that it was implicitely switched off in the past by the normal 
autoconf check testing for visibility support, which once determined that 
on x86-64 it indeed did not work.  Then we added the patch on our GCC, and 
it started to basically work (including the autoconf test), but it seems now 
not completely :(  I can reproduce it now (next time, please also attach 
a preprocessed file, accelerates the process a bit).  I'm looking at it. 
Comment 6 Michael Matz 2005-07-21 15:15:58 UTC
I've reduced it to this code: 
---------------------------------- 
struct A { 
  virtual bool operator== (const A &a) const; 
  virtual bool operator!= (const A &a) const; 
}; 
inline bool A::operator!= ( const A &a) const 
{ return !(*this == a); } 
void breakme(const A& newPath, A &b) 
{ 
  A(newPath) != b; 
} 
----------------------------------- 
 
The problem is, that no out-of-line copy of operator != is generated for 
this shared object.  This is so, because out-of-line copies are only generated 
in the object which contains the implementation of the key method (normally 
the first virtual function of the class).  So there's no implementation 
of operator!= in this DSO, which could be made hidden. 
 
In the case at hand GCC fails to inline this very call for whatever reasons. 
So the remaining call is generated _as if_ there is a local hidden 
implementation (because of the flag), which means a call not going over PLT. 
Such calls are not allowed in shared libs if they call to either undefined 
or non-local symbols. 
 
I don't know why this doesn't happen for CVS 4.0.  Perhaps there the call is 
inlined. 
Comment 7 Michael Matz 2005-07-21 15:32:39 UTC
It's not inlined because it is known too late which function actually is 
called.  It's a virtual function, so very early the called function is loaded 
over the vtable.  If the body of breakme is "newPath != b" (no copying of A), 
then there is no error, because the call over the vtable doesn't access 
a symbol.  But with the copy in there, the compiler can determine that the 
type of the object on which to call operator!= really is "A", and then 
can optimize the virtual call to a direct function call.  But at that 
time it's already too late for inlining.  So an uninlined call will remain, 
with the observed effects. 
Comment 8 Michael Matz 2005-07-21 15:35:48 UTC
Perhaps Honza has an idea. 
Comment 9 Michael Matz 2005-07-21 15:49:34 UTC
Ah, it's not just our compiler.  Exactly the same happen also in CVS 4.0. 
Comment 10 Dirk Mueller 2005-07-21 15:53:16 UTC
sorry. ok, filing bugreport upstream then. or did you already? 
Comment 11 Michael Matz 2005-07-21 16:02:16 UTC
I will do. 
Comment 12 Michael Matz 2005-08-22 06:10:43 UTC
Although I forgot to mention it here, I filed this as 
  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22592 
Comment 13 Dirk Mueller 2006-10-05 11:01:45 UTC
was resolved as invalid upstream.