예제 #1
0
 def test_checks_for_correct_explicit_size_on_parameters(self):
   ir = _make_ir_from_emb("struct Foo(y: UInt:300):\n"
                          "  0 [+1]  UInt  x\n")
   error_parameter = ir.module[0].type[0].runtime_parameter[0]
   error_location = error_parameter.physical_type_alias.source_location
   self.assertEqual(
       [[error.error("m.emb", error_location,
                     "Potential range of parameter is 0 to {}, which cannot "
                     "fit in a 64-bit signed or unsigned integer.".format(
                         2**300-1))]],
       error.filter_errors(constraints.check_constraints(ir)))
예제 #2
0
 def test_enum_value_too_wide_multiple_signed_error_message(self):
   ir = _make_ir_from_emb('[$default byte_order: "LittleEndian"]\n'
                          "enum Foo:\n"
                          "  LOW = -3\n"
                          "  LOW2 = -2\n"
                          "  LOW3 = -1\n"
                          "  HIGH = 0x8000_0000_0000_0000\n"
                          "  HIGH2 = 0x8000_0000_0000_0001\n")
   error_value = ir.module[0].type[0].enumeration.value[3].value
   error_value2 = ir.module[0].type[0].enumeration.value[4].value
   self.assertEqual([
       [error.error(
           "m.emb", error_value.source_location,
           "Value 9223372036854775808 is out of range for 64-bit signed "
           "enumeration.")],
       [error.error(
           "m.emb", error_value2.source_location,
           "Value 9223372036854775809 is out of range for 64-bit signed "
           "enumeration.")]
   ], error.filter_errors(constraints.check_constraints(ir)))
예제 #3
0
 def test_explicit_non_byte_size_array_element(self):
   ir = _make_ir_from_emb('[$default byte_order: "LittleEndian"]\n'
                          "struct Foo:\n"
                          "  0 [+2]  UInt:4[4]  nibbles\n")
   error_type = ir.module[0].type[0].structure.field[0].type.array_type
   self.assertEqual([
       [error.error(
           "m.emb", error_type.base_type.source_location,
           "Array elements in structs must have sizes which are a multiple of "
           "8 bits.")]
   ], error.filter_errors(constraints.check_constraints(ir)))
예제 #4
0
 def test_enum_value_too_low(self):
   ir = _make_ir_from_emb('[$default byte_order: "LittleEndian"]\n'
                          "enum Foo:\n"
                          "  LOW = -0x8000_0000_0000_0001\n")
   error_value = ir.module[0].type[0].enumeration.value[0].value
   self.assertEqual([
       [error.error(
           "m.emb", error_value.source_location,
           "Value -9223372036854775809 is out of range for 64-bit signed " +
           "enumeration.")]
   ], constraints.check_constraints(ir))
예제 #5
0
 def test_enum_value_too_wide_small_size_error_message(self):
   ir = _make_ir_from_emb('[$default byte_order: "LittleEndian"]\n'
                          "enum Foo:\n"
                          "  [maximum_bits: 8]\n"
                          "  HIGH = 0x100\n")
   error_value = ir.module[0].type[0].enumeration.value[0].value
   self.assertEqual([[
       error.error(
           "m.emb", error_value.source_location,
           "Value 256 is out of range for 8-bit unsigned enumeration.")
   ]], error.filter_errors(constraints.check_constraints(ir)))
예제 #6
0
 def test_next_in_first_field(self):
     ir = self._make_ir("struct Foo:\n"
                        "  $next [+2]  UInt:8[]  a\n"
                        "  $next [+4]  UInt      b\n")
     struct = ir.module[0].type[0].structure
     self.assertEqual([[
         error.error(
             "m.emb", struct.field[0].location.start.source_location,
             "`$next` may not be used in the first physical field of " +
             "a structure; perhaps you meant `0`?"),
     ]], synthetics.desugar(ir))
예제 #7
0
 def test_next_in_size(self):
     ir = self._make_ir("struct Foo:\n"
                        "  0 [+2]      UInt:8[]  a\n"
                        "  1 [+$next]  UInt      b\n")
     struct = ir.module[0].type[0].structure
     self.assertEqual([[
         error.error(
             "m.emb", struct.field[1].location.size.source_location,
             "`$next` may only be used in the start expression of a " +
             "physical field."),
     ]], synthetics.desugar(ir))
예제 #8
0
def _check_for_bad_next_keyword_in_size(expression, source_file_name, errors):
    if not expression.HasField("builtin_reference"):
        return
    if expression.builtin_reference.canonical_name.object_path[0] != "$next":
        return
    errors.append([
        error.error(
            source_file_name, expression.source_location,
            "`$next` may only be used in the start expression of a " +
            "physical field.")
    ])
