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
This commit is contained in:
Arthur Cohen 2022-04-07 11:48:22 +02:00
parent dfb5f548ce
commit 23fc3ff7fe
4 changed files with 88 additions and 11 deletions

View File

@ -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

View File

@ -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

View File

@ -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?

View File

@ -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