summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Mesnier <mesnierp@objectcomputing.com>2021-06-14 16:51:26 -0500
committerPhil Mesnier <mesnierp@objectcomputing.com>2021-06-14 16:51:26 -0500
commitf39d2560e0c5d304fee5cd90b2ec9e52c1482e69 (patch)
tree63adc2c6a183d18f5d07972cb6b7eb2170df5cc6
parent84438e5c0dfa16596fae1f9247d42e05b95db3c6 (diff)
downloadATCD-f39d2560e0c5d304fee5cd90b2ec9e52c1482e69.tar.gz
Fix and test for incorrect handling of empty enum-based union labels that happen to alias the default case.
-rw-r--r--TAO/TAO_IDL/ast/ast_union_branch.cpp16
-rw-r--r--TAO/tests/IDLv4/annotations/annotation_tests.cpp35
2 files changed, 40 insertions, 11 deletions
diff --git a/TAO/TAO_IDL/ast/ast_union_branch.cpp b/TAO/TAO_IDL/ast/ast_union_branch.cpp
index 8952cdfab21..075a88c7739 100644
--- a/TAO/TAO_IDL/ast/ast_union_branch.cpp
+++ b/TAO/TAO_IDL/ast/ast_union_branch.cpp
@@ -1,3 +1,5 @@
+// $Id$
+
/*
COPYRIGHT
@@ -181,22 +183,16 @@ AST_UnionBranch::label_list_length (void)
void
AST_UnionBranch::add_labels (AST_Union *u)
{
+ const bool enum_labels = (u->udisc_type () == AST_Expression::EV_enum);
for (UTL_LabellistActiveIterator i (this->pd_ll);
!i.is_done ();
i.next ())
{
if (AST_UnionLabel::UL_default == i.item ()->label_kind ())
- {
- return;
- }
- }
+ {
+ continue;
+ }
- const bool enum_labels = (u->udisc_type () == AST_Expression::EV_enum);
-
- for (UTL_LabellistActiveIterator i (this->pd_ll);
- !i.is_done ();
- i.next ())
- {
AST_Expression *ex = i.item ()->label_val ();
UTL_ScopedName *n = ex->n ();
diff --git a/TAO/tests/IDLv4/annotations/annotation_tests.cpp b/TAO/tests/IDLv4/annotations/annotation_tests.cpp
index 73b2359c178..83c16e7f874 100644
--- a/TAO/tests/IDLv4/annotations/annotation_tests.cpp
+++ b/TAO/tests/IDLv4/annotations/annotation_tests.cpp
@@ -4,7 +4,9 @@
#include <ast_porttype.h>
#include <ast_eventtype.h>
#include <ast_component.h>
-
+#include <ast_union_branch.h>
+#include <ast_union_label.h>
+#include <ast_expression.h>
#include <string>
namespace {
@@ -1060,6 +1062,37 @@ annotation_tests ()
}
} catch (Failed const &) {}
+ /* -------------------------------------------------------------------------
+ * Empty union cases aliasing the default case must always be evaluated
+ * -------------------------------------------------------------------------
+ * When the union has an enum discriminator, and one or more empty cases
+ * acting as an alias to the default case the IDL compiler was failing to
+ * resolve the ordinal value for these empty labels and this causes trouble
+ * for at least OpenDDS.
+ *
+ * This test is designed to verify that the condition is corrected by
+ * parsing a specially crafted union and validating the value of the
+ * label aliasing the default case.
+ */
+ try {
+ Annotation_Test t ("empty union branch label");
+ AST_Union *test_union = t.run (
+ "enum disc {A, B, C};\n"
+ "union empty_union switch (disc) {\n"
+ "case A: long along;\n"
+ "case B: short bshort;\n"
+ "case C:\n"
+ "default: float cfloat;\n"
+ "};\n").assert_node<AST_Union>("::empty_union");
+ AST_Field **af = 0;
+ test_union->field(af,2);
+ AST_UnionBranch *ub = dynamic_cast<AST_UnionBranch *>(*af);
+ AST_UnionLabel *ul = ub->label ();
+ if (ul->label_val()->ev()->u.ulval != 2) {
+ t.failed("did not get the correct label value");
+ }
+ } catch (Failed const &) {}
+
// Done, Print Overall Results
Annotation_Test::results ();
}