예제 #9
0
 def test_disallows_null_byte_order_on_multibyte_array_elements(self):
     ir = _make_ir_from_emb("struct Foo:\n"
                            "  0 [+4]  UInt:16[]  uint\n"
                            '    [byte_order: "Null"]\n')
     byte_order = ir.module[0].type[0].structure.field[0].attribute[0]
     self.assertEqual([[
         error.error(
             "m.emb", byte_order.value.source_location,
             "Attribute 'byte_order' may only be 'Null' for one-byte fields."
         )
     ]], attribute_checker.normalize_and_verify(ir))
예제 #10
0
 def test_disallows_unknown_byte_order(self):
     ir = _make_ir_from_emb("struct Foo:\n"
                            "  0 [+2]  UInt  bar\n"
                            '    [byte_order: "NoEndian"]\n')
     byte_order = ir.module[0].type[0].structure.field[0].attribute[0]
     self.assertEqual([[
         error.error(
             "m.emb", byte_order.value.source_location,
             "Attribute 'byte_order' must be 'BigEndian' or 'LittleEndian' or "
             "'Null'.")
     ]], attribute_checker.normalize_and_verify(ir))
예제 #11
0
 def test_error_non_fixed_size_inner_array_dimension(self):
   ir = _make_ir_from_emb("struct Foo:\n"
                          "  0 [+1]     UInt               size\n"
                          "  1 [+size]  UInt:8[size-1][1]  one_byte\n")
   error_array = ir.module[0].type[0].structure.field[1].type.array_type
   self.assertEqual([[
       error.error(
           "m.emb",
           error_array.base_type.array_type.element_count.source_location,
           "Inner array dimensions must be constant.")
   ]], error.filter_errors(constraints.check_constraints(ir)))
예제 #12
0
 def test_error_on_equality_mismatched_operands_bool_int(self):
     ir = self._make_ir("struct Foo:\n"
                        "  0 [+1]         UInt      x\n"
                        "  1 [+true==1]   UInt:8[]  y\n")
     expression = ir.module[0].type[0].structure.field[1].location.size
     self.assertEqual([[
         error.error(
             "m.emb", expression.source_location,
             "Both arguments of operator '==' must have the same "
             "type.")
     ]], error.filter_errors(type_check.annotate_types(ir)))
예제 #13
0
 def test_rejects_is_integer_with_non_constant_value(self):
     external_ir = _make_ir_from_emb(
         "external Foo:\n"
         "  [is_integer: $static_size_in_bits == 1]\n"
         "  [addressable_unit_size: 1]\n")
     external_type_ir = external_ir.module[0].type[0]
     self.assertEqual([[
         error.error(
             "m.emb", external_type_ir.attribute[0].value.source_location,
             "Attribute 'is_integer' must have a constant boolean value.")
     ]], attribute_checker.normalize_and_verify(external_ir))
예제 #14
0
 def test_enum_value_too_wide(self):
   ir = _make_ir_from_emb('[$default byte_order: "LittleEndian"]\n'
                          "enum Foo:\n"
                          "  LOW = -1\n"
                          "  HIGH = 0x8000_0000_0000_0000\n")
   error_value = ir.module[0].type[0].enumeration.value[0].value
   self.assertEqual([[
       error.error(
           "m.emb", error_value.source_location,
           "Value -1 is out of range for unsigned enumeration.")
   ]], error.filter_errors(constraints.check_constraints(ir)))
예제 #15
0
 def test_error_on_integer_type_in_existence_condition(self):
     ir = self._make_ir("struct Foo:\n"
                        "  0 [+1]       UInt:8[]  x\n"
                        "  if 1:\n"
                        "    1 [+9]     UInt:8[]  y\n")
     expression = ir.module[0].type[0].structure.field[
         1].existence_condition
     self.assertEqual([[
         error.error("m.emb", expression.source_location,
                     "Existence condition must be a boolean.")
     ]], type_check.check_types(ir))
예제 #16
0
 def test_error_on_bad_equality_left_operand(self):
     ir = self._make_ir("struct Foo:\n"
                        "  0 [+1]       UInt:8[]  x\n"
                        "  1 [+x==x]    UInt:8[]  y\n")
     expression = ir.module[0].type[0].structure.field[1].location.size
     self.assertEqual([[
         error.error(
             "m.emb", expression.function.args[0].source_location,
             "Left argument of operator '==' must be an integer, "
             "boolean, or enum.")
     ]], error.filter_errors(type_check.annotate_types(ir)))
