Commit 14b6f11d authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Added warning when function with 'out' or 'inout' parameters is started on PTC (bug 515512)



Change-Id: I83d28c7445cb1f429bf689ea907400484c22f089
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent dd6bd4a9
......@@ -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:
......
......@@ -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 "
......
......@@ -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,
......
......@@ -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 */
......
......@@ -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))
......
......@@ -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
......
......@@ -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;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment