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]