Skip to content

Commit

Permalink
Fix issue #457
Browse files Browse the repository at this point in the history
This fixes the issue of comparison operators not returning true for
unions with default cases not associated with a type for said default
case
Also added unittests for union comparison operators

Signed-off-by: Martijn Reicher <[email protected]>
  • Loading branch information
reicheratwork committed Nov 7, 2023
1 parent 0ddd39b commit 1e8b263
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 6 deletions.
59 changes: 59 additions & 0 deletions src/ddscxx/tests/Regression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,4 +404,63 @@ TEST_F(Regression, unaligned_access)
ASSERT_EQ(s.ll(), int64_t(0x08090A0B0C0D0E0F)); //size 4 reads should be done at 4 byte offsets in stream
}

TEST_F(Regression, union_comparisons)
{
regression_models::union_without_default u_1, u_2, u_3, u_4;
u_1.s("abcdef", regression_enum::case_1);
u_2.s("fedcba", regression_enum::case_1);
u_3.s("abcdef", regression_enum::case_2);
u_4._d(regression_enum::case_3);

regression_models::union_with_default w_1, w_2, w_3, w_4, w_5;
w_1.s("abcdef", regression_enum::case_1);
w_2.s("fedcba", regression_enum::case_1);
w_3.s("abcdef", regression_enum::case_2);
w_4.i(123);
w_5.i(456);

EXPECT_EQ(u_1, u_1);
EXPECT_NE(u_1, u_2);
EXPECT_NE(u_1, u_3);
EXPECT_NE(u_1, u_4);
EXPECT_NE(u_2, u_1);
EXPECT_EQ(u_2, u_2);
EXPECT_NE(u_2, u_3);
EXPECT_NE(u_2, u_4);
EXPECT_NE(u_3, u_1);
EXPECT_NE(u_3, u_2);
EXPECT_EQ(u_3, u_3);
EXPECT_NE(u_3, u_4);
EXPECT_NE(u_4, u_1);
EXPECT_NE(u_4, u_2);
EXPECT_NE(u_4, u_3);
EXPECT_EQ(u_4, u_4);

EXPECT_EQ(w_1, w_1);
EXPECT_NE(w_1, w_2);
EXPECT_NE(w_1, w_3);
EXPECT_NE(w_1, w_4);
EXPECT_NE(w_1, w_5);
EXPECT_NE(w_2, w_1);
EXPECT_EQ(w_2, w_2);
EXPECT_NE(w_2, w_3);
EXPECT_NE(w_2, w_4);
EXPECT_NE(w_2, w_5);
EXPECT_NE(w_3, w_1);
EXPECT_NE(w_3, w_2);
EXPECT_EQ(w_3, w_3);
EXPECT_NE(w_3, w_4);
EXPECT_NE(w_3, w_5);
EXPECT_NE(w_4, w_1);
EXPECT_NE(w_4, w_2);
EXPECT_NE(w_4, w_3);
EXPECT_EQ(w_4, w_4);
EXPECT_NE(w_4, w_5);
EXPECT_NE(w_5, w_1);
EXPECT_NE(w_5, w_2);
EXPECT_NE(w_5, w_3);
EXPECT_NE(w_5, w_4);
EXPECT_EQ(w_5, w_5);
}

DDSRT_WARNING_GNUC_ON(maybe-uninitialized)
20 changes: 20 additions & 0 deletions src/ddscxx/tests/data/RegressionModels.idl
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,24 @@ struct s_unaligned_access {
long long ll;
};

enum regression_enum {
case_1,
case_2,
case_3
};

union union_without_default switch (regression_enum) {
case case_1:
case case_2:
string s;
};

union union_with_default switch (regression_enum) {
case case_1:
case case_2:
string s;
default:
long i;
};

};
11 changes: 6 additions & 5 deletions src/idlcxx/src/streamers.c
Original file line number Diff line number Diff line change
Expand Up @@ -964,11 +964,12 @@ process_case(
if (idl_next(_case)) {
return IDL_RETCODE_OK;
} else {
//if last entry, and no default case was present for this union
const idl_case_label_t *def = _union->default_case;
if (idl_is_union(def->node.parent) &&
multi_putf(streams, READ, " default:\n instance._d(d);\n"))
return IDL_RETCODE_NO_MEMORY;
//if last entry, and the default case is an implicit default
if (_union == idl_parent(_union->default_case)) {
if (multi_putf(streams, READ, " default:\n instance._d(d);\n") ||
multi_putf(streams, WRITE | MOVE, " default:\n break;\n"))
return IDL_RETCODE_NO_MEMORY;
}
}

if (multi_putf(streams, NOMAX, " }\n"))
Expand Down
18 changes: 17 additions & 1 deletion src/idlcxx/src/types.c
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,8 @@ emit_union(
memset(&visitor, 0, sizeof(visitor));

_union = node;
/* check whether default label is associated with a union case */
const bool gen_default = (idl_parent(_union->default_case) == _union);
type_spec = _union->switch_type_spec->type_spec;

name = get_cpp11_name(_union);
Expand Down Expand Up @@ -1016,6 +1018,13 @@ emit_union(
if ((ret = idl_visit(pstate, _union->cases, &visitor, user_data)))
return ret;

if (gen_default) {
fmt = " default:\n"
" break;\n";
if (idl_fprintf(gen->header.handle, fmt, type) < 0)
return IDL_RETCODE_NO_MEMORY;
}

fmt = " }\n"
" return _default_discriminator;\n"
" }\n\n"
Expand Down Expand Up @@ -1073,8 +1082,15 @@ emit_union(
if ((ret = idl_visit(pstate, _union->cases, &visitor, user_data)))
return ret;

if (gen_default) {
fmt = " default:\n"
" return true;\n";
if (idl_fprintf(gen->header.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
}

fmt = " }\n"
" return false;\n"
" return true;\n"
" }\n\n"
" bool operator!=(const %s& _other) const\n"
" {\n"
Expand Down

0 comments on commit 1e8b263

Please sign in to comment.