From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 7725C3895FD7; Wed, 8 Jun 2022 12:46:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7725C3895FD7 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] privacy: Add base for privacy violation visitor X-Act-Checkin: gcc X-Git-Author: Arthur Cohen X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: d374eb47de109af21faa0cfe9fd76a353d9bd06f X-Git-Newrev: 48fc2df91b07709f41ab80499a661ac9f12f3be3 Message-Id: <20220608124651.7725C3895FD7@sourceware.org> Date: Wed, 8 Jun 2022 12:46:51 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jun 2022 12:46:51 -0000 https://gcc.gnu.org/g:48fc2df91b07709f41ab80499a661ac9f12f3be3 commit 48fc2df91b07709f41ab80499a661ac9f12f3be3 Author: Arthur Cohen Date: Thu May 12 13:26:34 2022 +0200 privacy: Add base for privacy violation visitor Diff: --- gcc/rust/Make-lang.in | 1 + gcc/rust/privacy/rust-privacy-check.cc | 2 + gcc/rust/privacy/rust-privacy-common.h | 9 +- gcc/rust/privacy/rust-privacy-reporter.cc | 645 ++++++++++++++++++++++++ gcc/rust/privacy/rust-privacy-reporter.h | 201 ++++++++ gcc/rust/privacy/rust-pub-restricted-visitor.cc | 1 + gcc/rust/privacy/rust-visibility-resolver.cc | 9 +- gcc/rust/privacy/rust-visibility-resolver.h | 1 + gcc/rust/util/rust-optional.h | 1 + gcc/testsuite/rust/compile/privacy1.rs | 11 + gcc/testsuite/rust/compile/pub_restricted_3.rs | 11 + 11 files changed, 885 insertions(+), 7 deletions(-) diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index 3f911ca8e17..f87ad547622 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -100,6 +100,7 @@ GRS_OBJS = \ rust/rust-reachability.o \ rust/rust-visibility-resolver.o \ rust/rust-pub-restricted-visitor.o \ + rust/rust-privacy-reporter.o \ rust/rust-tyty.o \ rust/rust-tyctx.o \ rust/rust-tyty-bounds.o \ diff --git a/gcc/rust/privacy/rust-privacy-check.cc b/gcc/rust/privacy/rust-privacy-check.cc index b2e33c0b059..dca5235806f 100644 --- a/gcc/rust/privacy/rust-privacy-check.cc +++ b/gcc/rust/privacy/rust-privacy-check.cc @@ -23,6 +23,7 @@ #include "rust-name-resolver.h" #include "rust-visibility-resolver.h" #include "rust-pub-restricted-visitor.h" +#include "rust-privacy-reporter.h" extern bool saw_errors (void); @@ -40,6 +41,7 @@ Resolver::resolve (HIR::Crate &crate) VisibilityResolver (*mappings, *resolver).go (crate); PubRestrictedVisitor (*mappings).go (crate); + PrivacyReporter (*mappings, *resolver).go (crate); auto visitor = ReachabilityVisitor (ctx, *ty_ctx); diff --git a/gcc/rust/privacy/rust-privacy-common.h b/gcc/rust/privacy/rust-privacy-common.h index 764e31ae5d4..ceafe91d886 100644 --- a/gcc/rust/privacy/rust-privacy-common.h +++ b/gcc/rust/privacy/rust-privacy-common.h @@ -24,6 +24,9 @@ namespace Privacy { /** * Visibility class related specifically to DefIds. This class allows defining * the visibility of an item with regard to a specific module. + * + * Items are either public throughout a crate, or restricted to a specific + * module. Private items are simply restricted to the current module. */ class ModuleVisibility { @@ -31,7 +34,6 @@ public: enum Type { Unknown, - Private, Public, Restricted, }; @@ -48,11 +50,6 @@ public: return ModuleVisibility (Type::Public, UNKNOWN_DEFID); } - static ModuleVisibility create_private () - { - return ModuleVisibility (Type::Private, UNKNOWN_DEFID); - } - Type get_kind () const { return kind; } const DefId &get_module_id () const { return module_id; } diff --git a/gcc/rust/privacy/rust-privacy-reporter.cc b/gcc/rust/privacy/rust-privacy-reporter.cc new file mode 100644 index 00000000000..4c18adb8615 --- /dev/null +++ b/gcc/rust/privacy/rust-privacy-reporter.cc @@ -0,0 +1,645 @@ +#include "rust-privacy-reporter.h" +#include "rust-hir-expr.h" +#include "rust-hir-stmt.h" +#include "rust-hir-item.h" + +namespace Rust { +namespace Privacy { + +PrivacyReporter::PrivacyReporter (Analysis::Mappings &mappings, + Resolver::Resolver &resolver) + : mappings (mappings), resolver (resolver), + current_module (Optional::none ()) +{} + +void +PrivacyReporter::go (HIR::Crate &crate) +{ + for (auto &item : crate.items) + item->accept_vis (*this); +} + +static bool +is_child_module (NodeId current_module, + Optional &> children) +{ + if (!children) + return false; + + // FIXME: This checks for one step - we need to go deeper + for (auto &child : *children) + if (child == current_module) + return true; + + return false; +} + +// FIXME: This function needs a lot of refactoring +void +PrivacyReporter::check_for_privacy_violation (const NodeId &use_id, + const Location &locus) +{ + NodeId ref_node_id; + + // FIXME: Don't assert here - we might be dealing with a type + rust_assert (resolver.lookup_resolved_name (use_id, &ref_node_id)); + + ModuleVisibility vis; + + // FIXME: Can we really return here if the item has no visibility? + if (!mappings.lookup_visibility (ref_node_id, vis)) + return; + + auto valid = true; + + switch (vis.get_kind ()) + { + case ModuleVisibility::Public: + break; + case ModuleVisibility::Restricted: { + // If we are in the crate, everything is restricted correctly, but we + // can't get a module for it + if (current_module.is_none ()) + return; + + auto module = mappings.lookup_defid (vis.get_module_id ()); + rust_assert (module != nullptr); + + auto mod_node_id = module->get_mappings ().get_nodeid (); + + // We are in the module referenced by the pub(restricted) visibility. + // This is valid + if (mod_node_id == current_module.get ()) + break; + + auto children = mappings.lookup_module_children (mod_node_id); + + // FIXME: This needs a LOT of TLC: hinting about the definition, a + // string to say if it's a module, function, type, etc... + if (!is_child_module (current_module.get (), children)) + valid = false; + } + break; + case ModuleVisibility::Unknown: + rust_unreachable (); + break; + } + + if (!valid) + rust_error_at (locus, "definition is private in this context"); +} + +void +PrivacyReporter::visit (HIR::IdentifierExpr &ident_expr) +{} + +void +PrivacyReporter::visit (HIR::Lifetime &lifetime) +{} + +void +PrivacyReporter::visit (HIR::LifetimeParam &lifetime_param) +{} + +void +PrivacyReporter::visit (HIR::PathInExpression &path) +{ + check_for_privacy_violation (path.get_mappings ().get_nodeid (), + path.get_locus ()); +} + +void +PrivacyReporter::visit (HIR::TypePathSegment &segment) +{} + +void +PrivacyReporter::visit (HIR::TypePathSegmentGeneric &segment) +{} + +void +PrivacyReporter::visit (HIR::TypePathSegmentFunction &segment) +{} + +void +PrivacyReporter::visit (HIR::TypePath &path) +{} + +void +PrivacyReporter::visit (HIR::QualifiedPathInExpression &path) +{} + +void +PrivacyReporter::visit (HIR::QualifiedPathInType &path) +{} + +void +PrivacyReporter::visit (HIR::LiteralExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::BorrowExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::DereferenceExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::ErrorPropagationExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::NegationExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::ArithmeticOrLogicalExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::ComparisonExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::LazyBooleanExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::TypeCastExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::AssignmentExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::CompoundAssignmentExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::GroupedExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::ArrayElemsValues &elems) +{} + +void +PrivacyReporter::visit (HIR::ArrayElemsCopied &elems) +{} + +void +PrivacyReporter::visit (HIR::ArrayExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::ArrayIndexExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::TupleExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::TupleIndexExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::StructExprStruct &expr) +{} + +void +PrivacyReporter::visit (HIR::StructExprFieldIdentifier &field) +{} + +void +PrivacyReporter::visit (HIR::StructExprFieldIdentifierValue &field) +{} + +void +PrivacyReporter::visit (HIR::StructExprFieldIndexValue &field) +{} + +void +PrivacyReporter::visit (HIR::StructExprStructFields &expr) +{} + +void +PrivacyReporter::visit (HIR::StructExprStructBase &expr) +{} + +void +PrivacyReporter::visit (HIR::CallExpr &expr) +{ + expr.get_fnexpr ()->accept_vis (*this); + + // rust_assert (mappings.lookup_visibility (definition_id, def_vis)); + // check_for_privacy_violation (def_vis, expr.get_locus ()); +} + +void +PrivacyReporter::visit (HIR::MethodCallExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::FieldAccessExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::ClosureExprInner &expr) +{} + +void +PrivacyReporter::visit (HIR::BlockExpr &expr) +{ + for (auto &stmt : expr.get_statements ()) + stmt->accept_vis (*this); + + auto &last_expr = expr.get_final_expr (); + if (last_expr) + last_expr->accept_vis (*this); +} + +void +PrivacyReporter::visit (HIR::ClosureExprInnerTyped &expr) +{} + +void +PrivacyReporter::visit (HIR::ContinueExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::BreakExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::RangeFromToExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::RangeFromExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::RangeToExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::RangeFullExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::RangeFromToInclExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::RangeToInclExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::ReturnExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::UnsafeBlockExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::LoopExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::WhileLoopExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::WhileLetLoopExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::ForLoopExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::IfExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::IfExprConseqElse &expr) +{} + +void +PrivacyReporter::visit (HIR::IfExprConseqIf &expr) +{} + +void +PrivacyReporter::visit (HIR::IfExprConseqIfLet &expr) +{} + +void +PrivacyReporter::visit (HIR::IfLetExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::IfLetExprConseqElse &expr) +{} + +void +PrivacyReporter::visit (HIR::IfLetExprConseqIf &expr) +{} + +void +PrivacyReporter::visit (HIR::IfLetExprConseqIfLet &expr) +{} + +void +PrivacyReporter::visit (HIR::MatchExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::AwaitExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::AsyncBlockExpr &expr) +{} + +void +PrivacyReporter::visit (HIR::TypeParam ¶m) +{} + +void +PrivacyReporter::visit (HIR::LifetimeWhereClauseItem &item) +{} + +void +PrivacyReporter::visit (HIR::TypeBoundWhereClauseItem &item) +{} + +void +PrivacyReporter::visit (HIR::Module &module) +{ + auto old_module = current_module; + current_module + = Optional::some (module.get_mappings ().get_nodeid ()); + + for (auto &item : module.get_items ()) + item->accept_vis (*this); + + current_module = old_module; +} + +void +PrivacyReporter::visit (HIR::ExternCrate &crate) +{} + +void +PrivacyReporter::visit (HIR::UseTreeGlob &use_tree) +{} + +void +PrivacyReporter::visit (HIR::UseTreeList &use_tree) +{} + +void +PrivacyReporter::visit (HIR::UseTreeRebind &use_tree) +{} + +void +PrivacyReporter::visit (HIR::UseDeclaration &use_decl) +{} + +void +PrivacyReporter::visit (HIR::Function &function) +{ + function.get_definition ()->accept_vis (*this); +} + +void +PrivacyReporter::visit (HIR::TypeAlias &type_alias) +{} + +void +PrivacyReporter::visit (HIR::StructStruct &struct_item) +{} + +void +PrivacyReporter::visit (HIR::TupleStruct &tuple_struct) +{} + +void +PrivacyReporter::visit (HIR::EnumItem &item) +{} + +void +PrivacyReporter::visit (HIR::EnumItemTuple &item) +{} + +void +PrivacyReporter::visit (HIR::EnumItemStruct &item) +{} + +void +PrivacyReporter::visit (HIR::EnumItemDiscriminant &item) +{} + +void +PrivacyReporter::visit (HIR::Enum &enum_item) +{} + +void +PrivacyReporter::visit (HIR::Union &union_item) +{} + +void +PrivacyReporter::visit (HIR::ConstantItem &const_item) +{} + +void +PrivacyReporter::visit (HIR::StaticItem &static_item) +{} + +void +PrivacyReporter::visit (HIR::TraitItemFunc &item) +{} + +void +PrivacyReporter::visit (HIR::TraitItemConst &item) +{} + +void +PrivacyReporter::visit (HIR::TraitItemType &item) +{} + +void +PrivacyReporter::visit (HIR::Trait &trait) +{} + +void +PrivacyReporter::visit (HIR::ImplBlock &impl) +{} + +void +PrivacyReporter::visit (HIR::ExternalStaticItem &item) +{} + +void +PrivacyReporter::visit (HIR::ExternalFunctionItem &item) +{} + +void +PrivacyReporter::visit (HIR::ExternBlock &block) +{} + +void +PrivacyReporter::visit (HIR::LiteralPattern &pattern) +{} + +void +PrivacyReporter::visit (HIR::IdentifierPattern &pattern) +{} + +void +PrivacyReporter::visit (HIR::WildcardPattern &pattern) +{} + +void +PrivacyReporter::visit (HIR::RangePatternBoundLiteral &bound) +{} + +void +PrivacyReporter::visit (HIR::RangePatternBoundPath &bound) +{} + +void +PrivacyReporter::visit (HIR::RangePatternBoundQualPath &bound) +{} + +void +PrivacyReporter::visit (HIR::RangePattern &pattern) +{} + +void +PrivacyReporter::visit (HIR::ReferencePattern &pattern) +{} + +void +PrivacyReporter::visit (HIR::StructPatternFieldTuplePat &field) +{} + +void +PrivacyReporter::visit (HIR::StructPatternFieldIdentPat &field) +{} + +void +PrivacyReporter::visit (HIR::StructPatternFieldIdent &field) +{} + +void +PrivacyReporter::visit (HIR::StructPattern &pattern) +{} + +void +PrivacyReporter::visit (HIR::TupleStructItemsNoRange &tuple_items) +{} + +void +PrivacyReporter::visit (HIR::TupleStructItemsRange &tuple_items) +{} + +void +PrivacyReporter::visit (HIR::TupleStructPattern &pattern) +{} + +void +PrivacyReporter::visit (HIR::TuplePatternItemsMultiple &tuple_items) +{} + +void +PrivacyReporter::visit (HIR::TuplePatternItemsRanged &tuple_items) +{} + +void +PrivacyReporter::visit (HIR::TuplePattern &pattern) +{} + +void +PrivacyReporter::visit (HIR::GroupedPattern &pattern) +{} + +void +PrivacyReporter::visit (HIR::SlicePattern &pattern) +{} + +void +PrivacyReporter::visit (HIR::EmptyStmt &stmt) +{} + +void +PrivacyReporter::visit (HIR::LetStmt &stmt) +{} + +void +PrivacyReporter::visit (HIR::ExprStmtWithoutBlock &stmt) +{ + stmt.get_expr ()->accept_vis (*this); +} + +void +PrivacyReporter::visit (HIR::ExprStmtWithBlock &stmt) +{} + +void +PrivacyReporter::visit (HIR::TraitBound &bound) +{} + +void +PrivacyReporter::visit (HIR::ImplTraitType &type) +{} + +void +PrivacyReporter::visit (HIR::TraitObjectType &type) +{} + +void +PrivacyReporter::visit (HIR::ParenthesisedType &type) +{} + +void +PrivacyReporter::visit (HIR::ImplTraitTypeOneBound &type) +{} + +void +PrivacyReporter::visit (HIR::TupleType &type) +{} + +void +PrivacyReporter::visit (HIR::NeverType &type) +{} + +void +PrivacyReporter::visit (HIR::RawPointerType &type) +{} + +void +PrivacyReporter::visit (HIR::ReferenceType &type) +{} + +void +PrivacyReporter::visit (HIR::ArrayType &type) +{} + +void +PrivacyReporter::visit (HIR::SliceType &type) +{} + +void +PrivacyReporter::visit (HIR::InferredType &type) +{} + +void +PrivacyReporter::visit (HIR::BareFunctionType &type) +{} + +} // namespace Privacy +} // namespace Rust diff --git a/gcc/rust/privacy/rust-privacy-reporter.h b/gcc/rust/privacy/rust-privacy-reporter.h new file mode 100644 index 00000000000..fafcec1edac --- /dev/null +++ b/gcc/rust/privacy/rust-privacy-reporter.h @@ -0,0 +1,201 @@ +// Copyright (C) 2020-2022 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + +#ifndef RUST_PRIVACY_REPORTER_H +#define RUST_PRIVACY_REPORTER_H + +#include "rust-hir-map.h" +#include "rust-hir-visitor.h" +#include "rust-mapping-common.h" +#include "rust-name-resolver.h" + +namespace Rust { +namespace Privacy { + +/** + * This visitor visits all items and expressions of a crate and reports privacy + * violations. It should be started after using the `VisibilityResolver` visitor + * which resolves the visibilities of all items of a crate. + */ +class PrivacyReporter : public HIR::HIRFullVisitor +{ +public: + PrivacyReporter (Analysis::Mappings &mappings, + Rust::Resolver::Resolver &resolver); + + /** + * Perform privacy error reporting on an entire crate + */ + void go (HIR::Crate &crate); + +private: + /** + * Check if a given item's visibility is accessible from the current module. + * + * This function reports the errors it finds. + * + * @param use_id NodeId of the expression/statement referencing an item with + * a visibility + * @param locus Location of said expression/statement + */ + void check_for_privacy_violation (const NodeId &use_id, + const Location &locus); + + virtual void visit (HIR::IdentifierExpr &ident_expr); + virtual void visit (HIR::Lifetime &lifetime); + virtual void visit (HIR::LifetimeParam &lifetime_param); + virtual void visit (HIR::PathInExpression &path); + virtual void visit (HIR::TypePathSegment &segment); + virtual void visit (HIR::TypePathSegmentGeneric &segment); + virtual void visit (HIR::TypePathSegmentFunction &segment); + virtual void visit (HIR::TypePath &path); + virtual void visit (HIR::QualifiedPathInExpression &path); + virtual void visit (HIR::QualifiedPathInType &path); + virtual void visit (HIR::LiteralExpr &expr); + virtual void visit (HIR::BorrowExpr &expr); + virtual void visit (HIR::DereferenceExpr &expr); + virtual void visit (HIR::ErrorPropagationExpr &expr); + virtual void visit (HIR::NegationExpr &expr); + virtual void visit (HIR::ArithmeticOrLogicalExpr &expr); + virtual void visit (HIR::ComparisonExpr &expr); + virtual void visit (HIR::LazyBooleanExpr &expr); + virtual void visit (HIR::TypeCastExpr &expr); + virtual void visit (HIR::AssignmentExpr &expr); + virtual void visit (HIR::CompoundAssignmentExpr &expr); + virtual void visit (HIR::GroupedExpr &expr); + virtual void visit (HIR::ArrayElemsValues &elems); + virtual void visit (HIR::ArrayElemsCopied &elems); + virtual void visit (HIR::ArrayExpr &expr); + virtual void visit (HIR::ArrayIndexExpr &expr); + virtual void visit (HIR::TupleExpr &expr); + virtual void visit (HIR::TupleIndexExpr &expr); + virtual void visit (HIR::StructExprStruct &expr); + virtual void visit (HIR::StructExprFieldIdentifier &field); + virtual void visit (HIR::StructExprFieldIdentifierValue &field); + virtual void visit (HIR::StructExprFieldIndexValue &field); + virtual void visit (HIR::StructExprStructFields &expr); + virtual void visit (HIR::StructExprStructBase &expr); + virtual void visit (HIR::CallExpr &expr); + virtual void visit (HIR::MethodCallExpr &expr); + virtual void visit (HIR::FieldAccessExpr &expr); + virtual void visit (HIR::ClosureExprInner &expr); + virtual void visit (HIR::BlockExpr &expr); + virtual void visit (HIR::ClosureExprInnerTyped &expr); + virtual void visit (HIR::ContinueExpr &expr); + virtual void visit (HIR::BreakExpr &expr); + virtual void visit (HIR::RangeFromToExpr &expr); + virtual void visit (HIR::RangeFromExpr &expr); + virtual void visit (HIR::RangeToExpr &expr); + virtual void visit (HIR::RangeFullExpr &expr); + virtual void visit (HIR::RangeFromToInclExpr &expr); + virtual void visit (HIR::RangeToInclExpr &expr); + virtual void visit (HIR::ReturnExpr &expr); + virtual void visit (HIR::UnsafeBlockExpr &expr); + virtual void visit (HIR::LoopExpr &expr); + virtual void visit (HIR::WhileLoopExpr &expr); + virtual void visit (HIR::WhileLetLoopExpr &expr); + virtual void visit (HIR::ForLoopExpr &expr); + virtual void visit (HIR::IfExpr &expr); + virtual void visit (HIR::IfExprConseqElse &expr); + virtual void visit (HIR::IfExprConseqIf &expr); + virtual void visit (HIR::IfExprConseqIfLet &expr); + virtual void visit (HIR::IfLetExpr &expr); + virtual void visit (HIR::IfLetExprConseqElse &expr); + virtual void visit (HIR::IfLetExprConseqIf &expr); + virtual void visit (HIR::IfLetExprConseqIfLet &expr); + virtual void visit (HIR::MatchExpr &expr); + virtual void visit (HIR::AwaitExpr &expr); + virtual void visit (HIR::AsyncBlockExpr &expr); + virtual void visit (HIR::TypeParam ¶m); + virtual void visit (HIR::LifetimeWhereClauseItem &item); + virtual void visit (HIR::TypeBoundWhereClauseItem &item); + virtual void visit (HIR::Module &module); + virtual void visit (HIR::ExternCrate &crate); + virtual void visit (HIR::UseTreeGlob &use_tree); + virtual void visit (HIR::UseTreeList &use_tree); + virtual void visit (HIR::UseTreeRebind &use_tree); + virtual void visit (HIR::UseDeclaration &use_decl); + virtual void visit (HIR::Function &function); + virtual void visit (HIR::TypeAlias &type_alias); + virtual void visit (HIR::StructStruct &struct_item); + virtual void visit (HIR::TupleStruct &tuple_struct); + virtual void visit (HIR::EnumItem &item); + virtual void visit (HIR::EnumItemTuple &item); + virtual void visit (HIR::EnumItemStruct &item); + virtual void visit (HIR::EnumItemDiscriminant &item); + virtual void visit (HIR::Enum &enum_item); + virtual void visit (HIR::Union &union_item); + virtual void visit (HIR::ConstantItem &const_item); + virtual void visit (HIR::StaticItem &static_item); + virtual void visit (HIR::TraitItemFunc &item); + virtual void visit (HIR::TraitItemConst &item); + virtual void visit (HIR::TraitItemType &item); + virtual void visit (HIR::Trait &trait); + virtual void visit (HIR::ImplBlock &impl); + virtual void visit (HIR::ExternalStaticItem &item); + virtual void visit (HIR::ExternalFunctionItem &item); + virtual void visit (HIR::ExternBlock &block); + virtual void visit (HIR::LiteralPattern &pattern); + virtual void visit (HIR::IdentifierPattern &pattern); + virtual void visit (HIR::WildcardPattern &pattern); + virtual void visit (HIR::RangePatternBoundLiteral &bound); + virtual void visit (HIR::RangePatternBoundPath &bound); + virtual void visit (HIR::RangePatternBoundQualPath &bound); + virtual void visit (HIR::RangePattern &pattern); + virtual void visit (HIR::ReferencePattern &pattern); + virtual void visit (HIR::StructPatternFieldTuplePat &field); + virtual void visit (HIR::StructPatternFieldIdentPat &field); + virtual void visit (HIR::StructPatternFieldIdent &field); + virtual void visit (HIR::StructPattern &pattern); + virtual void visit (HIR::TupleStructItemsNoRange &tuple_items); + virtual void visit (HIR::TupleStructItemsRange &tuple_items); + virtual void visit (HIR::TupleStructPattern &pattern); + virtual void visit (HIR::TuplePatternItemsMultiple &tuple_items); + virtual void visit (HIR::TuplePatternItemsRanged &tuple_items); + virtual void visit (HIR::TuplePattern &pattern); + virtual void visit (HIR::GroupedPattern &pattern); + virtual void visit (HIR::SlicePattern &pattern); + virtual void visit (HIR::EmptyStmt &stmt); + virtual void visit (HIR::LetStmt &stmt); + virtual void visit (HIR::ExprStmtWithoutBlock &stmt); + virtual void visit (HIR::ExprStmtWithBlock &stmt); + virtual void visit (HIR::TraitBound &bound); + virtual void visit (HIR::ImplTraitType &type); + virtual void visit (HIR::TraitObjectType &type); + virtual void visit (HIR::ParenthesisedType &type); + virtual void visit (HIR::ImplTraitTypeOneBound &type); + virtual void visit (HIR::TupleType &type); + virtual void visit (HIR::NeverType &type); + virtual void visit (HIR::RawPointerType &type); + virtual void visit (HIR::ReferenceType &type); + virtual void visit (HIR::ArrayType &type); + virtual void visit (HIR::SliceType &type); + virtual void visit (HIR::InferredType &type); + virtual void visit (HIR::BareFunctionType &type); + + Analysis::Mappings &mappings; + Rust::Resolver::Resolver &resolver; + + // `None` means we're in the root module - the crate + Optional current_module; +}; + +} // namespace Privacy +} // namespace Rust + +#endif // !RUST_PRIVACY_REPORTER_H diff --git a/gcc/rust/privacy/rust-pub-restricted-visitor.cc b/gcc/rust/privacy/rust-pub-restricted-visitor.cc index 09bddf0c169..e391653ea26 100644 --- a/gcc/rust/privacy/rust-pub-restricted-visitor.cc +++ b/gcc/rust/privacy/rust-pub-restricted-visitor.cc @@ -31,6 +31,7 @@ PubRestrictedVisitor::is_restriction_valid (NodeId item_id, // If there is no visibility in the mappings, then the item is private and // does not contain any restriction + // FIXME: Is that correct? if (!mappings.lookup_visibility (item_id, visibility)) return true; diff --git a/gcc/rust/privacy/rust-visibility-resolver.cc b/gcc/rust/privacy/rust-visibility-resolver.cc index a02740be3e8..421dff0ef3d 100644 --- a/gcc/rust/privacy/rust-visibility-resolver.cc +++ b/gcc/rust/privacy/rust-visibility-resolver.cc @@ -35,6 +35,8 @@ VisibilityResolver::go (HIR::Crate &crate) mappings.insert_visibility (crate.get_mappings ().get_nodeid (), ModuleVisibility::create_public ()); + current_module = crate.get_mappings ().get_defid (); + for (auto &item : crate.items) { if (item->get_hir_kind () == HIR::Node::VIS_ITEM) @@ -103,7 +105,7 @@ VisibilityResolver::resolve_visibility (const HIR::Visibility &visibility, switch (visibility.get_vis_type ()) { case HIR::Visibility::PRIVATE: - to_resolve = ModuleVisibility::create_private (); + to_resolve = ModuleVisibility::create_restricted (current_module); return true; case HIR::Visibility::PUBLIC: to_resolve = ModuleVisibility::create_public (); @@ -134,6 +136,9 @@ VisibilityResolver::resolve_and_update (const HIR::VisItem *item) void VisibilityResolver::visit (HIR::Module &mod) { + auto old_module = current_module; + current_module = mod.get_mappings ().get_defid (); + for (auto &item : mod.get_items ()) { if (item->get_hir_kind () == HIR::Node::VIS_ITEM) @@ -142,6 +147,8 @@ VisibilityResolver::visit (HIR::Module &mod) vis_item->accept_vis (*this); } } + + current_module = old_module; } void diff --git a/gcc/rust/privacy/rust-visibility-resolver.h b/gcc/rust/privacy/rust-visibility-resolver.h index c57d5182a78..20a581c16d4 100644 --- a/gcc/rust/privacy/rust-visibility-resolver.h +++ b/gcc/rust/privacy/rust-visibility-resolver.h @@ -94,6 +94,7 @@ public: private: Analysis::Mappings &mappings; Rust::Resolver::Resolver &resolver; + DefId current_module; }; } // namespace Privacy diff --git a/gcc/rust/util/rust-optional.h b/gcc/rust/util/rust-optional.h index 5a39893c5d8..56465400250 100644 --- a/gcc/rust/util/rust-optional.h +++ b/gcc/rust/util/rust-optional.h @@ -96,6 +96,7 @@ private: public: Optional (const Optional &other) = default; + Optional &operator= (const Optional &other) = default; Optional (Optional &&other) = default; static Optional some (T value) diff --git a/gcc/testsuite/rust/compile/privacy1.rs b/gcc/testsuite/rust/compile/privacy1.rs new file mode 100644 index 00000000000..1cc83c04abe --- /dev/null +++ b/gcc/testsuite/rust/compile/privacy1.rs @@ -0,0 +1,11 @@ +mod orange { + mod green { + fn sain() {} + pub fn doux() {} + } + + fn brown() { + green::sain(); // { dg-error "definition is private in this context" } + green::doux(); + } +} diff --git a/gcc/testsuite/rust/compile/pub_restricted_3.rs b/gcc/testsuite/rust/compile/pub_restricted_3.rs new file mode 100644 index 00000000000..d477385d761 --- /dev/null +++ b/gcc/testsuite/rust/compile/pub_restricted_3.rs @@ -0,0 +1,11 @@ +// { dg-additional-options "-w" } + +mod foo { + mod bar { + pub(in foo) fn baz() {} + } + + fn baz() { + bar::baz(); // no error, foo::bar::baz is public in foo + } +}