patches/gdb/6.3/700-debian_cp-pass-by-reference.patch
changeset 301 2be7232a73ac
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/patches/gdb/6.3/700-debian_cp-pass-by-reference.patch	Sat Jul 28 21:34:41 2007 +0000
     1.3 @@ -0,0 +1,464 @@
     1.4 +This patch needs to be submitted for the FSF.  Also, there may be testcases
     1.5 +already in the GDB testsuite (currently disabled) that it would probably fix.
     1.6 +
     1.7 +Index: gdb-6.3/gdb/infcall.c
     1.8 +===================================================================
     1.9 +--- gdb-6.3.orig/gdb/infcall.c	2004-10-08 04:15:56.000000000 -0400
    1.10 ++++ gdb-6.3/gdb/infcall.c	2004-11-10 12:30:07.000000000 -0500
    1.11 +@@ -36,6 +36,7 @@
    1.12 + #include "gdb_string.h"
    1.13 + #include "infcall.h"
    1.14 + #include "dummy-frame.h"
    1.15 ++#include "cp-abi.h"
    1.16 + 
    1.17 + /* NOTE: cagney/2003-04-16: What's the future of this code?
    1.18 + 
    1.19 +@@ -297,8 +298,8 @@ call_function_by_hand (struct value *fun
    1.20 + {
    1.21 +   CORE_ADDR sp;
    1.22 +   CORE_ADDR dummy_addr;
    1.23 +-  struct type *value_type;
    1.24 +-  unsigned char struct_return;
    1.25 ++  struct type *value_type, *target_value_type;
    1.26 ++  unsigned char struct_return = 0, cp_struct_return = 0;
    1.27 +   CORE_ADDR struct_addr = 0;
    1.28 +   struct regcache *retbuf;
    1.29 +   struct cleanup *retbuf_cleanup;
    1.30 +@@ -312,6 +313,7 @@ call_function_by_hand (struct value *fun
    1.31 +   struct regcache *caller_regcache;
    1.32 +   struct cleanup *caller_regcache_cleanup;
    1.33 +   struct frame_id dummy_id;
    1.34 ++  struct cleanup *args_cleanup;
    1.35 + 
    1.36 +   if (!target_has_execution)
    1.37 +     noprocess ();
    1.38 +@@ -410,10 +412,31 @@ call_function_by_hand (struct value *fun
    1.39 +     using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
    1.40 +   }
    1.41 + 
    1.42 +-  /* Are we returning a value using a structure return or a normal
    1.43 +-     value return? */
    1.44 ++  /* Are we returning a value using a structure return (passing a
    1.45 ++     hidden argument pointing to storage) or a normal value return?
    1.46 ++     There are two cases: C++ ABI mandated structure return and
    1.47 ++     target ABI structure return.  The variable STRUCT_RETURN only
    1.48 ++     describes the latter.  The C++ version is handled by passing
    1.49 ++     the return location as the first parameter to the function,
    1.50 ++     even preceding "this".  This is different from the target
    1.51 ++     ABI version, which is target-specific; for instance, on ia64
    1.52 ++     the first argument is passed in out0 but the hidden structure
    1.53 ++     return pointer would normally be passed in r8.  */
    1.54 + 
    1.55 +-  struct_return = using_struct_return (value_type, using_gcc);
    1.56 ++  if (current_language->la_language == language_cplus
    1.57 ++      && cp_pass_by_reference (value_type))
    1.58 ++    {
    1.59 ++      cp_struct_return = 1;
    1.60 ++
    1.61 ++      /* Tell the target specific argument pushing routine not to
    1.62 ++	 expect a value.  */
    1.63 ++      target_value_type = builtin_type_void;
    1.64 ++    }
    1.65 ++  else
    1.66 ++    {
    1.67 ++      struct_return = using_struct_return (value_type, using_gcc);
    1.68 ++      target_value_type = value_type;
    1.69 ++    }
    1.70 + 
    1.71 +   /* Determine the location of the breakpoint (and possibly other
    1.72 +      stuff) that the called function will return to.  The SPARC, for a
    1.73 +@@ -432,7 +455,7 @@ call_function_by_hand (struct value *fun
    1.74 +       if (INNER_THAN (1, 2))
    1.75 + 	{
    1.76 + 	  sp = push_dummy_code (current_gdbarch, sp, funaddr,
    1.77 +-				using_gcc, args, nargs, value_type,
    1.78 ++				using_gcc, args, nargs, target_value_type,
    1.79 + 				&real_pc, &bp_addr);
    1.80 + 	  dummy_addr = sp;
    1.81 + 	}
    1.82 +@@ -440,7 +463,7 @@ call_function_by_hand (struct value *fun
    1.83 + 	{
    1.84 + 	  dummy_addr = sp;
    1.85 + 	  sp = push_dummy_code (current_gdbarch, sp, funaddr,
    1.86 +-				using_gcc, args, nargs, value_type,
    1.87 ++				using_gcc, args, nargs, target_value_type,
    1.88 + 				&real_pc, &bp_addr);
    1.89 + 	}
    1.90 +       break;
    1.91 +@@ -507,9 +530,15 @@ call_function_by_hand (struct value *fun
    1.92 + 	  param_type = TYPE_FIELD_TYPE (ftype, i);
    1.93 + 	else
    1.94 + 	  param_type = NULL;
    1.95 +-	
    1.96 ++
    1.97 + 	args[i] = value_arg_coerce (args[i], param_type, prototyped);
    1.98 + 
    1.99 ++	/* FIXME: Is current_language the right language?  */
   1.100 ++	if (current_language->la_language == language_cplus
   1.101 ++	    && param_type != NULL
   1.102 ++	    && cp_pass_by_reference (param_type))
   1.103 ++	  args[i] = value_addr (args[i]);
   1.104 ++
   1.105 + 	/* elz: this code is to handle the case in which the function
   1.106 + 	   to be called has a pointer to function as parameter and the
   1.107 + 	   corresponding actual argument is the address of a function
   1.108 +@@ -607,7 +636,7 @@ You must use a pointer to function type 
   1.109 +      stack, if necessary.  Make certain that the value is correctly
   1.110 +      aligned. */
   1.111 + 
   1.112 +-  if (struct_return)
   1.113 ++  if (struct_return || cp_struct_return)
   1.114 +     {
   1.115 +       int len = TYPE_LENGTH (value_type);
   1.116 +       if (INNER_THAN (1, 2))
   1.117 +@@ -632,6 +661,22 @@ You must use a pointer to function type 
   1.118 + 	}
   1.119 +     }
   1.120 + 
   1.121 ++  if (cp_struct_return)
   1.122 ++    {
   1.123 ++      struct value **new_args;
   1.124 ++
   1.125 ++      /* Add the new argument to the front of the argument list.  */
   1.126 ++      new_args = xmalloc (sizeof (struct value *) * (nargs + 1));
   1.127 ++      new_args[0] = value_from_pointer (lookup_pointer_type (value_type),
   1.128 ++					struct_addr);
   1.129 ++      memcpy (&new_args[1], &args[0], sizeof (struct value *) * nargs);
   1.130 ++      args = new_args;
   1.131 ++      nargs++;
   1.132 ++      args_cleanup = make_cleanup (xfree, args);
   1.133 ++    }
   1.134 ++  else
   1.135 ++    args_cleanup = make_cleanup (null_cleanup, NULL);
   1.136 ++
   1.137 +   /* Create the dummy stack frame.  Pass in the call dummy address as,
   1.138 +      presumably, the ABI code knows where, in the call dummy, the
   1.139 +      return address should be pointed.  */
   1.140 +@@ -649,6 +694,8 @@ You must use a pointer to function type 
   1.141 +   else
   1.142 +     error ("This target does not support function calls");
   1.143 + 
   1.144 ++  do_cleanups (args_cleanup);
   1.145 ++
   1.146 +   /* Set up a frame ID for the dummy frame so we can pass it to
   1.147 +      set_momentary_breakpoint.  We need to give the breakpoint a frame
   1.148 +      ID so that the breakpoint code can correctly re-identify the
   1.149 +@@ -839,11 +886,7 @@ the function call).", name);
   1.150 +   /* Figure out the value returned by the function, return that.  */
   1.151 +   {
   1.152 +     struct value *retval;
   1.153 +-    if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
   1.154 +-      /* If the function returns void, don't bother fetching the
   1.155 +-	 return value.  */
   1.156 +-      retval = allocate_value (value_type);
   1.157 +-    else if (struct_return)
   1.158 ++    if (struct_return || cp_struct_return)
   1.159 +       /* NOTE: cagney/2003-09-27: This assumes that PUSH_DUMMY_CALL
   1.160 + 	 has correctly stored STRUCT_ADDR in the target.  In the past
   1.161 + 	 that hasn't been the case, the old MIPS PUSH_ARGUMENTS
   1.162 +@@ -853,6 +896,10 @@ the function call).", name);
   1.163 + 	 "struct return convention", check that PUSH_DUMMY_CALL isn't
   1.164 + 	 playing tricks.  */
   1.165 +       retval = value_at (value_type, struct_addr, NULL);
   1.166 ++    else if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
   1.167 ++      /* If the function returns void, don't bother fetching the
   1.168 ++	 return value.  */
   1.169 ++      retval = allocate_value (value_type);
   1.170 +     else
   1.171 +       {
   1.172 + 	/* This code only handles "register convention".  */
   1.173 +Index: gdb-6.3/gdb/cp-abi.h
   1.174 +===================================================================
   1.175 +--- gdb-6.3.orig/gdb/cp-abi.h	2003-04-12 13:41:25.000000000 -0400
   1.176 ++++ gdb-6.3/gdb/cp-abi.h	2004-11-10 12:30:07.000000000 -0500
   1.177 +@@ -1,7 +1,7 @@
   1.178 + /* Abstraction of various C++ ABI's we support, and the info we need
   1.179 +    to get from them.
   1.180 +    Contributed by Daniel Berlin <dberlin@redhat.com>
   1.181 +-   Copyright 2001 Free Software Foundation, Inc.
   1.182 ++   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
   1.183 + 
   1.184 +    This file is part of GDB.
   1.185 + 
   1.186 +@@ -145,6 +145,10 @@ extern struct type *value_rtti_type (str
   1.187 + extern int baseclass_offset (struct type *type, int index, char *valaddr,
   1.188 + 			     CORE_ADDR address);
   1.189 +                   
   1.190 ++/* Return non-zero if an argument of type TYPE should be passed by reference
   1.191 ++   instead of value.  */
   1.192 ++extern int cp_pass_by_reference (struct type *type);
   1.193 ++
   1.194 + struct cp_abi_ops
   1.195 + {
   1.196 +   const char *shortname;
   1.197 +@@ -162,6 +166,7 @@ struct cp_abi_ops
   1.198 + 			     int *using_enc);
   1.199 +   int (*baseclass_offset) (struct type *type, int index, char *valaddr,
   1.200 + 			   CORE_ADDR address);
   1.201 ++  int (*pass_by_reference) (struct type *type);
   1.202 + };
   1.203 + 
   1.204 + 
   1.205 +Index: gdb-6.3/gdb/cp-abi.c
   1.206 +===================================================================
   1.207 +--- gdb-6.3.orig/gdb/cp-abi.c	2003-11-26 17:04:00.000000000 -0500
   1.208 ++++ gdb-6.3/gdb/cp-abi.c	2004-11-10 12:30:07.000000000 -0500
   1.209 +@@ -1,5 +1,5 @@
   1.210 + /* Generic code for supporting multiple C++ ABI's
   1.211 +-   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
   1.212 ++   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
   1.213 + 
   1.214 +    This file is part of GDB.
   1.215 + 
   1.216 +@@ -94,6 +94,14 @@ value_rtti_type (struct value *v, int *f
   1.217 +   return (*current_cp_abi.rtti_type) (v, full, top, using_enc);
   1.218 + }
   1.219 + 
   1.220 ++int
   1.221 ++cp_pass_by_reference (struct type *type)
   1.222 ++{
   1.223 ++  if ((current_cp_abi.pass_by_reference) == NULL)
   1.224 ++    return 0;
   1.225 ++  return (*current_cp_abi.pass_by_reference) (type);
   1.226 ++}
   1.227 ++
   1.228 + /* Set the current C++ ABI to SHORT_NAME.  */
   1.229 + 
   1.230 + static int
   1.231 +Index: gdb-6.3/gdb/gnu-v3-abi.c
   1.232 +===================================================================
   1.233 +--- gdb-6.3.orig/gdb/gnu-v3-abi.c	2004-03-15 15:38:08.000000000 -0500
   1.234 ++++ gdb-6.3/gdb/gnu-v3-abi.c	2004-11-10 12:30:07.000000000 -0500
   1.235 +@@ -1,7 +1,7 @@
   1.236 + /* Abstraction of GNU v3 abi.
   1.237 +    Contributed by Jim Blandy <jimb@redhat.com>
   1.238 + 
   1.239 +-   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
   1.240 ++   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
   1.241 + 
   1.242 +    This file is part of GDB.
   1.243 + 
   1.244 +@@ -419,6 +419,84 @@ gnuv3_baseclass_offset (struct type *typ
   1.245 +   return base_offset;
   1.246 + }
   1.247 + 
   1.248 ++/* Return nonzero if a type should be passed by reference.
   1.249 ++
   1.250 ++   The rule in the v3 ABI document comes from section 3.1.1.  If the
   1.251 ++   type has a non-trivial copy constructor or destructor, then the
   1.252 ++   caller must make a copy (by calling the copy constructor if there
   1.253 ++   is one or perform the copy itself otherwise), pass the address of
   1.254 ++   the copy, and then destroy the temporary (if necessary).
   1.255 ++
   1.256 ++   For return values with non-trivial copy constructors or
   1.257 ++   destructors, space will be allocated in the caller, and a pointer
   1.258 ++   will be passed as the first argument (preceding "this").
   1.259 ++
   1.260 ++   We don't have a bulletproof mechanism for determining whether a
   1.261 ++   constructor or destructor is trivial.  For GCC and DWARF2 debug
   1.262 ++   information, we can check the artificial flag.
   1.263 ++
   1.264 ++   We don't do anything with the constructors or destructors yet,
   1.265 ++   but we have to get the argument passing right anyway.  */
   1.266 ++static int
   1.267 ++gnuv3_pass_by_reference (struct type *type)
   1.268 ++{
   1.269 ++  int fieldnum, fieldelem, basenum;
   1.270 ++
   1.271 ++  CHECK_TYPEDEF (type);
   1.272 ++
   1.273 ++  /* We're only interested in things that can have methods.  */
   1.274 ++  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
   1.275 ++      && TYPE_CODE (type) != TYPE_CODE_CLASS
   1.276 ++      && TYPE_CODE (type) != TYPE_CODE_UNION)
   1.277 ++    return 0;
   1.278 ++
   1.279 ++  for (fieldnum = 0; fieldnum < TYPE_NFN_FIELDS (type); fieldnum++)
   1.280 ++    for (fieldelem = 0; fieldelem < TYPE_FN_FIELDLIST_LENGTH (type, fieldnum);
   1.281 ++	 fieldelem++)
   1.282 ++      {
   1.283 ++	struct fn_field *fn = TYPE_FN_FIELDLIST1 (type, fieldnum);
   1.284 ++	char *name = TYPE_FN_FIELDLIST_NAME (type, fieldnum);
   1.285 ++	struct type *fieldtype = TYPE_FN_FIELD_TYPE (fn, fieldelem);
   1.286 ++
   1.287 ++	/* If this function is marked as artificial, it is compiler-generated,
   1.288 ++	   and we assume it is trivial.  */
   1.289 ++	if (TYPE_FN_FIELD_ARTIFICIAL (fn, fieldelem))
   1.290 ++	  continue;
   1.291 ++
   1.292 ++	/* If we've found a destructor, we must pass this by reference.  */
   1.293 ++	if (name[0] == '~')
   1.294 ++	  return 1;
   1.295 ++
   1.296 ++	/* If the mangled name of this method doesn't indicate that it
   1.297 ++	   is a constructor, we're not interested.
   1.298 ++
   1.299 ++	   FIXME drow/2004-05-27: We could do this using the name of
   1.300 ++	   the method and the name of the class instead of dealing
   1.301 ++	   with the mangled name.  We don't have a convenient function
   1.302 ++	   to strip off both leading scope qualifiers and trailing
   1.303 ++	   template arguments yet.  */
   1.304 ++	if (!is_constructor_name (TYPE_FN_FIELD_PHYSNAME (fn, fieldelem)))
   1.305 ++	  continue;
   1.306 ++
   1.307 ++	/* If this method takes two arguments, and the second argument is
   1.308 ++	   a reference to this class, then it is a copy constructor.  */
   1.309 ++	if (TYPE_NFIELDS (fieldtype) == 2
   1.310 ++	    && TYPE_CODE (TYPE_FIELD_TYPE (fieldtype, 1)) == TYPE_CODE_REF
   1.311 ++	    && check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (fieldtype, 1))) == type)
   1.312 ++	  return 1;
   1.313 ++      }
   1.314 ++
   1.315 ++  /* Even if all the constructors and destructors were artificial, one
   1.316 ++     of them may have invoked a non-artificial constructor or
   1.317 ++     destructor in a base class.  If any base class needs to be passed
   1.318 ++     by reference, so does this class.  */
   1.319 ++  for (basenum = 0; basenum < TYPE_N_BASECLASSES (type); basenum++)
   1.320 ++    if (gnuv3_pass_by_reference (TYPE_BASECLASS (type, basenum)))
   1.321 ++      return 1;
   1.322 ++
   1.323 ++  return 0;
   1.324 ++}
   1.325 ++
   1.326 + static void
   1.327 + init_gnuv3_ops (void)
   1.328 + {
   1.329 +@@ -434,6 +512,7 @@ init_gnuv3_ops (void)
   1.330 +   gnu_v3_abi_ops.rtti_type = gnuv3_rtti_type;
   1.331 +   gnu_v3_abi_ops.virtual_fn_field = gnuv3_virtual_fn_field;
   1.332 +   gnu_v3_abi_ops.baseclass_offset = gnuv3_baseclass_offset;
   1.333 ++  gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference;
   1.334 + }
   1.335 + 
   1.336 + extern initialize_file_ftype _initialize_gnu_v3_abi; /* -Wmissing-prototypes */
   1.337 +Index: gdb-6.3/gdb/hpacc-abi.c
   1.338 +===================================================================
   1.339 +--- gdb-6.3.orig/gdb/hpacc-abi.c	2003-06-08 14:27:13.000000000 -0400
   1.340 ++++ gdb-6.3/gdb/hpacc-abi.c	2004-11-10 12:30:07.000000000 -0500
   1.341 +@@ -3,7 +3,7 @@
   1.342 +    Most of the real code is from HP, i've just fiddled it to fit in
   1.343 +    the C++ ABI abstraction framework.
   1.344 + 
   1.345 +-   Copyright 2001 Free Software Foundation, Inc.
   1.346 ++   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
   1.347 + 
   1.348 +    This file is part of GDB.
   1.349 + 
   1.350 +Index: gdb-6.3/gdb/Makefile.in
   1.351 +===================================================================
   1.352 +--- gdb-6.3.orig/gdb/Makefile.in	2004-11-10 12:30:06.000000000 -0500
   1.353 ++++ gdb-6.3/gdb/Makefile.in	2004-11-10 12:30:07.000000000 -0500
   1.354 +@@ -2073,7 +2073,7 @@ ia64-tdep.o: ia64-tdep.c $(defs_h) $(inf
   1.355 + infcall.o: infcall.c $(defs_h) $(breakpoint_h) $(target_h) $(regcache_h) \
   1.356 + 	$(inferior_h) $(gdb_assert_h) $(block_h) $(gdbcore_h) $(language_h) \
   1.357 + 	$(objfiles_h) $(gdbcmd_h) $(command_h) $(gdb_string_h) $(infcall_h) \
   1.358 +-	$(dummy_frame_h)
   1.359 ++	$(dummy_frame_h) $(cp_abi_h)
   1.360 + inf-child.o: inf-child.c $(defs_h) $(regcache_h) $(memattr_h) $(symtab_h) \
   1.361 + 	$(target_h) $(inferior_h) $(gdb_string_h)
   1.362 + infcmd.o: infcmd.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
   1.363 +Index: gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.exp
   1.364 +===================================================================
   1.365 +--- /dev/null	1970-01-01 00:00:00.000000000 +0000
   1.366 ++++ gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.exp	2004-11-11 09:48:00.498518899 -0500
   1.367 +@@ -0,0 +1,38 @@
   1.368 ++# This testcase is part of GDB, the GNU debugger.
   1.369 ++
   1.370 ++# Copyright 2004 Free Software Foundation, Inc.
   1.371 ++
   1.372 ++# This program is free software; you can redistribute it and/or modify
   1.373 ++# it under the terms of the GNU General Public License as published by
   1.374 ++# the Free Software Foundation; either version 2 of the License, or
   1.375 ++# (at your option) any later version.
   1.376 ++#
   1.377 ++# This program is distributed in the hope that it will be useful,
   1.378 ++# but WITHOUT ANY WARRANTY; without even the implied warranty of
   1.379 ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   1.380 ++# GNU General Public License for more details.
   1.381 ++#
   1.382 ++# You should have received a copy of the GNU General Public License
   1.383 ++# along with this program; if not, write to the Free Software
   1.384 ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
   1.385 ++
   1.386 ++# Check that GDB can call C++ functions whose parameters have
   1.387 ++# object type, but are passed by reference.
   1.388 ++
   1.389 ++set testfile "pass-by-ref"
   1.390 ++set srcfile ${testfile}.cc
   1.391 ++set binfile ${objdir}/${subdir}/${testfile}
   1.392 ++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
   1.393 ++    return -1
   1.394 ++}
   1.395 ++
   1.396 ++gdb_exit
   1.397 ++gdb_start
   1.398 ++gdb_reinitialize_dir $srcdir/$subdir
   1.399 ++gdb_load ${binfile}
   1.400 ++
   1.401 ++if ![runto_main] then {
   1.402 ++    return -1
   1.403 ++}
   1.404 ++
   1.405 ++gdb_test "print foo (global_obj)" " = 3" "call function"
   1.406 +Index: gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.cc
   1.407 +===================================================================
   1.408 +--- /dev/null	1970-01-01 00:00:00.000000000 +0000
   1.409 ++++ gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.cc	2004-11-11 09:44:17.815014667 -0500
   1.410 +@@ -0,0 +1,57 @@
   1.411 ++/* This testcase is part of GDB, the GNU debugger.
   1.412 ++
   1.413 ++   Copyright 2004 Free Software Foundation, Inc.
   1.414 ++
   1.415 ++   This program is free software; you can redistribute it and/or modify
   1.416 ++   it under the terms of the GNU General Public License as published by
   1.417 ++   the Free Software Foundation; either version 2 of the License, or
   1.418 ++   (at your option) any later version.
   1.419 ++
   1.420 ++   This program is distributed in the hope that it will be useful,
   1.421 ++   but WITHOUT ANY WARRANTY; without even the implied warranty of
   1.422 ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   1.423 ++   GNU General Public License for more details.
   1.424 ++ 
   1.425 ++   You should have received a copy of the GNU General Public License
   1.426 ++   along with this program; if not, write to the Free Software
   1.427 ++   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
   1.428 ++   USA.  */
   1.429 ++
   1.430 ++class Obj {
   1.431 ++public:
   1.432 ++  Obj ();
   1.433 ++  Obj (const Obj &);
   1.434 ++  ~Obj ();
   1.435 ++  int var[2];
   1.436 ++};
   1.437 ++
   1.438 ++int foo (Obj arg)
   1.439 ++{
   1.440 ++  return arg.var[0] + arg.var[1];
   1.441 ++}
   1.442 ++
   1.443 ++Obj::Obj ()
   1.444 ++{
   1.445 ++  var[0] = 1;
   1.446 ++  var[1] = 2;
   1.447 ++}
   1.448 ++
   1.449 ++Obj::Obj (const Obj &obj)
   1.450 ++{
   1.451 ++  var[0] = obj.var[0];
   1.452 ++  var[1] = obj.var[1];
   1.453 ++}
   1.454 ++
   1.455 ++Obj::~Obj ()
   1.456 ++{
   1.457 ++
   1.458 ++}
   1.459 ++
   1.460 ++Obj global_obj;
   1.461 ++
   1.462 ++int
   1.463 ++main ()
   1.464 ++{
   1.465 ++  int bar = foo (global_obj);
   1.466 ++  return bar;
   1.467 ++}