[omniORB] create_union_tc fails with aliased discriminator types

Stephen Crawley crawley@dstc.edu.au
Tue, 15 Feb 2000 11:03:37 +1000


I'm having difficulty creating a union TypeCode where the type of the
discriminator is an alias (i.e. a typedef).  The problem is with the
label values for the union members.  If I supply a label (i.e. an Any)
whose TypeCode is the same as the discriminator TypeCode, the call to
create_union_tc throws BAD_PARAM.  Alternatively. if I supply a label
value whose TypeCode is the base type of the discriminator, the call
throws BAD_TYPECODE.

I traced the behaviour of create_union_tc() using gdb and found that
the problem appears to be in TypeCode_union_helper::extractLabel.
The code doesn't appear to handle aliasing in the label value at all.

Attached is a short program that demonstrates the problem.

-- Steve

=========================================================================
#include <stdlib.h>
#include <stdio.h>
#include <iostream.h>
#include <string.h>

#include <CORBA.h>

int main(int argc, char *argv[])
{
  CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "omniORB2");

  // Construct a TypeCode corresponding to the following IDL:
  //
  //   typedef long Int;
  //   union Onion (Int) {
  //     case 42: boolean foo;
  //   };

  // Create an alias typecode
  CORBA::TypeCode_var alias_tc = 
    orb -> create_alias_tc("IDL:Int:1.0", "Int", CORBA::_tc_long);

  // Create an aliased label value
  CORBA::Any base;
  base <<= (CORBA::Long) 42;

  CORBA::DynAny_var da = orb -> create_basic_dyn_any(alias_tc);
  CORBA::DynAny_var base_da = orb -> create_dyn_any(base);
  da -> assign(base_da);
  
  CORBA::Any label = *(da -> to_any());
  if (label.type() -> kind() == CORBA::tk_alias) {
    cerr << "label's type is an alias" << endl;
  }
  else {
    cerr << "label's type is not an alias" << endl;
  }

  // Create a union member seq
  CORBA::UnionMemberSeq ums;
  ums.length(1);
  ums[0].name = CORBA::string_dup("foo");
  ums[0].label = label;
  ums[0].type = CORBA::_tc_boolean;
  ums[0].type_def = CORBA::IDLType::_nil();

  // Create a union typecode
  try {
    CORBA::TypeCode_var utc = orb -> create_union_tc("IDL:Onion:1.0",
						     "Onion", alias_tc,
						     ums);
    cerr << "Union TC creation worked" << endl;
  }
  catch (CORBA::SystemException &ex) {
    cerr << "Caught an unexpected " << ex.NP_RepositoryId() 
	 << " exception" << endl;
  }

  // Try again, using the unaliased label value
  ums[0].label = base;
  try {
    CORBA::TypeCode_var utc = orb -> create_union_tc("IDL:Onion:1.0",
						     "Onion", alias_tc,
						     ums);
    cerr << "Second union TC creation worked" << endl;
  }
  catch (CORBA::SystemException &ex) {
    cerr << "Caught an unexpected " << ex.NP_RepositoryId() 
	 << " exception" << endl;
  }
}