From 14b6f11dc3f4319f2910a9b108eae722cc44d1d0 Mon Sep 17 00:00:00 2001 From: Botond Baranyi <botond.baranyi@ericsson.com> Date: Fri, 20 Oct 2017 17:07:34 +0200 Subject: [PATCH] Added warning when function with 'out' or 'inout' parameters is started on PTC (bug 515512) Change-Id: I83d28c7445cb1f429bf689ea907400484c22f089 Signed-off-by: Botond Baranyi <botond.baranyi@ericsson.com> --- compiler2/Type.hh | 2 +- compiler2/Type_chk.cc | 6 ++-- compiler2/ttcn3/AST_ttcn3.cc | 28 +++++++++++++------ compiler2/ttcn3/AST_ttcn3.hh | 5 ++-- compiler2/ttcn3/Statement.cc | 4 +-- compiler2/ttcn3_makefilegen.1 | 2 +- .../Semantic_Analyser/param/param_SE.ttcn | 27 ++++++++++++++++++ 7 files changed, 56 insertions(+), 18 deletions(-) diff --git a/compiler2/Type.hh b/compiler2/Type.hh index 4b0011328..d9b5543f6 100644 --- a/compiler2/Type.hh +++ b/compiler2/Type.hh @@ -873,7 +873,7 @@ namespace Common { * with the name of its definition. */ void chk_constructor_name(const Identifier& p_id); - bool chk_startability(); + bool chk_startability(Location* caller_location); /** Checks if it can be a return type */ void chk_as_return_type(bool as_value, const char* what); private: diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc index b23380e4d..5ed4470fe 100644 --- a/compiler2/Type_chk.cc +++ b/compiler2/Type_chk.cc @@ -3687,16 +3687,16 @@ void Type::chk_constructor_name(const Identifier& p_id) } } -bool Type::chk_startability() +bool Type::chk_startability(Location* caller_location) { if(typetype != T_FUNCTION) FATAL_ERROR("Type::chk_startable()"); if(!checked) chk_Fat(); + u.fatref.fp_list->chk_startability("Functions of type", + get_typename().c_str(), caller_location); if(u.fatref.is_startable) return true; if (!u.fatref.runs_on.ref) error("Functions of type `%s' cannot be started " "on a parallel test component because the type does not have `runs on' " "clause", get_typename().c_str()); - u.fatref.fp_list->chk_startability("Functions of type", - get_typename().c_str()); if (u.fatref.return_type && u.fatref.return_type->is_component_internal()) { map<Type*,void> type_chain; char* err_str = mprintf("the return type or embedded in the return type " diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc index 2f77de996..c1ba185d8 100644 --- a/compiler2/ttcn3/AST_ttcn3.cc +++ b/compiler2/ttcn3/AST_ttcn3.cc @@ -6528,14 +6528,14 @@ namespace Ttcn { } } - bool Def_Function::chk_startable() + bool Def_Function::chk_startable(Location* caller_location) { if (!checked) chk(); + fp_list->chk_startability("Function", get_fullname().c_str(), caller_location); if (is_startable) return true; if (!runs_on_ref) error("Function `%s' cannot be started on a parallel " "test component because it does not have `runs on' clause", get_fullname().c_str()); - fp_list->chk_startability("Function", get_fullname().c_str()); if (return_type && return_type->is_component_internal()) { map<Type*,void> type_chain; char* err_str = mprintf("the return type or embedded in the return type " @@ -9478,20 +9478,23 @@ namespace Ttcn { } } - void FormalParList::chk_startability(const char *p_what, const char *p_name) + void FormalParList::chk_startability(const char *p_what, const char *p_name, + Location* caller_location) { if(!checked) FATAL_ERROR("FormalParList::chk_startability()"); - if (is_startable) return; + bool has_out_or_inout = false; for (size_t i = 0; i < pars_v.size(); i++) { FormalPar *par = pars_v[i]; switch (par->get_asstype()) { - case Common::Assignment::A_PAR_VAL_IN: - case Common::Assignment::A_PAR_TEMPL_IN: case Common::Assignment::A_PAR_VAL_INOUT: case Common::Assignment::A_PAR_TEMPL_INOUT: case Common::Assignment::A_PAR_VAL_OUT: case Common::Assignment::A_PAR_TEMPL_OUT: - if (par->get_Type()->is_component_internal()) { + has_out_or_inout = true; + // no break + case Common::Assignment::A_PAR_VAL_IN: + case Common::Assignment::A_PAR_TEMPL_IN: + if (!is_startable && par->get_Type()->is_component_internal()) { map<Type*,void> type_chain; char* err_str = mprintf("a parameter or embedded in a parameter of " "a function used in a start operation. " @@ -9502,10 +9505,17 @@ namespace Ttcn { } break; default: - par->error("%s `%s' cannot be started on a parallel test component " - "because it has %s", p_what, p_name, par->get_description().c_str()); + if (!is_startable) { + par->error("%s `%s' cannot be started on a parallel test component " + "because it has %s", p_what, p_name, par->get_description().c_str()); + } } } + if (has_out_or_inout) { + caller_location->warning("The `out' and `inout' parameters of functions " + "started on parallel test components will remain unchanged at the end " + "of the operation."); + } } void FormalParList::chk_compatibility(FormalParList* p_fp_list, diff --git a/compiler2/ttcn3/AST_ttcn3.hh b/compiler2/ttcn3/AST_ttcn3.hh index 4ef74952e..7b78a3f70 100644 --- a/compiler2/ttcn3/AST_ttcn3.hh +++ b/compiler2/ttcn3/AST_ttcn3.hh @@ -1483,7 +1483,7 @@ namespace Ttcn { virtual void chk(); /** Checks and returns whether the function is startable. * Reports the appropriate error message(s) if not. */ - bool chk_startable(); + bool chk_startable(Location* caller_location); bool is_transparent() const { return transparent; } @@ -1883,7 +1883,8 @@ namespace Ttcn { * function cannot be started on a PTC. Used by functions and function * types. Parameter \a p_what shall contain "Function" or "Function type", * \a p_name shall contain the name of the function or function type. */ - void chk_startability(const char *p_what, const char *p_name); + void chk_startability(const char *p_what, const char *p_name, + Location* caller_location); /** Checks the compatibility of two formal parameter list. * They are compatible if every parameter is compatible, has the same * attribute, and name */ diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc index 64f7d35b2..1ddf88d11 100644 --- a/compiler2/ttcn3/Statement.cc +++ b/compiler2/ttcn3/Statement.cc @@ -4610,7 +4610,7 @@ error: Def_Function *t_func = dynamic_cast<Def_Function*>(t_ass); if (!t_func) FATAL_ERROR("Statement::chk_start_comp()"); // checking startability - if (!t_func->chk_startable()) return; + if (!t_func->chk_startable(this)) return; // 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; @@ -4683,7 +4683,7 @@ error: "'runs on self' clause"); return; } - if(!f_type->chk_startability()) return; + if(!f_type->chk_startability(this)) 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, NULL)) diff --git a/compiler2/ttcn3_makefilegen.1 b/compiler2/ttcn3_makefilegen.1 index 49f2879bb..aaa26dfc7 100644 --- a/compiler2/ttcn3_makefilegen.1 +++ b/compiler2/ttcn3_makefilegen.1 @@ -147,7 +147,7 @@ version of the base library. If this switch is omitted the executable is built for parallel mode by default. .TP .B \-S -Supresses all +Suppresses all .I makefilegen warning messages. .TP diff --git a/function_test/Semantic_Analyser/param/param_SE.ttcn b/function_test/Semantic_Analyser/param/param_SE.ttcn index f79c515d7..86e719268 100644 --- a/function_test/Semantic_Analyser/param/param_SE.ttcn +++ b/function_test/Semantic_Analyser/param/param_SE.ttcn @@ -22,4 +22,31 @@ function f_in(in integer x) //^In function definition// //^warning: Passing an \ f_out(x); //^In function instance// //^In actual parameter list of function// //^In parameter #1 for// } + +type component CT {} + +function f_start(in integer p1, out integer p2, inout integer p3) runs on CT { + p2 := p1; + p3 := p1; +} + +type function FT_start(in integer p1, out integer p2, inout integer p3) runs on CT; + +testcase tc() runs on CT { //^In testcase definition// + var CT ct1 := CT.create; + var CT ct2 := CT.create; + var CT ct3 := CT.create; + var integer x1 := 10; + var integer x2 := 20; + var integer x3 := 30; + var integer y1 := 15; + var integer y2 := 30; + var integer y3 := 45; + var FT_start ft := refers(f_start); + ct1.start(f_start(3, x1, y1)); //^In start test component statement// //The `out' and `inout' parameters of functions started on parallel test components will remain unchanged at the end of the operation// + ct2.start(f_start(6, x2, y2)); //^In start test component statement// //The `out' and `inout' parameters of functions started on parallel test components will remain unchanged at the end of the operation// + ct3.start(derefers(ft)(9, x3, y3)); //^In start test component statement// //The `out' and `inout' parameters of functions started on parallel test components will remain unchanged at the end of the operation// + all component.done; +} + } -- GitLab