public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] privacy: Add base for privacy-related visitors
@ 2022-06-08 12:28 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 12:28 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:8bf037fede04cd8539add51310464f121c7af613

commit 8bf037fede04cd8539add51310464f121c7af613
Author: Arthur Cohen <arthur.cohen@embecosm.com>
Date:   Tue Apr 5 11:33:31 2022 +0200

    privacy: Add base for privacy-related visitors

Diff:
---
 gcc/rust/Make-lang.in                  |   9 +++
 gcc/rust/privacy/rust-privacy-check.cc |  47 ++++++++++++++
 gcc/rust/privacy/rust-privacy-check.h  |  44 ++++++++++++++
 gcc/rust/privacy/rust-privacy-ctx.cc   |  35 +++++++++++
 gcc/rust/privacy/rust-privacy-ctx.h    |  61 +++++++++++++++++++
 gcc/rust/privacy/rust-reachability.cc  | 108 +++++++++++++++++++++++++++++++++
 gcc/rust/privacy/rust-reachability.h   |  65 ++++++++++++++++++++
 gcc/rust/rust-session-manager.cc       |   4 ++
 8 files changed, 373 insertions(+)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 6240011b3f6..840a2452f96 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 00000000000..cbacb6d90a9
--- /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 00000000000..e0c4091f3e4
--- /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 00000000000..e876e7855c7
--- /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 00000000000..2f10fd35cc5
--- /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 00000000000..3d6ae824354
--- /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 00000000000..157ef740c73
--- /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 6b1d03077f1..ec99be7be90 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);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 12:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 12:28 [gcc/devel/rust/master] privacy: Add base for privacy-related visitors Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).