From 5952fc78bd80f036e116db5385fae72784ad203f Mon Sep 17 00:00:00 2001
From: Botond Baranyi <botond.baranyi@ericsson.com>
Date: Thu, 17 Mar 2022 15:52:33 +0100
Subject: [PATCH] Fixed 'implicit omit' inside optional fields that are present
 (issue #588)

Signed-off-by: Botond Baranyi <botond.baranyi@ericsson.com>
---
 core/Optional.hh                        | 10 +++++++++
 regression_test/implicitOmit/config.cfg |  1 +
 regression_test/implicitOmit/io.ttcn    | 28 +++++++++++++++++++++++++
 3 files changed, 39 insertions(+)

diff --git a/core/Optional.hh b/core/Optional.hh
index d0bea3faf..9b887384e 100644
--- a/core/Optional.hh
+++ b/core/Optional.hh
@@ -364,6 +364,8 @@ public:
     * Redirects the call to the optional value. */
   virtual void remove_refd_index(int index);
 #endif
+
+  void set_implicit_omit();
 };
 
 #if HAVE_GCC(4,6)
@@ -1311,6 +1313,14 @@ int OPTIONAL<T_type>::TEXT_decode(const TTCN_Typedescriptor_t& p_td,
 
 #endif
 
+template<typename T_type>
+void OPTIONAL<T_type>::set_implicit_omit()
+{
+  if (is_present()) {
+    optional_value->set_implicit_omit();
+  }
+}
+
 #if defined(__GNUC__) && __GNUC__ >= 3
 /** Note: These functions allow most efficient operation by passing the left
  * operand OMIT_VALUE as value instead of constant reference.
diff --git a/regression_test/implicitOmit/config.cfg b/regression_test/implicitOmit/config.cfg
index f8ea3a4b4..4610fa321 100644
--- a/regression_test/implicitOmit/config.cfg
+++ b/regression_test/implicitOmit/config.cfg
@@ -30,6 +30,7 @@ mrecof1 := { [1] := { c := "clinton" } }
 msetof1 := { [1] := { c := "clinton" } }
 mrecof2 := { [1] := { mr2 := { c := "clinton" } } }
 msetof2 := { [1] := { ms2 := { c := "clinton" } } }
+mp_emb_opt := { m := { a := 2 } }
 
 [EXECUTE]
 io.control
diff --git a/regression_test/implicitOmit/io.ttcn b/regression_test/implicitOmit/io.ttcn
index 4d71ff9cb..3485cea51 100644
--- a/regression_test/implicitOmit/io.ttcn
+++ b/regression_test/implicitOmit/io.ttcn
@@ -37,6 +37,10 @@ type record MyRecord2 {
   MyRecord1 m
 }
 
+type record MyRecord3 {
+  MyRecord1 m optional
+}
+
 type set MySet2 {
   MySet1 m
 }
@@ -562,6 +566,29 @@ testcase tc_io_asn_record_empty() runs on O
   else { setverdict(fail, t_asn_rec_empty); }
 }
 
+// Implicit omit for fields of records embedded in an optional field of another record
+const MyRecord3 c_emb_opt := { m := { a := 2 } }
+with { optional "implicit omit" }
+
+template MyRecord3 t_emb_opt := { m := { a := ? } }
+with { optional "implicit omit" }
+
+modulepar MyRecord3 mp_emb_opt
+with { optional "implicit omit" }
+
+testcase tc_io_embedded_optional() runs on O {
+  if (not isbound(c_emb_opt) or c_emb_opt.m.b != omit) {
+    setverdict(fail, "c_emb_opt: ", c_emb_opt);
+  }
+  if (not isbound(t_emb_opt) or log2str(t_emb_opt.m.b) != "omit") {
+    setverdict(fail, "t_emb_opt: ", t_emb_opt);
+  }
+  if (not isbound(mp_emb_opt) or mp_emb_opt.m.b != omit) {
+    setverdict(fail, "c_emb_opt: ", mp_emb_opt);
+  }
+  setverdict(pass);
+}
+
 control {
 execute(tc12());
 execute(tc1ab());
@@ -605,6 +632,7 @@ execute(tc_HQ30261())
 execute(tc_io_embedded());
 execute(tc_io_notused());
 execute(tc_io_asn_record_empty());
+execute(tc_io_embedded_optional());
 }
 with {
   optional "implicit omit"
-- 
GitLab