From 53cbc51c71eefabbc15360b8867033c5b96c1e38 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Tue, 4 Oct 2022 13:37:36 +0200 Subject: [PATCH] Set discriminant for default union case to 0 Sets the discriminant value for default union case in the serializer ops to 0 in idlc and type builder. The value is not used, so there is no need to set it to the first available integer or enum value. Signed-off-by: Dennis Potman --- src/core/ddsc/tests/TypeBuilderTypes.idl | 40 ++++++++++++++++++++++-- src/core/ddsc/tests/typebuilder.c | 4 ++- src/core/ddsi/src/ddsi_typebuilder.c | 6 ++++ src/idl/include/idl/tree.h | 2 ++ src/idl/src/tree.c | 20 ++++++++++++ src/tools/idlc/src/descriptor.c | 4 +-- 6 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/core/ddsc/tests/TypeBuilderTypes.idl b/src/core/ddsc/tests/TypeBuilderTypes.idl index 00a23604d6..fef9beb4cf 100644 --- a/src/core/ddsc/tests/TypeBuilderTypes.idl +++ b/src/core/ddsc/tests/TypeBuilderTypes.idl @@ -272,9 +272,10 @@ module TypeBuilderTypes { }; /* enum with non-default bit-bound as switch type */ - union t17 switch(en8) { - case EN8_1: t14 u1; - case EN8_2: t15 u2; + @bit_bound(12) enum en16 { EN16_1, EN16_2 }; + union t17 switch(en16) { + case EN16_1: t14 u1; + case EN16_2: t15 u2; }; /* hash member id */ @@ -367,4 +368,37 @@ module TypeBuilderTypes { sequence u99; }; + union t25_1 switch(long) { + default: + string<9> u1; + }; + struct t25 { + t25_1 f1; + }; + + /* default case with non-zero value */ + @nested union t26_1 switch(octet) { + case 0: + long u1; + default: + long u2; + }; + struct t26 { + t26_1 f1; + }; + + /* default case with non-zero enum value */ + enum en27 { @value(4) E27_3, E27_1, @value(3) E27_2 }; + @nested union t27_1 switch(en27) { + case E27_1: + long u1; + case E27_3: + long u3; + default: + long ud; + }; + struct t27 { + t27_1 f1; + }; + }; diff --git a/src/core/ddsc/tests/typebuilder.c b/src/core/ddsc/tests/typebuilder.c index efeab32db5..3f7aae1751 100644 --- a/src/core/ddsc/tests/typebuilder.c +++ b/src/core/ddsc/tests/typebuilder.c @@ -136,8 +136,10 @@ static bool tmap_equal (ddsi_typemap_t *a, ddsi_typemap_t *b) CU_TheoryDataPoints (ddsc_typebuilder, topic_desc) = { CU_DataPoints (const dds_topic_descriptor_t *, &D(t1), &D(t2), &D(t3), &D(t4), &D(t5), &D(t6), &D(t7), &D(t8), &D(t9), &D(t10), &D(t11), &D(t12), &D(t13), &D(t14), &D(t15), &D(t16), - &D(t17), &D(t18), &D(t19), &D(t20), &D(t21), &D(t22), &D(t23), &D(t24) ), + &D(t17), &D(t18), &D(t19), &D(t20), &D(t21), &D(t22), &D(t23), &D(t24), + &D(t25), &D(t26), &D(t27) ), }; + #undef D CU_Theory((const dds_topic_descriptor_t *desc), ddsc_typebuilder, topic_desc, .init = typebuilder_init, .fini = typebuilder_fini) diff --git a/src/core/ddsi/src/ddsi_typebuilder.c b/src/core/ddsi/src/ddsi_typebuilder.c index ea991c9243..bfa2d52904 100644 --- a/src/core/ddsi/src/ddsi_typebuilder.c +++ b/src/core/ddsi/src/ddsi_typebuilder.c @@ -1207,6 +1207,12 @@ static dds_return_t get_ops_union (const struct typebuilder_union *tb_union, uin if (tb_union->disc_type.args.prim_args.is_signed) flags |= DDS_OP_FLAG_SGN; break; + case DDS_OP_VAL_ENU: + flags |= get_bitbound_flags (tb_union->disc_type.args.enum_args.bit_bound); + break; + case DDS_OP_VAL_BMK: + flags |= get_bitbound_flags (tb_union->disc_type.args.bitmask_args.bit_bound); + break; default: break; } diff --git a/src/idl/include/idl/tree.h b/src/idl/include/idl/tree.h index 2857011b1f..9e8b9f7bd2 100644 --- a/src/idl/include/idl/tree.h +++ b/src/idl/include/idl/tree.h @@ -543,6 +543,8 @@ IDL_EXPORT bool idl_is_case(const void *node); IDL_EXPORT bool idl_is_default_case(const void *node); IDL_EXPORT bool idl_is_implicit_default_case(const void *ptr); IDL_EXPORT bool idl_is_case_label(const void *node); +IDL_EXPORT bool idl_is_default_case_label(const void *node); +IDL_EXPORT bool idl_is_implicit_default_case_label(const void *node); IDL_EXPORT bool idl_is_enum(const void *node); IDL_EXPORT bool idl_is_enumerator(const void *node); IDL_EXPORT bool idl_is_bitmask(const void *node); diff --git a/src/idl/src/tree.c b/src/idl/src/tree.c index 88d191a692..4a75577423 100644 --- a/src/idl/src/tree.c +++ b/src/idl/src/tree.c @@ -2379,6 +2379,26 @@ bool idl_is_case_label(const void *ptr) return true; } +static bool idl_is_case_label_mask_impl(const void *ptr, const idl_mask_t mask) +{ + const idl_case_label_t *node = ptr; + if (!(idl_mask(node) & IDL_CASE_LABEL)) + return false; + if ((idl_mask(node) & mask) == mask) + return true; + return false; +} + +bool idl_is_default_case_label(const void *ptr) +{ + return idl_is_case_label_mask_impl (ptr, IDL_DEFAULT_CASE_LABEL); +} + +bool idl_is_implicit_default_case_label(const void *ptr) +{ + return idl_is_case_label_mask_impl (ptr, IDL_IMPLICIT_DEFAULT_CASE_LABEL); +} + static void delete_case_label(void *ptr) { idl_case_label_t *node = ptr; diff --git a/src/tools/idlc/src/descriptor.c b/src/tools/idlc/src/descriptor.c index 3fec79513f..c977fa22b7 100644 --- a/src/tools/idlc/src/descriptor.c +++ b/src/tools/idlc/src/descriptor.c @@ -818,8 +818,8 @@ emit_case( descriptor->n_opcodes++; /* this stashes an opcode, but is using stash_jeq_offset so we'll increase the opcode count here */ off++; } - /* generate union case discriminator */ - if ((ret = stash_constant(pstate, &ctype->instructions, off++, label->const_expr))) + /* generate union case discriminator, use 0 for default case */ + if ((ret = stash_constant(pstate, &ctype->instructions, off++, idl_is_default_case_label(label) || idl_is_implicit_default_case_label(label) ? 0 : label->const_expr))) return ret; /* generate union case member (address) offset; use offset 0 for empty types, as these members are not generated and no offset can be calculated */