Bug 62224 - [4.9 Regression] Possible regression in gcc-4.9-20140820
Summary: [4.9 Regression] Possible regression in gcc-4.9-20140820
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.9.2
: P1 normal
Target Milestone: 4.9.2
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-08-22 07:46 UTC by Chris Clayton
Modified: 2014-09-09 21:39 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Preprocessed source file (328.42 KB, application/x-xz)
2014-08-22 07:50 UTC, Chris Clayton
Details
Pre-processed cppcodemodelinspectordialog (346.77 KB, application/x-xz)
2014-09-02 19:09 UTC, Chris Clayton
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Clayton 2014-08-22 07:46:25 UTC
Building qt-creator-3.2.0 with this week's 4.9.2 (21040820) snapshot fails. Building it with last week's 4.9.2 (20140813) snapshot succeeds.

My system is a 32 bit user space running on a 64 bit 3.16.1 kernel built from source. The hardware is a Fujitsu Lifebook AH531 laptop with 8GB RAM.

The gcc build is configured with:

--prefix=/usr --build=i386-pc-linux-gnu --host=i386-pc-linux-gnu --target=i386-pc-linux-gnu --infodir=/usr/info --mandir=/usr/man --enable-shared --disable-static --with-system-zlib --enable-threads=posix --enable-haifa --enable-languages=c,c++ --enable-long-long --enable-namespaces --enable-multilib --with-gnu-as --with-gnu-ld --with-system-zlib --without-x --disable-werror --disable-checking --enable-__cxa_atexit --disable-nls --without-included-gettext i386-pc-linux

The compiler output is:

