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:
parent
dfb5f548ce
commit
23fc3ff7fe
|
@ -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)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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,12 +39,18 @@ 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 update_reachability (const Analysis::NodeMapping &mapping,
|
||||
ReachLevel reach);
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue