LCOV - code coverage report
Current view: top level - gcc/rust/backend - rust-compile-drop.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 62 62
Test Date: 2026-09-19 16:22:48 Functions: 100.0 % 4 4
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2026 Free Software Foundation, Inc.
       2              : 
       3              : // This file is part of GCC.
       4              : 
       5              : // GCC is free software; you can redistribute it and/or modify it under
       6              : // the terms of the GNU General Public License as published by the Free
       7              : // Software Foundation; either version 3, or (at your option) any later
       8              : // version.
       9              : 
      10              : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11              : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12              : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13              : // for more details.
      14              : 
      15              : // You should have received a copy of the GNU General Public License
      16              : // along with GCC; see the file COPYING3.  If not see
      17              : // <http://www.gnu.org/licenses/>.
      18              : 
      19              : #include "rust-compile-drop.h"
      20              : #include "rust-compile-drop-builder.h"
      21              : #include "rust-compile-base.h"
      22              : #include "rust-compile-context.h"
      23              : #include "rust-compile-implitem.h"
      24              : #include "rust-bir-drop-analysis.h"
      25              : #include "rust-hir-path-probe-impl-trait.h"
      26              : #include "rust-hir-trait-reference.h"
      27              : #include "rust-hir-type-bounds.h"
      28              : #include "rust-lang-item.h"
      29              : #include "rust-tyty.h"
      30              : 
      31              : namespace Rust {
      32              : namespace Compile {
      33              : 
      34        70589 : CompileDrop::CompileDrop (Context *ctx) : ctx (ctx) {}
      35              : 
      36              : bool
      37        31345 : CompileDrop::type_has_drop_impl (TyTy::BaseType *ty)
      38              : {
      39        31345 :   auto drop_lang_item
      40        31345 :     = ctx->get_mappings ().lookup_lang_item (LangItem::Kind::DROP);
      41              : 
      42        31345 :   if (!drop_lang_item.has_value ())
      43              :     return false;
      44              : 
      45          240 :   DefId drop_id = drop_lang_item.value ();
      46              : 
      47          240 :   auto candidates = Resolver::TypeBoundsProbe::Probe (ty);
      48          361 :   for (auto &candidate : candidates)
      49              :     {
      50          240 :       Resolver::TraitReference *trait_ref = candidate.first;
      51          361 :       if (trait_ref != nullptr && trait_ref->get_defid () == drop_id)
      52          119 :         return true;
      53              :     }
      54              : 
      55              :   return false;
      56          240 : }
      57              : 
      58              : // Find the Drop trait, look for the drop method, and build the function call.
      59              : tree
      60           58 : CompileDrop::compile_drop_call (Bvariable *var, TyTy::BaseType *ty,
      61              :                                 location_t locus)
      62              : {
      63           58 :   auto drop_lang = ctx->get_mappings ().lookup_lang_item (LangItem::Kind::DROP);
      64           58 :   if (!drop_lang.has_value ())
      65              :     return NULL_TREE;
      66              : 
      67           58 :   Resolver::TraitReference *drop_ref = nullptr;
      68           58 :   bool ok
      69           58 :     = ctx->get_tyctx ()->lookup_trait_reference (drop_lang.value (), &drop_ref);
      70           58 :   if (!ok)
      71              :     return NULL_TREE;
      72              : 
      73           58 :   HIR::PathIdentSegment segment ("drop");
      74           58 :   auto candidates
      75           58 :     = Resolver::PathProbeImplTrait::Probe (ty->get_root (), segment, drop_ref);
      76              : 
      77           58 :   rust_assert (candidates.size () == 1);
      78              : 
      79           58 :   auto &candidate = *candidates.begin ();
      80           58 :   rust_assert (candidate.is_impl_candidate ());
      81           58 :   rust_assert (candidate.ty->get_kind () == TyTy::TypeKind::FNDEF);
      82              : 
      83           58 :   auto *fn_type = static_cast<TyTy::FnType *> (candidate.ty);
      84           58 :   tree fn_addr
      85           58 :     = CompileInherentImplItem::Compile (candidate.item.impl.impl_item, ctx,
      86              :                                         fn_type, locus);
      87              : 
      88           58 :   tree var_expr = Backend::var_expression (var, locus);
      89           58 :   tree var_addr = HIRCompileBase::address_expression (var_expr, locus);
      90              : 
      91           58 :   return Backend::call_expression (fn_addr, {var_addr}, nullptr, locus);
      92           58 : }
      93              : 
      94              : tree
      95        39244 : CompileDrop::build_current_scope_drop_cleanup ()
      96              : {
      97        39244 :   std::vector<tree> drop_stmts;
      98              : 
      99        39244 :   DropBuilder drop_builder (*ctx);
     100        39244 :   auto &drop_candidates = drop_builder.peek_block_drop_candidates ();
     101              : 
     102        39307 :   for (auto it = drop_candidates.rbegin (); it != drop_candidates.rend (); ++it)
     103              :     {
     104           63 :       if (BIR::DropAnalysis::get ().is_definitely_dead (it->hirid))
     105            5 :         continue;
     106              : 
     107           58 :       TyTy::BaseType *ty = nullptr;
     108           58 :       Bvariable *var = nullptr;
     109              : 
     110           58 :       bool ok = ctx->get_tyctx ()->lookup_type (it->hirid, &ty);
     111           58 :       rust_assert (ok);
     112              : 
     113           58 :       ok = ctx->lookup_var_decl (it->hirid, &var);
     114           58 :       rust_assert (ok);
     115              : 
     116           58 :       tree drop_call = compile_drop_call (var, ty, it->locus);
     117           58 :       if (drop_call != NULL_TREE)
     118              :         {
     119           58 :           tree drop_stmt = convert_to_void (drop_call, ICV_STATEMENT);
     120           58 :           Bvariable *flag = nullptr;
     121           58 :           if (ctx->lookup_drop_flag (it->hirid, &flag))
     122              :             {
     123            1 :               tree condition = Backend::var_expression (flag, it->locus);
     124            1 :               tree clear = drop_builder.drop_flag_assignment (it->hirid, false,
     125            1 :                                                               it->locus);
     126            1 :               tree guarded_drop = Backend::statement_list ({clear, drop_stmt});
     127            1 :               drop_stmt
     128            1 :                 = Backend::if_statement (ctx->peek_fn ().fndecl, condition,
     129            1 :                                          guarded_drop, NULL_TREE, it->locus);
     130              :             }
     131           58 :           drop_stmts.push_back (drop_stmt);
     132              :         }
     133              :     }
     134              : 
     135        39244 :   if (drop_stmts.empty ())
     136              :     return NULL_TREE;
     137              : 
     138           50 :   return Backend::statement_list (drop_stmts);
     139        39244 : }
     140              : 
     141              : } // namespace Compile
     142              : } // namespace Rust
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.