diff --git a/compiler2/Setting.cc b/compiler2/Setting.cc index 5f1add8b48e4982d21237cef6e28e195420bf5f7..ada1fbf615653fa0750a4241877f699a773a8d75 100644 --- a/compiler2/Setting.cc +++ b/compiler2/Setting.cc @@ -609,7 +609,7 @@ namespace Common { Ttcn::RunsOnScope *t_ros = get_scope_runs_on(); if (t_ros) { Type *local_comptype = t_ros->get_component_type(); - if (!refd_comptype->is_compatible(local_comptype, NULL)) { + if (!refd_comptype->is_compatible(local_comptype, NULL, NULL)) { // the 'runs on' clause of the referred definition is not compatible // with that of the current scope (i.e. the referring definition) p_loc.error("Runs on clause mismatch: A definition that runs on " @@ -650,7 +650,7 @@ namespace Common { Ttcn::RunsOnScope *t_ros = get_scope_runs_on(); if (t_ros) { Type *local_comptype = t_ros->get_component_type(); - if (!refd_comptype->is_compatible(local_comptype, NULL)) { + if (!refd_comptype->is_compatible(local_comptype, NULL, NULL)) { // the 'runs on' clause of the function/altstep type is not compatible // with that of the current scope (i.e. the referring definition) p_loc.error("Runs on clause mismatch: A definition that runs on " diff --git a/compiler2/SigParam.cc b/compiler2/SigParam.cc index 05652c4e0ab6459bf6d71ce9e461173791d6693d..665bd0dca199f955fd45be64bd9ebf3670a7bae8 100644 --- a/compiler2/SigParam.cc +++ b/compiler2/SigParam.cc @@ -226,7 +226,7 @@ size_t SignatureExceptions::get_nof_compatible_types(Type *p_type) size_t ret_val = 0; for (size_t i = 0; i < exc_v.size(); i++) // Don't allow type compatibility. The types must match exactly. - if (exc_v[i]->is_compatible(p_type, NULL)) + if (exc_v[i]->is_compatible(p_type, NULL, NULL)) ret_val++; return ret_val; } diff --git a/compiler2/Type.cc b/compiler2/Type.cc index a0182ffd5a3954373f47ad3bd37f5972140d8539..9cd01254a7ca94021de2df24b40c42b4c253a84e 100644 --- a/compiler2/Type.cc +++ b/compiler2/Type.cc @@ -3228,7 +3228,7 @@ namespace Common { } } - bool Type::is_compatible(Type *p_type, TypeCompatInfo *p_info, + bool Type::is_compatible(Type *p_type, TypeCompatInfo *p_info, Location* p_loc, TypeChain *p_left_chain, TypeChain *p_right_chain, bool p_is_inline_template) { @@ -3374,25 +3374,25 @@ namespace Common { break; case T_SEQ_A: case T_SEQ_T: - is_type_comp = t1->is_compatible_record(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template); + is_type_comp = t1->is_compatible_record(t2, p_info, p_loc, p_left_chain, p_right_chain, p_is_inline_template); break; case T_SEQOF: - is_type_comp = t1->is_compatible_record_of(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template); + is_type_comp = t1->is_compatible_record_of(t2, p_info, p_loc, p_left_chain, p_right_chain, p_is_inline_template); break; case T_SET_A: case T_SET_T: - is_type_comp = t1->is_compatible_set(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template); + is_type_comp = t1->is_compatible_set(t2, p_info, p_loc, p_left_chain, p_right_chain, p_is_inline_template); break; case T_SETOF: - is_type_comp = t1->is_compatible_set_of(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template); + is_type_comp = t1->is_compatible_set_of(t2, p_info, p_loc, p_left_chain, p_right_chain, p_is_inline_template); break; case T_ARRAY: - is_type_comp = t1->is_compatible_array(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template); + is_type_comp = t1->is_compatible_array(t2, p_info, p_loc, p_left_chain, p_right_chain, p_is_inline_template); break; case T_CHOICE_T: case T_CHOICE_A: case T_ANYTYPE: - is_type_comp = t1->is_compatible_choice_anytype(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template); + is_type_comp = t1->is_compatible_choice_anytype(t2, p_info, p_loc, p_left_chain, p_right_chain, p_is_inline_template); break; case T_ENUM_A: case T_ENUM_T: @@ -3449,6 +3449,24 @@ namespace Common { } } } + if (is_type_comp && p_loc != NULL) { + // issue a warning for deprecated compatibilities: + // - records and record ofs/arrays + // - sets and set ofs + bool is_record = t1->typetype == T_SEQ_T || t1->typetype == T_SEQ_A || + t2->typetype == T_SEQ_T || t2->typetype == T_SEQ_A; + bool is_record_of = t1->typetype == T_SEQOF || t2->typetype == T_SEQOF; + bool is_array = t1->typetype == T_ARRAY || t2->typetype == T_ARRAY; + bool is_set = t1->typetype == T_SET_T || t1->typetype == T_SET_A || + t2->typetype == T_SET_T || t2->typetype == T_SET_A; + bool is_set_of = t1->typetype == T_SETOF || t2->typetype == T_SETOF; + if ((is_record && (is_record_of || is_array)) || + (is_set && is_set_of)) { + p_loc->warning("Compatibility between %s types and %s types is " + "deprecated.", is_record ? "record" : "set", + is_record_of ? "record of" : (is_set_of ? "set of" : "array")); + } + } return is_type_comp; } @@ -3516,6 +3534,7 @@ namespace Common { // Errors and warnings are reported in an upper level. We just make a // simple decision here. bool Type::is_compatible_record(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain, TypeChain *p_right_chain, bool p_is_inline_template) @@ -3566,7 +3585,7 @@ namespace Common { p_right_chain->add(p_cf_type); if (cf_type != p_cf_type && !(p_left_chain->has_recursion() && p_right_chain->has_recursion()) - && !cf_type->is_compatible(p_cf_type, &info_tmp, p_left_chain, + && !cf_type->is_compatible(p_cf_type, &info_tmp, p_loc, p_left_chain, p_right_chain, p_is_inline_template)) { p_info->append_ref_str(0, "." + cf_name + info_tmp.get_ref_str(0)); p_info->append_ref_str(1, "." + p_cf_name + info_tmp.get_ref_str(1)); @@ -3623,7 +3642,7 @@ namespace Common { p_right_chain->add(p_of_type); if (cf_type != p_of_type && !(p_left_chain->has_recursion() && p_right_chain->has_recursion()) - && !cf_type->is_compatible(p_of_type, &info_tmp, p_left_chain, + && !cf_type->is_compatible(p_of_type, &info_tmp, p_loc, p_left_chain, p_right_chain, p_is_inline_template)) { p_info->append_ref_str(0, "." + get_comp_byIndex(i) ->get_name().get_dispname() + info_tmp.get_ref_str(0)); @@ -3678,6 +3697,7 @@ namespace Common { } bool Type::is_compatible_record_of(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain, TypeChain *p_right_chain, bool p_is_inline_template) @@ -3722,7 +3742,7 @@ namespace Common { p_right_chain->add(p_cf_type); if (of_type != p_cf_type && !(p_left_chain->has_recursion() && p_right_chain->has_recursion()) - && !of_type->is_compatible(p_cf_type, &info_tmp, p_left_chain, + && !of_type->is_compatible(p_cf_type, &info_tmp, p_loc, p_left_chain, p_right_chain, p_is_inline_template)) { p_info->append_ref_str(0, "[]" + info_tmp.get_ref_str(0)); p_info->append_ref_str(1, "." + p_cf->get_name().get_dispname() + @@ -3761,7 +3781,7 @@ namespace Common { p_right_chain->add(p_of_type); if (of_type == p_of_type || (p_left_chain->has_recursion() && p_right_chain->has_recursion()) - || of_type->is_compatible(p_of_type, &info_tmp, p_left_chain, + || of_type->is_compatible(p_of_type, &info_tmp, p_loc, p_left_chain, p_right_chain, p_is_inline_template)) { if (!p_is_inline_template) { p_info->set_needs_conversion(true); @@ -3800,6 +3820,7 @@ namespace Common { } bool Type::is_compatible_array(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain, TypeChain *p_right_chain, bool p_is_inline_template) @@ -3809,7 +3830,7 @@ namespace Common { // the dimension of the array must be the same. if (this == p_type) return true; if (p_type->typetype == T_ARRAY && u.array.element_type - ->is_compatible(p_type->u.array.element_type, NULL, NULL, NULL, p_is_inline_template) + ->is_compatible(p_type->u.array.element_type, NULL, p_loc, NULL, NULL, p_is_inline_template) && u.array.dimension->is_identical(p_type->u.array.dimension)) return true; else if (!use_runtime_2 || !p_info @@ -3849,7 +3870,7 @@ namespace Common { p_right_chain->add(p_cf_type); if (of_type != p_cf_type && !(p_left_chain->has_recursion() && p_right_chain->has_recursion()) - && !of_type->is_compatible(p_cf_type, &info_tmp, p_left_chain, + && !of_type->is_compatible(p_cf_type, &info_tmp, p_loc, p_left_chain, p_right_chain, p_is_inline_template)) { p_info->append_ref_str(0, info_tmp.get_ref_str(0)); p_info->append_ref_str(1, "." + p_cf->get_name().get_dispname() + @@ -3893,7 +3914,7 @@ namespace Common { p_right_chain->add(p_of_type); if (of_type == p_of_type || (p_left_chain->has_recursion() && p_right_chain->has_recursion()) - || of_type->is_compatible(p_of_type, &info_tmp, p_left_chain, + || of_type->is_compatible(p_of_type, &info_tmp, p_loc, p_left_chain, p_right_chain, p_is_inline_template)) { if (!p_is_inline_template) { p_info->set_needs_conversion(true); @@ -3931,6 +3952,7 @@ namespace Common { } bool Type::is_compatible_set(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain, TypeChain *p_right_chain, bool p_is_inline_template) @@ -3979,7 +4001,7 @@ namespace Common { p_right_chain->add(p_cf_type); if (cf_type != p_cf_type && !(p_left_chain->has_recursion() && p_right_chain->has_recursion()) - && !cf_type->is_compatible(p_cf_type, &info_tmp, p_left_chain, + && !cf_type->is_compatible(p_cf_type, &info_tmp, p_loc, p_left_chain, p_right_chain, p_is_inline_template)) { p_info->append_ref_str(0, "." + cf_name + info_tmp.get_ref_str(0)); p_info->append_ref_str(1, "." + p_cf_name + info_tmp.get_ref_str(1)); @@ -4016,7 +4038,7 @@ namespace Common { p_right_chain->add(p_of_type); if (cf_type != p_of_type && !(p_left_chain->has_recursion() && p_right_chain->has_recursion()) - && !cf_type->is_compatible(p_of_type, &info_tmp, p_left_chain, + && !cf_type->is_compatible(p_of_type, &info_tmp, p_loc, p_left_chain, p_right_chain, p_is_inline_template)) { p_info->append_ref_str(0, "." + get_comp_byIndex(i) ->get_name().get_dispname() + info_tmp.get_ref_str(0)); @@ -4056,6 +4078,7 @@ namespace Common { } bool Type::is_compatible_set_of(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain, TypeChain *p_right_chain, bool p_is_inline_template) @@ -4100,7 +4123,7 @@ namespace Common { p_right_chain->add(p_cf_type); if (of_type != p_cf_type && !(p_left_chain->has_recursion() && p_right_chain->has_recursion()) - && !of_type->is_compatible(p_cf_type, &info_tmp, p_left_chain, + && !of_type->is_compatible(p_cf_type, &info_tmp, p_loc, p_left_chain, p_right_chain, p_is_inline_template)) { p_info->append_ref_str(0, "[]" + info_tmp.get_ref_str(0)); p_info->append_ref_str(1, "." + p_cf->get_name().get_dispname() + @@ -4136,7 +4159,7 @@ namespace Common { p_right_chain->add(p_of_type); if (of_type == p_of_type || (p_left_chain->has_recursion() && p_right_chain->has_recursion()) - || of_type->is_compatible(p_of_type, &info_tmp, p_left_chain, + || of_type->is_compatible(p_of_type, &info_tmp, p_loc, p_left_chain, p_right_chain, p_is_inline_template)) { if (!p_is_inline_template) { p_info->set_needs_conversion(true); @@ -4175,6 +4198,7 @@ namespace Common { bool Type::is_compatible_choice_anytype(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain, TypeChain *p_right_chain, bool p_is_inline_template) @@ -4239,7 +4263,7 @@ namespace Common { p_right_chain->add(p_cf_type); if (cf_type == p_cf_type || (p_left_chain->has_recursion() && p_right_chain->has_recursion()) - || cf_type->is_compatible(p_cf_type, &info_tmp, p_left_chain, + || cf_type->is_compatible(p_cf_type, &info_tmp, p_loc, p_left_chain, p_right_chain, p_is_inline_template)) { if (cf_type != p_cf_type && cf_type->is_structured_type() && p_cf_type->is_structured_type()) { diff --git a/compiler2/Type.hh b/compiler2/Type.hh index a51c6f1be6d9d48c3ad3cc8319505c878852e81c..a23a222092e3e4e2bf3c06ef6f6e246b01bab31e 100644 --- a/compiler2/Type.hh +++ b/compiler2/Type.hh @@ -573,6 +573,7 @@ namespace Common { * \p p_is_inline_template indicates that the conversion is requested for an * inline template. Type conversion code is not needed in this case. */ bool is_compatible(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain = NULL, TypeChain *p_right_chain = NULL, bool p_is_inline_template = false); @@ -600,26 +601,32 @@ namespace Common { * \p p_is_inline_template indicates that the conversion is requested for an * inline template. Type conversion code is not needed in this case. */ bool is_compatible_record(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain = NULL, TypeChain *p_right_chain = NULL, bool p_is_inline_template = false); bool is_compatible_record_of(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain = NULL, TypeChain *p_right_chain = NULL, bool p_is_inline_template = false); bool is_compatible_set(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain = NULL, TypeChain *p_right_chain = NULL, bool p_is_inline_template = false); bool is_compatible_set_of(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain = NULL, TypeChain *p_right_chain = NULL, bool p_is_inline_template = false); bool is_compatible_array(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain = NULL, TypeChain *p_right_chain = NULL, bool p_is_inline_template = false); bool is_compatible_choice_anytype(Type *p_type, TypeCompatInfo *p_info, + Location* p_loc, TypeChain *p_left_chain = NULL, TypeChain *p_right_chain = NULL, bool p_is_inline_template = false); diff --git a/compiler2/TypeCompat.cc b/compiler2/TypeCompat.cc index ce669c906f77bc8c980a2dc538a04e8e6016cd34..3b52bd89563e9bc355dc63aa86c9951c7cafb74a 100644 --- a/compiler2/TypeCompat.cc +++ b/compiler2/TypeCompat.cc @@ -700,7 +700,7 @@ void TypeConv::gen_conv_func_choice_anytype(char **p_bodies, Module *p_mod) get_conv_func(cf_type_from, cf_type_to, p_mod).c_str(), tmp_id_str, anytype_prefix, cf_id_from.get_name().c_str(), tmp_id_str, tmp_id_str); - } else if (cf_type_from->is_compatible(cf_type_to, NULL)) { // E.g. basic types. + } else if (cf_type_from->is_compatible(cf_type_to, NULL, NULL)) { // E.g. basic types. // The same module + field name is required for anytype field // types. Only for structured types. bool both_structured = cf_type_from->is_structured_type() diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc index 1b6abd4e81e4a0b13c5ef64e44f512242b679770..9b6fd3b54e528859501b8dddac213f91f57508c7 100644 --- a/compiler2/Type_chk.cc +++ b/compiler2/Type_chk.cc @@ -3435,7 +3435,7 @@ bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_v if (ref->get_subrefs()) info.set_str2_elem(ref->get_subrefs()->refers_to_string_element()); TypeChain l_chain; TypeChain r_chain; - if (!is_compatible(governor, &info, &l_chain, &r_chain)) { + if (!is_compatible(governor, &info, value, &l_chain, &r_chain)) { // Port or signature values do not exist at all. These errors are // already reported at those definitions. Extra errors should not be // reported here. @@ -3512,7 +3512,7 @@ void Type::chk_this_invoked_value(Value *value, Common::Assignment *, if (!t) value->error("The type `%s' has no return type, `%s' expected", invoked_t->get_typename().c_str(), get_typename().c_str()); - else if (!is_compatible(t, NULL)) { + else if (!is_compatible(t, NULL, value)) { value->error("Incompatible value: `%s' value was expected", get_typename().c_str()); } @@ -4951,7 +4951,7 @@ void Type::chk_this_value_FAT(Value *value) Ttcn::RunsOnScope *t_ros = value_scope->get_scope_runs_on(); if (t_ros) { Type *scope_comptype = t_ros->get_component_type(); - if (!t_runs_on_type->is_compatible(scope_comptype, NULL)) { + if (!t_runs_on_type->is_compatible(scope_comptype, NULL, NULL)) { value->error("Runs on clause mismatch: type `%s' has a " "'runs on self' clause and the current scope expects component " "type `%s', but %s runs on `%s'", get_typename().c_str(), @@ -4965,7 +4965,7 @@ void Type::chk_this_value_FAT(Value *value) ComponentTypeBody* ct_body = dynamic_cast<ComponentTypeBody*>(value_scope); if (ct_body) { - if (!t_runs_on_type->is_compatible(ct_body->get_my_type(), NULL)) { + if (!t_runs_on_type->is_compatible(ct_body->get_my_type(), NULL, NULL)) { value->error("Runs on clause mismatch: type `%s' has a " "'runs on self' clause and the current component definition " "is of type `%s', but %s runs on `%s'", @@ -4986,7 +4986,7 @@ void Type::chk_this_value_FAT(Value *value) } else { if (u.fatref.runs_on.ref) { if (u.fatref.runs_on.type && - !t_runs_on_type->is_compatible(u.fatref.runs_on.type, NULL)) { + !t_runs_on_type->is_compatible(u.fatref.runs_on.type, NULL, NULL)) { value->error("Runs on clause mismatch: type `%s' expects component " "type `%s', but %s runs on `%s'", get_typename().c_str(), u.fatref.runs_on.type->get_typename().c_str(), @@ -5011,7 +5011,7 @@ void Type::chk_this_value_FAT(Value *value) Type *my_system_type = u.fatref.system.ref ? u.fatref.system.type : u.fatref.runs_on.type; if (t_system_type && my_system_type && - !t_system_type->is_compatible(my_system_type, NULL)) { + !t_system_type->is_compatible(my_system_type, NULL, NULL)) { value->error("System clause mismatch: testcase type `%s' expects " "component type `%s', but %s has `%s'", get_typename().c_str(), my_system_type->get_typename().c_str(), @@ -5521,7 +5521,7 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed, Type *governor = t->get_expr_governor(EXPECTED_DYNAMIC_VALUE); if(!governor) t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR); - else if (!is_compatible(governor, NULL)) { + else if (!is_compatible(governor, NULL, t)) { t->error("Type mismatch: a value or template of type `%s' was " "expected instead of `%s'", get_typename().c_str(), governor->get_typename().c_str()); @@ -5564,7 +5564,7 @@ bool Type::chk_this_refd_template(Template *t, Common::Assignment *lhs) if (ref->get_subrefs()) info.set_str2_elem(ref->get_subrefs()->refers_to_string_element()); TypeChain l_chain; TypeChain r_chain; - if (!is_compatible(governor, &info, &l_chain, &r_chain)) { + if (!is_compatible(governor, &info, t, &l_chain, &r_chain)) { Type *type = get_type_refd_last(); switch (type->typetype) { case T_PORT: diff --git a/compiler2/Value.cc b/compiler2/Value.cc index 404bcdbc032061ba9c0ef8f340ab030eccea6fdf..ef37c9901bade2915270a9d970f343517876983f 100644 --- a/compiler2/Value.cc +++ b/compiler2/Value.cc @@ -3419,7 +3419,7 @@ namespace Common { if (v1_gov) { if (v2_gov) { // both have governors // return the type that is compatible with both (if there is no type mismatch) - if (v1_gov->is_compatible(v2_gov, NULL)) + if (v1_gov->is_compatible(v2_gov, NULL, NULL)) return v1_gov; else return v2_gov; } else return v1_gov; @@ -3857,7 +3857,7 @@ namespace Common { TypeChain l_chain; TypeChain r_chain; if (my_governor && my_governor->is_list_type(allow_array) - && !my_governor->is_compatible(t, &info, &l_chain, &r_chain)) { + && !my_governor->is_compatible(t, &info, this, &l_chain, &r_chain)) { if (info.is_subtype_error()) { // this is ok. if (info.needs_conversion()) set_needs_conversion(); @@ -4099,8 +4099,8 @@ namespace Common { u.expr.v_optype == OPTYPE_REPLACE); TypeChain l_chain1, l_chain2; TypeChain r_chain1, r_chain2; - bool compat_t1 = t1->is_compatible(t2, &info1, &l_chain1, &r_chain1); - bool compat_t2 = t2->is_compatible(t1, &info2, &l_chain2, &r_chain2); + bool compat_t1 = t1->is_compatible(t2, &info1, this, &l_chain1, &r_chain1); + bool compat_t2 = t2->is_compatible(t1, &info2, NULL, &l_chain2, &r_chain2); if (!compat_t1 && !compat_t2) { if (!info1.is_erroneous() && !info2.is_erroneous()) { // the subtypes don't need to be compatible here @@ -4235,7 +4235,7 @@ namespace Common { if (my_governor) { Type *my_governor_last = my_governor->get_type_refd_last(); if (my_governor_last->get_typetype() == Type::T_COMPONENT && - !my_governor_last->is_compatible(t_type, NULL)) { + !my_governor_last->is_compatible(t_type, NULL, NULL)) { u.expr.r1->error("Incompatible component types: operation " "`create' should refer to `%s' instead of " "`%s'", @@ -4284,7 +4284,7 @@ namespace Common { break; } if (t_comptype - && !my_governor_last->is_compatible(t_comptype, NULL)) { + && !my_governor_last->is_compatible(t_comptype, NULL, NULL)) { error("Incompatible component types: a component reference of " "type `%s' was expected, but `%s' has type `%s'", my_governor_last->get_typename().c_str(), get_opname(), @@ -6859,8 +6859,8 @@ error: chk_expr_operandtype_list(v2_gov, right, opname, v2, false); if (valuetype == V_ERROR) return; // 7.1.2 says that we shouldn't allow type compatibility. - if (!v1_gov->is_compatible(v2_gov, NULL) - && !v2_gov->is_compatible(v1_gov, NULL)) { + if (!v1_gov->is_compatible(v2_gov, NULL, this) + && !v2_gov->is_compatible(v1_gov, NULL, NULL)) { error("The operands of operation `%s' should be of compatible " "types", get_opname()); } @@ -11129,8 +11129,8 @@ error: Type *right_governor = right->get_my_governor(); if (right_governor) right_governor = right_governor->get_type_refd_last(); if (left_governor && right_governor - && !left_governor->is_compatible(right_governor, NULL) - && !right_governor->is_compatible(left_governor, NULL)) + && !left_governor->is_compatible(right_governor, NULL, NULL) + && !right_governor->is_compatible(left_governor, NULL, NULL)) FATAL_ERROR("Value::operator=="); // Not-A-Value is not equal to anything (NaN analogy:) diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc index 55bbbc47e7ae810f4b0fbb7f25a8f648fba4817e..dec0bdcf1172bf404327ffd4ea4e6b696d98732d 100644 --- a/compiler2/ttcn3/AST_ttcn3.cc +++ b/compiler2/ttcn3/AST_ttcn3.cc @@ -4302,7 +4302,7 @@ namespace Ttcn { false, true); TypeChain l_chain_base; TypeChain r_chain_base; - if (!type->is_compatible(base_type, &info_base, &l_chain_base, + if (!type->is_compatible(base_type, &info_base, this, &l_chain_base, &r_chain_base)) { if (info_base.is_subtype_error()) { type->error("%s", info_base.get_subtype_error().c_str()); @@ -4358,8 +4358,8 @@ namespace Ttcn { local_fp_type, true, false); TypeChain l_chain_par; TypeChain r_chain_par; - if (!base_fp_type->is_compatible(local_fp_type, &info_par, &l_chain_par, - &r_chain_par)) { + if (!base_fp_type->is_compatible(local_fp_type, &info_par, this, + &l_chain_par, &r_chain_par)) { if (info_par.is_subtype_error()) { local_fp_type->error("%s", info_par.get_subtype_error().c_str()); } else @@ -8263,7 +8263,8 @@ namespace Ttcn { false, is_template); TypeChain l_chain_base; TypeChain r_chain_base; - if (!type->is_compatible(ref_type, &info, &l_chain_base, &r_chain_base)) { + if (!type->is_compatible(ref_type, &info, actual_par, + &l_chain_base, &r_chain_base)) { if (info.is_subtype_error()) { ref->error("%s", info.get_subtype_error().c_str()); } @@ -8279,7 +8280,8 @@ namespace Ttcn { } else if ((asstype == A_PAR_VAL_OUT || asstype == A_PAR_VAL_INOUT || asstype == A_PAR_TEMPL_OUT || asstype == A_PAR_TEMPL_INOUT) && - !ref_type->is_compatible(type, &info, &l_chain_base, &r_chain_base)) { + !ref_type->is_compatible(type, &info, NULL, + &l_chain_base, &r_chain_base)) { // run the type compatibility check in the reverse order, too, for // 'out' and 'inout' parameters (they need to be converted back after // the function call) diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc index ed5f97873a9809e68efb790d28b434a2fc707859..27f2c823d51922242dc181d88c153d832b9eef41 100644 --- a/compiler2/ttcn3/Statement.cc +++ b/compiler2/ttcn3/Statement.cc @@ -4291,7 +4291,7 @@ error: // checking the 'runs on' clause against the type of component reference Type *runs_on_type = t_func->get_RunsOnType(); if (!comp_type || !runs_on_type) return; - if (!runs_on_type->is_compatible(comp_type, NULL)) + if (!runs_on_type->is_compatible(comp_type, NULL, NULL)) comp_op.compref->error("Component type mismatch: The component reference " "is of type `%s', but %s runs on `%s'", comp_type->get_typename().c_str(), t_func->get_description().c_str(), @@ -4363,7 +4363,7 @@ error: if(!f_type->chk_startability()) return; Type *runs_on_type = f_type->get_fat_runs_on_type(); if (!comp_type || !runs_on_type) return; - if (!runs_on_type->is_compatible(comp_type, NULL)) + if (!runs_on_type->is_compatible(comp_type, NULL, NULL)) comp_op.compref->error("Component type mismatch: The component reference " "is of type `%s', but functions of type `%s' run on `%s'", comp_type->get_typename().c_str(), f_type->get_typename().c_str(), @@ -4790,7 +4790,7 @@ error: bool is_address; Type *t_governor = port_op.s.toclause->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE); - if (t_governor) is_address = address_type->is_compatible(t_governor, NULL); + if (t_governor) is_address = address_type->is_compatible(t_governor, NULL, this); else is_address = port_op.s.toclause->get_expr_returntype(Type::EXPECTED_DYNAMIC_VALUE) != Type::T_COMPONENT; @@ -4883,7 +4883,7 @@ error: // the type of from clause is known port_op.r.fromclause->chk(from_clause_type); if (!address_type - || !address_type->is_compatible(from_clause_type, NULL)) { + || !address_type->is_compatible(from_clause_type, NULL, this)) { // from_clause_type must be a component type switch (from_clause_type->get_type_refd_last()->get_typetype()) { case Type::T_ERROR: @@ -4969,7 +4969,7 @@ error: if (t_stmt->port_op.r.rcvpar) { Type *t_sig = t_stmt->port_op.r.rcvpar ->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE); - if (!signature->is_compatible(t_sig, NULL)) + if (!signature->is_compatible(t_sig, NULL, NULL)) t_stmt->port_op.r.rcvpar->error("The `getreply' operation refers " "to a different signature than the previous `call' statement: " "`%s' was expected instead of `%s'", @@ -4979,7 +4979,7 @@ error: break; case S_CATCH: if (t_stmt->port_op.r.ctch.signature - && !signature->is_compatible(t_stmt->port_op.r.ctch.signature, NULL)) + && !signature->is_compatible(t_stmt->port_op.r.ctch.signature, NULL, NULL)) t_stmt->port_op.r.ctch.signature_ref->error("The `catch' " "operation refers to a different signature than the previous " "`call' statement: `%s' was expected instead of `%s'", @@ -9324,7 +9324,7 @@ error: } TypeChain l_chain; TypeChain r_chain; - if (!exp_type->is_compatible(var_type, &info, &l_chain, &r_chain)) { + if (!exp_type->is_compatible(var_type, &info, this, &l_chain, &r_chain)) { if (info.is_subtype_error()) { v[i]->error("%s", info.get_subtype_error().c_str()); } @@ -9764,7 +9764,7 @@ error: else { // if the variable reference and the received value (or its specified field) // are not of the same type, then a type conversion is needed (RT2 only) - if (use_runtime_2 && !ref_type->is_identical(redir_type)) { + if (!ref_type->is_identical(redir_type)) { Common::Module* mod = scope->get_scope_mod(); mod->add_type_conv(new TypeConv(redir_type, ref_type, false)); set_values_str = mputprintf(set_values_str, diff --git a/compiler2/ttcn3/TtcnTemplate.cc b/compiler2/ttcn3/TtcnTemplate.cc index 4eb296f6ce63832e495d3ed7f874b050616e9204..a05eff0d882bcfe6730a35e2e65d0d918117be94 100644 --- a/compiler2/ttcn3/TtcnTemplate.cc +++ b/compiler2/ttcn3/TtcnTemplate.cc @@ -5146,7 +5146,7 @@ compile_time: TypeChain l_chain; TypeChain r_chain; if (!governor) return type; - else if (governor->is_compatible(type, &info, &l_chain, &r_chain, true)) { + else if (governor->is_compatible(type, &info, NULL, &l_chain, &r_chain, true)) { return governor; } else { if (info.is_subtype_error()) { @@ -5193,7 +5193,7 @@ compile_time: true, false); TypeChain l_chain; TypeChain r_chain; - if (!governor->is_compatible(base_template_type, &info, &l_chain, + if (!governor->is_compatible(base_template_type, &info, this, &l_chain, &r_chain)) { if (info.is_subtype_error()) { derived_reference->error("%s", info.get_subtype_error().c_str()); diff --git a/compiler2/ttcn3/Ttcnstuff.cc b/compiler2/ttcn3/Ttcnstuff.cc index 21c2dcaceabb4f97ec6f2314a41b04ed66047e28..d4084478dd52792526e78fd55fafd859b277add5 100644 --- a/compiler2/ttcn3/Ttcnstuff.cc +++ b/compiler2/ttcn3/Ttcnstuff.cc @@ -925,7 +925,7 @@ namespace Ttcn { size_t nof_types = types_v.size(); for (size_t i = 0; i < nof_types; i++) { // Don't allow type compatibility. - if (types_v[i]->is_compatible(p_type, NULL)) ret_val++; + if (types_v[i]->is_compatible(p_type, NULL, NULL)) ret_val++; } return ret_val; } diff --git a/function_test/Makefile b/function_test/Makefile index 82ae2634321bff12e91f48f2d954222c4336a20a..1f8468c85b6df7e99ea2827c4405735d75f07c51 100644 --- a/function_test/Makefile +++ b/function_test/Makefile @@ -63,6 +63,7 @@ ifndef PLATFORM endif # ifndef PLATFORM export PLATFORM +export RT2 all check run: $(DIRS) diff --git a/function_test/Semantic_Analyser/Makefile.semantic b/function_test/Semantic_Analyser/Makefile.semantic index 52f3b3256dc51d10a8d08d71c716503cbb72f03e..61a1db5012bccf86437655c052645d601b5c8f44 100644 --- a/function_test/Semantic_Analyser/Makefile.semantic +++ b/function_test/Semantic_Analyser/Makefile.semantic @@ -12,6 +12,9 @@ # ############################################################################## SADIRS := ver xer encode param template +ifeq ($(RT2), yes) +SADIRS += deprecated +endif #$(wildcard TTCN3_[a0-9]* ASN_[a0-9]*) ver xer all run check clean distclean: diff --git a/function_test/Semantic_Analyser/common.mk b/function_test/Semantic_Analyser/common.mk index fca246433055d4d32ec8acf3f9d5237c68c13e46..a8be87ada062ceb5698ec857365e8f9b8e046129 100644 --- a/function_test/Semantic_Analyser/common.mk +++ b/function_test/Semantic_Analyser/common.mk @@ -17,7 +17,9 @@ # Flags for the TTCN-3 and ASN.1 compiler: COMPILER_FLAGS := -s -g - +ifeq ($(RT2), yes) +COMPILER_FLAGS += -R +endif # TTCN-3 modules of this project: TTCN3_MODULES := $(sort $(wildcard *A.ttcn *S[WE].ttcn *OK.ttcn)) diff --git a/function_test/Semantic_Analyser/deprecated/.gitignore b/function_test/Semantic_Analyser/deprecated/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2d293255e6d2f314e34950e486a48630d873491 --- /dev/null +++ b/function_test/Semantic_Analyser/deprecated/.gitignore @@ -0,0 +1,2 @@ +!Makefile +!*.ttcn diff --git a/function_test/Semantic_Analyser/deprecated/DeprecatedCompat_SE.ttcn b/function_test/Semantic_Analyser/deprecated/DeprecatedCompat_SE.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..7c40c45621462a72d171c29d0c3e943aefff2065 --- /dev/null +++ b/function_test/Semantic_Analyser/deprecated/DeprecatedCompat_SE.ttcn @@ -0,0 +1,108 @@ +/****************************************************************************** + * Copyright (c) 2000-2016 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Baranyi, Botond + * + ******************************************************************************/ + +module DeprecatedCompat_SE { //^In TTCN-3 module// + +type record Rec1 { + integer a, + integer b +} + +type record Rec2 { + integer x, + integer y +} + +type record of integer RecOf; +type integer Array[2]; + +type set Set1 { + integer a, + integer b +} + +type set Set2 { + integer x, + integer y +} + +type set of integer SetOf; + +type record Nested1 { + Rec1 a, + Array b +} + +type record Nested2 { + RecOf x, + Rec2 y +} + +type port PT message { + inout Rec1, Nested2 +} +with { + extension "internal"; +} + +type component CT { + port PT pt; +} + +testcase tc() runs on CT { //^In testcase definition// + // variables + var Rec1 v_rec1 := { 1, 2 }; + var Rec2 v_rec2 := v_rec1; + var RecOf v_recof := v_rec1; //^In variable definition// //Compatibility between record types and record of types is deprecated// + var Array v_array := v_recof; + var Set1 v_set1 := { a := 1, b := 2 }; + var Set2 v_set2 := v_set1; + var SetOf v_setof := v_set2; //^In variable definition// //Compatibility between set types and set of types is deprecated// + var Nested1 v_nested1 := { v_rec2, v_rec2 }; //^In variable definition// //^In value for record field// //Compatibility between record types and array types is deprecated// + var Nested2 v_nested2 := v_nested1; //^In variable definition// //Compatibility between record types and record of types is deprecated// //Compatibility between record types and array types is deprecated// + v_array := v_rec2; //^In variable assignment// //Compatibility between record types and array types is deprecated// + v_rec1 := v_array; //^In variable assignment// //Compatibility between record types and array types is deprecated// + v_rec2 := v_recof; //^In variable assignment// //Compatibility between record types and record of types is deprecated// + v_set1 := v_setof; //^In variable assignment// //Compatibility between set types and set of types is deprecated// + + // template variables + var template Rec1 vt_rec1 := { 1, 2 }; + var template Rec2 vt_rec2 := vt_rec1; + var template RecOf vt_recof := vt_rec1; //^In template variable definition// //Compatibility between record types and record of types is deprecated// + var template Array vt_array := vt_recof; + var template Set1 vt_set1 := { a := 1, b := 2 }; + var template Set2 vt_set2 := vt_set1; + var template SetOf vt_setof := vt_set2; //^In template variable definition// //Compatibility between set types and set of types is deprecated// + var template Nested1 vt_nested1 := { vt_rec2, vt_rec2 }; //^In template variable definition// //^In template for record field// //Compatibility between record types and array types is deprecated// + var template Nested2 vt_nested2 := vt_nested1; //^In template variable definition// //Compatibility between record types and record of types is deprecated// //Compatibility between record types and array types is deprecated// + vt_array := vt_rec2; //^In variable assignment// //Compatibility between record types and array types is deprecated// + vt_rec1 := vt_array; //^In variable assignment// //Compatibility between record types and array types is deprecated// + vt_rec2 := vt_recof; //^In variable assignment// //Compatibility between record types and record of types is deprecated// + vt_set1 := vt_setof; //^In variable assignment// //Compatibility between set types and set of types is deprecated// + + // in-line templates + log(match(v_recof, RecOf: vt_rec1)); //^In log statement// //^In the second argument of// //Compatibility between record types and record of types is deprecated// + log(match(v_array, Rec2: vt_recof)); //^In log statement// //^In the first argument of// //Compatibility between record types and array types is deprecated// //^In the second argument of// //Compatibility between record types and record of types is deprecated// + log(match(v_set2, Set1: vt_setof)); //^In log statement// //^In the second argument of// //Compatibility between set types and set of types is deprecated// + log(match(v_rec1, modifies vt_array := { [0] := 4 })); //^In log statement// //^In the first argument of// //Compatibility between record types and array types is deprecated// + log(match(v_setof, modifies vt_set2 := { x := 4 })); //^In log statement// //^In the first argument of// //Compatibility between set types and set of types is deprecated// + + // receive statements and value redirects + alt { //^In alt construct// + [] pt.receive(Rec1: vt_recof) //^In guard operation// //^In receive statement// //Compatibility between record types and record of types is deprecated// + -> value v_array { } //^In value redirect// //^In redirect #1// //Compatibility between record types and array types is deprecated// + [] pt.receive(Nested2: vt_nested1) //^In guard operation// //^In receive statement// //Compatibility between record types and record of types is deprecated// //Compatibility between record types and array types is deprecated// + -> value (v_nested1, v_array := x, v_recof := y) { } //^In value redirect// //^In redirect #1// //^In redirect #3// //Compatibility between record types and record of types is deprecated//2 //Compatibility between record types and array types is deprecated// + } +} + +} diff --git a/function_test/Semantic_Analyser/deprecated/Makefile b/function_test/Semantic_Analyser/deprecated/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..dc77112de71066ef0e782a90c0e3b2e90e007f7e --- /dev/null +++ b/function_test/Semantic_Analyser/deprecated/Makefile @@ -0,0 +1,12 @@ +############################################################################## +# Copyright (c) 2000-2016 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################## +include ../common.mk diff --git a/function_test/Semantic_Analyser/deprecated/t b/function_test/Semantic_Analyser/deprecated/t new file mode 100755 index 0000000000000000000000000000000000000000..3a4b58ec16cf2f1390a36c7a92f8823e3b94b425 --- /dev/null +++ b/function_test/Semantic_Analyser/deprecated/t @@ -0,0 +1,9 @@ +#!/usr/bin/perl +# note this is called through "perl -w" +use strict; + +my $self = $0; +$self =~ s!/t!!; + +exec('make check --no-print-directory -s -C ' . $self); +