From 3338a86d1e899d42019b56d42f518f9ce042cbb3 Mon Sep 17 00:00:00 2001
From: Botond Baranyi <botond.baranyi@ericsson.com>
Date: Thu, 7 Jan 2021 17:51:03 +0100
Subject: [PATCH] OOP: added semantic errors for starting a class method or a
 function with a class type parameter on a parallel component (bug 568748,
 568744, 568899)

Signed-off-by: Botond Baranyi <botond.baranyi@ericsson.com>
Change-Id: I51fe7e6e2f26efb2727d34081cf8430b3fc86955
---
 compiler2/ttcn3/AST_ttcn3.cc                    | 17 +++++++++++++++--
 compiler2/ttcn3/Statement.cc                    |  2 +-
 function_test/Semantic_Analyser/oop/oop_SE.ttcn | 11 +++++++++++
 3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc
index 9f4c539c2..3f2efb629 100644
--- a/compiler2/ttcn3/AST_ttcn3.cc
+++ b/compiler2/ttcn3/AST_ttcn3.cc
@@ -7011,7 +7011,7 @@ namespace Ttcn {
     }
 
     // decision of startability
-    is_startable = runs_on_ref != 0;
+    is_startable = runs_on_ref != 0 && !my_scope->is_class_scope();
     if (is_startable && !fp_list->get_startability()) is_startable = false;
     if (is_startable && return_type && return_type->is_component_internal())
           is_startable = false;
@@ -7040,6 +7040,10 @@ namespace Ttcn {
   bool Def_Function::chk_startable(Location* caller_location)
   {
     if (!checked) chk();
+    if (my_scope->is_class_scope()) {
+      caller_location->error("A method of a class cannot be started on a parallel test component");
+      return false;
+    }
     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 "
@@ -10333,8 +10337,11 @@ namespace Ttcn {
       case Common::Assignment::A_PAR_TEMPL_INOUT:
       case Common::Assignment::A_PAR_VAL_OUT:
       case Common::Assignment::A_PAR_TEMPL_OUT:
-        if (is_startable && par->get_Type()->is_component_internal())
+        if (is_startable && 
+            (par->get_Type()->is_component_internal() ||
+            (par->get_Type()->get_type_refd_last()->get_typetype() == Common::Type::T_CLASS))) {
           is_startable = false;
+        }
         break;
       default:
         is_startable = false;
@@ -10383,6 +10390,12 @@ namespace Ttcn {
           par->get_Type()->chk_component_internal(type_chain, err_str);
           Free(err_str);
         }
+        if (!is_startable &&
+            par->get_Type()->get_type_refd_last()->get_typetype() == Common::Type::T_CLASS) {
+          caller_location->error("%s `%s' cannot be started on a parallel test component "
+            "because parameter `%s' is of a class type",
+            p_what, p_name, par->get_id().get_dispname().c_str());
+        }
         break;
       default:
         if (!is_startable) {
diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc
index 9d18160f3..0a9ca5e87 100644
--- a/compiler2/ttcn3/Statement.cc
+++ b/compiler2/ttcn3/Statement.cc
@@ -4808,7 +4808,7 @@ error:
   {
     Error_Context cntxt(this, "In start test component statement");
     Type *comp_type = chk_comp_ref(comp_op.compref, false, false);
-    Common::Assignment *t_ass = comp_op.funcinstref->get_refd_assignment();
+    Common::Assignment *t_ass = comp_op.funcinstref->get_refd_assignment_last();
     if (!t_ass) return;
     // checking whether the referred definition is a function
     Common::Assignment::asstype_t asstype = t_ass->get_asstype();
diff --git a/function_test/Semantic_Analyser/oop/oop_SE.ttcn b/function_test/Semantic_Analyser/oop/oop_SE.ttcn
index f0bcb1de8..85945297a 100644
--- a/function_test/Semantic_Analyser/oop/oop_SE.ttcn
+++ b/function_test/Semantic_Analyser/oop/oop_SE.ttcn
@@ -524,6 +524,17 @@ function f_param_test() { //^In function definition//
   f_parameters(x.m2(), x.m2(), x.m2()); //^In function instance// //^In actual parameter list of function// //^In parameter #2// //^In parameter #3// //Reference to a variable or value parameter was expected for an \`inout\' value parameter instead of function// //Reference to a variable or value parameter was expected for an \`out\' value parameter instead of function//
 }
 
+function f_class_param(in C39 x) runs on Comp { }
+
+function f_start_comp() { //^In function definition//
+  var Comp ct := Comp.create alive;
+  var C39 x := C39.create;
+  ct.start(x.f_def(1)); //^In start test component statement// //A method of a class cannot be started on a parallel test component//
+  ct.done;
+  ct.start(f_class_param(x)); //^In start test component statement// //Function `@oop_SE.f_class_param' cannot be started on a parallel test component because parameter `x' is of a class type//
+  ct.done;
+}
+
 
 control { //^In control part//
   var C11 x := C11.create; //^In variable definition// //A definition without `runs on' clause cannot create a value of class type `@oop_SE.C11', which runs on component type `@oop_SE.CT_RunsOn'// //Cannot create value of class type `@oop_SE.C11', which has an `mtc' clause, in the control part.// //Cannot create value of class type `@oop_SE.C11', which has a `system' clause, in the control part.//
-- 
GitLab