]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix duplicated function generation on higher ranked trait bounds
authorPhilip Herron <philip.herron@embecosm.com>
Tue, 27 Sep 2022 11:19:43 +0000 (12:19 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 31 Jan 2023 13:16:52 +0000 (14:16 +0100)
Deuplicate function elimination can fail when we compile helpers during
higher ranked trait bound monomorphization. This because the
TyTy::BaseType info can be lost/reset during the compilation process. This
adds a second mechanism to match based on the manged names which is a bit
more reliable. This patch is required since the query based refactor of
the type system so this issue was likely hidden to to using duplicated type
info for higher ranked trait bounds.

gcc/rust/ChangeLog:

* backend/rust-compile-context.h: Add new optional `asm_name` string
argument to `lookup_function_decl`.
* backend/rust-compile-item.cc (CompileItem::visit): Compute assembly
name and pass it to `lookup_function_decl` when calling it.

gcc/rust/backend/rust-compile-context.h
gcc/rust/backend/rust-compile-item.cc

index 2d379c2a5fae275eb71d5bdc0450e2038dcbcec3..49f78e19b20e2e63548624fe8481f3622d97b2f2 100644 (file)
@@ -148,7 +148,8 @@ public:
   }
 
   bool lookup_function_decl (HirId id, tree *fn, DefId dId = UNKNOWN_DEFID,
-                            const TyTy::BaseType *ref = nullptr)
+                            const TyTy::BaseType *ref = nullptr,
+                            const std::string &asm_name = std::string ())
   {
     // for for any monomorphized fns
     if (ref != nullptr)
@@ -163,11 +164,29 @@ public:
          {
            const TyTy::BaseType *r = e.first;
            tree f = e.second;
+
            if (ref->is_equal (*r))
              {
                *fn = f;
                return true;
              }
+
+           if (DECL_ASSEMBLER_NAME_SET_P (f) && !asm_name.empty ())
+             {
+               tree raw = DECL_ASSEMBLER_NAME_RAW (f);
+               const char *rptr = IDENTIFIER_POINTER (raw);
+
+               bool lengths_match_p
+                 = IDENTIFIER_LENGTH (raw) == asm_name.size ();
+               if (lengths_match_p
+                   && strncmp (rptr, asm_name.c_str (),
+                               IDENTIFIER_LENGTH (raw))
+                        == 0)
+                 {
+                   *fn = f;
+                   return true;
+                 }
+             }
          }
        return false;
       }
index d1cdc3b66985b67e614f03fad830d6a499e2a798..b2e9b3fbf6ded1f0223fb1ea53fa257a7cf82476 100644 (file)
@@ -134,11 +134,18 @@ CompileItem::visit (HIR::Function &function)
        }
     }
 
+  const Resolver::CanonicalPath *canonical_path = nullptr;
+  bool ok = ctx->get_mappings ()->lookup_canonical_path (
+    function.get_mappings ().get_nodeid (), &canonical_path);
+  rust_assert (ok);
+
+  const std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
+
   // items can be forward compiled which means we may not need to invoke this
   // code. We might also have already compiled this generic function as well.
   tree lookup = NULL_TREE;
   if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
-                                fntype->get_id (), fntype))
+                                fntype->get_id (), fntype, asm_name))
     {
       // has this been added to the list then it must be finished
       if (ctx->function_completed (lookup))
@@ -160,11 +167,6 @@ CompileItem::visit (HIR::Function &function)
       fntype->override_context ();
     }
 
-  const Resolver::CanonicalPath *canonical_path = nullptr;
-  bool ok = ctx->get_mappings ()->lookup_canonical_path (
-    function.get_mappings ().get_nodeid (), &canonical_path);
-  rust_assert (ok);
-
   if (function.get_qualifiers ().is_const ())
     ctx->push_const_context ();