diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-01-23 14:13:32 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-01-23 14:16:48 -0800 |
commit | ee67a3417802a66e2d8741536dedf99baf78cc5a (patch) | |
tree | 86560ac5e7da6b461b2dd16b5b4b7fdd67843aa2 /056recipe_header.cc | |
parent | cf478e14aab32fbfcccd7443e6b2de4f2c247060 (diff) | |
download | mu-ee67a3417802a66e2d8741536dedf99baf78cc5a.tar.gz |
2596 - experiment: no unique addresses in calls
Reading http://www.jonathanturner.org/2016/01/rust-and-blub-paradox.html, I realize there's nothing currently stopping mu programs from taking a unique (non-shared) address into a shared allocation, abandoning the allocation and being left with an invalid address. No fix for this yet, but let's try to minimize its effect by limiting lifetimes of unique addresses. We really should only be using them to write to array or container elements.
Diffstat (limited to '056recipe_header.cc')
-rw-r--r-- | 056recipe_header.cc | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/056recipe_header.cc b/056recipe_header.cc index 026f44e6..df4ebdc9 100644 --- a/056recipe_header.cc +++ b/056recipe_header.cc @@ -218,15 +218,53 @@ void check_calls_against_header(const recipe_ordinal r) { for (long int i = 0; i < min(SIZE(inst.ingredients), SIZE(callee.ingredients)); ++i) { if (!types_coercible(callee.ingredients.at(i), inst.ingredients.at(i))) raise_error << maybe(caller.name) << "ingredient " << i << " has the wrong type at '" << inst.to_string() << "'\n" << end(); + if (is_unique_address(inst.ingredients.at(i))) + raise << maybe(caller.name) << "try to avoid passing non-shared addresses into calls, like ingredient " << i << " at '" << inst.to_string() << "'\n" << end(); } for (long int i = 0; i < min(SIZE(inst.products), SIZE(callee.products)); ++i) { if (is_dummy(inst.products.at(i))) continue; if (!types_coercible(callee.products.at(i), inst.products.at(i))) raise_error << maybe(caller.name) << "product " << i << " has the wrong type at '" << inst.to_string() << "'\n" << end(); + if (is_unique_address(inst.products.at(i))) + raise << maybe(caller.name) << "try to avoid getting non-shared addresses out of calls, like product " << i << " at '" << inst.to_string() << "'\n" << end(); } } } +bool is_unique_address(reagent x) { + if (!canonize_type(x)) return false; + if (!x.type) return false; + if (x.type->value != get(Type_ordinal, "address")) return false; + if (!x.type->right) return true; + return x.type->right->value != get(Type_ordinal, "shared"); +} + +//: additionally, warn on calls receiving non-shared addresses + +:(scenario warn_on_calls_with_addresses) +% Hide_warnings= true; +recipe main [ + 1:address:number <- copy 3/unsafe + foo 1:address:number +] +recipe foo x:address:number [ + local-scope + load-ingredients +] ++warn: main: try to avoid passing non-shared addresses into calls, like ingredient 0 at 'foo 1:address:number' + +:(scenario warn_on_calls_with_addresses_2) +% Hide_warnings= true; +recipe main [ + 1:address:number <- foo +] +recipe foo -> x:address:number [ + local-scope + load-ingredients + x <- copy 0 +] ++warn: main: try to avoid getting non-shared addresses out of calls, like product 0 at '1:address:number <- foo ' + //:: Check types going in and out of all recipes with headers. :(scenarios transform) |