Bug 1206815 - Link failure with -fno-implicit-templates
Summary: Link failure with -fno-implicit-templates
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: rawhide
Hardware: All
OS: All
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-03-28 19:50 UTC by Paulo Andrade
Modified: 2015-05-30 21:18 UTC (History)
5 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2015-05-30 21:18:33 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
GNU Compiler Collection 65630 0 None None None Never

Description Paulo Andrade 2015-03-28 19:50:50 UTC
This simple test:
---%<---
#include <string>
std::string test(int i)
{
    std::string t;
    std::string s = "(";
    t = "";
    for (int r = i; r; r>>=1) {
	if (r & 1)
	    t = "1" + t;
	else
	    t = "0" + t;
    }
    s += t;
    s += ")";
    return s;
}

int
main(int argc, char *argv[])
{
    std::string s = test(16);
    return 0;
}
---%<---

fails to link if compiled with -fno-implicit-templates

I believe it is a bug because, it did work before
(the above is a reduced test case), and if using
a temporary, or explicitly cast it works, e.g.:

-        t = "1" + t;
+        t = std::string("1") + t;

Comment 1 Jonathan Wakely 2015-03-30 13:25:48 UTC
The operator+ overloads for the new std::string are present but are not being exported from the library, I'll fix it upstream.

Comment 2 Jonathan Wakely 2015-03-30 14:57:10 UTC
What was the testcase reduced from?

The code has never been guaranteed to work, and is completely non-portable, but did happen to work with older versions of GCC.

Comment 3 Paulo Andrade 2015-03-30 17:22:44 UTC
It is in the Singular package. The patch I plan to
use is:

---8<---
diff -up Singular-3-1-6/Singular/Minor.cc.orig Singular-3-1-6/Singular/Minor.cc
--- Singular-3-1-6/Singular/Minor.cc.orig	2015-03-28 20:41:36.396539843 -0300
+++ Singular-3-1-6/Singular/Minor.cc	2015-03-28 20:42:33.458542028 -0300
@@ -799,7 +802,7 @@ string MinorKey::toString() const
     z = this->getRowKey(r);
     while (z != 0)
     {
-      if ((z % 2) != 0) t = "1" + t; else t = "0" + t;
+      if ((z % 2) != 0) t = string("1") + t; else t = string("0") + t;
       z = z / 2;
     }
     if (r < this->getNumberOfRowBlocks() - 1)
@@ -813,7 +816,7 @@ string MinorKey::toString() const
     z = this->getColumnKey(c);
     while (z != 0)
     {
-      if ((z % 2) != 0) t = "1" + t; else t = "0" + t;
+      if ((z % 2) != 0) t = string("1") + t; else t = string("0") + t;
       z = z / 2;
     }
     if (c < this->getNumberOfColumnBlocks() - 1)
---8<---

In master branch this function was even commented out:
https://github.com/Singular/Sources/blob/master/Singular/Minor.cc#L793

One of the README files still say need to use -fno-implicit-templates:
https://github.com/Singular/Sources/blob/master/factory/README#L358

Comment 4 Jonathan Wakely 2015-03-30 17:42:17 UTC
(In reply to Paulo Andrade from comment #3)
> -      if ((z % 2) != 0) t = "1" + t; else t = "0" + t;
> +      if ((z % 2) != 0) t = string("1") + t; else t = string("0") + t;

I would do simply t.insert(t.begin(), (z % 2) ? '1' : '0');

(Even that is still horribly inefficient, resulting in lots of bytes being shuffled around every time a new character is inserted at the beginning).


> One of the README files still say need to use -fno-implicit-templates:
> https://github.com/Singular/Sources/blob/master/factory/README#L358

That claim about "the most reliable way" is about 10 years out of date, but if the code is using -fno-implicit-templates then it should be explicitly instantiating the operator+ template in ftmpl_inst.cc instead of relying on undocumented instantiations in libstdc++.so. They shouldn't insist on doing their own manual instantations and then fail to actually instantiate them!

This seems like a bug in the package, and your patch just hides it.

Comment 5 Jonathan Wakely 2015-03-30 18:04:09 UTC
This is now fixed in upstream GCC by https://gcc.gnu.org/r221775

Comment 6 Paulo Andrade 2015-05-30 21:18:33 UTC
This bug can be closed, in the worst case, a simple patch
was already applied, and with time upstream will work
on it as well.


Note You need to log in before you can comment on or make changes to this bug.