diff --git a/compiler2/record_of.c b/compiler2/record_of.c index 2308ba76e85b8e9f891493db837e52480d5af5f3..806014a8d851a5a2672266926f86adb70b1fc46b 100644 --- a/compiler2/record_of.c +++ b/compiler2/record_of.c @@ -636,6 +636,10 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " Module_Param* const curr = mp->get_elem(i);\n" " if (curr->get_type()!=Module_Param::MP_NotUsed) {\n" " (*this)[i].set_param(*curr);\n" + " if (!(*this)[i].is_bound()) {\n" + " delete val_ptr->value_elements[i];\n" + " val_ptr->value_elements[i] = NULL;\n" + " }\n" " }\n" " }\n" " break;\n" @@ -643,6 +647,10 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " for (size_t i=0; i<mp->get_size(); ++i) {\n" " Module_Param* const curr = mp->get_elem(i);\n" " (*this)[curr->get_id()->get_index()].set_param(*curr);\n" + " if (!(*this)[curr->get_id()->get_index()].is_bound()) {\n" + " delete val_ptr->value_elements[curr->get_id()->get_index()];\n" + " val_ptr->value_elements[curr->get_id()->get_index()] = NULL;\n" + " }\n" " }\n" " break;\n" " default:\n" diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc index 1ddac029f5783313b5f287a4906a5fc9638c986f..9248c4b83ada915fbe615866bba0a042b2a059b2 100644 --- a/core2/Basetype2.cc +++ b/core2/Basetype2.cc @@ -2468,6 +2468,11 @@ void Record_Of_Type::set_param(Module_Param& param) { Module_Param* const curr = mp->get_elem(i); if (curr->get_type()!=Module_Param::MP_NotUsed) { get_at(i)->set_param(*curr); + if (!get_at(i)->is_bound()) { + // use null pointers for unbound elements + delete val_ptr->value_elements[i]; + val_ptr->value_elements[i] = NULL; + } } } break; @@ -2475,6 +2480,11 @@ void Record_Of_Type::set_param(Module_Param& param) { for (size_t i=0; i<mp->get_size(); ++i) { Module_Param* const current = mp->get_elem(i); get_at(current->get_id()->get_index())->set_param(*current); + if (!get_at(current->get_id()->get_index())->is_bound()) { + // use null pointers for unbound elements + delete val_ptr->value_elements[current->get_id()->get_index()]; + val_ptr->value_elements[current->get_id()->get_index()] = NULL; + } } break; default: diff --git a/regression_test/recofOper/TrecofOper.ttcn b/regression_test/recofOper/TrecofOper.ttcn index b2458f2b3ddd768949ab9d89370cecef4254c319..4014102740ba861cf53bda7908cd9f9a91054586 100644 --- a/regression_test/recofOper/TrecofOper.ttcn +++ b/regression_test/recofOper/TrecofOper.ttcn @@ -1317,6 +1317,30 @@ testcase tc_sizeof_lengthof_standard6() runs on recofOper_mycomp { if(lengthof(tr_roI5)==3) { setverdict(pass)}else { setverdict(fail) }; } +// test cases for bug 494614: +// when initializing a record-of-record element with an empty value ('{}') through module parameters, +// an actual unbound record element was created, instead of the usual null pointer used for unbound elements; +// copying this empty record caused a dynamic test case error + +modulepar recofOper_myrecof3 recofOper_mymodulepar; // initialized with value list notation +modulepar recofOper_myrecof3 recofOper_mymodulepar2; // initialized with assignment notation + +testcase tc_empty_record_element() runs on recofOper_mycomp { + var recofOper_myrecof3 copy := recofOper_mymodulepar; + copy[0].x1 := omit; // this is where the record-of is actually copied, and where the DTE occured + copy[0].x2 := 1.0; + if (copy == { { omit, 1.0 } }) { setverdict(pass); } + else { setverdict(fail); } +} + +testcase tc_empty_record_element2() runs on recofOper_mycomp { + var recofOper_myrecof3 copy := recofOper_mymodulepar2; + copy[0].x1 := omit; // this is where the record-of is actually copied, and where the DTE occured + copy[0].x2 := 1.0; + if (copy == { { omit, 1.0 } }) { setverdict(pass); } + else { setverdict(fail); } +} + control { const recofOper_trecord cl_temp1:={ x1:=omit, x2:=3.4 }; // constants in the control part const recofOper_trecof cl_temp2:={ 'AF12'O }; @@ -1390,6 +1414,9 @@ control { execute(tc_sizeof_lengthof_standard2()); execute(tc_sizeof_lengthof_standard4()); execute(tc_sizeof_lengthof_standard6()); + + execute(tc_empty_record_element()); + execute(tc_empty_record_element2()); } } diff --git a/regression_test/recofOper/config.cfg b/regression_test/recofOper/config.cfg index 1e893b4828997470684056ffa092a4f2dec034d0..eb20bd25a39909fa4d6c2ccbba10cb3465e69afa 100644 --- a/regression_test/recofOper/config.cfg +++ b/regression_test/recofOper/config.cfg @@ -12,6 +12,8 @@ # ############################################################################### [MODULE_PARAMETERS] +recofOper_mymodulepar := { {} } +recofOper_mymodulepar2 := { [0] := {} } [LOGGING] Logfile := "recofOper.log" FileMask := LOG_ALL diff --git a/regression_test/recofOper/config_rt2.cfg b/regression_test/recofOper/config_rt2.cfg index 268d161835b217f0bd97b53bd8603cac18a698a1..7572603a43cb89bf868ef515115976cbc3d36dfe 100644 --- a/regression_test/recofOper/config_rt2.cfg +++ b/regression_test/recofOper/config_rt2.cfg @@ -11,6 +11,8 @@ # ############################################################################### [MODULE_PARAMETERS] +recofOper_mymodulepar := { {} } +recofOper_mymodulepar2 := { [0] := {} } [LOGGING] Logfile := "recofOper.log" FileMask := LOG_ALL