The DFP classes are treated as transparent aggregates, so they get
mangled and passed like their first field. In the testcase it is
defined to have a base class, so the first field is an artificial base
field, which doesn't make any sense.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit a32242269caefe41d24777d21920775b464ba938
Author: Jason Merrill <ja...@redhat.com>
Date: Mon Aug 29 10:55:05 2011 -0400
PR c++/50207
* class.c (finish_struct_1): Complain if the first field is
artificial.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 89063ca..ca0529d 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5796,10 +5796,25 @@ finish_struct_1 (tree t)
/* Finish debugging output for this type. */
rest_of_type_compilation (t, ! LOCAL_CLASS_P (t));
- if (TYPE_TRANSPARENT_AGGR (t) && first_field (t) == NULL_TREE)
+ if (TYPE_TRANSPARENT_AGGR (t))
{
- error ("type transparent class %qT does not have any fields", t);
- TYPE_TRANSPARENT_AGGR (t) = 0;
+ tree field = first_field (t);
+ if (field == NULL_TREE || error_operand_p (field))
+ {
+ error ("type transparent class %qT does not have any fields", t);
+ TYPE_TRANSPARENT_AGGR (t) = 0;
+ }
+ else if (DECL_ARTIFICIAL (field))
+ {
+ if (DECL_FIELD_IS_BASE (field))
+ error ("type transparent class %qT has base classes", t);
+ else
+ {
+ gcc_checking_assert (DECL_VIRTUAL_P (field));
+ error ("type transparent class %qT has virtual functions", t);
+ }
+ TYPE_TRANSPARENT_AGGR (t) = 0;
+ }
}
}
diff --git a/gcc/testsuite/g++.dg/dfp/base.C b/gcc/testsuite/g++.dg/dfp/base.C
new file mode 100644
index 0000000..3e5dc50
--- /dev/null
+++ b/gcc/testsuite/g++.dg/dfp/base.C
@@ -0,0 +1,23 @@
+// PR c++/50207
+// { dg-do compile }
+
+namespace std
+{
+ namespace decimal
+ {
+ template <class _Fmt> struct _FmtTraits;
+ class decimal32;
+ template <> struct _FmtTraits <decimal32>
+ {
+ static const long _NumBytes = 4UL;
+ };
+ template <class _Tr> class _DecBase
+ {
+ unsigned char _Bytes[_Tr::_NumBytes];
+ };
+ class decimal32 : public _DecBase <_FmtTraits <decimal32> > // { dg-error "has base" }
+ {
+ decimal32 () { }
+ };
+ }
+}