This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/81760] New: attribute target uses the wrong default function argument
- From: "msebor at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 07 Aug 2017 21:45:23 +0000
- Subject: [Bug c++/81760] New: attribute target uses the wrong default function argument
- Auto-submitted: auto-generated
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]