diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/Make-lang.in | 9 | ||||
-rw-r--r-- | gcc/rust/privacy/rust-privacy-check.cc | 47 | ||||
-rw-r--r-- | gcc/rust/privacy/rust-privacy-check.h | 44 | ||||
-rw-r--r-- | gcc/rust/privacy/rust-privacy-ctx.cc | 35 | ||||
-rw-r--r-- | gcc/rust/privacy/rust-privacy-ctx.h | 61 | ||||
-rw-r--r-- | gcc/rust/privacy/rust-reachability.cc | 108 | ||||
-rw-r--r-- | gcc/rust/privacy/rust-reachability.h | 65 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 4 |
8 files changed, 373 insertions, 0 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index 6240011..840a245 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -89,6 +89,9 @@ GRS_OBJS = \ rust/rust-ast-resolve-expr.o \ rust/rust-ast-resolve-type.o \ rust/rust-hir-type-check.o \ + rust/rust-privacy-check.o \ + rust/rust-privacy-ctx.o \ + rust/rust-reachability.o \ rust/rust-tyty.o \ rust/rust-tyctx.o \ rust/rust-tyty-bounds.o \ @@ -278,6 +281,7 @@ RUST_INCLUDES = -I $(srcdir)/rust \ -I $(srcdir)/rust/resolve \ -I $(srcdir)/rust/util \ -I $(srcdir)/rust/typecheck \ + -I $(srcdir)/rust/privacy \ -I $(srcdir)/rust/lint # add files that require cross-folder includes - currently rust-lang.o, rust-lex.o @@ -339,6 +343,11 @@ rust/%.o: rust/typecheck/%.cc $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $< $(POSTCOMPILE) +# build rust/privacy files in rust folder +rust/%.o: rust/privacy/%.cc + $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $< + $(POSTCOMPILE) + # build rust/lint files in rust folder rust/%.o: rust/lint/%.cc $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $< diff --git a/gcc/rust/privacy/rust-privacy-check.cc b/gcc/rust/privacy/rust-privacy-check.cc new file mode 100644 index 0000000..cbacb6d --- /dev/null +++ b/gcc/rust/privacy/rust-privacy-check.cc @@ -0,0 +1,47 @@ +// 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-privacy-check.h" +#include "rust-reachability.h" + +extern bool +saw_errors (void); + +namespace Rust { +namespace Privacy { +void +Resolver::resolve (HIR::Crate &crate) +{ + PrivacyContext ctx; + auto visitor = ReachabilityVisitor (ctx); + + const auto &items = crate.items; + for (auto &item : items) + { + if (item->get_hir_kind () == HIR::VIS_ITEM) + { + auto vis_item = static_cast<HIR::VisItem *> (item.get ()); + vis_item->accept_vis (visitor); + } + } + + if (saw_errors ()) + return; +} +} // namespace Privacy +} // namespace Rust diff --git a/gcc/rust/privacy/rust-privacy-check.h b/gcc/rust/privacy/rust-privacy-check.h new file mode 100644 index 0000000..e0c4091 --- /dev/null +++ b/gcc/rust/privacy/rust-privacy-check.h @@ -0,0 +1,44 @@ +// 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_PRIVACY_CHECK_H +#define RUST_PRIVACY_CHECK_H + +#include "rust-hir-map.h" +#include "rust-hir.h" +#include "rust-hir-expr.h" +#include "rust-hir-stmt.h" +#include "rust-hir-item.h" + +namespace Rust { +namespace Privacy { +class Resolver +{ +public: + /** + * Perform the full privacy resolving pass on a crate. + * + * This resolver first computes the reachability of all items in a crate, + * before checking for privacy violations. + */ + static void resolve (HIR::Crate &crate); +}; +} // namespace Privacy +} // namespace Rust + +#endif // !RUST_PRIVACY_CHECK_H diff --git a/gcc/rust/privacy/rust-privacy-ctx.cc b/gcc/rust/privacy/rust-privacy-ctx.cc new file mode 100644 index 0000000..e876e78 --- /dev/null +++ b/gcc/rust/privacy/rust-privacy-ctx.cc @@ -0,0 +1,35 @@ +// 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-privacy-ctx.h" + +namespace Rust { +namespace Privacy { +void +PrivacyContext::insert_reachability (const Analysis::NodeMapping &mapping, + ReachLevel reach) +{} + +const ReachLevel * +PrivacyContext::lookup_reachability (const Analysis::NodeMapping &mapping) +{ + return nullptr; +} + +} // namespace Privacy +} // namespace Rust diff --git a/gcc/rust/privacy/rust-privacy-ctx.h b/gcc/rust/privacy/rust-privacy-ctx.h new file mode 100644 index 0000000..2f10fd3 --- /dev/null +++ b/gcc/rust/privacy/rust-privacy-ctx.h @@ -0,0 +1,61 @@ +// 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-hir-map.h" +#include "rust-privacy-check.h" + +namespace Rust { +namespace Privacy { + +/** + * Reachability levels of HIR nodes. These levels are computed through the + * `ReachabilityVisitor` visitor. + */ +enum ReachLevel +{ + Private, + Public, +}; + +class PrivacyContext +{ +public: + /** + * Insert a new resolved visibility for a given node + * + * @param mappings Mappings of the node to store the reach level for + * @param reach Level of reachability for the given node + */ + void insert_reachability (const Analysis::NodeMapping &mapping, + ReachLevel reach); + + /** + * Lookup the visibility of an already declared Node + * + * @param mapping Mappings of the node to fetch the reach level of + * + * @return `nullptr` if the reach level for the current node has not been + * added, a valid pointer otherwise + */ + const ReachLevel *lookup_reachability (const Analysis::NodeMapping &mapping); + +private: + std::unordered_map<HirId, ReachLevel> reachability_map; +}; +} // namespace Privacy +} // namespace Rust diff --git a/gcc/rust/privacy/rust-reachability.cc b/gcc/rust/privacy/rust-reachability.cc new file mode 100644 index 0000000..3d6ae82 --- /dev/null +++ b/gcc/rust/privacy/rust-reachability.cc @@ -0,0 +1,108 @@ +// 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-reachability.h" + +namespace Rust { +namespace Privacy { +void +ReachabilityVisitor::visit (HIR::Module &mod) +{ + for (auto &item : mod.get_items ()) + { + // FIXME: How do we refactor this pattern into something more ergonomic? + // FIXME: Add helper functions + // FIXME: Is that what we want to do? Yes? Only visit the items with + // visibility? + if (item->get_hir_kind () == HIR::VIS_ITEM) + { + auto vis_item = static_cast<HIR::VisItem *> (item.get ()); + vis_item->accept_vis (*this); + } + } +} + +void +ReachabilityVisitor::visit (HIR::ExternCrate &crate) +{} + +void +ReachabilityVisitor::visit (HIR::UseDeclaration &use_decl) +{} + +void +ReachabilityVisitor::visit (HIR::Function &func) +{} + +void +ReachabilityVisitor::visit (HIR::TypeAlias &type_alias) +{} + +void +ReachabilityVisitor::visit (HIR::StructStruct &struct_item) +{ + auto struct_reach = ReachLevel::Private; + // FIXME: This feels very wrong. Should we check for `has_visibility` + // beforehand? Is it just private otherwise? Should the `HIR::Visibility` also + // keep variants for private items? + if (struct_item.get_visibility ().get_vis_type () == HIR::Visibility::NONE) + struct_reach = ReachLevel::Public; + + // FIXME: Here we want to update only if the visibility is higher + ctx.insert_reachability (struct_item.get_mappings (), struct_reach); + + for (auto &field : struct_item.get_fields ()) + ctx.insert_reachability (field.get_mappings (), struct_reach); + + // FIXME: How do we get the constructor from `struct_item`? We need to update + // its visibility as well. Probably by keeping a reference to the TypeCtx? +} + +void +ReachabilityVisitor::visit (HIR::TupleStruct &tuple_struct) +{} + +void +ReachabilityVisitor::visit (HIR::Enum &enum_item) +{} + +void +ReachabilityVisitor::visit (HIR::Union &union_item) +{} + +void +ReachabilityVisitor::visit (HIR::ConstantItem &const_item) +{} + +void +ReachabilityVisitor::visit (HIR::StaticItem &static_item) +{} + +void +ReachabilityVisitor::visit (HIR::Trait &trait) +{} + +void +ReachabilityVisitor::visit (HIR::ImplBlock &impl) +{} + +void +ReachabilityVisitor::visit (HIR::ExternBlock &block) +{} +} // namespace Privacy +} // namespace Rust diff --git a/gcc/rust/privacy/rust-reachability.h b/gcc/rust/privacy/rust-reachability.h new file mode 100644 index 0000000..157ef74 --- /dev/null +++ b/gcc/rust/privacy/rust-reachability.h @@ -0,0 +1,65 @@ +// 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_REACHABILITY_H +#define RUST_REACHABILITY_H + +#include "rust-privacy-ctx.h" +#include "rust-hir-visitor.h" +#include "rust-hir.h" +#include "rust-hir-expr.h" +#include "rust-hir-stmt.h" +#include "rust-hir-item.h" + +namespace Rust { +namespace Privacy { + +// FIXME: The EmbargoVisitor from rustc is a fixed-point visitor which tries +// to reach more and more nodes until nothing has changed anymore. +// Do we need to reproduce this behavior? How long does it take to do this? + +class ReachabilityVisitor : public HIR::HIRVisItemVisitor +{ +public: + ReachabilityVisitor (PrivacyContext &ctx) + : current_level (ReachLevel::Private), ctx (ctx) + {} + + virtual void visit (HIR::Module &mod); + virtual void visit (HIR::ExternCrate &crate); + virtual void visit (HIR::UseDeclaration &use_decl); + virtual void visit (HIR::Function &func); + 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::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::Trait &trait); + virtual void visit (HIR::ImplBlock &impl); + virtual void visit (HIR::ExternBlock &block); + +private: + ReachLevel current_level; + PrivacyContext &ctx; +}; +} // namespace Privacy +} // namespace Rust + +#endif // !RUST_REACHABILITY_H diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index 6b1d030..ec99be7 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -25,6 +25,7 @@ #include "rust-ast-resolve.h" #include "rust-ast-lower.h" #include "rust-hir-type-check.h" +#include "rust-privacy-check.h" #include "rust-tycheck-dump.h" #include "rust-compile.h" #include "rust-cfg-parser.h" @@ -609,6 +610,9 @@ Session::parse_file (const char *filename) if (saw_errors ()) return; + // privacy pass + Privacy::Resolver::resolve (hir); + // do compile to gcc generic Compile::Context ctx (backend); Compile::CompileCrate::Compile (hir, &ctx); |