예제 #17
0
 def test_lower_bound_wrong_argument_type(self):
     ir = self._make_ir("struct Foo:\n"
                        "  $lower_bound(Bar.XX) [+1]  UInt:8[]  x\n"
                        "enum Bar:\n"
                        "  XX = 0\n")
     expression = ir.module[0].type[0].structure.field[0].location.start
     self.assertEqual([[
         error.error(
             "m.emb", expression.function.args[0].source_location,
             "Argument 0 of function '$lower_bound' must be an integer.")
     ]], error.filter_errors(type_check.annotate_types(ir)))
예제 #18
0
 def test_error_on_too_many_argument_has(self):
     ir = self._make_ir("struct Foo:\n"
                        "  if $present(y, y):\n"
                        "    0 [+1]  UInt  x\n"
                        "  1 [+1]  UInt  y\n")
     expression = ir.module[0].type[0].structure.field[
         0].existence_condition
     self.assertEqual([[
         error.error("m.emb", expression.source_location,
                     "Function '$present' requires exactly 1 argument.")
     ]], error.filter_errors(type_check.annotate_types(ir)))
예제 #19
0
 def test_error_on_bad_choice_mismatched_operands(self):
     ir = self._make_ir("struct Foo:\n"
                        "  0 [+1]                UInt:8[]  x\n"
                        "  1 [+true ? 0 : true]  UInt:8[]  y\n")
     expression = ir.module[0].type[0].structure.field[1].location.size
     self.assertEqual([[
         error.error(
             "m.emb", expression.source_location,
             "The if-true and if-false clauses of operator '?:' must "
             "have the same type.")
     ]], error.filter_errors(type_check.annotate_types(ir)))
예제 #20
0
 def test_rejects_non_constant_attribute(self):
     ir = _make_ir_from_emb('[$default byte_order: "LittleEndian"]\n'
                            "struct Foo:\n"
                            "  [fixed_size_in_bits: field1]\n"
                            "  0 [+2]  UInt  field1\n")
     attr = ir.module[0].type[0].attribute[0]
     self.assertEqual([[
         error.error(
             "m.emb", attr.value.source_location,
             "Attribute 'fixed_size_in_bits' must have a constant value.")
     ]], attribute_checker.normalize_and_verify(ir))
예제 #21
0
 def test_rejects_duplicate_attribute(self):
     ir = _make_ir_from_emb("external Foo:\n"
                            "  [is_integer: true]\n"
                            "  [is_integer: true]\n")
     self.assertEqual([[
         error.error("m.emb",
                     ir.module[0].type[0].attribute[1].source_location,
                     "Duplicate attribute 'is_integer'."),
         error.note("m.emb",
                    ir.module[0].type[0].attribute[0].source_location,
                    "Original attribute"),
     ]], attribute_checker.normalize_and_verify(ir))
예제 #22
0
 def test_explicit_enumeration_size_too_big(self):
   ir = _make_ir_from_emb('[$default byte_order: "BigEndian"]\n'
                          "struct Foo:\n"
                          "  0 [+9]  Bar  seventy_two_bit\n"
                          "enum Bar:\n"
                          "  BAZ = 0\n")
   error_type = ir.module[0].type[0].structure.field[0].type
   self.assertEqual([[
       error.error("m.emb", error_type.source_location,
                   "Enumeration type 'Bar' cannot be 72 bits; enumerations "
                   "must be between 1 and 64 bits, inclusive."),
   ]], error.filter_errors(constraints.check_constraints(ir)))
예제 #23
0
 def test_undersized_anonymous_bit_field(self):
   ir = _make_ir_from_emb('[$default byte_order: "LittleEndian"]\n'
                          "struct Foo:\n"
                          "  0 [+1]  bits:\n"
                          "    0 [+32]  UInt  field\n")
   error_type = ir.module[0].type[0].structure.field[0].type
   self.assertEqual([[
       error.error(
           "m.emb", error_type.source_location,
           "Fixed-size anonymous type cannot be placed in field of size 8 "
           "bits; requires 32 bits.")
   ]], error.filter_errors(constraints.check_constraints(ir)))
예제 #24
0
 def test_field_type_not_allowed_in_bits(self):
   ir = _make_ir_from_emb('[$default byte_order: "LittleEndian"]\n'
                          "bits Foo:\n"
                          "  0 [+16]  Bar  bar\n"
                          "external Bar:\n"
                          "  [addressable_unit_size: 8]\n")
   error_type = ir.module[0].type[0].structure.field[0].type
   self.assertEqual([[
       error.error(
           "m.emb", error_type.source_location,
           "Byte-oriented type 'Bar' cannot be used in a bits field.")
   ]], error.filter_errors(constraints.check_constraints(ir)))
