From a685eb2e9e9d36e03c9ba415d1c1a40cf245dc1e Mon Sep 17 00:00:00 2001 From: Botond Baranyi <botond.baranyi@ericsson.com> Date: Wed, 18 Nov 2020 17:04:14 +0100 Subject: [PATCH] When checking whether a reference can be generated as a single expression, the subreferences are taken into account, too (bug 563718) Signed-off-by: Botond Baranyi <botond.baranyi@ericsson.com> Change-Id: I383875aa8802d050a9cd4bd3cd75a88e7c2342a4 --- compiler2/Type.cc | 4 ++-- compiler2/ttcn3/AST_ttcn3.cc | 26 ++++++++++++++++++++++++-- compiler2/ttcn3/AST_ttcn3.hh | 8 ++++++-- regression_test/oop/oop.ttcn | 12 ++++++++++-- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/compiler2/Type.cc b/compiler2/Type.cc index be2d4838c..ca1ccb5d6 100644 --- a/compiler2/Type.cc +++ b/compiler2/Type.cc @@ -1817,7 +1817,7 @@ namespace Common { } ap_list->set_fullname(parsed_pars->get_fullname()); ap_list->set_my_scope(parsed_pars->get_my_scope()); - ref->set_actual_par_list(ap_list); + ref->set_parameter_list(ap_list, NULL); } t = get_pooltype(T_USTR); // todo: set *last_method @@ -1876,7 +1876,7 @@ namespace Common { } ap_list->set_fullname(parsed_pars->get_fullname()); ap_list->set_my_scope(parsed_pars->get_my_scope()); - ref->set_actual_par_list(ap_list); + ref->set_parameter_list(ap_list, fp_list); } if (last_method != NULL) { *last_method = ass; diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc index 1e8c2fdcf..0291a21a0 100644 --- a/compiler2/ttcn3/AST_ttcn3.cc +++ b/compiler2/ttcn3/AST_ttcn3.cc @@ -236,14 +236,23 @@ namespace Ttcn { return u.ff.ap_list; } - void FieldOrArrayRef::set_actual_par_list(ActualParList* p_ap_list) + FormalParList* FieldOrArrayRef::get_formal_par_list() const + { + if (ref_type != FUNCTION_REF || !u.ff.checked) { + FATAL_ERROR("FieldOrArrayRef::get_formal_par_list()"); + } + return u.ff.fp_list; + } + + void FieldOrArrayRef::set_parameter_list(ActualParList* p_ap_list, FormalParList* p_fp_list) { if (ref_type != FUNCTION_REF || u.ff.checked) { - FATAL_ERROR("FieldOrArrayRef::set_actual_par_list()"); + FATAL_ERROR("FieldOrArrayRef::set_parameter_list()"); } u.ff.checked = true; delete u.ff.parsed_pars; u.ff.ap_list = p_ap_list; + u.ff.fp_list = p_fp_list; } void FieldOrArrayRef::append_stringRepr(string& str) const @@ -1080,6 +1089,19 @@ namespace Ttcn { } } } + for (size_t i = 0; i < subrefs.get_nof_refs(); ++i) { + FieldOrArrayRef* subref = subrefs.get_ref(i); + if (subref->get_type() == FieldOrArrayRef::FUNCTION_REF) { + ActualParList* ap_list = subref->get_actual_par_list(); + FormalParList* fp_list = subref->get_formal_par_list(); + for (size_t j = 0; j < ap_list->get_nof_pars(); ++j) { + if (!ap_list->get_par(j)->has_single_expr( + fp_list != NULL ? fp_list->get_fp_byIndex(i) : NULL)) { + return false; + } + } + } + } return true; } diff --git a/compiler2/ttcn3/AST_ttcn3.hh b/compiler2/ttcn3/AST_ttcn3.hh index 1ba3bdd15..2730f9048 100644 --- a/compiler2/ttcn3/AST_ttcn3.hh +++ b/compiler2/ttcn3/AST_ttcn3.hh @@ -205,7 +205,10 @@ namespace Ttcn { bool checked; union { ParsedActualParameters* parsed_pars; ///< parsed function parameters, used by FUNCTION_REF - ActualParList* ap_list; ///< actual parameter list (after semantic analysis), used by FUNCTION_REF + struct { + ActualParList* ap_list; ///< actual parameter list (after semantic analysis), used by FUNCTION_REF + FormalParList* fp_list; ///< formal parameter list (after semantic analysis, not owned), used by FUNCTION_REF + }; }; } ff; ///< field or function Value *arp; ///< value of the index, used by ARRAY_REF @@ -230,8 +233,9 @@ namespace Ttcn { Value* get_val() const; ParsedActualParameters* get_parsed_pars() const; ActualParList* get_actual_par_list() const; + FormalParList* get_formal_par_list() const; bool parameters_checked() const; - void set_actual_par_list(ActualParList* p_ap_list); + void set_parameter_list(ActualParList* p_ap_list, FormalParList* p_fp_list); /** Appends the string representation of the sub-reference to \a str. */ void append_stringRepr(string& str) const; /** Sets the first letter in the name of the field to lowercase if it's an diff --git a/regression_test/oop/oop.ttcn b/regression_test/oop/oop.ttcn index c6a9290d7..3a731723c 100644 --- a/regression_test/oop/oop.ttcn +++ b/regression_test/oop/oop.ttcn @@ -470,6 +470,12 @@ function f_test_in(Node p1, Node2 p2) { p2.f(p1.get_next()); } +type class InParTester { + public function test(object x) return boolean { + return x of Node; + } +} + testcase tc_function_pars_in() runs on CT { var Node n1 := Node.create(1, Node.create(2, null)); var Node2 n2 := Node2.create(null, null); @@ -477,9 +483,11 @@ testcase tc_function_pars_in() runs on CT { if (log2str(n2.get_data()) != log2str(n1.get_next())) { setverdict(fail, "Expected: ", n1.get_next(), ", got: ", n2.get_data()); } - else { - setverdict(pass); + var InParTester t := InParTester.create; + if (not t.test(n1.get_next())) { + setverdict(fail, "InParTester failed"); } + setverdict(pass); } type class Something { -- GitLab