https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57546
Andrew Pinski <pinskia at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |rejects-valid, wrong-code Ever confirmed|0 |1 Summary|templated gnu multiversion |gnu multiversion function |function pointer returns |pointer returns wrong value |wrong value |or gets rejected Last reconfirmed| |2021-08-12 Status|UNCONFIRMED |NEW --- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Confirmed, starting in GCC 6.4 (and 7+), GCC rejects it (even a non-template version): <source>: In constructor 'constexpr Foo<int>::Foo()': <source>:3:7: error: cannot convert 'int (*)(Foo<int>*)' to 'int (Foo<int>::*)()' in initialization class Foo ^~~ <source>: In function 'int main()': <source>:19:12: note: synthesized method 'constexpr Foo<int>::Foo()' first required here Foo<int> f; ^ Which is totally bogus. note even the non-templated version is wrong. Here is that: class Foo { public: /* Default version of foo. */ __attribute__ ((target("default"))) int foo () { return 0; } /* corei7 version of foo. */ __attribute__ ((target("arch=corei7"))) int foo () { return 0; } }; #include <stdio.h> int main () { Foo f; int i = f.foo(); int (Foo::*p1)() = &Foo::foo; int j = (f.*p1)(); if (i==j && j==0) { printf("PASSED\n"); return 0; } else { printf("FAILED i:%d j:0x%x\n", i, j); return -1; } } ----- CUT ---- Note for the above testcase GCC 6.4.0 and 7.1.0 both actually pass at -O0 but ICEs at -O2 and they actually do the right thing for -O0: mov QWORD PTR [rbp-32], OFFSET FLAT:_ZN3Foo3fooEv.ifunc(Foo*)