This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/81760] New: attribute target uses the wrong default function argument


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

            Bug ID: 81760
           Summary: attribute target uses the wrong default function
                    argument
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

GCC allows multiple functions with attribute target to be declared with
conflicting default arguments.  The function that ends up invoked may or may
not be passed the default argument values corresponding to its declaration.

The test case below should print one of two lines.  Either

  foo ("arch=silvermont") [arch=silvermont]

on a Silvermont CPU, or

  foo ("default") [default]

on a lesser processor, but it instead prints:

  foo ("arch=silvermont") [default]

indicating that the default function is invoked with the default argument value
corresponding to the one Silvermont overload.

Since C++ normally prohibits declaring the same function with two different
default argument values it seems that rejecting it on distinct overloads that
differ only in the target attribute would make the most sense.


$ cat a.c && gcc -Wall -Wextra -fdump-tree-optimized=/dev/stdout -xc++ a.c &&
./a.out
$ cat a.c && /ssd/build/gcc-git/gcc/xgcc -B /ssd/build/gcc-git/gcc -Wall
-Wextra -fdump-tree-optimized=/dev/stdout -xc++ a.c && ./a.out 
#define A "arch=silvermont"

void __attribute__ ((target ("default")))
foo (const char* = "default");

void __attribute__ ((target (A)))
foo (const char * = A);   // accepted (bug)

int main ()
{
  foo ();
}

int __attribute__ ((target ("default")))
foo (const char *a)
{
  __builtin_printf ("foo (\"%s\") [default]\n", a);
  return 0;
}

int __attribute__ ((target (A)))
foo (const char *a)
{
  __builtin_printf ("foo (\"%s\") [%s]\n", a, A);
  return 0;
}


;; Function int main() (main, funcdef_no=0, decl_uid=2445, cgraph_uid=3,
symbol_order=3)

int main() ()
{
  int D.2460;
  int _3;

  <bb 2> [0.00%] [count: INV]:
  _Z3fooPKc ("arch=silvermont");
  _3 = 0;

  <bb 3> [0.00%] [count: INV]:
<L0>:
  return _3;

}



;; Function int foo(const char*) (_Z3fooPKc, funcdef_no=1, decl_uid=2455,
cgraph_uid=4, symbol_order=4)

__attribute__((target ("default")))
int foo(const char*) (const char * a)
{
  int D.2467;
  int _4;

  <bb 2> [0.00%] [count: INV]:
  __builtin_printf ("foo (\"%s\") [default]\n", a_2(D));
  _4 = 0;

  <bb 3> [0.00%] [count: INV]:
<L0>:
  return _4;

}



;; Function int foo(const char*) (_Z3fooPKc.arch_silvermont, funcdef_no=2,
decl_uid=2458, cgraph_uid=5, symbol_order=5)

__attribute__((target ("arch=silvermont")))
int foo(const char*) (const char * a)
{
  int D.2469;
  int _4;

  <bb 2> [0.00%] [count: INV]:
  __builtin_printf ("foo (\"%s\") [%s]\n", a_2(D), "arch=silvermont");
  _4 = 0;

  <bb 3> [0.00%] [count: INV]:
<L0>:
  return _4;

}



;; Function _Z3fooPKc.resolver (_Z3fooPKc.resolver, funcdef_no=4,
decl_uid=2462, cgraph_uid=6, symbol_order=6)

_Z3fooPKc.resolver ()
{
  void * D.2466;
  int D.2465;
  void * D.2464;
  int _3;
  void * _4;
  void * _5;

  <bb 2> [100.00%] [count: INV]:
  __builtin_cpu_init ();
  _3 = __builtin_cpu_is (&"silvermont"[0]);
  if (_3 > 0)
    goto <bb 3>; [100.00%] [count: INV]
  else
    goto <bb 4>; [INV] [count: INV]

  <bb 3> [100.00%] [count: INV]:
  _5 = (void *) foo;
  return _5;

  <bb 4> [100.00%] [count: INV]:
  _4 = (void *) foo;
  return _4;

}


foo ("arch=silvermont") [default]

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]