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*)

Reply via email to