From e920805d81d249f3a19a0a8a205b47169279431d Mon Sep 17 00:00:00 2001
From: Botond Baranyi <botond.baranyi@ericsson.com>
Date: Thu, 25 May 2017 10:25:58 +0200
Subject: [PATCH] Fixed record of concatenation with empty record of value
 (artf516414)

Change-Id: I01a041d6eb1dd6311e664a6e6ed375afd655f894
Signed-off-by: Botond Baranyi <botond.baranyi@ericsson.com>
---
 compiler2/record_of.c                            | 16 ++++++++++++++++
 compiler2/ttcn3/compiler.y                       |  4 ++--
 regression_test/recofOper/TrecofOper.ttcn        |  5 ++++-
 regression_test/setofOper/TsetofOper.ttcn        |  5 ++++-
 .../templateConcat/TemplateConcatRecof.ttcn      |  5 +++++
 .../templateConcat/TemplateConcatSetof.ttcn      |  5 +++++
 6 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/compiler2/record_of.c b/compiler2/record_of.c
index d0e9e7a46..7be4e31ef 100644
--- a/compiler2/record_of.c
+++ b/compiler2/record_of.c
@@ -3225,6 +3225,14 @@ void defRecordOfClass2(const struct_of_def *sdef, output_struct *output)
     "}\n"
     "TTCN_error(\"Unbound or omitted right operand of %s concatenation.\");\n"
     "}\n\n", name, name, name, name, sdef->dispname);
+  
+  def = mputprintf(def,
+    "%s operator+(null_type) const;\n\n", name);
+  src = mputprintf(src,
+    "%s %s::operator+(null_type) const\n"
+    "{\n"
+    "return *this;\n"
+    "}\n\n", name, name);
 
   /* substr() */
   def = mputprintf(def,
@@ -4726,6 +4734,14 @@ void defRecordOfTemplate2(const struct_of_def *sdef, output_struct *output)
     "return ret_val;\n"
     "}\n\n", name, name, name, name);
   
+  def = mputprintf(def,
+    "%s_template operator+(null_type) const;\n\n", name);
+  src = mputprintf(src,
+    "%s_template %s_template::operator+(null_type) const\n"
+    "{\n"
+    "return *this;\n"
+    "}\n\n", name, name);
+  
   /* indexing operators */
   def = mputprintf(def,
     "%s_template& operator[](int index_value);\n"
diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y
index 9cb4f35f6..58f9fa3fe 100644
--- a/compiler2/ttcn3/compiler.y
+++ b/compiler2/ttcn3/compiler.y
@@ -2096,8 +2096,8 @@ optPackageNameList:
 ;
 
 PackageNameList:
-  ',' FreeText
-|  PackageNameList ',' FreeText
+  ',' FreeText { Free($2); }
+|  PackageNameList ',' FreeText { Free($3); }
 ;
 
 ModuleBody:
diff --git a/regression_test/recofOper/TrecofOper.ttcn b/regression_test/recofOper/TrecofOper.ttcn
index 9fb877d43..ce0ff3bef 100644
--- a/regression_test/recofOper/TrecofOper.ttcn
+++ b/regression_test/recofOper/TrecofOper.ttcn
@@ -701,7 +701,7 @@ testcase recofEmpty() runs on recofOper_mycomp{
 testcase recofListOperator() runs on recofOper_mycomp{
   var recofOper_myrecof1 x1;
   var recofOper_myrecof1 x2,x3,x4,x5,x6;
-  var recofOper_myrecof1 res1, res2, res3, res4;
+  var recofOper_myrecof1 res1, res2, res3, res4, res5;
   x1:={1,2};
   x2:={1,2};
   x3:={1};
@@ -713,6 +713,7 @@ testcase recofListOperator() runs on recofOper_mycomp{
   res2 := x2 & x3;
   res3 := x2 & x3 & x5;
   res4 := x3 & x4;
+  res5 := x1 & {};
   if (res1 == {1,2,1,2}) {setverdict(pass);}
   else {setverdict(fail);}
   if (res2 == {1,2,1}) {setverdict(pass);}
@@ -721,6 +722,8 @@ testcase recofListOperator() runs on recofOper_mycomp{
   else {setverdict(fail);}
   if (res4 == {1,1,3}) {setverdict(pass);}
   else {setverdict(fail);}
+  if (res5 == {1,2}) {setverdict(pass);}
+  else {setverdict(fail);}
 }
 
 testcase recofRotateOperators() runs on recofOper_mycomp{
diff --git a/regression_test/setofOper/TsetofOper.ttcn b/regression_test/setofOper/TsetofOper.ttcn
index c77dd2052..96c3222f8 100644
--- a/regression_test/setofOper/TsetofOper.ttcn
+++ b/regression_test/setofOper/TsetofOper.ttcn
@@ -729,7 +729,7 @@ testcase setofCompUnbound() runs on setofOper_mycomp{
 testcase setofListOperator() runs on setofOper_mycomp{
   var setofOper_mysetof1 x1:={1,2};
   var setofOper_mysetof1 x2,x3,x4,x5,x6;	//set of basic types
-  var setofOper_mysetof1 res1, res2, res3, res4;
+  var setofOper_mysetof1 res1, res2, res3, res4, res5;
   x2:={ 1, 2 };
   x3:={1};
   x4:={1};
@@ -740,6 +740,7 @@ testcase setofListOperator() runs on setofOper_mycomp{
   res2 := x1 & x3;
   res3 := x2 & x3 & x5;
   res4 := x3 & x4;
+  res5 := x1 & {};
   if (res1 == {1,2,1,2}) {setverdict(pass);}
   else {setverdict(fail);}
   if (res2 == {1,2,1}) {setverdict(pass);}
@@ -748,6 +749,8 @@ testcase setofListOperator() runs on setofOper_mycomp{
   else {setverdict(fail);}
   if (res4 == {1,1,3}) {setverdict(pass);}
   else {setverdict(fail);}
+  if (res5 == {1,2}) {setverdict(pass);}
+  else {setverdict(fail);}
 }
 
 testcase setofRotateOperators() runs on setofOper_mycomp{
diff --git a/regression_test/templateConcat/TemplateConcatRecof.ttcn b/regression_test/templateConcat/TemplateConcatRecof.ttcn
index 8f6cf6ae1..b93b6ec75 100644
--- a/regression_test/templateConcat/TemplateConcatRecof.ttcn
+++ b/regression_test/templateConcat/TemplateConcatRecof.ttcn
@@ -97,6 +97,8 @@ testcase tc_recof_vt_w_refs_and_literals() runs on CT {
   var template RecOfInt vt_recof4 := ? length(2..2) & { 4, 5 } & * length(3);
   var template RecOfInt vt_recof4_exp := { ?, ?, 4, 5, ?, ?, ? };
   
+  var template RecOfInt vt_recof5 := t_recof_op1 & {};
+  
   if (log2str(vt_recof1) != log2str(vt_recof1_exp)) {
     setverdict(fail, "Expected: ", vt_recof1_exp, ", got: ", vt_recof1);
   }
@@ -109,6 +111,9 @@ testcase tc_recof_vt_w_refs_and_literals() runs on CT {
   else if (log2str(vt_recof4) != log2str(vt_recof4_exp)) {
     setverdict(fail, "Expected: ", vt_recof4_exp, ", got: ", vt_recof4);
   }
+  else if (log2str(vt_recof5) != log2str(t_recof_op1)) {
+    setverdict(fail, "Expected: ", t_recof_op1, ", got: ", vt_recof4);
+  }
   else {
     setverdict(pass);
   }
diff --git a/regression_test/templateConcat/TemplateConcatSetof.ttcn b/regression_test/templateConcat/TemplateConcatSetof.ttcn
index cf9d7121d..b67a51eea 100644
--- a/regression_test/templateConcat/TemplateConcatSetof.ttcn
+++ b/regression_test/templateConcat/TemplateConcatSetof.ttcn
@@ -97,6 +97,8 @@ testcase tc_setof_vt_w_refs_and_literals() runs on CT {
   var template SetOfInt vt_setof4 := ? length(2..2) & { 4, 5 } & * length(3);
   var template SetOfInt vt_setof4_exp := { ?, ?, 4, 5, ?, ?, ? };
   
+  var template SetOfInt vt_setof5 := t_setof_op1 & {};
+  
   if (log2str(vt_setof1) != log2str(vt_setof1_exp)) {
     setverdict(fail, "Expected: ", vt_setof1_exp, ", got: ", vt_setof1);
   }
@@ -109,6 +111,9 @@ testcase tc_setof_vt_w_refs_and_literals() runs on CT {
   else if (log2str(vt_setof4) != log2str(vt_setof4_exp)) {
     setverdict(fail, "Expected: ", vt_setof4_exp, ", got: ", vt_setof4);
   }
+  else if (log2str(vt_setof5) != log2str(t_setof_op1)) {
+    setverdict(fail, "Expected: ", t_setof_op1, ", got: ", vt_setof4);
+  }
   else {
     setverdict(pass);
   }
-- 
GitLab