On 3/4/21 4:03 PM, Jason Merrill wrote:
Do you really need to register all these pairs? I was expecting that you'd
just look through DECL_LOCAL_DECL_ALIAS and then register the pair you end up
with. Local decls shouldn't need a cgraph node.
Well, doing that:
commit 662c486edafa467ec41091e84857d594eaf280a2
Author: Martin Liska <mli...@suse.cz>
Date: Wed Mar 3 09:38:55 2021 +0100
c++: support target attr for DECL_LOCAL_DECL_P fns
gcc/cp/ChangeLog:
PR c++/99108
* call.c (get_function_version_dispatcher): Understand
DECL_LOCAL_DECL_ALIAS.
* decl.c (record_function_versions): New.
(maybe_version_functions): Call record_function_versions
for both declarations and DECL_LOCAL_DECL_ALIAS aliases.
gcc/testsuite/ChangeLog:
PR c++/99108
* g++.target/i386/pr99108.C: New test.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 123f06b1f2b..117f1755191 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8467,6 +8467,10 @@ get_function_version_dispatcher (tree fn)
{
tree dispatcher_decl = NULL;
+ if (DECL_LOCAL_DECL_P (fn)
+ && DECL_LOCAL_DECL_ALIAS (fn) != NULL_TREE)
+ fn = DECL_LOCAL_DECL_ALIAS (fn);
+
gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
&& DECL_FUNCTION_VERSIONED (fn));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 1742e286d9f..a092539bfa0 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1115,6 +1115,14 @@ decls_match (tree newdecl, tree olddecl, bool
record_versions /* = true */)
bool
maybe_version_functions (tree newdecl, tree olddecl, bool record)
{
+ if (DECL_LOCAL_DECL_P (olddecl)
+ && DECL_LOCAL_DECL_ALIAS (olddecl) != NULL_TREE)
+ olddecl = DECL_LOCAL_DECL_ALIAS (olddecl);
+
+ if (DECL_LOCAL_DECL_P (newdecl)
+ && DECL_LOCAL_DECL_ALIAS (newdecl) != NULL_TREE)
+ newdecl = DECL_LOCAL_DECL_ALIAS (newdecl);
+
if (!targetm.target_option.function_versions (newdecl, olddecl))
return false;
The compilation then fails:
/home/marxin/Programming/gcc/gcc/testsuite/g++.target/i386/pr99108.C: In member
function ‘void A::foo(auto:2)’:
/home/marxin/Programming/gcc/gcc/testsuite/g++.target/i386/pr99108.C:12:13:
error: call of overloaded ‘f()’ is ambiguous
12 | int b = f();
| ^
/home/marxin/Programming/gcc/gcc/testsuite/g++.target/i386/pr99108.C:10:7:
note: candidate: ‘int f()’
10 | int f(void) __attribute__((target("default")));
| ^
/home/marxin/Programming/gcc/gcc/testsuite/g++.target/i386/pr99108.C:11:7:
note: candidate: ‘int f()’
11 | int f(void) __attribute__((target("arch=atom")));
| ^
likely because DECL_FUNCTION_VERSIONED is missing for the local decls.
Martin