On 3/4/21 10:39 AM, Martin Liška wrote:
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.

Sure, I guess you do need to set that flag for the local decls, but that should be all.

Jason

Reply via email to