LCOV - code coverage report
Current view: top level - gcc/rust/checks/errors/privacy - rust-reachability.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.2 % 103 95
Test Date: 2026-10-24 16:24:59 Functions: 88.2 % 17 15
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-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-reachability.h"
      20              : #include "rust-tyty.h"
      21              : 
      22              : namespace Rust {
      23              : namespace Privacy {
      24              : 
      25              : static HIR::VisItem *
      26         4173 : maybe_get_vis_item (std::unique_ptr<HIR::Item> &item)
      27              : {
      28         4173 :   if (item->get_hir_kind () != HIR::Node::VIS_ITEM)
      29              :     return nullptr;
      30              : 
      31         4173 :   return static_cast<HIR::VisItem *> (item.get ());
      32              : }
      33              : 
      34              : ReachLevel
      35        21064 : ReachabilityVisitor::get_reachability_level (
      36              :   const HIR::Visibility &item_visibility)
      37              : {
      38        21064 :   return item_visibility.is_public () ? current_level : ReachLevel::Unreachable;
      39              : }
      40              : 
      41              : void
      42        19321 : ReachabilityVisitor::visit_generic_predicates (
      43              :   const std::vector<std::unique_ptr<HIR::GenericParam>> &generics,
      44              :   ReachLevel item_reach)
      45              : {
      46        19321 :   if (item_reach == ReachLevel::Unreachable)
      47              :     return;
      48              : 
      49         9183 :   for (const auto &generic : generics)
      50              :     {
      51         4371 :       if (generic->get_kind () == HIR::GenericParam::GenericKind::TYPE)
      52              :         {
      53         4333 :           TyTy::BaseType *ty = nullptr;
      54         4333 :           auto ok
      55         4333 :             = ty_ctx.lookup_type (generic->get_mappings ().get_hirid (), &ty);
      56         4333 :           rust_assert (ok);
      57              : 
      58         9056 :           for (const auto &bound : ty->get_specified_bounds ())
      59              :             {
      60         4723 :               const auto trait = bound.get ()->get_hir_trait_ref ();
      61         4723 :               ctx.update_reachability (trait->get_mappings (), item_reach);
      62              :             }
      63              :         }
      64              :     }
      65              : }
      66              : 
      67              : void
      68         1245 : ReachabilityVisitor::visit (HIR::Module &mod)
      69              : {
      70         1245 :   auto reach = get_reachability_level (mod.get_visibility ());
      71         1245 :   reach = ctx.update_reachability (mod.get_mappings (), reach);
      72              : 
      73         5418 :   for (auto &item : mod.get_items ())
      74              :     {
      75              :       // FIXME: Is that what we want to do? Yes? Only visit the items with
      76              :       // visibility?
      77              :       //
      78              :       // Imagine if we had `maybe_get_vis_item(item)?->accept_vis(*this)` ;)
      79         4173 :       auto vis_item = maybe_get_vis_item (item);
      80         4173 :       if (vis_item)
      81         4173 :         vis_item->accept_vis (*this);
      82              :     }
      83         1245 : }
      84              : 
      85              : void
      86            0 : ReachabilityVisitor::visit (HIR::ExternCrate &crate)
      87              : {
      88            0 :   auto reach = get_reachability_level (crate.get_visibility ());
      89            0 :   reach = ctx.update_reachability (crate.get_mappings (), reach);
      90            0 : }
      91              : 
      92              : void
      93            0 : ReachabilityVisitor::visit (HIR::UseDeclaration &use_decl)
      94              : {
      95            0 :   auto reach = get_reachability_level (use_decl.get_visibility ());
      96            0 :   reach = ctx.update_reachability (use_decl.get_mappings (), reach);
      97            0 : }
      98              : 
      99              : void
     100         6710 : ReachabilityVisitor::visit (HIR::Function &func)
     101              : {
     102         6710 :   auto fn_reach = get_reachability_level (func.get_visibility ());
     103              : 
     104         6710 :   fn_reach = ctx.update_reachability (func.get_mappings (), fn_reach);
     105         6710 :   visit_generic_predicates (func.get_generic_params (), fn_reach);
     106         6710 : }
     107              : 
     108              : void
     109           61 : ReachabilityVisitor::visit (HIR::TypeAlias &type_alias)
     110              : {
     111           61 :   auto type_reach = get_reachability_level (type_alias.get_visibility ());
     112              : 
     113           61 :   visit_generic_predicates (type_alias.get_generic_params (), type_reach);
     114           61 : }
     115              : 
     116              : void
     117         1511 : ReachabilityVisitor::visit (HIR::StructStruct &struct_item)
     118              : {
     119         1511 :   auto struct_reach = get_reachability_level (struct_item.get_visibility ());
     120              : 
     121         1511 :   struct_reach
     122         1511 :     = ctx.update_reachability (struct_item.get_mappings (), struct_reach);
     123              : 
     124         1511 :   auto old_level = current_level;
     125         1511 :   current_level = struct_reach;
     126              : 
     127         1511 :   visit_generic_predicates (struct_item.get_generic_params (), struct_reach);
     128              : 
     129         1511 :   if (struct_reach != ReachLevel::Unreachable)
     130              :     {
     131          729 :       for (auto &field : struct_item.get_fields ())
     132          359 :         if (field.get_visibility ().is_public ())
     133          267 :           ctx.update_reachability (field.get_field_type ().get_mappings (),
     134              :                                    struct_reach);
     135              :     }
     136              : 
     137         1511 :   current_level = old_level;
     138         1511 : }
     139              : 
     140              : void
     141          834 : ReachabilityVisitor::visit (HIR::TupleStruct &)
     142          834 : {}
     143              : 
     144              : void
     145          526 : ReachabilityVisitor::visit (HIR::Enum &enum_item)
     146              : {
     147          526 :   auto enum_reach = get_reachability_level (enum_item.get_visibility ());
     148              : 
     149          526 :   enum_reach = ctx.update_reachability (enum_item.get_mappings (), enum_reach);
     150          526 :   visit_generic_predicates (enum_item.get_generic_params (), enum_reach);
     151              : 
     152         1764 :   for (const auto &variant : enum_item.get_variants ())
     153              :     {
     154         1238 :       auto variant_reach
     155         1238 :         = ctx.update_reachability (variant->get_mappings (), enum_reach);
     156              : 
     157         1238 :       switch (variant->get_enum_item_kind ())
     158              :         {
     159          433 :         case HIR::EnumItem::Tuple:
     160          433 :           {
     161              :             // Should we update the fields only if they are public? Similarly to
     162              :             // what we do in the ReachabilityVisitor for HIR::TupleStruct?
     163          433 :             auto tuple_variant
     164          433 :               = static_cast<HIR::EnumItemTuple *> (variant.get ());
     165          898 :             for (const auto &field : tuple_variant->get_tuple_fields ())
     166          465 :               ctx.update_reachability (field.get_mappings (), variant_reach);
     167              :             break;
     168              :           }
     169           79 :         case HIR::EnumItem::Struct:
     170           79 :           {
     171              :             // Should we update the fields only if they are public? Similarly to
     172              :             // what we do in the ReachabilityVisitor for HIR::StructStruct?
     173           79 :             auto struct_variant
     174           79 :               = static_cast<HIR::EnumItemStruct *> (variant.get ());
     175          209 :             for (const auto &field : struct_variant->get_struct_fields ())
     176          130 :               ctx.update_reachability (field.get_mappings (), variant_reach);
     177              :             break;
     178              :           }
     179              :         // Nothing nested to visit in that case
     180              :         case HIR::EnumItem::Named:
     181              :         case HIR::EnumItem::Discriminant:
     182              :           break;
     183              :         }
     184              :     }
     185          526 : }
     186              : 
     187              : void
     188          102 : ReachabilityVisitor::visit (HIR::Union &union_item)
     189              : {
     190          102 :   auto union_reach = get_reachability_level (union_item.get_visibility ());
     191              : 
     192          102 :   union_reach
     193          102 :     = ctx.update_reachability (union_item.get_mappings (), union_reach);
     194          102 :   visit_generic_predicates (union_item.get_generic_params (), union_reach);
     195          102 : }
     196              : 
     197              : void
     198          424 : ReachabilityVisitor::visit (HIR::ConstantItem &const_item)
     199              : {
     200          424 :   auto reach = get_reachability_level (const_item.get_visibility ());
     201          424 :   reach = ctx.update_reachability (const_item.get_mappings (), reach);
     202          424 : }
     203              : 
     204              : void
     205           74 : ReachabilityVisitor::visit (HIR::StaticItem &static_item)
     206              : {
     207           74 :   auto reach = get_reachability_level (static_item.get_visibility ());
     208           74 :   reach = ctx.update_reachability (static_item.get_mappings (), reach);
     209           74 : }
     210              : 
     211              : void
     212         4064 : ReachabilityVisitor::visit (HIR::Trait &trait)
     213              : {
     214         4064 :   auto trait_reach = get_reachability_level (trait.get_visibility ());
     215              : 
     216         4064 :   trait_reach = ctx.update_reachability (trait.get_mappings (), trait_reach);
     217         4064 :   visit_generic_predicates (trait.get_generic_params (), trait_reach);
     218         4064 : }
     219              : 
     220              : void
     221         6347 : ReachabilityVisitor::visit (HIR::ImplBlock &impl)
     222              : {
     223         6347 :   auto impl_reach = get_reachability_level (impl.get_visibility ());
     224              : 
     225         6347 :   impl_reach = ctx.update_reachability (impl.get_mappings (), impl_reach);
     226         6347 :   visit_generic_predicates (impl.get_generic_params (), impl_reach);
     227         6347 : }
     228              : 
     229              : void
     230         1696 : ReachabilityVisitor::visit (HIR::ExternBlock &)
     231         1696 : {}
     232              : 
     233              : // FIXME: How can we visit Blocks in the current configuration? Have a full
     234              : // visitor?
     235              : } // namespace Privacy
     236              : } // namespace Rust
        

Generated by: LCOV version 2.5.0-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.