public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] pass C++ decimal classes same as scalars
@ 2009-11-24  0:23 Janis Johnson
  2009-11-25 10:35 ` Paolo Bonzini
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Janis Johnson @ 2009-11-24  0:23 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason

This patch causes G++ to pass std::decimal::decimal32/64/128 the same
as their corresponding scalar types; a longer rationale is in:

  http://gcc.gnu.org/ml/gcc-patches/2009-10/msg00866.html  

Jason said here:

  http://gcc.gnu.org/ml/gcc-patches/2009-11/msg00110.html

that the original patch looks good except for a change that I've made
to the new one, to use a single macro for both the old
TYPE_TRANSPARENT_UNION and the new use for record types that are
passed the same as the single scalar member.  I call the new macro
TYPE_PASS_AS_TRANSPARENT but am certainly open to suggestions.  Jason
also said he'd like this change in 4.5.

Tested on powerpc64-linux for -m32/-m64.  OK for trunk after the
C++ ABI patch is accepted?  I pinged that last week but so far Jason
is the only one who has commented on it.

2009-11-23  Janis Johnson  <janis187@us.ibm.com>

	* tree.h (TYPE_TRANSPARENT_UNION): Replace with ...
	(TYPE_PASS_AS_TRANSPARENT): this, for union and record.
	* calls.c (initialize argument_information): Handle it.
	* c-common.c (handle_transparent_union_attribute): Use new name.
	* c-decl.c (finish_struct): Ditto.
	* c-typeck.c (type_lists_compatible_p): Ditto.
	(convert_for_assignment): Use new name and also handle record.
	* function.c (aggregate_value_p): Handle it.
	(pass_by_reference): Ditto.
	(assign_parm_data_types): Ditto.
	* print-tree.c (print_node): Ditto.
	* lto-streamer-in.c (unpack_ts_type_value_fields): Ditto.
	* lto-streamer-out.c (pack_ts_type_value_fields): Ditto.

gcc/cp/
	* mangle.c (write_type): Mangle transparent record as member type.
	* semantics.c (begin_class_definition): Recognize decimal classes
	and set TYPE__ASS_AS_TRANSPARENT.

gcc/testsuite/
	* g++.dg/compat/decimal/compat-common.h: New file.
	* g++.dg/compat/decimal/decimal-dummy.h: New file.
	* g++.dg/compat/decimal/pass_x.h: New file.
	* g++.dg/compat/decimal/pass_y.h: New file.
	* g++.dg/compat/decimal/pass-1_main.C: New file.
	* g++.dg/compat/decimal/pass-1_x.C: New file.
	* g++.dg/compat/decimal/pass-1_y.C: New file.
	* g++.dg/compat/decimal/pass-2_main.C: New file.
	* g++.dg/compat/decimal/pass-2_x.C: New file.
	* g++.dg/compat/decimal/pass-2_y.C: New file.
	* g++.dg/compat/decimal/pass-3_main.C: New file.
	* g++.dg/compat/decimal/pass-3_x.C: New file.
	* g++.dg/compat/decimal/pass-3_y.C: New file.
	* g++.dg/compat/decimal/pass-4_main.C: New file.
	* g++.dg/compat/decimal/pass-4_x.C: New file.
	* g++.dg/compat/decimal/pass-4_y.C: New file.
	* g++.dg/compat/decimal/pass-5_main.C: New file.
	* g++.dg/compat/decimal/pass-5_x.C: New file.
	* g++.dg/compat/decimal/pass-5_y.C: New file.
	* g++.dg/compat/decimal/pass-6_main.C: New file.
	* g++.dg/compat/decimal/pass-6_x.C: New file.
	* g++.dg/compat/decimal/pass-6_y.C: New file.
	* g++.dg/compat/decimal/return_x.h: New file.
	* g++.dg/compat/decimal/return_y.h: New file.
	* g++.dg/compat/decimal/return-1_main.C: New file.
	* g++.dg/compat/decimal/return-1_x.C: New file.
	* g++.dg/compat/decimal/return-1_y.C: New file.
	* g++.dg/compat/decimal/return-2_main.C: New file.
	* g++.dg/compat/decimal/return-2_x.C: New file.
	* g++.dg/compat/decimal/return-2_y.C: New file.
	* g++.dg/compat/decimal/return-3_main.C: New file.
	* g++.dg/compat/decimal/return-3_x.C: New file.
	* g++.dg/compat/decimal/return-3_y.C: New file.
	* g++.dg/compat/decimal/return-4_main.C: New file.
	* g++.dg/compat/decimal/return-4_x.C: New file.
	* g++.dg/compat/decimal/return-4_y.C: New file.
	* g++.dg/compat/decimal/return-5_main.C: New file.
	* g++.dg/compat/decimal/return-5_x.C: New file.
	* g++.dg/compat/decimal/return-5_y.C: New file.
	* g++.dg/compat/decimal/return-6_main.C: New file.
	* g++.dg/compat/decimal/return-6_x.C: New file.
	* g++.dg/compat/decimal/return-6_y.C: New file.

Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 154478)
+++ gcc/tree.h	(working copy)
@@ -2254,10 +2254,12 @@ extern enum machine_mode vector_type_mod
 #define TYPE_NEEDS_CONSTRUCTING(NODE) \
   (TYPE_CHECK (NODE)->type.needs_constructing_flag)
 
-/* Indicates that objects of this type (a UNION_TYPE), should be passed
-   the same way that the first union alternative would be passed.  */
-#define TYPE_TRANSPARENT_UNION(NODE)  \
-  (UNION_TYPE_CHECK (NODE)->type.transparent_union_flag)
+/* Indicates that a UNION_TYPE object should be passed the same way that
+   the first union alternative would be passed, or that a RECORD_TYPE
+   object should be passed the same way that the first (and only) member
+   would be passed.  */
+#define TYPE_PASS_AS_TRANSPARENT(NODE) \
+  (RECORD_OR_UNION_CHECK (NODE)->type.transparent_union_flag)
 
 /* For an ARRAY_TYPE, indicates that it is not permitted to take the
    address of a component of the type.  This is the counterpart of
Index: gcc/calls.c
===================================================================
--- gcc/calls.c	(revision 154478)
+++ gcc/calls.c	(working copy)
@@ -1014,10 +1014,11 @@ initialize_argument_information (int num
       if (type == error_mark_node || !COMPLETE_TYPE_P (type))
 	args[i].tree_value = integer_zero_node, type = integer_type_node;
 
-      /* If TYPE is a transparent union, pass things the way we would
-	 pass the first field of the union.  We have already verified that
-	 the modes are the same.  */
-      if (TREE_CODE (type) == UNION_TYPE && TYPE_TRANSPARENT_UNION (type))
+      /* If TYPE is a transparent union or record, pass things the way
+	 we would pass the first field of the union or record.  We have
+	 already verified that the modes are the same.  */
+      if ((TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == RECORD_TYPE)
+	   && TYPE_PASS_AS_TRANSPARENT (type))
 	type = TREE_TYPE (TYPE_FIELDS (type));
 
       /* Decide where to pass this arg.
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c	(revision 154478)
+++ gcc/c-common.c	(working copy)
@@ -6247,7 +6247,7 @@ handle_transparent_union_attribute (tree
 	  *node = type = build_duplicate_type (type);
 	}
 
-      TYPE_TRANSPARENT_UNION (type) = 1;
+      TYPE_PASS_AS_TRANSPARENT (type) = 1;
       return NULL_TREE;
     }
 
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 154478)
+++ gcc/c-decl.c	(working copy)
@@ -6939,10 +6939,10 @@ finish_struct (location_t loc, tree t, t
   /* If this was supposed to be a transparent union, but we can't
      make it one, warn and turn off the flag.  */
   if (TREE_CODE (t) == UNION_TYPE
-      && TYPE_TRANSPARENT_UNION (t)
+      && TYPE_PASS_AS_TRANSPARENT (t)
       && (!TYPE_FIELDS (t) || TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t))))
     {
-      TYPE_TRANSPARENT_UNION (t) = 0;
+      TYPE_PASS_AS_TRANSPARENT (t) = 0;
       warning_at (loc, 0, "union cannot be made transparent");
     }
 
Index: gcc/c-typeck.c
===================================================================
--- gcc/c-typeck.c	(revision 154478)
+++ gcc/c-typeck.c	(working copy)
@@ -1622,7 +1622,7 @@ type_lists_compatible_p (const_tree args
 	     and  wait (union wait *)  to be compatible.  */
 	  if (TREE_CODE (a1) == UNION_TYPE
 	      && (TYPE_NAME (a1) == 0
-		  || TYPE_TRANSPARENT_UNION (a1))
+		  || TYPE_PASS_AS_TRANSPARENT (a1))
 	      && TREE_CODE (TYPE_SIZE (a1)) == INTEGER_CST
 	      && tree_int_cst_equal (TYPE_SIZE (a1),
 				     TYPE_SIZE (a2)))
@@ -1643,7 +1643,7 @@ type_lists_compatible_p (const_tree args
 	    }
 	  else if (TREE_CODE (a2) == UNION_TYPE
 		   && (TYPE_NAME (a2) == 0
-		       || TYPE_TRANSPARENT_UNION (a2))
+		       || TYPE_PASS_AS_TRANSPARENT (a2))
 		   && TREE_CODE (TYPE_SIZE (a2)) == INTEGER_CST
 		   && tree_int_cst_equal (TYPE_SIZE (a2),
 					  TYPE_SIZE (a1)))
@@ -4992,9 +4992,10 @@ convert_for_assignment (location_t locat
       && comptypes (type, rhstype))
     return convert_and_check (type, rhs);
 
-  /* Conversion to a transparent union from its member types.
+  /* Conversion to a transparent union or record from its member types.
      This applies only to function arguments.  */
-  if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type)
+  if (((codel == UNION_TYPE || codel == RECORD_TYPE)
+      && TYPE_PASS_AS_TRANSPARENT (type))
       && errtype == ic_argpass)
     {
       tree memb, marginal_memb = NULL_TREE;
Index: gcc/function.c
===================================================================
--- gcc/function.c	(revision 154478)
+++ gcc/function.c	(working copy)
@@ -1872,6 +1872,11 @@ aggregate_value_p (const_tree exp, const
   if (TREE_CODE (type) == VOID_TYPE)
     return 0;
 
+  /* If a record should be passed the same as its first (and only) member
+     don't pass it as an aggregate.  */
+  if (TREE_CODE (type) == RECORD_TYPE && TYPE_PASS_AS_TRANSPARENT (type))
+    return 0;
+
   /* If the front end has decided that this needs to be passed by
      reference, do so.  */
   if ((TREE_CODE (exp) == PARM_DECL || TREE_CODE (exp) == RESULT_DECL)
@@ -1986,6 +1991,14 @@ pass_by_reference (CUMULATIVE_ARGS *ca, 
       /* GCC post 3.4 passes *all* variable sized types by reference.  */
       if (!TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
 	return true;
+
+      /* If a record type should be passed the same as its first (and only)
+	 member, use the type and mode of that member.  */
+      if (TREE_CODE (type) == RECORD_TYPE && TYPE_PASS_AS_TRANSPARENT (type))
+	{
+	  type = TREE_TYPE (TYPE_FIELDS (type));
+	  mode = TYPE_MODE (type);
+	}
     }
 
   return targetm.calls.pass_by_reference (ca, mode, type, named_arg);
@@ -2210,11 +2223,12 @@ assign_parm_find_data_types (struct assi
   passed_mode = TYPE_MODE (passed_type);
   nominal_mode = TYPE_MODE (nominal_type);
 
-  /* If the parm is to be passed as a transparent union, use the type of
-     the first field for the tests below.  We have already verified that
-     the modes are the same.  */
-  if (TREE_CODE (passed_type) == UNION_TYPE
-      && TYPE_TRANSPARENT_UNION (passed_type))
+  /* If the parm is to be passed as a transparent union or record, use the
+     type of the first field for the tests below.  We have already verified
+     that the modes are the same.  */
+  if ((TREE_CODE (passed_type) == UNION_TYPE
+       || TREE_CODE (passed_type) == RECORD_TYPE)
+      && TYPE_PASS_AS_TRANSPARENT (passed_type)) 
     passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
 
   /* See if this arg was passed by invisible reference.  */
Index: gcc/print-tree.c
===================================================================
--- gcc/print-tree.c	(revision 154478)
+++ gcc/print-tree.c	(working copy)
@@ -582,8 +582,10 @@ print_node (FILE *file, const char *pref
 
       /* The transparent-union flag is used for different things in
 	 different nodes.  */
-      if (code == UNION_TYPE && TYPE_TRANSPARENT_UNION (node))
+      if (code == UNION_TYPE && TYPE_PASS_AS_TRANSPARENT (node))
 	fputs (" transparent-union", file);
+      if (code == RECORD_TYPE && TYPE_PASS_AS_TRANSPARENT (node))
+	fputs (" transparent-record", file);
       else if (code == ARRAY_TYPE
 	       && TYPE_NONALIASED_COMPONENT (node))
 	fputs (" nonaliased-component", file);
Index: gcc/lto-streamer-in.c
===================================================================
--- gcc/lto-streamer-in.c	(revision 154478)
+++ gcc/lto-streamer-in.c	(working copy)
@@ -1750,8 +1750,8 @@ unpack_ts_type_value_fields (struct bitp
   TYPE_STRING_FLAG (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_NO_FORCE_BLK (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_NEEDS_CONSTRUCTING(expr) = (unsigned) bp_unpack_value (bp, 1);
-  if (TREE_CODE (expr) == UNION_TYPE)
-    TYPE_TRANSPARENT_UNION (expr) = (unsigned) bp_unpack_value (bp, 1);
+  if (TREE_CODE (expr) == UNION_TYPE || TREE_CODE (expr) == RECORD_TYPE)
+    TYPE_PASS_AS_TRANSPARENT (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr)
Index: gcc/lto-streamer-out.c
===================================================================
--- gcc/lto-streamer-out.c	(revision 154478)
+++ gcc/lto-streamer-out.c	(working copy)
@@ -517,8 +517,8 @@ pack_ts_type_value_fields (struct bitpac
   bp_pack_value (bp, TYPE_STRING_FLAG (expr), 1);
   bp_pack_value (bp, TYPE_NO_FORCE_BLK (expr), 1);
   bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING(expr), 1);
-  if (TREE_CODE (expr) == UNION_TYPE)
-    bp_pack_value (bp, TYPE_TRANSPARENT_UNION (expr), 1);
+  if (TREE_CODE (expr) == UNION_TYPE || TREE_CODE (expr) == RECORD_TYPE)
+    bp_pack_value (bp, TYPE_PASS_AS_TRANSPARENT (expr), 1);
   bp_pack_value (bp, TYPE_PACKED (expr), 1);
   bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
   bp_pack_value (bp, TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr), 2);
Index: gcc/cp/mangle.c
===================================================================
--- gcc/cp/mangle.c	(revision 154478)
+++ gcc/cp/mangle.c	(working copy)
@@ -1728,6 +1728,12 @@ write_type (tree type)
   if (find_substitution (type))
     return;
 
+  /* According to the C++ ABI, some library classes are passed the
+     same as the scalar type of their single member and use the same
+     mangling.  */
+  if (TREE_CODE (type) == RECORD_TYPE && TYPE_PASS_AS_TRANSPARENT (type))
+    type = TREE_TYPE (TYPE_FIELDS (type));
+
   if (write_CV_qualifiers_for_type (type) > 0)
     /* If TYPE was CV-qualified, we just wrote the qualifiers; now
        mangle the unqualified type.  The recursive call is needed here
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 154478)
+++ gcc/cp/semantics.c	(working copy)
@@ -2339,6 +2339,18 @@ begin_class_definition (tree t, tree att
       error ("definition of %q#T inside template parameter list", t);
       return error_mark_node;
     }
+
+  /* According to the C++ ABI, decimal classes defined in ISO/IEC TR 24733
+     are passed the same as decimal scalar types.  */
+  if (TREE_CODE (t) == RECORD_TYPE)
+    {
+      const char *n = type_as_string (t, TFF_CLASS_KEY_OR_ENUM);
+      if ((strcmp (n, "class std::decimal::decimal32") == 0)
+	  || (strcmp (n, "class std::decimal::decimal64") == 0)
+	  || (strcmp (n, "class std::decimal::decimal128") == 0))
+	TYPE_PASS_AS_TRANSPARENT (t) = 1;
+    }
+
   /* A non-implicit typename comes from code like:
 
        template <typename T> struct A {
Index: gcc/testsuite/g++.dg/compat/decimal/compat-common.h
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/compat-common.h	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/compat-common.h	(revision 0)
@@ -0,0 +1,55 @@
+/*  Several of the binary compatibility tests use these macros to
+    allow debugging the test or tracking down a failure by getting an
+    indication of whether each individual check passed or failed.
+    When DBG is defined, each check is shown by a dot (pass) or 'F'
+    (fail) rather than aborting as soon as a failure is detected.  */
+
+#ifdef DBG
+#include <stdio.h>
+#define DEBUG_INIT setbuf (stdout, NULL);
+#define DEBUG_FPUTS(x) fputs (x, stdout);
+#define DEBUG_DOT putc ('.', stdout);
+#define DEBUG_NL putc ('\n', stdout);
+#define DEBUG_FAIL putc ('F', stdout); fails++;
+#define DEBUG_CHECK { DEBUG_FAIL } else { DEBUG_DOT }
+#define DEBUG_FINI if (fails) DEBUG_FPUTS ("failed\n") \
+		   else DEBUG_FPUTS ("passed\n")
+#else
+#define DEBUG_INIT
+#define DEBUG_FPUTS(x)
+#define DEBUG_DOT
+#define DEBUG_NL
+#define DEBUG_FAIL abort ();
+#define DEBUG_CHECK abort ();
+#define DEBUG_FINI
+#endif
+
+#ifdef SKIP_COMPLEX
+#ifndef SKIP_COMPLEX_INT
+#define SKIP_COMPLEX_INT
+#endif
+#endif
+
+#ifndef SKIP_COMPLEX
+#ifdef __GNUC__
+#define CINT(x, y) (x + y * __extension__ 1i)
+#define CDBL(x, y) (x + y * __extension__ 1i)
+#else
+#ifdef __SUNPRO_C
+/* ??? Complex support without <complex.h>.  */
+#else
+#include <complex.h>
+#endif
+#ifndef SKIP_COMPLEX_INT
+#define CINT(x, y) ((_Complex int) (x + y * _Complex_I))
+#endif
+#define CDBL(x, y) (x + y * _Complex_I)
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void abort (void);
+#else
+extern void abort (void);
+#endif
+extern int fails;
Index: gcc/testsuite/g++.dg/compat/decimal/decimal-dummy.h
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/decimal-dummy.h	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/decimal-dummy.h	(revision 0)
@@ -0,0 +1,67 @@
+namespace std {
+namespace decimal {
+
+  class decimal32
+  {
+  public:
+    typedef float __dec32 __attribute__((mode(SD)));
+    decimal32 () : __val(0.e-101DF) {}
+    decimal32 (__dec32 x) : __val(x) {}
+    __dec32 __val;
+  };
+
+  class decimal64
+  {
+  public:
+    typedef float __dec64 __attribute__((mode(DD)));
+    decimal64 () : __val(0.e-398dd) {}
+    decimal64 (__dec64 x) : __val(x) {}
+    __dec64 __val;
+  };
+
+  class decimal128
+  {
+  public:
+    typedef float __dec128 __attribute__((mode(TD)));
+    decimal128 () : __val(0.e-6176DL) {}
+    decimal128 (__dec128 x) : __val(x) {}
+    __dec128 __val;
+  };
+
+  inline decimal32 operator+ (decimal32 lhs, decimal32 rhs)
+  {
+    decimal32 tmp;
+    tmp.__val = lhs.__val + rhs.__val;
+    return tmp;
+  }
+
+  inline decimal64 operator+ (decimal64 lhs, decimal64 rhs)
+  {
+    decimal64 tmp;
+    tmp.__val = lhs.__val + rhs.__val;
+    return tmp;
+  }
+
+  inline decimal128 operator+ (decimal128 lhs, decimal128 rhs)
+  {
+    decimal128 tmp;
+    tmp.__val = lhs.__val + rhs.__val;
+    return tmp;
+  }
+
+  inline bool operator!= (decimal32 lhs, decimal32 rhs)
+  {
+    return lhs.__val != rhs.__val;
+  }
+
+  inline bool operator!= (decimal64 lhs, decimal64 rhs)
+  {
+    return lhs.__val != rhs.__val;
+  }
+
+  inline bool operator!= (decimal128 lhs, decimal128 rhs)
+  {
+    return lhs.__val != rhs.__val;
+  }
+}
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass_x.h
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass_x.h	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass_x.h	(revision 0)
@@ -0,0 +1,151 @@
+#include "compat-common.h"
+
+#define T(NAME, TYPE, INITVAL)					\
+TYPE g01##NAME, g02##NAME, g03##NAME, g04##NAME;		\
+TYPE g05##NAME, g06##NAME, g07##NAME, g08##NAME;		\
+TYPE g09##NAME, g10##NAME, g11##NAME, g12##NAME;		\
+TYPE g13##NAME, g14##NAME, g15##NAME, g16##NAME;		\
+								\
+extern void init##NAME (TYPE *p, TYPE v);			\
+extern void checkg##NAME (void);				\
+extern void							\
+test##NAME (TYPE x01, TYPE x02, TYPE x03, TYPE x04,		\
+            TYPE x05, TYPE x06, TYPE x07, TYPE x08,		\
+            TYPE x09, TYPE x10, TYPE x11, TYPE x12,		\
+            TYPE x13, TYPE x14, TYPE x15, TYPE x16);		\
+extern void testva##NAME (int n, ...);				\
+								\
+extern void							\
+check##NAME (TYPE x, TYPE v)					\
+{								\
+  if (x != v + INITVAL)						\
+    DEBUG_CHECK							\
+}								\
+								\
+extern void							\
+test2_##NAME (TYPE x01, TYPE x02, TYPE x03, TYPE x04,		\
+	      TYPE x05, TYPE x06, TYPE x07, TYPE x08)		\
+{								\
+  test##NAME (x01, g02##NAME, x02, g04##NAME,			\
+	      x03, g06##NAME, x04, g08##NAME,			\
+	      x05, g10##NAME, x06, g12##NAME,			\
+	      x07, g14##NAME, x08, g16##NAME);			\
+}								\
+								\
+extern void							\
+testit##NAME (void)						\
+{								\
+  DEBUG_FPUTS (#NAME)						\
+  DEBUG_FPUTS (" init: ")					\
+  init##NAME (&g01##NAME,  1);					\
+  init##NAME (&g02##NAME,  2);					\
+  init##NAME (&g03##NAME,  3);					\
+  init##NAME (&g04##NAME,  4);					\
+  init##NAME (&g05##NAME,  5);					\
+  init##NAME (&g06##NAME,  6);					\
+  init##NAME (&g07##NAME,  7);					\
+  init##NAME (&g08##NAME,  8);					\
+  init##NAME (&g09##NAME,  9);					\
+  init##NAME (&g10##NAME, 10);					\
+  init##NAME (&g11##NAME, 11);					\
+  init##NAME (&g12##NAME, 12);					\
+  init##NAME (&g13##NAME, 13);					\
+  init##NAME (&g14##NAME, 14);					\
+  init##NAME (&g15##NAME, 15);					\
+  init##NAME (&g16##NAME, 16);					\
+  checkg##NAME ();						\
+  DEBUG_NL							\
+  DEBUG_FPUTS (#NAME)						\
+  DEBUG_FPUTS (" test: ")					\
+  test##NAME (g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+	      g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+	      g09##NAME, g10##NAME, g11##NAME, g12##NAME,	\
+	      g13##NAME, g14##NAME, g15##NAME, g16##NAME);	\
+  DEBUG_NL							\
+  DEBUG_FPUTS (#NAME)						\
+  DEBUG_FPUTS (" testva: ")					\
+  DEBUG_NL							\
+  testva##NAME (1,						\
+		g01##NAME);					\
+  DEBUG_NL							\
+  testva##NAME (2,						\
+		g01##NAME, g02##NAME);				\
+  DEBUG_NL							\
+  testva##NAME (3,						\
+		g01##NAME, g02##NAME, g03##NAME);		\
+  DEBUG_NL							\
+  testva##NAME (4,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME);	\
+  DEBUG_NL							\
+  testva##NAME (5,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME);					\
+  DEBUG_NL							\
+  testva##NAME (6,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME);				\
+  DEBUG_NL							\
+  testva##NAME (7,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME);		\
+  DEBUG_NL							\
+  testva##NAME (8,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME);	\
+  DEBUG_NL							\
+  testva##NAME (9,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME);					\
+  DEBUG_NL							\
+  testva##NAME (10,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME);				\
+  DEBUG_NL							\
+  testva##NAME (11,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME);		\
+  DEBUG_NL							\
+  testva##NAME (12,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME, g12##NAME);	\
+  DEBUG_NL							\
+  testva##NAME (13,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME, g12##NAME,	\
+		g13##NAME);					\
+  DEBUG_NL							\
+  testva##NAME (14,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME, g12##NAME,	\
+		g13##NAME, g14##NAME);				\
+  DEBUG_NL							\
+  testva##NAME (15,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME, g12##NAME,	\
+		g13##NAME, g14##NAME, g15##NAME);		\
+  DEBUG_NL							\
+  testva##NAME (16,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME, g12##NAME,	\
+		g13##NAME, g14##NAME, g15##NAME, g16##NAME);	\
+  DEBUG_NL							\
+  DEBUG_FPUTS (#NAME)						\
+  DEBUG_FPUTS (" test2: ")					\
+  test2_##NAME (g01##NAME, g03##NAME, g05##NAME, g07##NAME,	\
+		g09##NAME, g11##NAME, g13##NAME, g15##NAME);	\
+  DEBUG_NL							\
+}
+
+T(d32, dec32, (dec32)1.5DF)
+T(d64, dec64, (dec64)2.5DD)
+T(d128, dec128, (dec128)3.5DL)
+
+#undef T
Index: gcc/testsuite/g++.dg/compat/decimal/pass_y.h
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass_y.h	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass_y.h	(revision 0)
@@ -0,0 +1,89 @@
+#include <stdarg.h>
+
+#include "compat-common.h"
+
+#ifdef SKIP_VA
+const int test_va = 0;
+#else
+const int test_va = 1;
+#endif
+
+#define T(NAME, TYPE, INITVAL)					\
+extern TYPE g01##NAME, g02##NAME, g03##NAME, g04##NAME;		\
+extern TYPE g05##NAME, g06##NAME, g07##NAME, g08##NAME;		\
+extern TYPE g09##NAME, g10##NAME, g11##NAME, g12##NAME;		\
+extern TYPE g13##NAME, g14##NAME, g15##NAME, g16##NAME;		\
+								\
+extern void check##NAME (TYPE x, TYPE v);			\
+								\
+extern void							\
+init##NAME (TYPE *p, TYPE v)					\
+{								\
+  *p = v + INITVAL;						\
+}								\
+								\
+extern void							\
+checkg##NAME (void)						\
+{								\
+  check##NAME (g01##NAME,  1);					\
+  check##NAME (g02##NAME,  2);					\
+  check##NAME (g03##NAME,  3);					\
+  check##NAME (g04##NAME,  4);					\
+  check##NAME (g05##NAME,  5);					\
+  check##NAME (g06##NAME,  6);					\
+  check##NAME (g07##NAME,  7);					\
+  check##NAME (g08##NAME,  8);					\
+  check##NAME (g09##NAME,  9);					\
+  check##NAME (g10##NAME, 10);					\
+  check##NAME (g11##NAME, 11);					\
+  check##NAME (g12##NAME, 12);					\
+  check##NAME (g13##NAME, 13);					\
+  check##NAME (g14##NAME, 14);					\
+  check##NAME (g15##NAME, 15);					\
+  check##NAME (g16##NAME, 16);					\
+}								\
+								\
+extern void							\
+test##NAME (TYPE x01, TYPE x02, TYPE x03, TYPE x04,		\
+            TYPE x05, TYPE x06, TYPE x07, TYPE x08,		\
+            TYPE x09, TYPE x10, TYPE x11, TYPE x12,		\
+            TYPE x13, TYPE x14, TYPE x15, TYPE x16)		\
+{								\
+  check##NAME (x01,  1);					\
+  check##NAME (x02,  2);					\
+  check##NAME (x03,  3);					\
+  check##NAME (x04,  4);					\
+  check##NAME (x05,  5);					\
+  check##NAME (x06,  6);					\
+  check##NAME (x07,  7);					\
+  check##NAME (x08,  8);					\
+  check##NAME (x09,  9);					\
+  check##NAME (x10, 10);					\
+  check##NAME (x11, 11);					\
+  check##NAME (x12, 12);					\
+  check##NAME (x13, 13);					\
+  check##NAME (x14, 14);					\
+  check##NAME (x15, 15);					\
+  check##NAME (x16, 16);					\
+}								\
+								\
+extern void							\
+testva##NAME (int n, ...)					\
+{								\
+  int i;							\
+  va_list ap;							\
+  if (test_va)							\
+    {								\
+      va_start (ap, n);						\
+      for (i = 0; i < n; i++)					\
+	{							\
+	  TYPE t = va_arg (ap, TYPE);				\
+	  check##NAME (t, i+1);					\
+	}							\
+      va_end (ap);						\
+    }								\
+}
+
+T(d32, dec32, (dec32)1.5DF)
+T(d64, dec64, (dec64)2.5DD)
+T(d128, dec128, (dec128)3.5DL)
Index: gcc/testsuite/g++.dg/compat/decimal/pass-1_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-1_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-1_main.C	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test passing decimal scalars by value.  */
+
+extern void pass_1_x (void);
+int fails;
+
+int
+main ()
+{
+  pass_1_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-1_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-1_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-1_x.C	(revision 0)
@@ -0,0 +1,30 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "pass_x.h"
+
+void
+pass_1_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+#ifndef SKIP_DECIMAL32
+T(d32)
+#endif
+#ifndef SKIP_DECIMAL64
+T(d64)
+#endif
+#ifndef SKIP_DECIMAL128
+T(d128)
+#endif
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-1_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-1_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-1_y.C	(revision 0)
@@ -0,0 +1,5 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "pass_y.h"
Index: gcc/testsuite/g++.dg/compat/decimal/pass-2_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-2_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-2_main.C	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test passing decimal classes by value.  */
+
+extern void pass_2_x (void);
+int fails;
+
+int
+main ()
+{
+  pass_2_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-2_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-2_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-2_x.C	(revision 0)
@@ -0,0 +1,32 @@
+#include "decimal-dummy.h"
+
+#define dec32 std::decimal::decimal32
+#define dec64 std::decimal::decimal64
+#define dec128 std::decimal::decimal128
+
+#include "pass_x.h"
+
+void
+pass_2_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+#ifndef SKIP_DECIMAL32
+T(d32)
+#endif
+#ifndef SKIP_DECIMAL64
+T(d64)
+#endif
+#ifndef SKIP_DECIMAL128
+T(d128)
+#endif
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-2_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-2_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-2_y.C	(revision 0)
@@ -0,0 +1,7 @@
+#include "decimal-dummy.h"
+
+#define dec32 std::decimal::decimal32
+#define dec64 std::decimal::decimal64
+#define dec128 std::decimal::decimal128
+
+#include "pass_y.h"
Index: gcc/testsuite/g++.dg/compat/decimal/pass-3_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-3_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-3_main.C	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test passing decimal scalars and classes by value.  */
+
+extern void pass_3_x (void);
+int fails;
+
+int
+main ()
+{
+  pass_3_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-3_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-3_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-3_x.C	(revision 0)
@@ -0,0 +1,30 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "pass_x.h"
+
+void
+pass_3_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+#ifndef SKIP_DECIMAL32
+T(d32)
+#endif
+#ifndef SKIP_DECIMAL64
+T(d64)
+#endif
+#ifndef SKIP_DECIMAL128
+T(d128)
+#endif
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-3_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-3_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-3_y.C	(revision 0)
@@ -0,0 +1,7 @@
+#include "decimal-dummy.h"
+
+#define dec32 std::decimal::decimal32
+#define dec64 std::decimal::decimal64
+#define dec128 std::decimal::decimal128
+
+#include "pass_y.h"
Index: gcc/testsuite/g++.dg/compat/decimal/pass-4_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-4_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-4_main.C	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test passing decimal classes and scalars by value.  */
+
+extern void pass_4_x (void);
+int fails;
+
+int
+main ()
+{
+  pass_4_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-4_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-4_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-4_x.C	(revision 0)
@@ -0,0 +1,32 @@
+#include "decimal-dummy.h"
+
+#define dec32 std::decimal::decimal32
+#define dec64 std::decimal::decimal64
+#define dec128 std::decimal::decimal128
+
+#include "pass_x.h"
+
+void
+pass_4_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+#ifndef SKIP_DECIMAL32
+T(d32)
+#endif
+#ifndef SKIP_DECIMAL64
+T(d64)
+#endif
+#ifndef SKIP_DECIMAL128
+T(d128)
+#endif
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-4_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-4_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-4_y.C	(revision 0)
@@ -0,0 +1,5 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "pass_y.h"
Index: gcc/testsuite/g++.dg/compat/decimal/pass-5_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-5_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-5_main.C	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test passing decimal scalars and typedef'd classes by value.  */
+
+extern void pass_5_x (void);
+int fails;
+
+int
+main ()
+{
+  pass_5_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-5_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-5_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-5_x.C	(revision 0)
@@ -0,0 +1,30 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "pass_x.h"
+
+void
+pass_5_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+#ifndef SKIP_DECIMAL32
+T(d32)
+#endif
+#ifndef SKIP_DECIMAL64
+T(d64)
+#endif
+#ifndef SKIP_DECIMAL128
+T(d128)
+#endif
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-5_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-5_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-5_y.C	(revision 0)
@@ -0,0 +1,7 @@
+#include "decimal-dummy.h"
+
+typedef std::decimal::decimal32 dec32;
+typedef std::decimal::decimal64 dec64;
+typedef std::decimal::decimal128 dec128;
+
+#include "pass_y.h"
Index: gcc/testsuite/g++.dg/compat/decimal/pass-6_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-6_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-6_main.C	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test passing typedef'd decimal classes and scalars by value.  */
+
+extern void pass_6_x (void);
+int fails;
+
+int
+main ()
+{
+  pass_6_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-6_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-6_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-6_x.C	(revision 0)
@@ -0,0 +1,32 @@
+#include "decimal-dummy.h"
+
+typedef std::decimal::decimal32 dec32;
+typedef std::decimal::decimal64 dec64;
+typedef std::decimal::decimal128 dec128;
+
+#include "pass_x.h"
+
+void
+pass_6_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+#ifndef SKIP_DECIMAL32
+T(d32)
+#endif
+#ifndef SKIP_DECIMAL64
+T(d64)
+#endif
+#ifndef SKIP_DECIMAL128
+T(d128)
+#endif
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/pass-6_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/pass-6_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/pass-6_y.C	(revision 0)
@@ -0,0 +1,5 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "pass_y.h"
Index: gcc/testsuite/g++.dg/compat/decimal/return_x.h
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return_x.h	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return_x.h	(revision 0)
@@ -0,0 +1,90 @@
+#include "compat-common.h"
+
+#ifdef SKIP_VA
+const int test_va = 0;
+#else
+const int test_va = 1;
+#endif
+
+#define T(NAME, TYPE, INITVAL) 					\
+TYPE g01##NAME, g02##NAME, g03##NAME, g04##NAME;		\
+TYPE g05##NAME, g06##NAME, g07##NAME, g08##NAME;		\
+TYPE g09##NAME, g10##NAME, g11##NAME, g12##NAME;		\
+TYPE g13##NAME, g14##NAME, g15##NAME, g16##NAME;		\
+								\
+extern void init##NAME (TYPE *p, TYPE v);			\
+extern void checkg##NAME (void);				\
+extern TYPE test0##NAME (void);					\
+extern TYPE test1##NAME (TYPE);					\
+extern TYPE testva##NAME (int n, ...);				\
+								\
+extern void							\
+check##NAME (TYPE x, TYPE v)					\
+{								\
+  if (x != v)							\
+    DEBUG_CHECK							\
+}								\
+								\
+extern void							\
+testit##NAME (void)						\
+{								\
+  TYPE rslt;							\
+  DEBUG_FPUTS (#NAME)						\
+  DEBUG_FPUTS (" init: ")					\
+  init##NAME (&g01##NAME,  1);					\
+  init##NAME (&g02##NAME,  2);					\
+  init##NAME (&g03##NAME,  3);					\
+  init##NAME (&g04##NAME,  4);					\
+  init##NAME (&g05##NAME,  5);					\
+  init##NAME (&g06##NAME,  6);					\
+  init##NAME (&g07##NAME,  7);					\
+  init##NAME (&g08##NAME,  8);					\
+  init##NAME (&g09##NAME,  9);					\
+  init##NAME (&g10##NAME, 10);					\
+  init##NAME (&g11##NAME, 11);					\
+  init##NAME (&g12##NAME, 12);					\
+  init##NAME (&g13##NAME, 13);					\
+  init##NAME (&g14##NAME, 14);					\
+  init##NAME (&g15##NAME, 15);					\
+  init##NAME (&g16##NAME, 16);					\
+  checkg##NAME ();						\
+  DEBUG_NL							\
+  DEBUG_FPUTS (#NAME)						\
+  DEBUG_FPUTS (" test0: ")					\
+  rslt = test0##NAME ();					\
+  check##NAME (rslt, g01##NAME);				\
+  DEBUG_NL							\
+  DEBUG_FPUTS (#NAME)						\
+  DEBUG_FPUTS (" test1: ")					\
+  rslt = test1##NAME (g01##NAME);				\
+  check##NAME (rslt, g01##NAME);				\
+  if (test_va)							\
+    {								\
+      DEBUG_NL							\
+      DEBUG_FPUTS (#NAME)					\
+      DEBUG_FPUTS (" testva: ")					\
+      rslt = testva##NAME (1, g01##NAME);			\
+      check##NAME (rslt, g01##NAME);				\
+      rslt = testva##NAME (5, g01##NAME, g02##NAME, g03##NAME,	\
+			   g04##NAME, g05##NAME);		\
+      check##NAME (rslt, g05##NAME);				\
+      rslt = testva##NAME (9, g01##NAME, g02##NAME, g03##NAME,	\
+			   g04##NAME, g05##NAME, g06##NAME,	\
+			   g07##NAME, g08##NAME, g09##NAME);	\
+      check##NAME (rslt, g09##NAME);				\
+      rslt = testva##NAME (16, g01##NAME, g02##NAME, g03##NAME,	\
+			   g04##NAME, g05##NAME, g06##NAME,	\
+			   g07##NAME, g08##NAME, g09##NAME,	\
+			   g10##NAME, g11##NAME, g12##NAME,	\
+			   g13##NAME, g14##NAME, g15##NAME,	\
+			   g16##NAME);				\
+      check##NAME (rslt, g16##NAME);				\
+    }								\
+  DEBUG_NL							\
+}
+
+T(d32, dec32, (dec32)1.5DF);
+T(d64, dec64, (dec64)2.5DD);
+T(d128, dec128, (dec128)3.5DL);
+
+#undef T
Index: gcc/testsuite/g++.dg/compat/decimal/return_y.h
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return_y.h	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return_y.h	(revision 0)
@@ -0,0 +1,67 @@
+#include <stdarg.h>
+
+#include "compat-common.h"
+
+#define T(NAME, TYPE, INITVAL)					\
+extern TYPE g01##NAME, g02##NAME, g03##NAME, g04##NAME;		\
+extern TYPE g05##NAME, g06##NAME, g07##NAME, g08##NAME;		\
+extern TYPE g09##NAME, g10##NAME, g11##NAME, g12##NAME;		\
+extern TYPE g13##NAME, g14##NAME, g15##NAME, g16##NAME;		\
+								\
+extern void check##NAME (TYPE x, TYPE v);			\
+								\
+extern void							\
+init##NAME (TYPE *p, TYPE v)					\
+{								\
+  *p = v + INITVAL;						\
+}								\
+								\
+extern void							\
+checkg##NAME (void)						\
+{								\
+  check##NAME (g01##NAME,  1+INITVAL);				\
+  check##NAME (g02##NAME,  2+INITVAL);				\
+  check##NAME (g03##NAME,  3+INITVAL);				\
+  check##NAME (g04##NAME,  4+INITVAL);				\
+  check##NAME (g05##NAME,  5+INITVAL);				\
+  check##NAME (g06##NAME,  6+INITVAL);				\
+  check##NAME (g07##NAME,  7+INITVAL);				\
+  check##NAME (g08##NAME,  8+INITVAL);				\
+  check##NAME (g09##NAME,  9+INITVAL);				\
+  check##NAME (g10##NAME, 10+INITVAL);				\
+  check##NAME (g11##NAME, 11+INITVAL);				\
+  check##NAME (g12##NAME, 12+INITVAL);				\
+  check##NAME (g13##NAME, 13+INITVAL);				\
+  check##NAME (g14##NAME, 14+INITVAL);				\
+  check##NAME (g15##NAME, 15+INITVAL);				\
+  check##NAME (g16##NAME, 16+INITVAL);				\
+}								\
+								\
+extern TYPE							\
+test0##NAME (void)						\
+{								\
+  return g01##NAME;						\
+}								\
+								\
+extern TYPE							\
+test1##NAME (TYPE x01)						\
+{								\
+  return x01;							\
+}								\
+								\
+extern TYPE							\
+testva##NAME (int n, ...)					\
+{								\
+  int i;							\
+  TYPE rslt;							\
+  va_list ap;							\
+  va_start (ap, n);						\
+  for (i = 0; i < n; i++)					\
+    rslt = va_arg (ap, TYPE);					\
+  va_end (ap);							\
+  return rslt;							\
+}
+
+T(d32, dec32, (dec32)1.5)
+T(d64, dec64, (dec64)2.5)
+T(d128, dec128, (dec128)3.5)
Index: gcc/testsuite/g++.dg/compat/decimal/return-1_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-1_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-1_main.C	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test function return values for decimal float scalars.  */
+
+extern void return_1_x (void);
+int fails;
+
+int
+main ()
+{
+  return_1_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-1_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-1_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-1_x.C	(revision 0)
@@ -0,0 +1,24 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "return_x.h"
+
+void
+return_1_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+T(d32)
+T(d64)
+T(d128)
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-1_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-1_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-1_y.C	(revision 0)
@@ -0,0 +1,5 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "return_y.h"
Index: gcc/testsuite/g++.dg/compat/decimal/return-2_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-2_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-2_main.C	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test function return values for decimal classes.  */
+
+extern void return_2_x (void);
+int fails;
+
+int
+main ()
+{
+  return_2_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-2_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-2_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-2_x.C	(revision 0)
@@ -0,0 +1,26 @@
+#include "decimal-dummy.h"
+
+#define dec32 std::decimal::decimal32
+#define dec64 std::decimal::decimal64
+#define dec128 std::decimal::decimal128
+
+#include "return_x.h"
+
+void
+return_2_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+T(d32)
+T(d64)
+T(d128)
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-2_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-2_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-2_y.C	(revision 0)
@@ -0,0 +1,7 @@
+#include "decimal-dummy.h"
+
+#define dec32 std::decimal::decimal32
+#define dec64 std::decimal::decimal64
+#define dec128 std::decimal::decimal128
+
+#include "return_y.h"
Index: gcc/testsuite/g++.dg/compat/decimal/return-3_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-3_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-3_main.C	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test function return values for decimal float scalars and classes.  */
+
+extern void return_3_x (void);
+int fails;
+
+int
+main ()
+{
+  return_3_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-3_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-3_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-3_x.C	(revision 0)
@@ -0,0 +1,24 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "return_x.h"
+
+void
+return_3_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+T(d32)
+T(d64)
+T(d128)
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-3_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-3_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-3_y.C	(revision 0)
@@ -0,0 +1,7 @@
+#include "decimal-dummy.h"
+
+#define dec32 std::decimal::decimal32
+#define dec64 std::decimal::decimal64
+#define dec128 std::decimal::decimal128
+
+#include "return_y.h"
Index: gcc/testsuite/g++.dg/compat/decimal/return-4_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-4_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-4_main.C	(revision 0)
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test function return values for decimal float classes and scalars.  */
+
+extern void return_4_x (void);
+int fails;
+
+int
+main ()
+{
+  return_4_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-4_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-4_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-4_x.C	(revision 0)
@@ -0,0 +1,26 @@
+#include "decimal-dummy.h"
+
+#define dec32 std::decimal::decimal32
+#define dec64 std::decimal::decimal64
+#define dec128 std::decimal::decimal128
+
+#include "return_x.h"
+
+void
+return_4_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+T(d32)
+T(d64)
+T(d128)
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-4_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-4_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-4_y.C	(revision 0)
@@ -0,0 +1,5 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "return_y.h"
Index: gcc/testsuite/g++.dg/compat/decimal/return-5_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-5_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-5_main.C	(revision 0)
@@ -0,0 +1,14 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test function return values for decimal float scalars and typedef'd
+   classes.  */
+
+extern void return_5_x (void);
+int fails;
+
+int
+main ()
+{
+  return_5_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-5_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-5_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-5_x.C	(revision 0)
@@ -0,0 +1,24 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "return_x.h"
+
+void
+return_5_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+T(d32)
+T(d64)
+T(d128)
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-5_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-5_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-5_y.C	(revision 0)
@@ -0,0 +1,7 @@
+#include "decimal-dummy.h"
+
+typedef std::decimal::decimal32 dec32;
+typedef std::decimal::decimal64 dec64;
+typedef std::decimal::decimal128 dec128;
+
+#include "return_y.h"
Index: gcc/testsuite/g++.dg/compat/decimal/return-6_main.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-6_main.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-6_main.C	(revision 0)
@@ -0,0 +1,14 @@
+/* { dg-require-effective-target dfp } */
+
+/* Test function return values for typedef'd decimal float classes
+   and scalars.  */
+
+extern void return_6_x (void);
+int fails;
+
+int
+main ()
+{
+  return_6_x ();
+  return 0;
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-6_x.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-6_x.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-6_x.C	(revision 0)
@@ -0,0 +1,26 @@
+#include "decimal-dummy.h"
+
+typedef std::decimal::decimal32 dec32;
+typedef std::decimal::decimal64 dec64;
+typedef std::decimal::decimal128 dec128;
+
+#include "return_x.h"
+
+void
+return_6_x (void)
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+T(d32)
+T(d64)
+T(d128)
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc/testsuite/g++.dg/compat/decimal/return-6_y.C
===================================================================
--- gcc/testsuite/g++.dg/compat/decimal/return-6_y.C	(revision 0)
+++ gcc/testsuite/g++.dg/compat/decimal/return-6_y.C	(revision 0)
@@ -0,0 +1,5 @@
+typedef float dec32 __attribute__((mode(SD)));
+typedef float dec64 __attribute__((mode(DD)));
+typedef float dec128 __attribute__((mode(TD)));
+
+#include "return_y.h"


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] pass C++ decimal classes same as scalars
  2009-11-24  0:23 [PATCH] pass C++ decimal classes same as scalars Janis Johnson
@ 2009-11-25 10:35 ` Paolo Bonzini
  2009-11-30 21:45   ` Janis Johnson
  2010-01-14  1:51 ` Jason Merrill
  2010-01-28  8:28 ` H.J. Lu
  2 siblings, 1 reply; 6+ messages in thread
From: Paolo Bonzini @ 2009-11-25 10:35 UTC (permalink / raw)
  To: gcc-patches

On 11/24/2009 12:34 AM, Janis Johnson wrote:
> +  /* If a record should be passed the same as its first (and only) member
> +     don't pass it as an aggregate.  */
> +  if (TREE_CODE (type) == RECORD_TYPE && TYPE_PASS_AS_TRANSPARENT (type))
> +    return 0;
> +

Wouldn't that be "return aggregate_value_p (TYPE_FIELDS (type));" instead?

Paolo

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] pass C++ decimal classes same as scalars
  2009-11-25 10:35 ` Paolo Bonzini
