diff options
author | Phil Mesnier <mesnierp@objectcomputing.com> | 2021-06-14 16:51:26 -0500 |
---|---|---|
committer | Phil Mesnier <mesnierp@objectcomputing.com> | 2021-06-14 16:51:26 -0500 |
commit | f39d2560e0c5d304fee5cd90b2ec9e52c1482e69 (patch) | |
tree | 63adc2c6a183d18f5d07972cb6b7eb2170df5cc6 | |
parent | 84438e5c0dfa16596fae1f9247d42e05b95db3c6 (diff) | |
download | ATCD-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.cpp | 16 | ||||
-rw-r--r-- | TAO/tests/IDLv4/annotations/annotation_tests.cpp | 35 |
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 (); } |