Bug 53954 - [C++11] Undefined reference to non-odr-used static const member variable of variadic class template in DSO with -flto and -Wl,--export-dynamic
Summary: [C++11] Undefined reference to non-odr-used static const member variable of v...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: link-failure, lto
Depends on:
Blocks:
 
Reported: 2012-07-13 14:20 UTC by Ai Azuma
Modified: 2012-07-19 03:12 UTC (History)
1 user (show)

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


Attachments
Command-line log (2.06 KB, text/plain)
2012-07-13 14:20 UTC, Ai Azuma
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ai Azuma 2012-07-13 14:20:11 UTC
Created attachment 27785 [details]
Command-line log

The following code shows the problem with GCC 4.7.2 20120707 on x86_64-unknown-linux-gnu.

//////////////////////////////////
// foo.cpp
template<typename...>
struct S
{
  static const bool value = false;
};

void f() {
  typedef decltype(S<>::value) B;
}
//////////////////////////////////

Obviously, `S<>::value' is not odr-used. Therefore, the program should not require its definition. However, when a DSO is created from the above code with GCC 4.7.2 20120707, `-flto' and `-Wl,--export-dynamic' options, it requires the definition of `S<>::value'.

For example, the following command lines result in a link error.

$ g++ -std=c++11 -fPIC -flto -Wl,--export-dynamic -o libfoo.so -shared foo.cpp

$ g++ -std=c++11 -fPIC main.cpp -L. -lfoo
./libfoo.so: undefined reference to `S<>::value'
./libfoo.so: undefined reference to `S<>::value'
collect2: error: ld returned 1 exit status

where main.cpp is a trivial C++ source file like "int main(){}".

Note that neither GCC 4.6.4 20120706 nor 4.8.0 20120708 reproduces the problem.

Note also that the above reproducer originally comes from a likely C++ code using `std::vector' and `-std=c++11' option, like the following;

/////////////////////
#include <vector>

void f()
{
  std::vector<int> v;
  v.push_back(0);
}
/////////////////////

When a DSO is created from this code with `-std=c++11', `-lfto' and `-Wl,--export-dynamic' options, it requires the definition of `std::allocator_traits<std::allocator<int> >::__construct_helper<int, int>::value'.
Comment 1 Richard Biener 2012-07-16 09:49:59 UTC
Not sure what happens here, but I believe not odr-using value does not make
the definition not necessary.
Comment 2 Jonathan Wakely 2012-07-16 09:54:18 UTC
(In reply to comment #0)
> When a DSO is created from this code with `-std=c++11', `-lfto' and
> `-Wl,--export-dynamic' options, it requires the definition of
> `std::allocator_traits<std::allocator<int> >::__construct_helper<int,
> int>::value'.

Ah, that's actually a bug in my libstdc++ code, the definition should be present.
Comment 3 Jonathan Wakely 2012-07-16 09:58:57 UTC
I've created PR 53978 for the libstdc++ fixes
Comment 4 Jonathan Wakely 2012-07-16 20:55:02 UTC
(In reply to comment #0)
> Note also that the above reproducer originally comes from a likely C++ code
> using `std::vector' and `-std=c++11' option, like the following;
> 
> /////////////////////
> #include <vector>
> 
> void f()
> {
>   std::vector<int> v;
>   v.push_back(0);
> }
> /////////////////////
> 
> When a DSO is created from this code with `-std=c++11', `-lfto' and
> `-Wl,--export-dynamic' options, it requires the definition of
> `std::allocator_traits<std::allocator<int> >::__construct_helper<int,
> int>::value'.

I have no view on whether this PR is valid or not, but the std::vector failure is fixed for 4.7.2
Comment 5 Ai Azuma 2012-07-19 03:12:21 UTC
Hmm, now I have arrived at the conclusion that non-odr-used variables might require the definition, depending on compiler options etc., and this PR is invalid, since there is no guarantee in the specification that non-odr-used-ness of variables makes the definition unnecessary.

I'm sorry. I created this PR based on the wrong assumption. I should have created a PR reporting the bug in libstdc++. And thank you for the quick fixes.

Again, thank you for your time.