@ 2009-11-30 21:45   ` Janis Johnson
  2009-12-01 19:22     ` Janis Johnson
  0 siblings, 1 reply; 6+ messages in thread
From: Janis Johnson @ 2009-11-30 21:45 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: gcc-patches

On Wed, 2009-11-25 at 10:11 +0100, Paolo Bonzini wrote:
> On 11/24/2009 12:34 AM, Janis Johnson wrote:
> > +  /* If a record should be passed the same as its first (and only) member
> > +     don't pass it as an aggregate.  */
> > +  if (TREE_CODE (type) == RECORD_TYPE && TYPE_PASS_AS_TRANSPARENT (type))
> > +    return 0;
> > +
> 
> Wouldn't that be "return aggregate_value_p (TYPE_FIELDS (type));" instead?

That makes sense, I'm testing it now.

Janis

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] pass C++ decimal classes same as scalars
  2009-11-30 21:45   ` Janis Johnson
@ 2009-12-01 19:22     ` Janis Johnson
  0 siblings, 0 replies; 6+ messages in thread
From: Janis Johnson @ 2009-12-01 19:22 UTC (permalink / raw)
  To: jason; +Cc: gcc-patches, bonzini

On Mon, 2009-11-30 at 13:28 -0800, Janis Johnson wrote:
> On Wed, 2009-11-25 at 10:11 +0100, Paolo Bonzini wrote:
> > On 11/24/2009 12:34 AM, Janis Johnson wrote:
> > > +  /* If a record should be passed the same as its first (and only) member
> > > +     don't pass it as an aggregate.  */
> > > +  if (TREE_CODE (type) == RECORD_TYPE && TYPE_PASS_AS_TRANSPARENT (type))
> > > +    return 0;
> > > +
> > 
> > Wouldn't that be "return aggregate_value_p (TYPE_FIELDS (type));" instead?
> 
> That makes sense, I'm testing it now.

