aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2022-04-07 11:48:22 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2022-04-12 14:26:23 +0200
commit23fc3ff7fe9405797d5961f7792540d3f487a287 (patch)
treee74d64a9f7829347a178380c15ae92a0712a35cd
parentdfb5f548cee6874be343d3a337e9779ac30a5eb5 (diff)
downloadgcc-23fc3ff7fe9405797d5961f7792540d3f487a287.zip
gcc-23fc3ff7fe9405797d5961f7792540d3f487a287.tar.gz
gcc-23fc3ff7fe9405797d5961f7792540d3f487a287.tar.bz2
privacy: ctx: Add proper implementations for insert_reachability() and
lookup_reachability() Inserting reach levels in the reachability_map should only be done if the existing reach level is lower than the provided one. If the node is not yet present in the reachability map, insert it no matter what
-rw-r--r--gcc/rust/privacy/rust-privacy-ctx.cc66
-rw-r--r--gcc/rust/privacy/rust-privacy-ctx.h24
-rw-r--r--gcc/rust/privacy/rust-reachability.cc6
-rw-r--r--gcc/rust/rust-lang.cc3
4 files changed, 88 insertions, 11 deletions
diff --git a/gcc/rust/privacy/rust-privacy-ctx.cc b/gcc/rust/privacy/rust-privacy-ctx.cc
index e876e78..3a44ce0 100644
--- a/gcc/rust/privacy/rust-privacy-ctx.cc
+++ b/gcc/rust/privacy/rust-privacy-ctx.cc
@@ -17,19 +17,75 @@
// <http://www.gnu.org/licenses/>.
#include "rust-privacy-ctx.h"
+#include "selftest.h"
namespace Rust {
namespace Privacy {
-void
-PrivacyContext::insert_reachability (const Analysis::NodeMapping &mapping,
+static ReachLevel
+insert_if_higher (ReachLevel new_level,
+ std::unordered_map<HirId, ReachLevel>::iterator &existing)
+{
+ if (new_level > existing->second)
+ existing->second = new_level;
+
+ return existing->second;
+}
+
+ReachLevel
+PrivacyContext::update_reachability (const Analysis::NodeMapping &mapping,
ReachLevel reach)
-{}
+{
+ auto existing_reach = reachability_map.find (mapping.get_hirid ());
+ if (existing_reach != reachability_map.end ())
+ return insert_if_higher (reach, existing_reach);
+
+ reachability_map.insert ({mapping.get_hirid (), reach});
+ return reach;
+}
const ReachLevel *
PrivacyContext::lookup_reachability (const Analysis::NodeMapping &mapping)
{
- return nullptr;
-}
+ auto existing_reach = reachability_map.find (mapping.get_hirid ());
+ if (existing_reach == reachability_map.end ())
+ return nullptr;
+ return &existing_reach->second;
+}
} // namespace Privacy
} // namespace Rust
+
+#if CHECKING_P
+namespace selftest {
+static void
+update_reachability_test (void)
+{
+ auto ctx = Rust::Privacy::PrivacyContext ();
+ // Bogus values for the mappings
+ auto mapping = Rust::Analysis::NodeMapping (15, 15, 15, 15);
+
+ auto new_level
+ = ctx.update_reachability (mapping, Rust::Privacy::ReachLevel::Unreachable);
+
+ ASSERT_EQ (new_level, Rust::Privacy::ReachLevel::Unreachable);
+
+ ASSERT_TRUE (ctx.lookup_reachability (mapping));
+ ASSERT_EQ (*ctx.lookup_reachability (mapping),
+ Rust::Privacy::ReachLevel::Unreachable);
+
+ new_level
+ = ctx.update_reachability (mapping, Rust::Privacy::ReachLevel::Reachable);
+
+ ASSERT_EQ (new_level, Rust::Privacy::ReachLevel::Reachable);
+ ASSERT_TRUE (ctx.lookup_reachability (mapping));
+ ASSERT_EQ (*ctx.lookup_reachability (mapping),
+ Rust::Privacy::ReachLevel::Reachable);
+}
+
+void
+rust_privacy_ctx_test (void)
+{
+ update_reachability_test ();
+}
+} // namespace selftest
+#endif // !CHECKING_P
diff --git a/gcc/rust/privacy/rust-privacy-ctx.h b/gcc/rust/privacy/rust-privacy-ctx.h
index 2a11b56..7626df3 100644
--- a/gcc/rust/privacy/rust-privacy-ctx.h
+++ b/gcc/rust/privacy/rust-privacy-ctx.h
@@ -16,6 +16,9 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#ifndef RUST_PRIVACY_CTX_H
+#define RUST_PRIVACY_CTX_H
+
#include "rust-hir-map.h"
#include "rust-privacy-check.h"
@@ -36,13 +39,19 @@ class PrivacyContext
{
public:
/**
- * Insert a new resolved visibility for a given node
+ * Insert a new resolved visibility for a given node. If the node is already
+ * present in the reachability map, then its visibility will only be updated
+ * if the given visibility is higher.
*
* @param mappings Mappings of the node to store the reach level for
* @param reach Level of reachability for the given node
+ *
+ * @return The new reachability level for this node. If this was the first
+ * time inserting this node, then return `reach`. Otherwise, return `reach` or
+ * the existing reach level if it was higher.
*/
- void insert_reachability (const Analysis::NodeMapping &mapping,
- ReachLevel reach);
+ ReachLevel update_reachability (const Analysis::NodeMapping &mapping,
+ ReachLevel reach);
/**
* Lookup the visibility of an already declared Node
@@ -59,3 +68,12 @@ private:
};
} // namespace Privacy
} // namespace Rust
+
+#if CHECKING_P
+namespace selftest {
+void
+rust_privacy_ctx_test (void);
+}
+#endif // !CHECKING_P
+
+#endif // !RUST_PRIVACY_CTX_H
diff --git a/gcc/rust/privacy/rust-reachability.cc b/gcc/rust/privacy/rust-reachability.cc
index 5cab439..1876222 100644
--- a/gcc/rust/privacy/rust-reachability.cc
+++ b/gcc/rust/privacy/rust-reachability.cc
@@ -63,14 +63,14 @@ ReachabilityVisitor::visit (HIR::StructStruct &struct_item)
if (struct_item.get_visibility ().get_vis_type () == HIR::Visibility::NONE)
struct_reach = ReachLevel::Reachable;
- // FIXME: Here we want to update only if the visibility is higher
- ctx.insert_reachability (struct_item.get_mappings (), struct_reach);
+ struct_reach
+ = ctx.update_reachability (struct_item.get_mappings (), struct_reach);
// FIXME: We need to also visit the fields as they might have their own set
// of reachability levels
for (auto &field : struct_item.get_fields ())
- ctx.insert_reachability (field.get_mappings (), struct_reach);
+ ctx.update_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?
diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
index 5ecd79b..c746941 100644
--- a/gcc/rust/rust-lang.cc
+++ b/gcc/rust/rust-lang.cc
@@ -32,8 +32,10 @@
#include "convert.h"
#include "langhooks.h"
#include "langhooks-def.h"
+
#include "selftest.h"
#include "rust-cfg-parser.h"
+#include "rust-privacy-ctx.h"
#include <mpfr.h>
// note: header files must be in this order or else forward declarations don't
@@ -455,6 +457,7 @@ run_rust_tests ()
// Call tests for the rust frontend here
simple_assert ();
rust_cfg_parser_test ();
+ rust_privacy_ctx_test ();
}
} // namespace selftest