cd cppeditor/ && make -f Makefile
make[3]: Entering directory '/home/chris/rpm/BUILD/qt-creator-opensource-src-3.2.0/qt-creator-3.2.0-build/src/plugins/cppeditor'
rm -f libCppEditor.so
g++ -Wl,-z,origin '-Wl,-rpath,$ORIGIN:$ORIGIN/..' -Wl,--no-undefined -Wl,-O1 -shared -Wl,-soname,libCppEditor.so -o libCppEditor.so .obj/release-shared/cppautocompleter.o .obj/release-shared/cppcanonicalsymbol.o .obj/release-shared/cppclasswizard.o .obj/release-shared/cppcodemodelinspectordialog.o .obj/release-shared/cppdocumentationcommenthelper.o .obj/release-shared/cppeditor.o .obj/release-shared/cppeditordocument.o .obj/release-shared/cppeditoroutline.o .obj/release-shared/cppeditorplugin.o .obj/release-shared/cppelementevaluator.o .obj/release-shared/cppfilewizard.o .obj/release-shared/cppfollowsymbolundercursor.o .obj/release-shared/cppfunctiondecldeflink.o .obj/release-shared/cpphighlighter.o .obj/release-shared/cpphoverhandler.o .obj/release-shared/cppincludehierarchy.o .obj/release-shared/cppincludehierarchyitem.o .obj/release-shared/cppincludehierarchymodel.o .obj/release-shared/cppincludehierarchytreeview.o .obj/release-shared/cppinsertvirtualmethods.o .obj/release-shared/cpplocalrenaming.o .obj/release-shared/cppoutline.o .obj/release-shared/cpppreprocessordialog.o .obj/release-shared/cppquickfix.o .obj/release-shared/cppquickfixassistant.o .obj/release-shared/cppquickfixes.o .obj/release-shared/cppsnippetprovider.o .obj/release-shared/cpptypehierarchy.o .obj/release-shared/cppvirtualfunctionassistprovider.o .obj/release-shared/cppvirtualfunctionproposalitem.o .obj/release-shared/moc_cppclasswizard.o .obj/release-shared/moc_cppcodemodelinspectordialog.o .obj/release-shared/moc_cppdocumentationcommenthelper.o .obj/release-shared/moc_cppeditor.o .obj/release-shared/moc_cppeditordocument.o .obj/release-shared/moc_cppeditoroutline.o .obj/release-shared/moc_cppeditorplugin.o .obj/release-shared/moc_cppfilewizard.o .obj/release-shared/moc_cppfunctiondecldeflink.o .obj/release-shared/moc_cpphighlighter.o .obj/release-shared/moc_cpphoverhandler.o .obj/release-shared/moc_cppincludehierarchy.o .obj/release-shared/moc_cppincludehierarchymodel.o .obj/release-shared/moc_cppinsertvirtualmethods.o .obj/release-shared/moc_cpplocalrenaming.o .obj/release-shared/moc_cppoutline.o .obj/release-shared/moc_cpppreprocessordialog.o .obj/release-shared/moc_cppquickfix.o .obj/release-shared/moc_cpptypehierarchy.o .obj/release-shared/qrc_cppeditor.o    -L/home/chris/rpm/BUILD/qt-creator-opensource-src-3.2.0/qt-creator-3.2.0-build/lib/qtcreator -L/home/chris/rpm/BUILD/qt-creator-opensource-src-3.2.0/qt-creator-3.2.0-build/lib/qtcreator/plugins -lTextEditor -lCore -lCppTools -lProjectExplorer -lCPlusPlus -lAggregation -lExtensionSystem -lQtcSsh -lUtils -lLanguageUtils -lQtGui -lQtNetwork -lQtCore -lpthread
.obj/release-shared/cppcodemodelinspectordialog.o: In function `CppEditor::Internal::CppCodeModelInspectorDialog::refresh()':
cppcodemodelinspectordialog.cpp:(.text+0x79bd): undefined reference to `CppTools::Internal::CppModelManager::ensureUpdated()'
cppcodemodelinspectordialog.cpp:(.text+0x79fc): undefined reference to `CppTools::Internal::CppModelManager::ensureUpdated()'
.obj/release-shared/cppcodemodelinspectordialog.o: In function `CppTools::Internal::CppModelManager::definedMacros()':
cppcodemodelinspectordialog.cpp:(.text._ZN8CppTools8Internal15CppModelManager13definedMacrosEv[_ZN8CppTools8Internal15CppModelManager13definedMacrosEv]+0x26): undefined reference to `CppTools::Internal::CppModelManager::ensureUpdated()'
.obj/release-shared/cppcodemodelinspectordialog.o: In function `CppTools::Internal::CppModelManager::headerPaths()':
cppcodemodelinspectordialog.cpp:(.text._ZN8CppTools8Internal15CppModelManager11headerPathsEv[_ZN8CppTools8Internal15CppModelManager11headerPathsEv]+0x26): undefined reference to `CppTools::Internal::CppModelManager::ensureUpdated()'
collect2: error: ld returned 1 exit status
Makefile:216: recipe for target '../../../lib/qtcreator/plugins/libCppEditor.so' failed
make[3]: *** [../../../lib/qtcreator/plugins/libCppEditor.so] Error 1
make[3]: Leaving directory '/home/chris/rpm/BUILD/qt-creator-opensource-src-3.2.0/qt-creator-3.2.0-build/src/plugins/cppeditor'
Makefile:134: recipe for target 'sub-cppeditor-make_default' failed
make[2]: *** [sub-cppeditor-make_default] Error 2
make[2]: Leaving directory '/home/chris/rpm/BUILD/qt-creator-opensource-src-3.2.0/qt-creator-3.2.0-build/src/plugins'
Makefile:114: recipe for target 'sub-plugins-make_default-ordered' failed
make[1]: *** [sub-plugins-make_default-ordered] Error 2
make[1]: Leaving directory '/home/chris/rpm/BUILD/qt-creator-opensource-src-3.2.0/qt-creator-3.2.0-build/src'
Makefile:41: recipe for target 'sub-src-make_default-ordered' failed
make: *** [sub-src-make_default-ordered] Error 2

The undefined CppTools::Internal::CppModelManager::ensureUpdated() is defined in src/plugins/cpptools/cppmodelmanager.cpp and I attach the prepocessed file.
Comment 1 Chris Clayton 2014-08-22 07:50:02 UTC
Created attachment 33377 [details]
Preprocessed source file

ETOOBIG on uncompressed attachment. Now compressed with xz.
Comment 2 Richard Biener 2014-08-26 10:58:54 UTC
Raising to P1 to be on the radar for the 4.9.2 release.  _Not_ confirmed yet.

I hope the preprocessed source file is that providing the functions the
unresolved references look for.
Comment 3 Chris Clayton 2014-08-28 07:55:33 UTC
Yes, the preprocessed file is the one providing the unresolved references.

It surely won't be a surprise to anyone to here that the same failure occurs when building with yesterday's 4.9 snapshot 4.9-20140827.
Comment 4 Jakub Jelinek 2014-09-01 09:22:53 UTC
So perhaps the r214208 change?  Can you try to back that out and retry?
Comment 5 Chris Clayton 2014-09-01 21:32:34 UTC
I reverted the code change from r214208 with the following patch:

--- gcc-4.9-20140827-orig/gcc/cp/decl2.c        2014-08-20 02:54:40.000000000 +0100
+++ gcc-4.9-20140827/gcc/cp/decl2.c     2014-09-01 21:07:29.799905722 +0100
@@ -1934,11 +1934,6 @@ decl_needed_p (tree decl)
   if (flag_keep_inline_dllexport
       && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
     return true;
-  /* Virtual functions might be needed for devirtualization.  */
-  if (flag_devirtualize
-      && TREE_CODE (decl) == FUNCTION_DECL
-      && DECL_VIRTUAL_P (decl))
-    return true;
   /* Otherwise, DECL does not need to be emitted -- yet.  A subsequent
      reference to DECL might cause it to be emitted later.  */
   return false;

With this patch applied to gcc-4.9-20140827, I can now build qt-creator-3.2.0 successfully.
Comment 6 Jason Merrill 2014-09-02 17:57:00 UTC
I don't see cppmodelmanager in that link command, so I'm guessing ensureUpdated is hidden in a different .so?  Certainly compiling the preprocessed file you attached provides a definition of the symbol.  Can you also attach a preprocessed cppcodemodelinspectordialog?
Comment 7 Chris Clayton 2014-09-02 19:09:32 UTC
Created attachment 33439 [details]
Pre-processed cppcodemodelinspectordialog

cppcodemodelinspectordialog.ii compressed with xz.
Comment 8 Markus Trippelsdorf 2014-09-02 20:20:45 UTC
I don't think this is a compiler bug.
cppmodelmanager.o is simply missing in the object file list of the
libCppEditor.so link command. 

And the undefined symbol from cppcodemodelinspectordialog.ii is also correct,
because "void ensureUpdated()" is declared, but not defined in that file.
Comment 9 Chris Clayton 2014-09-02 20:54:58 UTC
That seems odd to me, although I'm happy to be told I'm wrong. I base this on the fact that reverting the code change from r214208 permits a successful build. MoreOver, in both the failed and sucessful builds, ensureUpdated is present in cppmodelmanager.o and that is linked into libCppTools.so as can be seen by:

[chris:~/rpm/build/qt-creator-opensource-src-3.2.0-fail/qt-creator-3.2.0-build]$ nm lib/qtcreator/plugins/libCppTools.so | grep ensureUpdated
000af430 t _ZN8CppTools8Internal15CppModelManager13ensureUpdatedEv
[chris:~/rpm/build/qt-creator-opensource-src-3.2.0-fail/qt-creator-3.2.0-build]$ cd ~/rpm/build/qt-creator-opensource-src-3.2.0/qt-creator-3.2.0-build
[chris:~/rpm/build/qt-creator-opensource-src-3.2.0/qt-creator-3.2.0-build]$ nm lib/qtcreator/plugins/libCppTools.so | grep ensureUpdated
000af640 t _ZN8CppTools8Internal15CppModelManager13ensureUpdatedEv

cppmodelmanager.0 is listed (in Makefile) as an object to be included in the link of libCppTools.so in both builds.

I don't know whether it will be of any help, but I've diffed cppmodelmanager.ii produced in the two builds and the output is:

--- cppmodelmanager.ii.good     2014-09-02 21:25:02.559799184 +0100
+++ cppmodelmanager.ii.fail     2014-08-22 08:27:06.000000000 +0100
@@ -18581,23 +18581,7 @@ namespace std __attribute__ ((__visibili
     inline basic_istream<_CharT, _Traits>&
     getline(basic_istream<_CharT, _Traits>& __is,
      basic_string<_CharT, _Traits, _Alloc>& __str)
-    { return std::getline(__is, __str, __is.widen('\n')); }
-
-
-
-  template<typename _CharT, typename _Traits, typename _Alloc>
-    inline basic_istream<_CharT, _Traits>&
-    getline(basic_istream<_CharT, _Traits>&& __is,
-     basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
-    { return std::getline(__is, __str, __delim); }
-
-
-  template<typename _CharT, typename _Traits, typename _Alloc>
-    inline basic_istream<_CharT, _Traits>&
-    getline(basic_istream<_CharT, _Traits>&& __is,
-     basic_string<_CharT, _Traits, _Alloc>& __str)
-    { return std::getline(__is, __str); }
-
+    { return getline(__is, __str, __is.widen('\n')); }

   template<>
     basic_istream<char>&
@@ -19695,7 +19679,7 @@ namespace __gnu_cxx __attribute__ ((__vi


 }
-# 2851 "/usr/include/c++/4.9.2/bits/basic_string.h" 2 3
+# 2835 "/usr/include/c++/4.9.2/bits/basic_string.h" 2 3

 namespace std __attribute__ ((__visibility__ ("default")))
 {
@@ -20103,7 +20087,7 @@ namespace std __attribute__ ((__visibili


 }
-# 3069 "/usr/include/c++/4.9.2/bits/basic_string.h" 2 3
+# 3053 "/usr/include/c++/4.9.2/bits/basic_string.h" 2 3

 namespace std __attribute__ ((__visibility__ ("default")))
 {
@@ -20174,7 +20158,7 @@ namespace std __attribute__ ((__visibili
   template<>
     struct __is_fast_hash<hash<u32string>> : std::false_type
     { };
-# 3173 "/usr/include/c++/4.9.2/bits/basic_string.h" 3
+# 3157 "/usr/include/c++/4.9.2/bits/basic_string.h" 3

 }
 # 53 "/usr/include/c++/4.9.2/string" 2 3
Comment 10 Markus Trippelsdorf 2014-09-02 21:22:00 UTC
(In reply to Chris Clayton from comment #9)
> That seems odd to me, although I'm happy to be told I'm wrong. I base this
> on the fact that reverting the code change from r214208 permits a successful
> build. MoreOver, in both the failed and sucessful builds, ensureUpdated is
> present in cppmodelmanager.o and that is linked into libCppTools.so.

Before r214208 the body of "virtual QByteArray CppTools::Internal::CppModelManager::definedMacros()" (and the other two virtual functions) that call ensureUpdated() were removed:

_ZN8CppTools8Internal15CppModelManager13definedMacrosEv/6495 (virtual QByteArray CppTools::Internal::CppModelManager::definedMacros()) @0x7f601c207520
Type: function
Body removed by symtab_remove_unreachable_nodes
Visibility: external public weak comdat comdat_group:_ZN8CppTools8Internal15CppModelManager13definedMacrosEv one_only virtual

Now these virtual function bodies are kept:

_ZN8CppTools8Internal15CppModelManager13definedMacrosEv/6495 (virtual QByteArray CppTools::Internal::CppModelManager::definedMacros()) @0x7f67c0347520                        
  Type: function definition analyzed
  Visibility: externally_visible public weak comdat comdat_group:_ZN8CppTools8Internal15CppModelManager13definedMacrosEv one_only virtual
  previous sharing asm name: 12475
  Address is taken.
  References:
  Referring: _ZN9CppEditor8Internal27CppCodeModelInspectorDialog7refreshEv/6819 (addr) (speculative)
  Availability: available
  First run: 0
  Function flags: body
  Called by:
  Calls: _ZN8CppTools8Internal15CppModelManager13ensureUpdatedEv/10759 (1.00 per call) (can throw external)

And there is nothing wrong with that AFAICS.
Comment 11 Markus Trippelsdorf 2014-09-03 06:56:53 UTC
Here's a small testcase:

markus@x4 tmp % cat cppcodemodelinspectordialog.ii
namespace CppTools
{
class A
{
public:
  virtual void headerPaths () = 0;
};
namespace Internal
{
class CppModelManager : CppTools::A
{
  void
  headerPaths ()
  {
    ensureUpdated ();
  }
  void ensureUpdated ();
};
}
}
CppTools::A *a;
void
fn1 ()
{
  a->headerPaths ();
}

(before r214208)
markus@x4 tmp % g++ -Wl,--no-undefined -shared -fPIC -O2 cppcodemodelinspectordialog.ii
markus@x4 tmp %

(after r214208)
markus@x4 tmp % g++ -Wl,--no-undefined -shared -fPIC -O2 cppcodemodelinspectordialog.ii
/tmp/ccMZQE0g.o:cppcodemodelinspectordialog.ii:function fn1(): error: undefined reference to 'CppTools::Internal::CppModelManager::ensureUpdated()'
/tmp/ccMZQE0g.o:cppcodemodelinspectordialog.ii:function CppTools::Internal::CppModelManager::headerPaths(): error: undefined reference to 'CppTools::Internal::CppModelManager::ensureUpdated()'
collect2: error: ld returned 1 exit status

(one can use -fno-devirtualize-speculatively as a workaround)
markus@x4 tmp % g++ -Wl,--no-undefined -fno-devirtualize-speculatively -shared -fPIC -O2 cppcodemodelinspectordialog.ii
markus@x4 tmp %
Comment 12 Chris Clayton 2014-09-03 07:33:45 UTC
Sorry, you'll have to stick with me here while a figure out what that means.

I think you are saying that prior to r214208, the symbols definedMacros() and headerPaths() were present but effectively no-ops. Post r214208 they now "contain" operations including calls to ensureUpdated().

Given that the symbol for ensureUpdated() appears to be present in libCppTools.so (along with the symbols for its two post-r214208 callers), does that suggest a problem with the linker, which is /usr/bin/ld from the latest version (2.24) of binutils?

Or could it be anything to do with my system being a 32bit userspace on a 64bit kernel? I usually build packages as rpms and have the rpm binary wrapped in a script which uses prefixes the call to the actual rpm binary with "setarch i386". I've been careful whilst investigated this problem to make sure that I prefix calls to qmake and make with "setarch i386". I've built loads and loads of packages with this setup (including gcc).

I'm just trying to figure out the next port of call with this problem. I note that the Debian folks have a bug logged but seem to be waiting on resolution via this bug report - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=759862.
Comment 13 Markus Trippelsdorf 2014-09-03 07:44:15 UTC
(In reply to Chris Clayton from comment #12)
> Sorry, you'll have to stick with me here while a figure out what that means.
> 
> I think you are saying that prior to r214208, the symbols definedMacros()
> and headerPaths() were present but effectively no-ops. Post r214208 they now
> "contain" operations including calls to ensureUpdated().
> 
> Given that the symbol for ensureUpdated() appears to be present in
> libCppTools.so (along with the symbols for its two post-r214208 callers),
> does that suggest a problem with the linker, which is /usr/bin/ld from the
> latest version (2.24) of binutils?

No. This has nothing to do with libCppTools.so. As I wrote before the 
build system of qt-creator must be changed to provide the missing symbol
by simply adding cppmodelmanager.o to the libCppEditor.so link command.
Comment 14 Markus Trippelsdorf 2014-09-03 09:26:03 UTC
(In reply to Markus Trippelsdorf from comment #13)
> (In reply to Chris Clayton from comment #12)
> > Sorry, you'll have to stick with me here while a figure out what that means.
> > 
> > I think you are saying that prior to r214208, the symbols definedMacros()
> > and headerPaths() were present but effectively no-ops. Post r214208 they now
> > "contain" operations including calls to ensureUpdated().
> > 
> > Given that the symbol for ensureUpdated() appears to be present in
> > libCppTools.so (along with the symbols for its two post-r214208 callers),
> > does that suggest a problem with the linker, which is /usr/bin/ld from the
> > latest version (2.24) of binutils?
> 
> No. This has nothing to do with libCppTools.so. As I wrote before the 
> build system of qt-creator must be changed to provide the missing symbol
> by simply adding cppmodelmanager.o to the libCppEditor.so link command.

Out of curiosity, I have downloaded and tried to build qt-creator-3.2.0.
The build failed exactly as you described in commment 0.

The fix is simple, just add  __attribute__ ((visibility ("default"))) to
CppModelManager::ensureUpdated() in src/plugins/cpptools/cppmodelmanager.cpp:

294  __attribute__ ((visibility ("default")))
295 void CppModelManager::ensureUpdated()
296 {

This will make _ZN8CppTools8Internal15CppModelManager13ensureUpdatedEv external
for libCppTools.so and everything is fine.
Comment 15 Jason Merrill 2014-09-09 11:57:57 UTC
Author: jason
Date: Tue Sep  9 11:57:25 2014
New Revision: 215061

URL: https://gcc.gnu.org/viewcvs?rev=215061&root=gcc&view=rev
Log:
	PR c++/61214
	PR c++/62224
gcc/
	* gimple-fold.c (can_refer_decl_in_current_unit_p): Don't allow
	reference to a DECL_EXTERNAL COMDAT.
gcc/cp/
	* decl2.c (decl_needed_p): Revert virtual functions change.

Added:
    branches/gcc-4_9-branch/gcc/testsuite/g++.dg/ipa/devirt-40.C
Modified:
    branches/gcc-4_9-branch/gcc/ChangeLog
    branches/gcc-4_9-branch/gcc/cp/ChangeLog
    branches/gcc-4_9-branch/gcc/cp/decl2.c
    branches/gcc-4_9-branch/gcc/gimple-fold.c
    branches/gcc-4_9-branch/gcc/testsuite/g++.dg/ipa/devirt-39.C
Comment 16 Markus Trippelsdorf 2014-09-09 12:13:30 UTC
Changing resolution. Fixed.
Comment 17 Chris Clayton 2014-09-09 21:39:03 UTC
I can confirm that with Jason's code changes (referenced in comment 15) to gcc/cp/decl2.c and gcc/gimple-fold.c, the resultant compiler successfully builds qt-creator-3.2.0. Thanks Jason.