diff --git a/compiler2/Constraint.cc b/compiler2/Constraint.cc index d56158103f59345e05a858f7b2213bd7d5cf8810..5c88f69f061d9d773006a0e09ed39846973f48d3 100644 --- a/compiler2/Constraint.cc +++ b/compiler2/Constraint.cc @@ -62,12 +62,14 @@ namespace Common { if (my_type) p_con->set_my_type(my_type); } - Constraint* Constraints::get_tableconstraint() const + const Constraint* Constraints::get_tableconstraint() const { size_t nof_cons = cons.size(); for (size_t i = 0; i < nof_cons; i++) { Constraint *con = cons[i]; - if (con->get_constrtype() == Constraint::CT_TABLE) return con; + if (con->get_constrtype() == Constraint::CT_TABLE) { + return con->get_tableconstraint(); + } } return 0; } @@ -116,15 +118,18 @@ namespace Common { extension = 0; } if (subtype) { - if (sc->is_subset(subtype)==TFALSE) { - cons[i]->error("Constraint #%lu is %s, this is not a subset of %s", + if (sc->can_intersect(subtype)==TFALSE) { + cons[i]->error("Constraint #%lu is %s, intersecting this with %s " + "results in an empty set (no values satisfy the type's restrictions)", (unsigned long) (i + 1), sc->to_string().c_str(), subtype->to_string().c_str()); break; // stop on error } - if (sc_ext && (sc_ext->is_subset(subtype)==TFALSE)) { - cons[i]->error("Extension addition of constraint #%lu is %s, this is not a subset of %s", + if (sc_ext && (sc_ext->can_intersect(subtype)==TFALSE)) { + cons[i]->error("Extension addition of constraint #%lu is %s, " + "intersecting this with %s results in an empty set (no values " + "satisfy the type's restrictions)", (unsigned long) (i + 1), sc_ext->to_string().c_str(), subtype->to_string().c_str()); @@ -218,7 +223,12 @@ namespace Common { } return false; } - + + const Constraint* Constraint::get_tableconstraint() const + { + FATAL_ERROR("Constraint::get_tableconstraint()"); + } + // ================================= // ===== ElementSetSpecsConstraint // ================================= @@ -1145,5 +1155,128 @@ namespace Common { block->set_fullname(p_fullname); if (constraint) constraint->set_fullname(p_fullname); } + + // ================================= + // ===== UndefinedBlockConstraint + // ================================= + + UndefinedBlockConstraint::UndefinedBlockConstraint(const UndefinedBlockConstraint& p) + : Constraint(p) + { + switch (constrtype) { + case CT_UNDEFINEDBLOCK: + block = p.block->clone(); + break; + case CT_SINGLEVALUE: + single = p.single->clone(); + break; + case CT_TABLE: + table = p.table->clone(); + break; + default: + FATAL_ERROR("UndefinedBlockConstraint::UndefinedBlockConstraint"); + } + } + + UndefinedBlockConstraint::UndefinedBlockConstraint(Block* p_block) + : Constraint(CT_UNDEFINEDBLOCK), block(p_block) + { + if (p_block == NULL) { + FATAL_ERROR("UndefinedBlockConstraint::UndefinedBlockConstraint()"); + } + } + + UndefinedBlockConstraint::~UndefinedBlockConstraint() + { + switch (constrtype) { + case CT_UNDEFINEDBLOCK: + delete block; + break; + case CT_SINGLEVALUE: + delete single; + break; + case CT_TABLE: + delete table; + break; + default: + FATAL_ERROR("UndefinedBlockConstraint::~UndefinedBlockConstraint"); + } + } + + void UndefinedBlockConstraint::chk() + { + if (checked) return; + checked = true; + if (my_parent != NULL && my_parent->get_constrtype() == CT_SETOPERATION) { + single = new SingleValueConstraint(new Value(Value::V_UNDEF_BLOCK, block)); + constrtype = CT_SINGLEVALUE; + single->set_my_type(my_type); + single->set_my_scope(my_scope); + single->set_my_parent(my_parent); + single->chk(); + extendable = single->is_extendable(); + } + else { + table = new Asn::TableConstraint(block, NULL); + constrtype = CT_TABLE; + table->set_my_type(my_type); + table->set_my_scope(my_scope); + table->set_my_parent(my_parent); + table->chk(); + extendable = table->is_extendable(); + } + } + + void UndefinedBlockConstraint::set_fullname(const string& p_fullname) + { + Node::set_fullname(p_fullname); + switch (constrtype) { + case CT_UNDEFINEDBLOCK: + block->set_fullname(p_fullname + ".<block>"); + break; + case CT_SINGLEVALUE: + single->set_fullname(p_fullname); + break; + case CT_TABLE: + table->set_fullname(p_fullname); + break; + default: + FATAL_ERROR("UndefinedBlockConstraint::UndefinedBlockConstraint"); + } + } + + SubtypeConstraint* UndefinedBlockConstraint::get_subtype() const + { + switch (constrtype) { + case CT_SINGLEVALUE: + return single->get_subtype(); + case CT_TABLE: + return table->get_subtype(); + case CT_UNDEFINEDBLOCK: + default: + FATAL_ERROR("UndefinedBlockConstraint::get_subtype"); + } + } + + SubtypeConstraint* UndefinedBlockConstraint::get_extension() const + { + switch (constrtype) { + case CT_SINGLEVALUE: + return single->get_extension(); + case CT_TABLE: + return table->get_extension(); + case CT_UNDEFINEDBLOCK: + default: + FATAL_ERROR("UndefinedBlockConstraint::get_extension"); + } + } + + const Constraint* UndefinedBlockConstraint::get_tableconstraint() const + { + if (constrtype != CT_TABLE) { + FATAL_ERROR("UndefinedBlockConstraint::get_tableconstraint()"); + } + return table; + } } // namespace Common diff --git a/compiler2/Constraint.hh b/compiler2/Constraint.hh index de70f84c2ada64e7c59500663a2c30c5db2ae35f..5557b10437f69a45cc0d419bdeee6e0075a582fd 100644 --- a/compiler2/Constraint.hh +++ b/compiler2/Constraint.hh @@ -20,6 +20,7 @@ namespace Asn { class Block; + class TableConstraint; } namespace Common { @@ -42,7 +43,7 @@ namespace Common { class Value; class SubtypeConstraint; class Identifier; - + using Asn::Block; /** @@ -51,6 +52,7 @@ namespace Common { class Constraint : public Node, public Location { public: enum constrtype_t { + CT_UNDEFINEDBLOCK, /** UndefinedBlockConstraint (turns into CT_TABLE or CT_SINGLEVALUE after semantic analysis) */ CT_ELEMENTSETSPEC, /** ElementSetSpecsConstraint */ CT_IGNORE, /**< Constraint : used if erroneous or not yet supported */ CT_TABLE, /**< TableConstraint */ @@ -96,9 +98,9 @@ namespace Common { Constraints* get_my_cons(); virtual void chk() = 0; /** return the subtype constraint */ - SubtypeConstraint* get_subtype() const { return subtype; } + virtual SubtypeConstraint* get_subtype() const { return subtype; } bool is_extendable() const { return extendable; } - SubtypeConstraint* get_extension() const { return extension; } + virtual SubtypeConstraint* get_extension() const { return extension; } /** returns the name of this constraint which can be used in error messages */ virtual const char* get_name() const = 0; /** if this constraint is inside a FROM() constraint then we are in @@ -112,6 +114,11 @@ namespace Common { somehow drop or simplify their constraint, example: (inner subtype) EXCEPT (inner subtype) */ virtual bool is_ignored() const { return false; } + + /** Returns this (for TableConstraints) or the embedded TableConstraint + * object (for UndefinedBlockConstraints that contain a TableConstraint + * after semantic analysis) */ + virtual const Constraint* get_tableconstraint() const; }; /** @@ -135,7 +142,7 @@ namespace Common { void add_con(Constraint *p_con); size_t get_nof_cons() const {return cons.size();} Constraint* get_con_byIndex(size_t p_i) const { return cons[p_i]; } - Constraint* get_tableconstraint() const; + const Constraint* get_tableconstraint() const; void set_my_type(Type *p_my_type); Type* get_my_type() const { return my_type; } void chk(SubtypeConstraint* parent_subtype); @@ -488,6 +495,36 @@ namespace Common { const char* get_name() const { return "inner type constraint"; } bool is_ignored() const { return true; } }; + + + // ================================= + // ===== UndefinedBlockConstraint + // ================================= + + /** This class represents a constraint containing a block. + * During semantic analysis the block is parsed and causes this object to act + * as either a SingleValueConstraint or a TableConstraint afterwards. */ + class UndefinedBlockConstraint : public Constraint + { + union { + Block* block; // CT_UNDEFINEDBLOCK, before chk() + SingleValueConstraint* single; // CT_SINGLEVALUE, after chk() + Asn::TableConstraint* table; // CT_TABLE, after chk() + }; + UndefinedBlockConstraint(const UndefinedBlockConstraint& p); + /// Assignment disabled + UndefinedBlockConstraint& operator=(const UndefinedBlockConstraint& p); + public: + UndefinedBlockConstraint(Block* p_block); + virtual ~UndefinedBlockConstraint(); + UndefinedBlockConstraint* clone() const { return new UndefinedBlockConstraint(*this); } + void chk(); + const char* get_name() const { return "Undefined block constraint"; } + void set_fullname(const string& p_fullname); + SubtypeConstraint* get_subtype() const; + SubtypeConstraint* get_extension() const; + const Constraint* get_tableconstraint() const; + }; } // namespace Common diff --git a/compiler2/Value.hh b/compiler2/Value.hh index ba7f960456b6f87be00a128027c20d4eca6f6f7b..a886290e8e5785cf7f5c660cf4d0b5682ca04eb4 100644 --- a/compiler2/Value.hh +++ b/compiler2/Value.hh @@ -315,7 +315,7 @@ namespace Common { ttcn3float val_Real; struct { string *val_str; - map<size_t, Value> *str_elements; + map<size_t, Value> *str_elements; } str; struct { ustring *val_ustr; diff --git a/compiler2/asn1/TableConstraint.cc b/compiler2/asn1/TableConstraint.cc index a799bf75b95988760868489d33748dbfb3b74b4f..6228ab539465e10a6f8124ea9068deb4068e1907 100644 --- a/compiler2/asn1/TableConstraint.cc +++ b/compiler2/asn1/TableConstraint.cc @@ -225,7 +225,7 @@ namespace Asn { Constraints *t_cons=t_type->get_constraints(); if(!t_cons) break; t_cons->chk_table(); - TableConstraint *t_tc=dynamic_cast<TableConstraint*> + const TableConstraint *t_tc=dynamic_cast<const TableConstraint*> (t_cons->get_tableconstraint()); if(!t_tc) break; Type *t_ocft=t_tc->consdtype; diff --git a/compiler2/asn1/TableConstraint.hh b/compiler2/asn1/TableConstraint.hh index d16b3eedbe8ff0ccbb369edadd3cee116b881b48..7ad7233bd17b0fd7afa98a24879161be4d747e26 100644 --- a/compiler2/asn1/TableConstraint.hh +++ b/compiler2/asn1/TableConstraint.hh @@ -103,6 +103,7 @@ namespace Asn { ObjectSet* get_os() const {return os;} const Identifier* get_oc_fieldname() const {return oc_fieldname;} const char* get_name() const { return "table constraint"; } + const Constraint* get_tableconstraint() const { return this; } private: void parse_blocks(); }; diff --git a/compiler2/asn1/asn1p.y b/compiler2/asn1/asn1p.y index 8407f8221877de13954c0a67e9b579b1e8e1253a..25e6f654de339c3c4ab03dd95b4b5b5f0b78bf35 100644 --- a/compiler2/asn1/asn1p.y +++ b/compiler2/asn1/asn1p.y @@ -2780,10 +2780,9 @@ SingleValue: } | TOK_Block { - /** \todo: It would be more straightforward to create an undefined - * constraint here and classify it later on during parsing or semantic - * analysis to SimpleTableConstraint or SingleValue. */ - $$ = new TableConstraint($1, 0); + /* Create an undefined constraint for now, and classify it later on during + semantic analysis to TableConstraint or SingleValueConstraint. */ + $$ = new UndefinedBlockConstraint($1); $$->set_location(asn1_infile, @1.first_line); } | ReferencedValue_reg diff --git a/compiler2/subtype.cc b/compiler2/subtype.cc index d45497c7f3cfc23f84d7cfe16de2fb0c8b6d870b..de5568798de8fb8a74c6c64f6e7ade3d3ccd965d 100644 --- a/compiler2/subtype.cc +++ b/compiler2/subtype.cc @@ -934,7 +934,7 @@ SubtypeConstraint* SubtypeConstraint::create_asn_size_constraint( static const int_val_t zero((Int)0); static const int_limit_t ilt0(zero); IntegerRangeListConstraint valid_range(ilt0, int_limit_t::maximum); - if (integer_stc->integer_st->is_subset(valid_range)==TFALSE) { + if (integer_stc->integer_st->can_intersect(valid_range)==TFALSE) { loc->error("Range %s is not a valid range for a size constraint", integer_stc->to_string().c_str()); } else { bool success = convert_int_to_size(*(integer_stc->integer_st), size_constraint); @@ -1707,38 +1707,38 @@ void SubtypeConstraint::intersection(const SubtypeConstraint* other) } } -tribool SubtypeConstraint::is_subset(const SubtypeConstraint* other) const +tribool SubtypeConstraint::can_intersect(const SubtypeConstraint* other) const { if (other==NULL) return TTRUE; - if (other->subtype!=subtype) FATAL_ERROR("SubtypeConstraint::is_subset()"); + if (other->subtype!=subtype) FATAL_ERROR("SubtypeConstraint::can_intersect()"); switch (subtype) { case ST_INTEGER: if (other->integer_st==NULL) return TTRUE; - return integer_st ? integer_st->is_subset(*(other->integer_st)) : TTRUE; + return integer_st ? integer_st->can_intersect(*(other->integer_st)) : TTRUE; case ST_FLOAT: if (other->float_st==NULL) return TTRUE; - return float_st ? float_st->is_subset(*(other->float_st)) : TTRUE; + return float_st ? float_st->can_intersect(*(other->float_st)) : TTRUE; case ST_BOOLEAN: if (other->boolean_st==NULL) return TTRUE; - return boolean_st ? boolean_st->is_subset(*(other->boolean_st)) : TTRUE; + return boolean_st ? boolean_st->can_intersect(*(other->boolean_st)) : TTRUE; case ST_VERDICTTYPE: if (other->verdict_st==NULL) return TTRUE; - return verdict_st ? verdict_st->is_subset(*(other->verdict_st)) : TTRUE; + return verdict_st ? verdict_st->can_intersect(*(other->verdict_st)) : TTRUE; case ST_BITSTRING: if (other->bitstring_st==NULL) return TTRUE; - return bitstring_st ? bitstring_st->is_subset(*(other->bitstring_st)) : TTRUE; + return bitstring_st ? bitstring_st->can_intersect(*(other->bitstring_st)) : TTRUE; case ST_HEXSTRING: if (other->hexstring_st==NULL) return TTRUE; - return hexstring_st ? hexstring_st->is_subset(*(other->hexstring_st)) : TTRUE; + return hexstring_st ? hexstring_st->can_intersect(*(other->hexstring_st)) : TTRUE; case ST_OCTETSTRING: if (other->octetstring_st==NULL) return TTRUE; - return octetstring_st ? octetstring_st->is_subset(*(other->octetstring_st)) : TTRUE; + return octetstring_st ? octetstring_st->can_intersect(*(other->octetstring_st)) : TTRUE; case ST_CHARSTRING: if (other->charstring_st==NULL) return TTRUE; - return charstring_st ? charstring_st->is_subset(other->charstring_st) : TTRUE; + return charstring_st ? charstring_st->can_intersect(other->charstring_st) : TTRUE; case ST_UNIVERSAL_CHARSTRING: if (other->universal_charstring_st==NULL) return TTRUE; - return universal_charstring_st ? universal_charstring_st->is_subset(other->universal_charstring_st) : TTRUE; + return universal_charstring_st ? universal_charstring_st->can_intersect(other->universal_charstring_st) : TTRUE; case ST_OBJID: case ST_RECORD: case ST_SET: @@ -1748,13 +1748,13 @@ tribool SubtypeConstraint::is_subset(const SubtypeConstraint* other) const case ST_ALTSTEP: case ST_TESTCASE: if (other->value_st==NULL) return TTRUE; - return value_st ? value_st->is_subset(*(other->value_st)) : TTRUE; + return value_st ? value_st->can_intersect(*(other->value_st)) : TTRUE; case ST_RECORDOF: case ST_SETOF: if (other->recof_st==NULL) return TTRUE; - return recof_st ? recof_st->is_subset(*(other->recof_st)) : TTRUE; + return recof_st ? recof_st->can_intersect(*(other->recof_st)) : TTRUE; default: - FATAL_ERROR("SubtypeConstraint::is_subset()"); + FATAL_ERROR("SubtypeConstraint::can_intersect()"); } return TUNKNOWN; } @@ -2857,9 +2857,11 @@ void SubType::chk() if (subtype==ST_ERROR) { checked = STC_YES; return; } if (parent_subtype) { - if (is_subset(parent_subtype->get_root())==TFALSE) { - my_owner->error("The subtype restriction is not a subset of the restriction on the parent type. " - "Subtype %s is not subset of subtype %s", to_string().c_str(), parent_subtype->get_root()->to_string().c_str()); + if (can_intersect(parent_subtype->get_root())==TFALSE) { + my_owner->error("The intersection between the subtype restriction, %s, " + "and the parent type's restriction, %s, is empty. (No values satisfy " + "the type's restrictions.)", + to_string().c_str(), parent_subtype->get_root()->to_string().c_str()); set_to_error(); checked = STC_YES; return; diff --git a/compiler2/subtype.hh b/compiler2/subtype.hh index cb1a36221c6764acea3fe2a0dc8ff6a26df525a1..a610a08762a19cd8b9a64c0792df2b267ec6dec3 100644 --- a/compiler2/subtype.hh +++ b/compiler2/subtype.hh @@ -189,7 +189,7 @@ public: void union_(const SubtypeConstraint* other); void except(const SubtypeConstraint* other); - tribool is_subset(const SubtypeConstraint* other) const; + tribool can_intersect(const SubtypeConstraint* other) const; /** special ASN.1 types (NumericString, etc.) have default subtype constraints, return default constraint or NULL */ diff --git a/compiler2/subtypestuff.hh b/compiler2/subtypestuff.hh index 8c17ad30b11b4a9f5d2f3483df366dc514167279..c60f5a5374c45185fc8f51075ef029ccc5af9ea9 100644 --- a/compiler2/subtypestuff.hh +++ b/compiler2/subtypestuff.hh @@ -260,7 +260,7 @@ public: RangeListConstraint operator*(const RangeListConstraint& other) const { return set_operation(other, false); } // intersection RangeListConstraint operator~() const; // complement - tribool is_subset(const RangeListConstraint& other) const { return (*this*~other).is_empty(); } + tribool can_intersect(const RangeListConstraint& other) const { return !(*this * other).is_empty(); } RangeListConstraint operator-(const RangeListConstraint& other) const { return ( *this * ~other ); } // except // will return the minimal value that is part of the interval, @@ -616,7 +616,7 @@ public: RealRangeListConstraint operator*(const RealRangeListConstraint& other) const { return set_operation(other, false); } // intersection RealRangeListConstraint operator~() const; // complement - tribool is_subset(const RealRangeListConstraint& other) const { return (*this*~other).is_empty(); } + tribool can_intersect(const RealRangeListConstraint& other) const { return !(*this * other).is_empty(); } RealRangeListConstraint operator-(const RealRangeListConstraint& other) const { return ( *this * ~other ); } // except tribool is_range_empty() const { return rlc.is_empty(); } @@ -656,7 +656,7 @@ public: BooleanListConstraint operator*(const BooleanListConstraint& other) const { BooleanListConstraint rv; rv.values = values & other.values; return rv; } BooleanListConstraint operator~() const { BooleanListConstraint rv; rv.values = values ^ BC_ALL; return rv; } - tribool is_subset(const BooleanListConstraint& other) const { return (*this*~other).is_empty(); } + tribool can_intersect(const BooleanListConstraint& other) const { return !(*this * other).is_empty(); } BooleanListConstraint operator-(const BooleanListConstraint& other) const { return ( *this * ~other ); } @@ -695,7 +695,7 @@ public: VerdicttypeListConstraint operator*(const VerdicttypeListConstraint& other) const { VerdicttypeListConstraint rv; rv.values = values & other.values; return rv; } VerdicttypeListConstraint operator~() const { VerdicttypeListConstraint rv; rv.values = values ^ VC_ALL; return rv; } - tribool is_subset(const VerdicttypeListConstraint& other) const { return (*this*~other).is_empty(); } + tribool can_intersect(const VerdicttypeListConstraint& other) const { return !(*this * other).is_empty(); } VerdicttypeListConstraint operator-(const VerdicttypeListConstraint& other) const { return ( *this * ~other ); } @@ -745,7 +745,7 @@ public: StringSizeAndValueListConstraint operator*(const StringSizeAndValueListConstraint& other) const { return set_operation(other, false); } // intersection StringSizeAndValueListConstraint operator~() const; // complement - tribool is_subset(const StringSizeAndValueListConstraint& other) const { return (*this*~other).is_empty(); } + tribool can_intersect(const StringSizeAndValueListConstraint& other) const { return !(*this * other).is_empty(); } StringSizeAndValueListConstraint operator-(const StringSizeAndValueListConstraint& other) const { return ( *this * ~other ); } // except tribool get_size_limit(bool is_upper, size_limit_t& limit) const; @@ -1067,7 +1067,7 @@ public: StringPatternConstraint operator*(const StringPatternConstraint& other) const { return set_operation(other, false); } // intersection StringPatternConstraint operator~() const { FATAL_ERROR("StringPatternConstraint::operator~(): not implemented"); } - tribool is_subset(const StringPatternConstraint&) const { return TUNKNOWN; } + tribool can_intersect(const StringPatternConstraint&) const { return TUNKNOWN; } StringPatternConstraint operator-(const StringPatternConstraint& other) const { return ( *this * ~other ); } // except string to_string() const; @@ -1101,7 +1101,7 @@ public: StringValueConstraint operator+(const StringValueConstraint& other) const { return set_operation(other, true); } // union StringValueConstraint operator*(const StringValueConstraint& other) const { return set_operation(other, false); } // intersection - tribool is_subset(const StringValueConstraint& other) const { return (*this-other).is_empty(); } + tribool can_intersect(const StringValueConstraint& other) const { return !(*this * other).is_empty(); } StringValueConstraint operator-(const StringValueConstraint& other) const; // except // remove strings that are or are not elements of the set defined by the XXX_constraint object, @@ -1301,7 +1301,7 @@ public: tribool is_full() const; tribool is_equal(const StringSubtypeTreeElement* other) const; bool is_element(const STRINGTYPE& s) const; - tribool is_subset(const StringSubtypeTreeElement* other) const; + tribool can_intersect(const StringSubtypeTreeElement* other) const; bool is_single_constraint() const { return ( (elementtype==ET_CONSTRAINT) || (elementtype==ET_NONE) || (elementtype==ET_ALL) ); } void set_none() { clean_up(); elementtype = ET_NONE; } @@ -1803,9 +1803,9 @@ bool StringSubtypeTreeElement<STRINGTYPE,CHARLIMITTYPE>::is_element(const STRING // if the constraints are ortogonal (e.g. size and alphabet) or just different then return TUNKNOWN // in case of ortogonal constraints we should return TFALSE (if other is not full set) // but it seems that the standard wants to ignore such trivial cases, example: -// length(1..4) is_subset ('a'..'z') shall not report an error +// length(1..4) can_intersect ('a'..'z') shall not report an error template <class STRINGTYPE, class CHARLIMITTYPE> -tribool StringSubtypeTreeElement<STRINGTYPE,CHARLIMITTYPE>::is_subset(const StringSubtypeTreeElement<STRINGTYPE,CHARLIMITTYPE>* other) const +tribool StringSubtypeTreeElement<STRINGTYPE,CHARLIMITTYPE>::can_intersect(const StringSubtypeTreeElement<STRINGTYPE,CHARLIMITTYPE>* other) const { switch (elementtype) { case ET_NONE: @@ -1817,18 +1817,18 @@ tribool StringSubtypeTreeElement<STRINGTYPE,CHARLIMITTYPE>::is_subset(const Stri if (elementtype!=other->elementtype) return TUNKNOWN; if (u.cs.constrainttype!=other->u.cs.constrainttype) return TUNKNOWN; switch (u.cs.constrainttype) { - case CT_SIZE: return u.cs.s->is_subset(*(other->u.cs.s)); - case CT_ALPHABET: return u.cs.a.c->is_subset(*(other->u.cs.a.c)); - case CT_VALUES: return u.cs.v->is_subset(*(other->u.cs.v)); - case CT_PATTERN: return u.cs.p->is_subset(*(other->u.cs.p)); - default: FATAL_ERROR("StringSubtypeTreeElement::is_subset()"); + case CT_SIZE: return u.cs.s->can_intersect(*(other->u.cs.s)); + case CT_ALPHABET: return u.cs.a.c->can_intersect(*(other->u.cs.a.c)); + case CT_VALUES: return u.cs.v->can_intersect(*(other->u.cs.v)); + case CT_PATTERN: return u.cs.p->can_intersect(*(other->u.cs.p)); + default: FATAL_ERROR("StringSubtypeTreeElement::can_intersect()"); } case ET_INTERSECTION: case ET_UNION: case ET_EXCEPT: return TUNKNOWN; default: - FATAL_ERROR("StringSubtypeTreeElement::is_subset()"); + FATAL_ERROR("StringSubtypeTreeElement::can_intersect()"); } return TUNKNOWN; } @@ -2197,7 +2197,7 @@ public: ValueList operator*(const ValueList& other) const { return set_operation(other, false); } // intersection ValueList operator-(const ValueList& other) const; // except - tribool is_subset(const ValueList& other) const { return (*this-other).is_empty(); } + tribool can_intersect(const ValueList& other) const { return !(*this * other).is_empty(); } string to_string() const; }; @@ -2222,8 +2222,8 @@ public: ValueListConstraint operator*(const ValueListConstraint& other) const; // intersection ValueListConstraint operator~() const; // complement - inline tribool is_subset(const ValueListConstraint& other) const - { return (*this*~other).is_empty(); } + inline tribool can_intersect(const ValueListConstraint& other) const + { return !(*this * other).is_empty(); } inline ValueListConstraint operator-(const ValueListConstraint& other) const { return ( *this * ~other ); } // except @@ -2257,7 +2257,7 @@ public: inline RecofConstraint operator*(const RecofConstraint& other) const { return set_operation(other, false); } // intersection RecofConstraint operator~() const; // complement - inline tribool is_subset(const RecofConstraint& other) const { return (*this*~other).is_empty(); } + inline tribool can_intersect(const RecofConstraint& other) const { return !(*this * other).is_empty(); } inline RecofConstraint operator-(const RecofConstraint& other) const { return ( *this * ~other ); } // except tribool get_size_limit(bool is_upper, size_limit_t& limit) const; diff --git a/function_test/Semantic_Analyser/ASN_SA_1_TD.script b/function_test/Semantic_Analyser/ASN_SA_1_TD.script index a8dfb57fc44b70d088aa3283959e3b97ef185a3a..7d34d22ea342d8f47d4c295dda7b3d3df7f3547d 100644 --- a/function_test/Semantic_Analyser/ASN_SA_1_TD.script +++ b/function_test/Semantic_Analyser/ASN_SA_1_TD.script @@ -6337,7 +6337,7 @@ MyInt3 ::= INTEGER ( SIZE(10) EXCEPT FROM(1..10) ) MyInt4 ::= MyInt2 (MyInt3) MyInt5 ::= INTEGER ( PATTERN "abc" EXCEPT 5 ) MyInt6 ::= INTEGER ( ALL EXCEPT ((MIN..0) UNION (0..MAX)) ) -MyInt7 ::= INTEGER (1..10) (5..15) +MyInt7 ::= INTEGER (1..10) (12..15) MyInt9 ::= INTEGER (5..6 EXCEPT 1..10) MyInt10::= INTEGER ( MIN..MAX ) MyInt11::= INTEGER ( INTEGER ) @@ -6363,7 +6363,7 @@ END (?im)\berror: The subtype is an empty set <END_RESULT> <RESULT COUNT 1> -(?im)\berror: Constraint #2 is \(5..15\), this is not a subset of \(1..10\) +(?im)\berror: Constraint #2 is \(12..15\), intersecting this with \(1..10\) results in an empty set \(no values satisfy the type's restrictions\) <END_RESULT> <RESULT COUNT 1> (?im)\bwarning: The subtype of type `integer' is a full set, it does not constrain the root type. @@ -6559,12 +6559,6 @@ END (?im)\berror: 0 is not a valid value for type `integer' which has subtype \(-100..-11,11..100\) <END_RESULT> <RESULT COUNT 1> -(?im)\berror: Constraint #1 is \(-100..100\), this is not a subset of \(-100..-11,11..100\) -<END_RESULT> -<RESULT COUNT 1> -(?im)\berror: Constraint #1 is from\(" ".."6"\), this is not a subset of from\(" ","0".."9"\) -<END_RESULT> -<RESULT COUNT 1> (?im)\berror: "abc" is not a valid value for type `NumericString' which has subtype from\("3".."9"\) <END_RESULT> <RESULT COUNT 1> @@ -6583,7 +6577,7 @@ END (?im)\berror: Cannot determine the value of MAX: the parent subtype has no range <END_RESULT> <RESULT COUNT 1> -(?im)\berror: Constraint #2 is \(-INF..INF\), this is not a subset of \(NaN\) +(?im)\berror: Constraint #2 is \(-INF..INF\), intersecting this with \(NaN\) results in an empty set \(no values satisfy the type's restrictions\) <END_RESULT> <RESULT COUNT 1> (?im)\berror: Cannot determine the value of MAX: the parent subtype does not define a maximal size value @@ -6591,7 +6585,7 @@ END <RESULT COUNT 1> (?im)\berror: Cannot determine the value of MIN: the parent subtype does not define a minimal size value <END_RESULT> -<RESULT COUNT 11> +<RESULT COUNT 9> (?is)\berror: <END_RESULT> <RESULT COUNT 2> @@ -6644,9 +6638,6 @@ END (?im)\berror: Size constraint is not allowed for type `integer' <END_RESULT> <RESULT COUNT 1> -(?im)\berror: Constraint #2 is \(1..20\), this is not a subset of \(1..10\) -<END_RESULT> -<RESULT COUNT 1> (?im)\berror: 22 is not a valid value for type `integer' which has subtype \(1..20\) <END_RESULT> <RESULT COUNT 1> @@ -6655,7 +6646,7 @@ END <RESULT COUNT 1> (?im)\berror: 222 is not a valid value for type `integer' which has subtype \(1..20\) <END_RESULT> -<RESULT COUNT 6> +<RESULT COUNT 5> (?is)\berror: <END_RESULT> <END_TC> @@ -6715,12 +6706,9 @@ END (?im)\berror: INF is not a valid value for type `float' which has subtype \(0.0e0..!INF,NaN\) <END_RESULT> <RESULT IF_PASS COUNT 1> -(?im)\berror: Constraint #1 is \(1..20\), this is not a subset of \(1..10\) -<END_RESULT> -<RESULT IF_PASS COUNT 1> (?im)\berror: 21 is not a valid value for type `integer' which has subtype \(1..20\) <END_RESULT> -<RESULT IF_PASS COUNT 6> +<RESULT IF_PASS COUNT 5> (?is)\berror: <END_RESULT> <END_TC> @@ -6823,12 +6811,6 @@ B3 ::= B (FALSE,...,TRUE) END <END_MODULE> <RESULT COUNT 1> -(?im)\berror: Constraint #1 is \(1..128\), this is not a subset of \(1..32\) -<END_RESULT> -<RESULT COUNT 1> -(?im)\berror: Constraint #2 is \(1..128\), this is not a subset of \(1..32\) -<END_RESULT> -<RESULT COUNT 1> (?im)\berror: -1 is not a valid value for type `integer' which has subtype \(1..256\) <END_RESULT> <RESULT COUNT 1> @@ -6838,7 +6820,7 @@ END (?im)\bwarning: The subtype of type `integer' is a full set, it does not constrain the root type. <END_RESULT> <RESULT COUNT 1> -(?im)\berror: Constraint #1 is \(73\), this is not a subset of \(1..6\) +(?im)\berror: Constraint #1 is \(73\), intersecting this with \(1..6\) results in an empty set \(no values satisfy the type's restrictions\) <END_RESULT> <RESULT COUNT 1> (?im)\berror: 99 is not a valid value for type `integer' which has subtype \(1..6\), ..., \(73..80\) @@ -6862,9 +6844,9 @@ END (?im)\bwarning: The subtype of type `boolean' is a full set, it does not constrain the root type. <END_RESULT> <RESULT COUNT 1> -(?im)\berror: Extension addition of constraint #1 is \(true\), this is not a subset of \(false\) +(?im)\berror: Extension addition of constraint #1 is \(true\), intersecting this with \(false\) results in an empty set \(no values satisfy the type's restrictions\) <END_RESULT> -<RESULT COUNT 12> +<RESULT COUNT 10> (?is)\berror: <END_RESULT> <RESULT COUNT 2> diff --git a/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script index 2b68de2107d28e6faa88bfc1d5d94fa0a6df1b7b..f6cd793a053cd9f3ebe920e61fa8f9b7e0af3d74 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script @@ -5403,7 +5403,7 @@ module module1 (?is)\berror: inconc is not a valid value for type `verdicttype' which has subtype \(none,pass,fail\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(inconc\) is not subset of subtype \(none,pass,fail\) +(?is)\berror: The intersection between the subtype restriction, \(inconc\), and the parent type's restriction, \(none,pass,fail\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 9> (?is)\berror: @@ -5449,7 +5449,7 @@ module module1 (?is)\berror: false is not a valid value for type `boolean' which has subtype \(true\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(false\) is not subset of subtype \(true\) +(?is)\berror: The intersection between the subtype restriction, \(false\), and the parent type's restriction, \(true\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 9> (?is)\berror: @@ -5511,13 +5511,13 @@ module module1 (?is)\berror: 4 is not a valid value for type `integer' which has subtype \(1..3\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(4\) is not subset of subtype \(1..3\) +(?is)\berror: The intersection between the subtype restriction, \(4\), and the parent type's restriction, \(1..3\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(4..8\) is not subset of subtype \(1..3\) +(?is)\berror: The intersection between the subtype restriction, \(4..8\), and the parent type's restriction, \(1..3\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(4..8,16\) is not subset of subtype \(1..3\) +(?is)\berror: The intersection between the subtype restriction, \(4..8,16\), and the parent type's restriction, \(1..3\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 1> (?is)\berror: While checking circular type references in subtype definitions: Circular reference: `\@module1.myi6' -> `\@module1.myi7' -> `\@module1.myi6' @@ -5571,13 +5571,13 @@ module module1 (?is)\berror: 4.0e0 is not a valid value for type `float' which has subtype \(1.0e0,2.0e0,3.0e0\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(4.0e0\) is not subset of subtype \(1.0e0,2.0e0,3.0e0\) +(?is)\berror: The intersection between the subtype restriction, \(4.0e0\), and the parent type's restriction, \(1.0e0,2.0e0,3.0e0\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(4.0e0..8.0e0\) is not subset of subtype \(1.0e0,2.0e0,3.0e0\) +(?is)\berror: The intersection between the subtype restriction, \(4.0e0..8.0e0\), and the parent type's restriction, \(1.0e0,2.0e0,3.0e0\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(4.0e0..8.0e0,1.6e1\) is not subset of subtype \(1.0e0,2.0e0,3.0e0\) +(?is)\berror: The intersection between the subtype restriction, \(4.0e0..8.0e0,1.6e1\), and the parent type's restriction, \(1.0e0,2.0e0,3.0e0\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 11> (?is)\berror: @@ -5744,7 +5744,7 @@ module module1 (?is)\berror: '10'B is not a valid value for type `bitstring' which has subtype length\(1\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype length\(1\) is not subset of subtype \('00'B,'01'B\) +(?is)\berror: The intersection between the subtype restriction, length\(1\), and the parent type's restriction, \('00'B,'01'B\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 3> (?is)\berror: Subtype mismatch: subtype length\(1\) has no common value with subtype \('00'B,'01'B\) @@ -5796,7 +5796,7 @@ module module1 (?is)\berror: '10'H is not a valid value for type `hexstring' which has subtype length\(1\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype length\(1\) is not subset of subtype \('00'H,'01'H\) +(?is)\berror: The intersection between the subtype restriction, length\(1\), and the parent type's restriction, \('00'H,'01'H\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 3> (?is)\berror: Subtype mismatch: subtype length\(1\) has no common value with subtype \('00'H,'01'H\) @@ -5852,7 +5852,7 @@ module module1 (?is)\berror: '1010'O is not a valid value for type `octetstring' which has subtype length\(1\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype length\(2\) is not subset of subtype \('00'O,'01'O\) +(?is)\berror: The intersection between the subtype restriction, length\(2\), and the parent type's restriction, \('00'O,'01'O\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 2> (?is)\berror: '1010'O is not a valid value for type `octetstring' which has subtype \('00'O,'01'O\) @@ -6157,9 +6157,6 @@ module module1 } } <END_MODULE> -<RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(\{ 1, 2 \}\) union length\(1\) is not subset of subtype length\(1\) -<END_RESULT> <RESULT COUNT 2> (?is)\berror: There must not be more than 1 elements in the list <END_RESULT> @@ -6173,7 +6170,7 @@ module module1 (?is)\berror: At least 4 elements must be present in the list <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(\{ <erroneous> \},\{ <erroneous> \}\) is not subset of subtype length\(5\) +(?is)\berror: The intersection between the subtype restriction, \(\{ <erroneous> \},\{ <erroneous> \}\), and the parent type's restriction, length\(5\), is empty. \(No values satisfy the type's restrictions.\) <END_RESULT> <RESULT COUNT 2> (?is)\berror: record of value was expected @@ -6187,7 +6184,7 @@ module module1 <RESULT COUNT 1> (?is)\berror: Reference `myro2' must refer to a type which has the same root type as this type <END_RESULT> -<RESULT COUNT 21> +<RESULT COUNT 20> (?is)\berror: <END_RESULT> <END_TC> @@ -6243,9 +6240,6 @@ module module1 <RESULT COUNT 2> (?is)\berror: Reference `myso2' must refer to a type which has the same root type as this type <END_RESULT> -<RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(\{ 1, 2 \}\) union length\(1\) is not subset of subtype length\(1\) -<END_RESULT> <RESULT COUNT 2> (?is)\berror: There must not be more than 1 elements in the list <END_RESULT> @@ -6264,7 +6258,7 @@ module module1 <RESULT COUNT 3> (?is)\berror: Type mismatch: `\@module1.myso1' and `\@module1.myso2' are not compatible: Incompatible set of/SET OF subtypes <END_RESULT> -<RESULT COUNT 20> +<RESULT COUNT 19> (?is)\berror: <END_RESULT> <END_TC> @@ -6397,12 +6391,9 @@ module module1 (?is)\berror: 10 is not a valid value for type `integer' which has subtype \(2..9,11..19\) <END_RESULT> <RESULT COUNT 1> -(?is)\berror: The subtype restriction is not a subset of the restriction on the parent type. Subtype \(2..19\) is not subset of subtype \(2..9,11..19\) -<END_RESULT> -<RESULT COUNT 1> (?is)\berror: 20 is not a valid value for type `integer' which has subtype \(2..19\) <END_RESULT> -<RESULT COUNT 6> +<RESULT COUNT 5> (?is)\berror: <END_RESULT> <END_TC> diff --git a/function_test/Semantic_Analyser/float/subtype_SE.ttcn b/function_test/Semantic_Analyser/float/subtype_SE.ttcn index 4900780ee24cd8313973d44fd75636a99ae2b66e..c87810647f97836eb15e57cef2e4e5401b309bcc 100644 --- a/function_test/Semantic_Analyser/float/subtype_SE.ttcn +++ b/function_test/Semantic_Analyser/float/subtype_SE.ttcn @@ -29,8 +29,8 @@ type float myf9 (myf123, minf_to_zero) type myf9 myf10 (myf123) type two31_32 myf11 (2147483648.0..4294967296.0, 4294967296.0..4294967300.0) -type myf123 su2 (3.14); //^In type definition// //^error\: The subtype restriction is not a subset of the restriction on the parent type\. Subtype \(3\.14e0\) is not subset of subtype \(1\.0e0,2\.0e0,3\.0e0\)$// -type minf_to_zero su3 (!6.0 .. 10.0); //^In type definition// //^error\: The subtype restriction is not a subset of the restriction on the parent type\. Subtype \(\!6\.0e0\.\.1\.0e1\) is not subset of subtype \(\-INF\.\.0\.0e0\)$// +type myf123 su2 (3.14); //^In type definition// //^error\: The intersection between the subtype restriction, \(3\.14e0\), and the parent type's restriction, \(1\.0e0,2\.0e0,3\.0e0\), is empty. \(No values satisfy the type's restrictions.\)$// +type minf_to_zero su3 (!6.0 .. 10.0); //^In type definition// //^error\: The intersection between the subtype restriction, \(\!6\.0e0\.\.1\.0e1\), and the parent type's restriction, \(\-INF\.\.0\.0e0\), is empty. \(No values satisfy the type's restrictions.\)$// type float buzz_lightyear (infinity .. not_a_number) //^In type definition// //^error: upper boundary cannot be not_a_number in float subtype range$// // to infinity and beyond diff --git a/regression_test/ASN1/parse/Test1.asn b/regression_test/ASN1/parse/Test1.asn index 602f04a4e1a15f32c49c96c51e5278961eb51c82..5d0f29262f1d317de9391018384a4dc6557aeee2 100644 --- a/regression_test/ASN1/parse/Test1.asn +++ b/regression_test/ASN1/parse/Test1.asn @@ -937,6 +937,14 @@ MyElementSetType9-String2 ::= IA5String ( FROM ("A".. "Z" UNION "a".. "z")) MyElementSetType10 ::= INTEGER (0|1|4|6) +MyElementSetType11 ::= BIT STRING { bit0 (0), bit1 (1) } (SIZE (8)) (ALL EXCEPT {}) + +MyElementSetType12 ::= BIT STRING { bit0 (0), bit1 (1) } (SIZE (8)) (ALL EXCEPT { bit0 }) + +MyElementSetType13 ::= BIT STRING { bit0 (0), bit1 (1) } (SIZE (8)) (ALL EXCEPT { bit1 }) + +MyElementSetType14 ::= BIT STRING { bit0 (0), bit1 (1) } (SIZE (8)) (ALL EXCEPT { bit0, bit1 }) + -- 46 SUBTYPE ELEMENTS ******************************************************************* -- to be added later