Jason, is this patch OK for trunk?  Testing completed for the patch at
http://gcc.gnu.org/ml/gcc-patches/2009-11/msg01321.html plus Paolo's
suggestion for "return aggregate_value_p (TYPE_FIELDS (type), fntype);".

Janis

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] pass C++ decimal classes same as scalars
  2009-11-24  0:23 [PATCH] pass C++ decimal classes same as scalars Janis Johnson
  2009-11-25 10:35 ` Paolo Bonzini
@ 2010-01-14  1:51 ` Jason Merrill
  2010-01-28  8:28 ` H.J. Lu
  2 siblings, 0 replies; 6+ messages in thread
From: Jason Merrill @ 2010-01-14  1:51 UTC (permalink / raw)
  To: janis187; +Cc: gcc-patches

On 11/23/2009 06:34 PM, Janis Johnson wrote:
> 	* tree.h (TYPE_TRANSPARENT_UNION): Replace with ...
> 	(TYPE_PASS_AS_TRANSPARENT): this, for union and record.

Maybe "TYPE_TRANSPARENT_AGGR"?  And change the field name as well.

> +  /* If a record should be passed the same as its first (and only) member
> +     don't pass it as an aggregate.  */
> +  if (TREE_CODE (type) == RECORD_TYPE&&  TYPE_PASS_AS_TRANSPARENT (type))
> +    return 0;

What if its field is itself an aggregate?  Unlikely, but we might as 
well recurse.

> +  /* According to the C++ ABI, some library classes are passed the
> +     same as the scalar type of their single member and use the same
> +     mangling.  */
> +  if (TREE_CODE (type) == RECORD_TYPE&&  TYPE_PASS_AS_TRANSPARENT (type))
> +    type = TREE_TYPE (TYPE_FIELDS (type));

I'm nervous about assuming that the first element of TYPE_FIELDS is a 
FIELD_DECL (rather than TYPE_DECL or VAR_DECL), though I know calls.c 
does the same thing.  Maybe add a function get_first_field?

> +  /* According to the C++ ABI, decimal classes defined in ISO/IEC TR 24733
> +     are passed the same as decimal scalar types.  */
> +  if (TREE_CODE (t) == RECORD_TYPE)
> +    {
> +      const char *n = type_as_string (t, TFF_CLASS_KEY_OR_ENUM);
> +      if ((strcmp (n, "class std::decimal::decimal32") == 0)
> +	  || (strcmp (n, "class std::decimal::decimal64") == 0)
> +	  || (strcmp (n, "class std::decimal::decimal128") == 0))
> +	TYPE_PASS_AS_TRANSPARENT (t) = 1;
> +    }

Relying on the formatting from type_as_string seems a bit fragile, 
though I suppose in this case it's unlikely to change.

Jason

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] pass C++ decimal classes same as scalars
  2009-11-24  0:23 [PATCH] pass C++ decimal classes same as scalars Janis Johnson
  2009-11-25 10:35 ` Paolo Bonzini
  2010-01-14  1:51 ` Jason Merrill
@ 2010-01-28  8:28 ` H.J. Lu
  2 siblings, 0 replies; 6+ messages in thread
