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-03 16:17:38 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        20785 : ReachabilityVisitor::get_reachability_level (
      36              :   const HIR::Visibility &item_visibility)
      37              : {
      38        20785 :   return item_visibility.is_public () ? current_level : ReachLevel::Unreachable;
      39              : }
      40              : 
      41              : void
      42        19076 : ReachabilityVisitor::visit_generic_predicates (
      43              :   const std::vector<std::unique_ptr<HIR::GenericParam>> &generics,
      44              :   ReachLevel item_reach)
      45              : {
      46        19076 :   if (item_reach == ReachLevel::Unreachable)
      47              :     return;
      48              : 
      49         9096 :   for (const auto &generic : generics)
      50              :     {
      51         4321 :       if (generic->get_kind () == HIR::GenericParam::GenericKind::TYPE)
      52              :         {
      53         4290 :           TyTy::BaseType *ty = nullptr;
      54         4290 :           auto ok
      55         4290 :             = ty_ctx.lookup_type (generic->get_mappings ().get_hirid (), &ty);
      56         4290 :           rust_assert (ok);
      57              : 
      58         8960 :           for (const auto &bound : ty->get_specified_bounds ())
      59              :             {
      60         4670 :               const auto trait = bound.get ()->get_hir_trait_ref ();
      61         4670 :               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         6602 : ReachabilityVisitor::visit (HIR::Function &func)
     101              : {
     102         6602 :   auto fn_reach = get_reachability_level (func.get_visibility ());
     103              : 
     104         6602 :   fn_reach = ctx.update_reachability (func.get_mappings (), fn_reach);
     105         6602 :   visit_generic_predicates (func.get_generic_params (), fn_reach);
     106         6602 : }
     107              : 
     108              : void
     109           60 : ReachabilityVisitor::visit (HIR::TypeAlias &type_alias)
     110              : {
     111           60 :   auto type_reach = get_reachability_level (type_alias.get_visibility ());
     112              : 
     113           60 :   visit_generic_predicates (type_alias.get_generic_params (), type_reach);
     114           60 : }
     115              : 
     116              : void
     117         1480 : ReachabilityVisitor::visit (HIR::StructStruct &struct_item)
     118              : {
     119         1480 :   auto struct_reach = get_reachability_level (struct_item.get_visibility ());
     120              : 
     121         1480 :   struct_reach
     122         1480 :     = ctx.update_reachability (struct_item.get_mappings (), struct_reach);
     123              : 
     124         1480 :   auto old_level = current_level;
     125         1480 :   current_level = struct_reach;
     126              : 
     127         1480 :   visit_generic_predicates (struct_item.get_generic_params (), struct_reach);
     128              : 
     129         1480 :   if (struct_reach != ReachLevel::Unreachable)
     130              :     {
     131          717 :       for (auto &field : struct_item.get_fields ())
     132          352 :         if (field.get_visibility ().is_public ())
     133          266 :           ctx.update_reachability (field.get_field_type ().get_mappings (),
     134              :                                    struct_reach);
     135              :     }
     136              : 
     137         1480 :   current_level = old_level;
     138         1480 : }
     139              : 
     140              : void
     141          819 : ReachabilityVisitor::visit (HIR::TupleStruct &)
     142          819 : {}
     143              : 
     144              : void
     145          514 : ReachabilityVisitor::visit (HIR::Enum &enum_item)
     146              : {
     147          514 :   auto enum_reach = get_reachability_level (enum_item.get_visibility ());
     148              : 
     149          514 :   enum_reach = ctx.update_reachability (enum_item.get_mappings (), enum_reach);
     150          514 :   visit_generic_predicates (enum_item.get_generic_params (), enum_reach);
     151              : 
     152         1720 :   for (const auto &variant : enum_item.get_variants ())
     153              :     {
     154         1206 :       auto variant_reach
     155         1206 :         = ctx.update_reachability (variant->get_mappings (), enum_reach);
     156              : 
     157         1206 :       switch (variant->get_enum_item_kind ())
     158              :         {
     159          414 :         case HIR::EnumItem::Tuple:
     160          414 :           {
     161              :             // Should we update the fields only if they are public? Similarly to
     162              :             // what we do in the ReachabilityVisitor for HIR::TupleStruct?
     163          414 :             auto tuple_variant
     164          414 :               = static_cast<HIR::EnumItemTuple *> (variant.get ());
     165          852 :             for (const auto &field : tuple_variant->get_tuple_fields ())
     166          438 :               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          514 : }
     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          409 : ReachabilityVisitor::visit (HIR::ConstantItem &const_item)
     199              : {
     200          409 :   auto reach = get_reachability_level (const_item.get_visibility ());
     201          409 :   reach = ctx.update_reachability (const_item.get_mappings (), reach);
     202          409 : }
     203              : 
     204              : void
     205           55 : ReachabilityVisitor::visit (HIR::StaticItem &static_item)
     206              : {
     207           55 :   auto reach = get_reachability_level (static_item.get_visibility ());
     208           55 :   reach = ctx.update_reachability (static_item.get_mappings (), reach);
     209           55 : }
     210              : 
     211              : void
     212         4000 : ReachabilityVisitor::visit (HIR::Trait &trait)
     213              : {
     214         4000 :   auto trait_reach = get_reachability_level (trait.get_visibility ());
     215              : 
     216         4000 :   trait_reach = ctx.update_reachability (trait.get_mappings (), trait_reach);
     217         4000 :   visit_generic_predicates (trait.get_generic_params (), trait_reach);
     218         4000 : }
     219              : 
     220              : void
     221         6318 : ReachabilityVisitor::visit (HIR::ImplBlock &impl)
     222              : {
     223         6318 :   auto impl_reach = get_reachability_level (impl.get_visibility ());
     224              : 
     225         6318 :   impl_reach = ctx.update_reachability (impl.get_mappings (), impl_reach);
     226         6318 :   visit_generic_predicates (impl.get_generic_params (), impl_reach);
     227         6318 : }
     228              : 
     229              : void
     230         1687 : ReachabilityVisitor::visit (HIR::ExternBlock &)
     231         1687 : {}
     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.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.