[PATCH] fix c++/46862, ICE with non-standard def for decimal class
Janis Johnson
janis.marie.johnson@gmail.com
Thu Dec 16 01:46:00 GMT 2010
This patch fixes PR c++/46862.
The C++ ABI requires that classes decimal32, decimal64, and decimal128
from namespace std::decimal be passed the same as the corresponding
scalar types in C. The classes are defined in the libstdc++ header
files, but the C++ compiler needs to know about them in order to pass
decimal class arguments as scalars. To do that it uses a tree flag
TYPE_TRANSPARENT_AGGR.
Currently the decimal classes are recognized and the flag is set in
begin_class_definition, before the contents of the class are known.
This patch moves the code to recognize them to layout_class_type, when
the compiler can also verify that the class has a first non-static data
member and that the field is a decimal float scalar. If it isn't then a
warning is issued with -Wabi and the TYPE_TRANSPARENT_AGGR flag is not
set, avoiding an ICE if, as in the testcase from the PR, there is no
member to dereference.
Tested on i686-pc-linux-gnu with c,c++ bootstrap and testsuite.
OK for trunk?
Janis
-------------- next part --------------
2010-12-15 Janis Johnson <janis.marie.johnson@gmail.com>
gcc/cp/
PR c++/46862
* semantics.c (begin_class_definition): Move code to recognize
a standard decimal class and mark it to be passed as the
associated decimal scalar from here ...
* class.c (layout_class_type): ... to here, and warn if it cannot
be passed as required by the C++ ABI.
gcc/testsuite/
PR c++/46862
* g++.dg/abi/pr46862.C: New test.
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c (revision 167809)
+++ gcc/cp/semantics.c (working copy)
@@ -2382,25 +2382,6 @@ begin_class_definition (tree t, tree att
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
- && !processing_template_decl)
- {
- tree ns = TYPE_CONTEXT (t);
- if (ns && TREE_CODE (ns) == NAMESPACE_DECL
- && DECL_CONTEXT (ns) == std_node
- && DECL_NAME (ns)
- && !strcmp (IDENTIFIER_POINTER (DECL_NAME (ns)), "decimal"))
- {
- const char *n = TYPE_NAME_STRING (t);
- if ((strcmp (n, "decimal32") == 0)
- || (strcmp (n, "decimal64") == 0)
- || (strcmp (n, "decimal128") == 0))
- TYPE_TRANSPARENT_AGGR (t) = 1;
- }
- }
-
/* A non-implicit typename comes from code like:
template <typename T> struct A {
Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c (revision 167809)
+++ gcc/cp/class.c (working copy)
@@ -5322,6 +5322,44 @@ layout_class_type (tree t, tree *virtual
last_field_was_bitfield = DECL_C_BIT_FIELD (field);
}
+ /* The C++ ABI requires that the decimal classes in std::decimal, as
+ defined in ISO/IEC TR 24733, be passed the same as the corresponding
+ decimal float scalar types. */
+ if (!processing_template_decl)
+ {
+ tree ns = TYPE_CONTEXT (t);
+ if (ns && TREE_CODE (ns) == NAMESPACE_DECL
+ && DECL_CONTEXT (ns) == std_node
+ && DECL_NAME (ns)
+ && !strcmp (IDENTIFIER_POINTER (DECL_NAME (ns)), "decimal"))
+ {
+ const char *n = TYPE_NAME_STRING (t);
+ if ((strcmp (n, "decimal64") == 0)
+ || (strcmp (n, "decimal32") == 0)
+ || (strcmp (n, "decimal128") == 0))
+ {
+ tree first_field = NULL;
+
+ /* Find the first non-static data member, if there is one. */
+ field = non_static_data_members;
+ while (field && first_field == NULL)
+ {
+ if (TREE_CODE (field) == FIELD_DECL)
+ first_field = field;
+ field = DECL_CHAIN (field);
+ }
+
+ if (first_field && (DECIMAL_FLOAT_MODE_P (TYPE_MODE (
+ TREE_TYPE (first_field)))))
+ TYPE_TRANSPARENT_AGGR (t) = 1;
+ else
+ warning (OPT_Wabi,
+ "class %qT cannot be passed as corresponding "
+ "scalar and is not ABI-compliant", t);
+ }
+ }
+ }
+
if (abi_version_at_least (2) && !integer_zerop (rli->bitpos))
{
/* Make sure that we are on a byte boundary so that the size of
Index: gcc/testsuite/g++.dg/abi/pr46862.C
===================================================================
--- gcc/testsuite/g++.dg/abi/pr46862.C (revision 0)
+++ gcc/testsuite/g++.dg/abi/pr46862.C (revision 0)
@@ -0,0 +1,32 @@
+// { dg-do compile }
+// { dg-options "-Wabi" }
+
+// This test does NOT depend on support for decimal float types.
+
+int foo ();
+static __typeof (foo) bar __attribute__ ((__weakref__ ("foo")));
+namespace std
+{
+ namespace decimal
+ {
+ class decimal32;
+ template <class> struct S { };
+ template <> struct S <decimal32> { static const bool value = true; };
+ template <class> class T { };
+ class decimal32 : public T <decimal32> { }; // { dg-warning "corresponding scalar" }
+ }
+}
+
+namespace std
+{
+ namespace decimal
+ {
+ class decimal64 { // { dg-warning "corresponding scalar" }
+ private:
+ double x;
+ };
+
+ class decimal128 { // { dg-warning "corresponding scalar" }
+ };
+ }
+}
More information about the Gcc-patches
mailing list