From 6c361f6565a05189d2b359a8c6690a9970a759f4 Mon Sep 17 00:00:00 2001 From: parsons Date: Wed, 22 Apr 2009 18:11:24 +0000 Subject: ChangeLogTag: Wed Apr 22 17:59:18 UTC 2009 Jeff Parsons --- TAO/ChangeLog | 25 ++++++++++++++++++++ TAO/TAO_IDL/ast/ast_interface.cpp | 11 ++++++++- TAO/TAO_IDL/ast/ast_sequence.cpp | 6 +++++ TAO/TAO_IDL/fe/idl.yy | 48 ++++++++++++++++++++++++++++++++++---- TAO/TAO_IDL/fe/y.tab.cpp | 48 ++++++++++++++++++++++++++++++++++---- TAO/TAO_IDL/include/ast_sequence.h | 4 ++++ TAO/TAO_IDL/tao_idl.mpc | 2 +- TAO/TAO_IDL/util/utl_err.cpp | 2 +- 8 files changed, 135 insertions(+), 11 deletions(-) diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 08436762ba0..f7de5a4d0b7 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,28 @@ +Wed Apr 22 17:59:18 UTC 2009 Jeff Parsons + + * TAO_IDL/include/ast_sequence.h: + * TAO_IDL/ast/ast_interface.cpp: + * TAO_IDL/ast/ast_sequence.cpp: + * TAO_IDL/fe/y.tab.cpp: + * TAO_IDL/fe/idl.yy: + + Added check to catch illegal use of incomplete sequence + type (sequence of undefined struct or union) as an + operation return type or parameter. Thanks to + Ron van Hoof for reporting the bug + and for sending in the example IDL. This fix closes + [BUGID:3648]. + + * TAO_IDL/util/utl_err.cpp: + + Changed message associated with EIDL_ILLEGAL_ADD flag + to be more informative. + + * TAO_IDL/tao_idl.mpc: + + Removed a redundant item from the 'after' line of + TAO_IDL_EXE. + Wed Apr 22 09:07:44 UTC 2009 Vladimir Zykov * tests/Bug_3632_Regression/test.cpp: diff --git a/TAO/TAO_IDL/ast/ast_interface.cpp b/TAO/TAO_IDL/ast/ast_interface.cpp index f0839916907..d3839adae34 100644 --- a/TAO/TAO_IDL/ast/ast_interface.cpp +++ b/TAO/TAO_IDL/ast/ast_interface.cpp @@ -1090,7 +1090,7 @@ AST_Interface::fwd_redefinition_helper (AST_Interface *&i, // lookup is all that's needed. AST_Decl *d = s->lookup_by_name_local (i->local_name (), 0); - + AST_Interface *fd = 0; if (d != 0) @@ -1139,6 +1139,14 @@ AST_Interface::fwd_redefinition_helper (AST_Interface *&i, idl_global->err ()->redef_error (i->full_name (), d->full_name ()); } + + AST_InterfaceFwd *fwd = + AST_InterfaceFwd::narrow_from_decl (d); + + if (fwd != 0) + { + fwd->set_as_defined (); + } } // If it is a forward declared interface.. else if (!fd->is_defined ()) @@ -1368,6 +1376,7 @@ AST_Interface::redefine (AST_Interface *from) this->set_file_name (idl_global->filename ()->get_string ()); this->ifr_added_ = from->ifr_added_; this->ifr_fwd_added_ = from->ifr_fwd_added_; + this->fwd_decl_->set_as_defined (); } // Data accessors. diff --git a/TAO/TAO_IDL/ast/ast_sequence.cpp b/TAO/TAO_IDL/ast/ast_sequence.cpp index 221b41cee66..bbe2a9276e3 100644 --- a/TAO/TAO_IDL/ast/ast_sequence.cpp +++ b/TAO/TAO_IDL/ast/ast_sequence.cpp @@ -246,6 +246,12 @@ AST_Sequence::legal_for_primary_key (void) const return this->base_type ()->legal_for_primary_key (); } +bool +AST_Sequence::is_defined (void) +{ + return this->pd_base_type->is_defined (); +} + void AST_Sequence::destroy (void) { diff --git a/TAO/TAO_IDL/fe/idl.yy b/TAO/TAO_IDL/fe/idl.yy index 7158b8728b2..9e001e752ec 100644 --- a/TAO/TAO_IDL/fe/idl.yy +++ b/TAO/TAO_IDL/fe/idl.yy @@ -4224,16 +4224,56 @@ param_type_spec { d->last_referenced_as ($1); AST_Decl::NodeType nt = d->node_type (); + AST_Type *t = AST_Type::narrow_from_decl (d); + AST_Typedef *td = 0; + bool can_be_undefined = false; if (nt == AST_Decl::NT_struct_fwd || nt == AST_Decl::NT_union_fwd || nt == AST_Decl::NT_struct - || nt == AST_Decl::NT_union) + || nt == AST_Decl::NT_union + || nt == AST_Decl::NT_typedef) { - if (! AST_Type::narrow_from_decl (d)->is_defined ()) + // This code block ensures that a sequence of + // as-yet-undefined struct or union isn't used + // as a return type or argument. + if (nt == AST_Decl::NT_typedef) { - idl_global->err ()->error1 (UTL_Error::EIDL_ILLEGAL_ADD, - d); + td = AST_Typedef::narrow_from_decl (d); + AST_Type *pbt = td->primitive_base_type (); + + if (pbt->node_type () == AST_Decl::NT_sequence) + { + t = pbt; + AST_Sequence *seq_type = + AST_Sequence::narrow_from_decl (pbt); + AST_Type *elem_type = + seq_type->base_type (); + AST_Decl::NodeType elem_nt = + elem_type->node_type (); + + if (elem_nt == AST_Decl::NT_typedef) + { + AST_Typedef *elem_td = + AST_Typedef::narrow_from_decl (elem_type); + elem_type = elem_td->primitive_base_type (); + elem_nt = elem_type->node_type (); + } + + if (elem_nt == AST_Decl::NT_interface + || elem_nt == AST_Decl::NT_valuetype + || elem_nt == AST_Decl::NT_component) + { + can_be_undefined = true; + } + } + } + + if (! t->is_defined () && ! can_be_undefined) + { + idl_global->err ()->error1 ( + UTL_Error::EIDL_ILLEGAL_ADD, + (nt == AST_Decl::NT_typedef ? td : t)); /* If we don't return here, we'll crash later.*/ return 1; diff --git a/TAO/TAO_IDL/fe/y.tab.cpp b/TAO/TAO_IDL/fe/y.tab.cpp index 7a720d016c4..2636562d6fc 100644 --- a/TAO/TAO_IDL/fe/y.tab.cpp +++ b/TAO/TAO_IDL/fe/y.tab.cpp @@ -6388,16 +6388,56 @@ tao_yyreduce: { d->last_referenced_as (tao_yyvsp[0].idlist); AST_Decl::NodeType nt = d->node_type (); + AST_Type *t = AST_Type::narrow_from_decl (d); + AST_Typedef *td = 0; + bool can_be_undefined = false; if (nt == AST_Decl::NT_struct_fwd || nt == AST_Decl::NT_union_fwd || nt == AST_Decl::NT_struct - || nt == AST_Decl::NT_union) + || nt == AST_Decl::NT_union + || nt == AST_Decl::NT_typedef) { - if (! AST_Type::narrow_from_decl (d)->is_defined ()) + // This code block ensures that a sequence of + // as-yet-undefined struct or union isn't used + // as a return type or argument. + if (nt == AST_Decl::NT_typedef) { - idl_global->err ()->error1 (UTL_Error::EIDL_ILLEGAL_ADD, - d); + td = AST_Typedef::narrow_from_decl (d); + AST_Type *pbt = td->primitive_base_type (); + + if (pbt->node_type () == AST_Decl::NT_sequence) + { + t = pbt; + AST_Sequence *seq_type = + AST_Sequence::narrow_from_decl (pbt); + AST_Type *elem_type = + seq_type->base_type (); + AST_Decl::NodeType elem_nt = + elem_type->node_type (); + + if (elem_nt == AST_Decl::NT_typedef) + { + AST_Typedef *elem_td = + AST_Typedef::narrow_from_decl (elem_type); + elem_type = elem_td->primitive_base_type (); + elem_nt = elem_type->node_type (); + } + + if (elem_nt == AST_Decl::NT_interface + || elem_nt == AST_Decl::NT_valuetype + || elem_nt == AST_Decl::NT_component) + { + can_be_undefined = true; + } + } + } + + if (! t->is_defined () && ! can_be_undefined) + { + idl_global->err ()->error1 ( + UTL_Error::EIDL_ILLEGAL_ADD, + (nt == AST_Decl::NT_typedef ? td : t)); /* If we don't return here, we'll crash later.*/ return 1; diff --git a/TAO/TAO_IDL/include/ast_sequence.h b/TAO/TAO_IDL/include/ast_sequence.h index ac21f2b357a..42646602968 100644 --- a/TAO/TAO_IDL/include/ast_sequence.h +++ b/TAO/TAO_IDL/include/ast_sequence.h @@ -104,6 +104,10 @@ public: // union, array, typedef, and interface. virtual bool legal_for_primary_key (void) const; + // Is the element type a forward declared struct or union + // that hasn't yet been fully defined? + virtual bool is_defined (void); + // Cleanup method. virtual void destroy (void); diff --git a/TAO/TAO_IDL/tao_idl.mpc b/TAO/TAO_IDL/tao_idl.mpc index 232a217f66f..d8760007ad5 100644 --- a/TAO/TAO_IDL/tao_idl.mpc +++ b/TAO/TAO_IDL/tao_idl.mpc @@ -86,7 +86,7 @@ project(TAO_IDL_EXE) : aceexe, install, tao_output, crosscompile, mcpp, tao_idl_ exename = tao_idl libs += TAO_IDL_BE TAO_IDL_FE exeout = $(ACE_ROOT)/bin - after += TAO_IDL_BE TAO_IDL_FE gperf + after += TAO_IDL_BE gperf includes += $(TAO_ROOT) specific (automake) { diff --git a/TAO/TAO_IDL/util/utl_err.cpp b/TAO/TAO_IDL/util/utl_err.cpp index 3e0cd97df09..506648e4899 100644 --- a/TAO/TAO_IDL/util/utl_err.cpp +++ b/TAO/TAO_IDL/util/utl_err.cpp @@ -129,7 +129,7 @@ error_string (UTL_Error::ErrorCode c) case UTL_Error::EIDL_LABEL_TYPE: return "label type incompatible with union discriminator type, "; case UTL_Error::EIDL_ILLEGAL_ADD: - return "forward declared type may be used only as a sequence element, "; + return "illegal use of incomplete type, "; case UTL_Error::EIDL_ILLEGAL_USE: return "illegal type used in expression, "; case UTL_Error::EIDL_ILLEGAL_RAISES: -- cgit v1.2.1