From: H.J. Lu @ 2010-01-28  8:28 UTC (permalink / raw)
  To: janis187; +Cc: gcc-patches, jason

On Mon, Nov 23, 2009 at 3:34 PM, Janis Johnson <janis187@us.ibm.com> wrote:
> This patch causes G++ to pass std::decimal::decimal32/64/128 the same
> as their corresponding scalar types; a longer rationale is in:
>
>  http://gcc.gnu.org/ml/gcc-patches/2009-10/msg00866.html
>
> Jason said here:
>
>  http://gcc.gnu.org/ml/gcc-patches/2009-11/msg00110.html
>
> that the original patch looks good except for a change that I've made
> to the new one, to use a single macro for both the old
> TYPE_TRANSPARENT_UNION and the new use for record types that are
> passed the same as the single scalar member.  I call the new macro
> TYPE_PASS_AS_TRANSPARENT but am certainly open to suggestions.  Jason
> also said he'd like this change in 4.5.
>
> Tested on powerpc64-linux for -m32/-m64.  OK for trunk after the
> C++ ABI patch is accepted?  I pinged that last week but so far Jason
> is the only one who has commented on it.
>
> 2009-11-23  Janis Johnson  <janis187@us.ibm.com>
>
>        * tree.h (TYPE_TRANSPARENT_UNION): Replace with ...
>        (TYPE_PASS_AS_TRANSPARENT): this, for union and record.
>        * calls.c (initialize argument_information): Handle it.
>        * c-common.c (handle_transparent_union_attribute): Use new name.
>        * c-decl.c (finish_struct): Ditto.
>        * c-typeck.c (type_lists_compatible_p): Ditto.
>        (convert_for_assignment): Use new name and also handle record.
>        * function.c (aggregate_value_p): Handle it.
>        (pass_by_reference): Ditto.
>        (assign_parm_data_types): Ditto.
>        * print-tree.c (print_node): Ditto.
>        * lto-streamer-in.c (unpack_ts_type_value_fields): Ditto.
>        * lto-streamer-out.c (pack_ts_type_value_fields): Ditto.
>
> gcc/cp/
>        * mangle.c (write_type): Mangle transparent record as member type.
>        * semantics.c (begin_class_definition): Recognize decimal classes
>        and set TYPE__ASS_AS_TRANSPARENT.
>
> gcc/testsuite/
>        * g++.dg/compat/decimal/compat-common.h: New file.
>        * g++.dg/compat/decimal/decimal-dummy.h: New file.
>        * g++.dg/compat/decimal/pass_x.h: New file.
>        * g++.dg/compat/decimal/pass_y.h: New file.
>        * g++.dg/compat/decimal/pass-1_main.C: New file.
>        * g++.dg/compat/decimal/pass-1_x.C: New file.
>        * g++.dg/compat/decimal/pass-1_y.C: New file.
>        * g++.dg/compat/decimal/pass-2_main.C: New file.
>        * g++.dg/compat/decimal/pass-2_x.C: New file.
>        * g++.dg/compat/decimal/pass-2_y.C: New file.
>        * g++.dg/compat/decimal/pass-3_main.C: New file.
>        * g++.dg/compat/decimal/pass-3_x.C: New file.
>        * g++.dg/compat/decimal/pass-3_y.C: New file.
>        * g++.dg/compat/decimal/pass-4_main.C: New file.
>        * g++.dg/compat/decimal/pass-4_x.C: New file.
>        * g++.dg/compat/decimal/pass-4_y.C: New file.
>        * g++.dg/compat/decimal/pass-5_main.C: New file.
>        * g++.dg/compat/decimal/pass-5_x.C: New file.
>        * g++.dg/compat/decimal/pass-5_y.C: New file.
>        * g++.dg/compat/decimal/pass-6_main.C: New file.
>        * g++.dg/compat/decimal/pass-6_x.C: New file.
>        * g++.dg/compat/decimal/pass-6_y.C: New file.
>        * g++.dg/compat/decimal/return_x.h: New file.
>        * g++.dg/compat/decimal/return_y.h: New file.
>        * g++.dg/compat/decimal/return-1_main.C: New file.
>        * g++.dg/compat/decimal/return-1_x.C: New file.
>        * g++.dg/compat/decimal/return-1_y.C: New file.
>        * g++.dg/compat/decimal/return-2_main.C: New file.
>        * g++.dg/compat/decimal/return-2_x.C: New file.
>        * g++.dg/compat/decimal/return-2_y.C: New file.
>        * g++.dg/compat/decimal/return-3_main.C: New file.
>        * g++.dg/compat/decimal/return-3_x.C: New file.
>        * g++.dg/compat/decimal/return-3_y.C: New file.
>        * g++.dg/compat/decimal/return-4_main.C: New file.
>        * g++.dg/compat/decimal/return-4_x.C: New file.
>        * g++.dg/compat/decimal/return-4_y.C: New file.
>        * g++.dg/compat/decimal/return-5_main.C: New file.
>        * g++.dg/compat/decimal/return-5_x.C: New file.
>        * g++.dg/compat/decimal/return-5_y.C: New file.
>        * g++.dg/compat/decimal/return-6_main.C: New file.
>        * g++.dg/compat/decimal/return-6_x.C: New file.
>        * g++.dg/compat/decimal/return-6_y.C: New file.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42880

-- 
H.J.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-01-28  6:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-24  0:23 [PATCH] pass C++ decimal classes same as scalars Janis Johnson
2009-11-25 10:35 ` Paolo Bonzini
2009-11-30 21:45   ` Janis Johnson
2009-12-01 19:22     ` Janis Johnson
2010-01-14  1:51 ` Jason Merrill
2010-01-28  8:28 ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).