3

The following code:

template<typename T>
constexpr T foo { 1.2345 };

template<typename T>
T fun(T x) {
  return -foo<T> * x;
}

int main() {
  fun(2.0);
}

compiled using gcc version 5.1.0 on Linux

g++ gcc-bug.cpp -std=c++14

fails during the linking step with the following message:

/tmp/ccuciovi.o: In function `double fun<double>(double)':
gcc-bug.cpp:(.text._Z3funIdET_S0_[_Z3funIdET_S0_]+0xd): undefined reference to `foo<double>'
collect2: error: ld returned 1 exit status

Removing the unary minus (which changes the meaning of the code), gets rid of the linking error. Prepending zero (which does not change the meaning of the code) also gets rid of the error. The following two implementations of foo lead to a successful compilation:

template<typename T>
T fun(T x) {
  return foo<T> * x; // different meaning
}

template<typename T>
T fun(T x) {
  return 0 - foo<T> * x; // same meaning
}

I do not observe this behavior in other compilers. The original code (with the unary minus) compiles and runs fine using clang 3.6.0 and gcc 5.2.0.

Before I submit this as a bug in gcc 5.1.0 I'd like to hear your take on this behavior.

Escualo
  • 40,844
  • 23
  • 87
  • 135

1 Answers1

2

runs fine using ... gcc 5.2.0

Possibly https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65719

Chris Morley
  • 891
  • 6
  • 16
  • Good catch. It may be related, but it puzzles me that it only manifests itself when it is preceded by unary minus. It is some sort of parsing error or AST generation error. I'll probably open a new bug and link 65719. – Escualo Mar 02 '16 at 23:53
  • I submitted the bug (id 70056) and the GCC maintainers did mark it as an exact duplicate of 65719. So, you got it! – Escualo Mar 03 '16 at 00:13
  • I can't say that looking at the diff of the change makes it completely clear to me either - I assume that there was some inconsistency between how the declaration and the reference were treated wrt extern vs internal linkage. – Chris Morley Mar 04 '16 at 02:22