예제 #25
0
 def test_struct_field_too_big_for_type(self):
   ir = _make_ir_from_emb("struct Foo:\n"
                          "  0 [+2]  Byte  double_byte\n"
                          "struct Byte:\n"
                          "  0 [+1]  UInt  b\n")
   error_type = ir.module[0].type[0].structure.field[0].type
   self.assertEqual([[
       error.error(
           "m.emb", error_type.source_location,
           "Fixed-size type 'Byte' cannot be placed in field of size 16 bits; "
           "requires 8 bits.")
   ]], error.filter_errors(constraints.check_constraints(ir)))
예제 #26
0
 def test_error_on_bad_choice_if_true_operand(self):
     ir = self._make_ir("struct Foo:\n"
                        "  0 [+1]             UInt:8[]  x\n"
                        "  1 [+true ? x : x]  UInt:8[]  y\n")
     expression = ir.module[0].type[0].structure.field[1].location.size
     if_true_arg = expression.function.args[1]
     self.assertEqual([[
         error.error(
             "m.emb", if_true_arg.source_location,
             "If-true clause of operator '?:' must be an integer, "
             "boolean, or enum.")
     ]], error.filter_errors(type_check.annotate_types(ir)))
예제 #27
0
 def test_rejects_requires_on_array(self):
     ir = _make_ir_from_emb("struct Foo:\n"
                            "  0 [+4]  UInt:8[]  array\n"
                            "    [requires: false]\n")
     field_ir = ir.module[0].type[0].structure.field[0]
     self.assertEqual([[
         error.error(
             "m.emb", field_ir.attribute[0].value.source_location,
             "Attribute 'requires' is only allowed on integer, "
             "enumeration, or boolean fields, not arrays."),
         error.note("m.emb", field_ir.type.source_location, "Field type."),
     ]], error.filter_errors(attribute_checker.normalize_and_verify(ir)))
예제 #28
0
 def test_error_on_passing_unneeded_parameter(self):
     ir = self._make_ir("struct Foo:\n"
                        "  0 [+1]  Bar(1)  b\n"
                        "struct Bar:\n"
                        "  0 [+1]       UInt:8[]  x\n")
     type_ir = ir.module[0].type[0].structure.field[0].type
     bar = ir.module[0].type[1]
     self.assertEqual([[
         error.error("m.emb", type_ir.source_location,
                     "Type Bar requires 0 parameters; 1 parameter given."),
         error.note("m.emb", bar.source_location, "Definition of type Bar.")
     ]], type_check.check_types(ir))
예제 #29
0
 def test_rejects_requires_on_float(self):
     ir = _make_ir_from_emb('[$default byte_order: "LittleEndian"]\n'
                            "struct Foo:\n"
                            "  0 [+4]  Float  float\n"
                            "    [requires: false]\n")
     field_ir = ir.module[0].type[0].structure.field[0]
     self.assertEqual([[
         error.error(
             "m.emb", field_ir.attribute[0].value.source_location,
             "Attribute 'requires' is only allowed on integer, "
             "enumeration, or boolean fields.")
     ]], error.filter_errors(attribute_checker.normalize_and_verify(ir)))
예제 #30
0
def _verify_byte_order_attribute_on_field(field, type_definition,
                                          source_file_name, ir, errors):
  """Verifies the byte_order attribute on the given field."""
  byte_order_attr = ir_util.get_attribute(field.attribute,
                                          attributes.BYTE_ORDER)
  field_needs_byte_order = _field_needs_byte_order(field, type_definition, ir)
  if byte_order_attr and not field_needs_byte_order:
    errors.append([error.error(
        source_file_name, byte_order_attr.source_location,
        "Attribute 'byte_order' not allowed on field which is not byte order "
        "dependent.")])
  if not byte_order_attr and field_needs_byte_order:
    errors.append([error.error(
        source_file_name, field.source_location,
        "Attribute 'byte_order' required on field which is byte order "
        "dependent.")])
  if (byte_order_attr and byte_order_attr.string_constant.text == "Null" and
      not _field_may_have_null_byte_order(field, type_definition, ir)):
    errors.append([error.error(
        source_file_name, byte_order_attr.source_location,
        "Attribute 'byte_order' may only be 'Null' for one-byte fields.")])