about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-02-15 12:25:13 -0800
committerKartik K. Agaram <vc@akkartik.com>2016-02-15 12:25:13 -0800
commitc36eb25ca3ac555ba7c27796e0ba84a7de696be4 (patch)
tree555bb044433910fd3e61dac697e791a9dd9ce6bf
parent5ba1c3b9e101b31fc38dae1701b62c373d5ef6f7 (diff)
downloadmu-c36eb25ca3ac555ba7c27796e0ba84a7de696be4.tar.gz
2658 - warn when containers contain arrays
The rule is: a container type's size must be fixed. Arrays can violate
this rule if the array length isn't included in the type. But we haven't
been warning about this, and 'new' has been silently turning array
elements to be empty.
-rw-r--r--030container.cc1
-rw-r--r--032array.cc32
2 files changed, 33 insertions, 0 deletions
diff --git a/030container.cc b/030container.cc
index 07e9718e..43d518e8 100644
--- a/030container.cc
+++ b/030container.cc
@@ -436,6 +436,7 @@ void insert_container(const string& command, kind_of_type kind, istream& in) {
     info.elements.push_back(new_type_tree_with_new_types_for_unknown(info.element_type_names.back(), info));
     for (long long int i = 0; i < SIZE(info.elements); ++i)
       trace(9993, "parse") << "  type: " << info.elements.at(i)->value << end();
+    // End Load Container Element Definition
   }
   assert(SIZE(info.elements) == SIZE(info.element_names));
   info.size = SIZE(info.elements);
diff --git a/032array.cc b/032array.cc
index f2eacb03..188e3477 100644
--- a/032array.cc
+++ b/032array.cc
@@ -116,6 +116,38 @@ if (r.type && r.type->value == get(Type_ordinal, "array")) {
   return 1 + get_or_insert(Memory, r.value)*size_of(array_element(r.type));
 }
 
+//: arrays are disallowed inside containers unless their length is fixed in
+//: advance
+
+:(scenario container_contains_array)
+% Hide_errors = true;
+container foo [
+  x:array:number:3
+]
+$error: 0
+
+:(scenario container_warns_on_dynamic_array_element)
+% Hide_errors = true;
+container foo [
+  x:array:number
+]
++error: container 'foo' cannot determine size of element x
+
+:(before "End Load Container Element Definition")
+{
+  const string_tree* type_name = info.element_type_names.back();
+  if (type_name->value == "array") {
+    if (!type_name->right) {
+      raise_error << "container '" << name << "' doesn't specify type of array elements for " << info.element_names.back() << '\n' << end();
+      break;
+    }
+    if (!type_name->right->right) {  // array has no length
+      raise_error << "container '" << name << "' cannot determine size of element " << info.element_names.back() << '\n' << end();
+      break;
+    }
+  }
+}
+
 //:: To access elements of an array, use 'index'
 
 :(scenario index)