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

Reply via email to