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