aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-07-16 16:36:10 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-07-16 16:36:10 -0400
commitc32097d8b4fb21997c571cf6520431fa7d06090f (patch)
tree100c59a1743caa8ea59faa87406fd5f529be94f4 /gcc
parentb3c5a40978985447d8ccf7d583929a4e8a78a91d (diff)
downloadgcc-c32097d8b4fb21997c571cf6520431fa7d06090f.zip
gcc-c32097d8b4fb21997c571cf6520431fa7d06090f.tar.gz
gcc-c32097d8b4fb21997c571cf6520431fa7d06090f.tar.bz2
re PR libstdc++/37907 ([c++0x] support for std::is_standard_layout)
PR libstdc++/37907 Support std::is_standard_layout and std::is_trivial traits, change POD to C++0x version (except for layout). * gcc/c-common.c (c_common_reswords): Add __is_standard_layout and __is_trivial. * gcc/c-common.h (enum rid): Add RID_IS_STD_LAYOUT and RID_IS_TRIVIAL. * gcc/cp/cp-tree.h (enum cp_trait_kind): Add CPTK_IS_STD_LAYOUT, CPTK_IS_TRIVIAL. (struct lang_type_class): Add non_std_layout. (CLASSTYPE_NON_STD_LAYOUT): New. * gcc/cp/class.c (check_bases): Set it. (check_field_decls): Likewise. (check_bases_and_members): Likewise. * gcc/cp/parser.c (cp_parser_primary_expression): Handle RID_IS_STD_LAYOUT, RID_IS_TRIVIAL. (cp_parser_trait_expr): Likewise. * gcc/cp/semantics.c (trait_expr_value): Handle CPTK_IS_STD_LAYOUT, CPTK_IS_TRIVIAL. (finish_trait_expr): Likewise. * gcc/cp/tree.c (scalarish_type_p, trivial_type_p, std_layout_type_p): New. (pod_type_p): Use them. * gcc/cp/typeck.c (build_class_member_access_expr): Check CLASSTYPE_NON_STD_LAYOUT rather than CLASSTYPE_NON_POD_P. * libstdc++-v3/include/std/type_traits: Add is_standard_layout, is_trivial. From-SVN: r149721
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/c-common.c2
-rw-r--r--gcc/c-common.h1
-rw-r--r--gcc/cp/ChangeLog34
-rw-r--r--gcc/cp/call.c50
-rw-r--r--gcc/cp/class.c69
-rw-r--r--gcc/cp/cp-tree.h22
-rw-r--r--gcc/cp/cxx-pretty-print.c6
-rw-r--r--gcc/cp/decl.c40
-rw-r--r--gcc/cp/init.c4
-rw-r--r--gcc/cp/parser.c8
-rw-r--r--gcc/cp/semantics.c26
-rw-r--r--gcc/cp/tree.c116
-rw-r--r--gcc/cp/typeck.c4
-rw-r--r--gcc/doc/gcc.texi2
-rw-r--r--gcc/doc/implement-cxx.texi47
-rw-r--r--gcc/testsuite/ChangeLog18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/std-layout1.C91
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/trivial1.C82
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_assign.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/has_trivial_assign.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/has_trivial_copy.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/is_pod.C4
-rw-r--r--gcc/testsuite/g++.dg/other/offsetof3.C7
-rw-r--r--gcc/testsuite/g++.dg/overload/ellipsis1.C5
-rw-r--r--gcc/testsuite/g++.dg/warn/var-args1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash63.C3
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash64.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/overload8.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/vaarg3.C13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/vaarg3.C4
33 files changed, 572 insertions, 111 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 173cabf..28ff163 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2009-07-16 Jason Merrill <jason@redhat.com>
+
+ PR libstdc++/37907
+ * c-common.c (c_common_reswords): Add __is_standard_layout
+ and __is_trivial.
+ * c-common.h (enum rid): Add RID_IS_STD_LAYOUT and RID_IS_TRIVIAL.
+ * doc/implement-cxx.texi: New.
+ * doc/gcc.texi: Include it.
+
2009-07-16 DJ Delorie <dj@redhat.com>
* config/m32c/m32c.c (m32c_compare_redundant): Avoid removing
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 11a4bcb..18f25d5 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3777,7 +3777,7 @@ TEXI_GCC_FILES = gcc.texi gcc-common.texi gcc-vers.texi frontends.texi \
gcov.texi trouble.texi bugreport.texi service.texi \
contribute.texi compat.texi funding.texi gnu.texi gpl_v3.texi \
fdl.texi contrib.texi cppenv.texi cppopts.texi \
- implement-c.texi arm-neon-intrinsics.texi
+ implement-c.texi implement-cxx.texi arm-neon-intrinsics.texi
TEXI_GCCINT_FILES = gccint.texi gcc-common.texi gcc-vers.texi \
contribute.texi makefile.texi configterms.texi options.texi \
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 20dac6b..069452c 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -598,6 +598,8 @@ const struct c_common_resword c_common_reswords[] =
{ "__is_enum", RID_IS_ENUM, D_CXXONLY },
{ "__is_pod", RID_IS_POD, D_CXXONLY },
{ "__is_polymorphic", RID_IS_POLYMORPHIC, D_CXXONLY },
+ { "__is_standard_layout", RID_IS_STD_LAYOUT, D_CXXONLY },
+ { "__is_trivial", RID_IS_TRIVIAL, D_CXXONLY },
{ "__is_union", RID_IS_UNION, D_CXXONLY },
{ "__imag", RID_IMAGPART, 0 },
{ "__imag__", RID_IMAGPART, 0 },
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 04a1945..ec5705e 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -110,6 +110,7 @@ enum rid
RID_IS_CONVERTIBLE_TO, RID_IS_CLASS,
RID_IS_EMPTY, RID_IS_ENUM,
RID_IS_POD, RID_IS_POLYMORPHIC,
+ RID_IS_STD_LAYOUT, RID_IS_TRIVIAL,
RID_IS_UNION,
/* C++0x */
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4265fa9..81cc8e0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,37 @@
+2009-07-16 Jason Merrill <jason@redhat.com>
+
+ PR libstdc++/37907
+ Split POD into "standard-layout" and "trivial" as per N2230,
+ Support std::is_standard_layout and std::is_trivial traits.
+ * cp-tree.h (enum cp_trait_kind): Add CPTK_IS_STD_LAYOUT,
+ CPTK_IS_TRIVIAL.
+ (struct lang_type_class): Add non_std_layout.
+ (CLASSTYPE_NON_STD_LAYOUT): New.
+ * class.c (check_bases): Set it.
+ (check_field_decls): Likewise.
+ (check_bases_and_members): Likewise.
+ * parser.c (cp_parser_primary_expression): Handle RID_IS_STD_LAYOUT,
+ RID_IS_TRIVIAL.
+ (cp_parser_trait_expr): Likewise.
+ * semantics.c (trait_expr_value): Handle CPTK_IS_STD_LAYOUT,
+ CPTK_IS_TRIVIAL.
+ (finish_trait_expr): Likewise.
+ * tree.c (scalarish_type_p, trivial_type_p, std_layout_type_p): New.
+ (pod_type_p): Use them.
+ (type_has_nontrivial_copy_init, type_has_nontrivial_default_init): New.
+
+ Adjust bits of the language that no longer refer to POD types.
+ * call.c (convert_arg_to_ellipsis): Use type_has_nontrivial_copy_init
+ and TYPE_HAS_NONTRIVIAL_DESTRUCTOR rather than pod_type_p.
+ (build_x_va_arg): Likewise.
+ (call_builtin_trap): Remove.
+ * decl.c (declare_local_label): Use type_has_nontrivial_default_init
+ and TYPE_HAS_NONTRIVIAL_DESTRUCTOR rather than pod_type_p.
+ (cp_finish_decl): Likewise.
+ (check_previous_goto_1, check_goto): Adjust error.
+ * typeck.c (build_class_member_access_expr): Check
+ CLASSTYPE_NON_STD_LAYOUT rather than CLASSTYPE_NON_POD_P.
+
2009-07-14 Taras Glek <tglek@mozilla.com>
Rafael Espindola <espindola@google.com>
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 588c997..6a7a1b8 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -197,7 +197,6 @@ static conversion *direct_reference_binding (tree, conversion *);
static bool promoted_arithmetic_type_p (tree);
static conversion *conditional_conversion (tree, tree);
static char *name_as_c_string (tree, tree, bool *);
-static tree call_builtin_trap (void);
static tree prep_operand (tree);
static void add_candidates (tree, const VEC(tree,gc) *, tree, bool, tree, tree,
int, struct z_candidate **);
@@ -5042,18 +5041,6 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
return expr;
}
-/* Build a call to __builtin_trap. */
-
-static tree
-call_builtin_trap (void)
-{
- tree fn = implicit_built_in_decls[BUILT_IN_TRAP];
-
- gcc_assert (fn != NULL);
- fn = build_call_n (fn, 0);
- return fn;
-}
-
/* ARG is being passed to a varargs function. Perform any conversions
required. Return the converted value. */
@@ -5082,20 +5069,23 @@ convert_arg_to_ellipsis (tree arg)
arg = require_complete_type (arg);
if (arg != error_mark_node
- && !pod_type_p (TREE_TYPE (arg)))
+ && (type_has_nontrivial_copy_init (TREE_TYPE (arg))
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (arg))))
{
- /* Undefined behavior [expr.call] 5.2.2/7. We used to just warn
- here and do a bitwise copy, but now cp_expr_size will abort if we
- try to do that.
+ /* [expr.call] 5.2.2/7:
+ Passing a potentially-evaluated argument of class type (Clause 9)
+ with a non-trivial copy constructor or a non-trivial destructor
+ with no corresponding parameter is conditionally-supported, with
+ implementation-defined semantics.
+
+ We used to just warn here and do a bitwise copy, but now
+ cp_expr_size will abort if we try to do that.
+
If the call appears in the context of a sizeof expression,
- there is no need to emit a warning, since the expression won't be
- evaluated. We keep the builtin_trap just as a safety check. */
+ it is not potentially-evaluated. */
if (cp_unevaluated_operand == 0)
- warning (0, "cannot pass objects of non-POD type %q#T through %<...%>; "
- "call will abort at runtime", TREE_TYPE (arg));
- arg = call_builtin_trap ();
- arg = build2 (COMPOUND_EXPR, integer_type_node, arg,
- integer_zero_node);
+ error ("cannot pass objects of non-trivially-copyable "
+ "type %q#T through %<...%>", TREE_TYPE (arg));
}
return arg;
@@ -5114,16 +5104,16 @@ build_x_va_arg (tree expr, tree type)
if (expr == error_mark_node || !type)
return error_mark_node;
- if (! pod_type_p (type))
+ if (type_has_nontrivial_copy_init (type)
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ || TREE_CODE (type) == REFERENCE_TYPE)
{
/* Remove reference types so we don't ICE later on. */
tree type1 = non_reference (type);
- /* Undefined behavior [expr.call] 5.2.2/7. */
- warning (0, "cannot receive objects of non-POD type %q#T through %<...%>; "
- "call will abort at runtime", type);
+ /* conditionally-supported behavior [expr.call] 5.2.2/7. */
+ error ("cannot receive objects of non-trivially-copyable type %q#T "
+ "through %<...%>; ", type);
expr = convert (build_pointer_type (type1), null_node);
- expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr),
- call_builtin_trap (), expr);
expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
return expr;
}
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 4668c68..373f457 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1248,9 +1248,15 @@ check_bases (tree t,
int seen_non_virtual_nearly_empty_base_p;
tree base_binfo;
tree binfo;
+ tree field = NULL_TREE;
seen_non_virtual_nearly_empty_base_p = 0;
+ if (!CLASSTYPE_NON_STD_LAYOUT (t))
+ for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL)
+ break;
+
for (binfo = TYPE_BINFO (t), i = 0;
BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
{
@@ -1305,6 +1311,36 @@ check_bases (tree t,
CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
|= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_HAS_COMPLEX_DFLT (basetype);
+
+ /* A standard-layout class is a class that:
+ ...
+ * has no non-standard-layout base classes, */
+ CLASSTYPE_NON_STD_LAYOUT (t) |= CLASSTYPE_NON_STD_LAYOUT (basetype);
+ if (!CLASSTYPE_NON_STD_LAYOUT (t))
+ {
+ tree basefield;
+ /* ...has no base classes of the same type as the first non-static
+ data member... */
+ if (field && DECL_CONTEXT (field) == t
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (field), basetype)))
+ CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+ else
+ /* ...either has no non-static data members in the most-derived
+ class and at most one base class with non-static data
+ members, or has no base classes with non-static data
+ members */
+ for (basefield = TYPE_FIELDS (basetype); basefield;
+ basefield = TREE_CHAIN (basefield))
+ if (TREE_CODE (basefield) == FIELD_DECL)
+ {
+ if (field)
+ CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+ else
+ field = basefield;
+ break;
+ }
+ }
}
}
@@ -2870,6 +2906,7 @@ check_field_decls (tree t, tree *access_decls,
bool has_pointers;
int any_default_members;
int cant_pack = 0;
+ int field_access = -1;
/* Assume there are no access declarations. */
*access_decls = NULL_TREE;
@@ -2883,6 +2920,7 @@ check_field_decls (tree t, tree *access_decls,
{
tree x = *field;
tree type = TREE_TYPE (x);
+ int this_field_access;
next = &TREE_CHAIN (x);
@@ -2957,10 +2995,21 @@ check_field_decls (tree t, tree *access_decls,
if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
CLASSTYPE_NON_AGGREGATE (t) = 1;
+ /* A standard-layout class is a class that:
+ ...
+ has the same access control (Clause 11) for all non-static data members,
+ ... */
+ this_field_access = TREE_PROTECTED (x) ? 1 : TREE_PRIVATE (x) ? 2 : 0;
+ if (field_access == -1)
+ field_access = this_field_access;
+ else if (this_field_access != field_access)
+ CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+
/* If this is of reference type, check if it needs an init. */
if (TREE_CODE (type) == REFERENCE_TYPE)
{
- CLASSTYPE_NON_POD_P (t) = 1;
+ CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;
+ CLASSTYPE_NON_STD_LAYOUT (t) = 1;
if (DECL_INITIAL (x) == NULL_TREE)
SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
@@ -2975,7 +3024,7 @@ check_field_decls (tree t, tree *access_decls,
if (TYPE_PACKED (t))
{
- if (!pod_type_p (type) && !TYPE_PACKED (type))
+ if (!layout_pod_type_p (type) && !TYPE_PACKED (type))
{
warning
(0,
@@ -3024,10 +3073,13 @@ check_field_decls (tree t, tree *access_decls,
if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
CLASSTYPE_HAS_MUTABLE (t) = 1;
- if (! pod_type_p (type))
+ if (! layout_pod_type_p (type))
/* DR 148 now allows pointers to members (which are POD themselves),
to be allowed in POD structs. */
- CLASSTYPE_NON_POD_P (t) = 1;
+ CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;
+
+ if (!std_layout_type_p (type))
+ CLASSTYPE_NON_STD_LAYOUT (t) = 1;
if (! zero_init_p (type))
CLASSTYPE_NON_ZERO_INIT_P (t) = 1;
@@ -4280,7 +4332,7 @@ type_requires_array_cookie (tree type)
/* Check the validity of the bases and members declared in T. Add any
implicitly-generated functions (like copy-constructors and
assignment operators). Compute various flag bits (like
- CLASSTYPE_NON_POD_T) for T. This routine works purely at the C++
+ CLASSTYPE_NON_LAYOUT_POD_T) for T. This routine works purely at the C++
level: i.e., independently of the ABI in use. */
static void
@@ -4346,9 +4398,12 @@ check_bases_and_members (tree t)
elsewhere. */
CLASSTYPE_NON_AGGREGATE (t)
|= (type_has_user_provided_constructor (t) || TYPE_POLYMORPHIC_P (t));
- CLASSTYPE_NON_POD_P (t)
+ /* This is the C++98/03 definition of POD; it changed in C++0x, but we
+ retain the old definition internally for ABI reasons. */
+ CLASSTYPE_NON_LAYOUT_POD_P (t)
|= (CLASSTYPE_NON_AGGREGATE (t)
|| saved_nontrivial_dtor || saved_complex_asn_ref);
+ CLASSTYPE_NON_STD_LAYOUT (t) |= TYPE_CONTAINS_VPTR_P (t);
TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_CONTAINS_VPTR_P (t);
TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t);
@@ -5031,7 +5086,7 @@ layout_class_type (tree t, tree *virtuals_p)
/* Create the version of T used for virtual bases. We do not use
make_class_type for this version; this is an artificial type. For
a POD type, we just reuse T. */
- if (CLASSTYPE_NON_POD_P (t) || CLASSTYPE_EMPTY_P (t))
+ if (CLASSTYPE_NON_LAYOUT_POD_P (t) || CLASSTYPE_EMPTY_P (t))
{
base_t = make_node (TREE_CODE (t));
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 933da19..6ad039a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -494,6 +494,8 @@ typedef enum cp_trait_kind
CPTK_IS_ENUM,
CPTK_IS_POD,
CPTK_IS_POLYMORPHIC,
+ CPTK_IS_STD_LAYOUT,
+ CPTK_IS_TRIVIAL,
CPTK_IS_UNION
} cp_trait_kind;
@@ -1124,6 +1126,7 @@ struct GTY(()) lang_type_class {
unsigned non_aggregate : 1;
unsigned has_complex_dflt : 1;
unsigned has_list_ctor : 1;
+ unsigned non_std_layout : 1;
/* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template. If
@@ -1132,7 +1135,7 @@ struct GTY(()) lang_type_class {
/* There are some bits left to fill out a 32-bit word. Keep track
of this by updating the size of this bitfield whenever you add or
remove a flag. */
- unsigned dummy : 10;
+ unsigned dummy : 9;
tree primary_base;
VEC(tree_pair_s,gc) *vcall_indices;
@@ -1385,8 +1388,14 @@ struct GTY(()) lang_type {
#define CLASSTYPE_HAS_MUTABLE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_mutable)
#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
-/* Nonzero means that this class type is a non-POD class. */
-#define CLASSTYPE_NON_POD_P(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->non_pod_class)
+/* Nonzero means that this class type is not POD for the purpose of layout
+ (as defined in the ABI). This is different from the language's POD. */
+#define CLASSTYPE_NON_LAYOUT_POD_P(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->non_pod_class)
+
+/* Nonzero means that this class type is a non-standard-layout class. */
+#define CLASSTYPE_NON_STD_LAYOUT(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->non_std_layout)
/* Nonzero means that this class contains pod types whose default
initialization is not a zero initialization (namely, pointers to
@@ -4877,7 +4886,12 @@ extern void stabilize_aggr_init (tree, tree *);
extern bool stabilize_init (tree, tree *);
extern tree add_stmt_to_compound (tree, tree);
extern void init_tree (void);
-extern int pod_type_p (const_tree);
+extern bool pod_type_p (const_tree);
+extern bool layout_pod_type_p (const_tree);
+extern bool std_layout_type_p (const_tree);
+extern bool trivial_type_p (const_tree);
+extern bool type_has_nontrivial_default_init (const_tree);
+extern bool type_has_nontrivial_copy_init (const_tree);
extern bool class_tmpl_impl_spec_p (const_tree);
extern int zero_init_p (const_tree);
extern tree strip_typedefs (tree);
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index b8732896..0b13bc1 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -2296,6 +2296,12 @@ pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
case CPTK_IS_POLYMORPHIC:
pp_cxx_ws_string (pp, "__is_polymorphic");
break;
+ case CPTK_IS_STD_LAYOUT:
+ pp_cxx_ws_string (pp, "__is_std_layout");
+ break;
+ case CPTK_IS_TRIVIAL:
+ pp_cxx_ws_string (pp, "__is_trivial");
+ break;
case CPTK_IS_UNION:
pp_cxx_ws_string (pp, "__is_union");
break;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e1b6678..e65e636 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2473,20 +2473,28 @@ declare_local_label (tree id)
static int
decl_jump_unsafe (tree decl)
{
+ /* [stmt.dcl]/3: A program that jumps from a point where a local variable
+ with automatic storage duration is not in scope to a point where it is
+ in scope is ill-formed unless the variable has scalar type, class type
+ with a trivial default constructor and a trivial destructor, a
+ cv-qualified version of one of these types, or an array of one of the
+ preceding types and is declared without an initializer (8.5). */
+ tree type = TREE_TYPE (decl);
+
if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)
- || TREE_TYPE (decl) == error_mark_node)
+ || type == error_mark_node)
return 0;
- if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
+ type = strip_array_types (type);
+
+ if (type_has_nontrivial_default_init (TREE_TYPE (decl))
|| DECL_NONTRIVIALLY_INITIALIZED_P (decl))
return 2;
- if (pod_type_p (TREE_TYPE (decl)))
- return 0;
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+ return 1;
- /* The POD stuff is just pedantry; why should it matter if the class
- contains a field of pointer to member type? */
- return 1;
+ return 0;
}
/* A subroutine of check_previous_goto_1 to identify a branch to the user. */
@@ -2541,7 +2549,8 @@ check_previous_goto_1 (tree decl, struct cp_binding_level* level, tree names,
if (problem > 1)
error (" crosses initialization of %q+#D", new_decls);
else
- permerror (input_location, " enters scope of non-POD %q+#D", new_decls);
+ permerror (input_location, " enters scope of %q+#D which has "
+ "non-trivial destructor", new_decls);
}
if (b == level)
@@ -2656,7 +2665,8 @@ check_goto (tree decl)
else if (u > 1)
error (" skips initialization of %q+#D", b);
else
- permerror (input_location, " enters scope of non-POD %q+#D", b);
+ permerror (input_location, " enters scope of %q+#D which has "
+ "non-trivial destructor", b);
}
if (ent->in_try_scope)
@@ -5687,11 +5697,13 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
if (TREE_CODE (decl) == VAR_DECL)
{
- /* Only PODs can have thread-local storage. Other types may require
- various kinds of non-trivial initialization. */
- if (DECL_THREAD_LOCAL_P (decl) && !pod_type_p (TREE_TYPE (decl)))
- error ("%qD cannot be thread-local because it has non-POD type %qT",
- decl, TREE_TYPE (decl));
+ /* Only variables with trivial initialization and destruction can
+ have thread-local storage. */
+ if (DECL_THREAD_LOCAL_P (decl)
+ && (type_has_nontrivial_default_init (TREE_TYPE (decl))
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
+ error ("%qD cannot be thread-local because it has non-trivial "
+ "type %qT", decl, TREE_TYPE (decl));
/* If this is a local variable that will need a mangled name,
register it now. We must do this before processing the
initializer for the variable, since the initialization might
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 19b2489..9118c61 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -2703,7 +2703,7 @@ build_vec_init (tree base, tree maxindex, tree init,
|| ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
|| from_array))
{
- /* Do non-default initialization of POD arrays resulting from
+ /* Do non-default initialization of trivial arrays resulting from
brace-enclosed initializers. In this case, digest_init and
store_constructor will handle the semantics for us. */
@@ -2769,7 +2769,7 @@ build_vec_init (tree base, tree maxindex, tree init,
if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR)
{
- /* Do non-default initialization of non-POD arrays resulting from
+ /* Do non-default initialization of non-trivial arrays resulting from
brace-enclosed initializers. */
unsigned HOST_WIDE_INT idx;
tree elt;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 94fba02..e64d0bf 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -3399,6 +3399,8 @@ cp_parser_primary_expression (cp_parser *parser,
case RID_IS_ENUM:
case RID_IS_POD:
case RID_IS_POLYMORPHIC:
+ case RID_IS_STD_LAYOUT:
+ case RID_IS_TRIVIAL:
case RID_IS_UNION:
return cp_parser_trait_expr (parser, token->keyword);
@@ -6865,6 +6867,12 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
case RID_IS_POLYMORPHIC:
kind = CPTK_IS_POLYMORPHIC;
break;
+ case RID_IS_STD_LAYOUT:
+ kind = CPTK_IS_STD_LAYOUT;
+ break;
+ case RID_IS_TRIVIAL:
+ kind = CPTK_IS_TRIVIAL;
+ break;
case RID_IS_UNION:
kind = CPTK_IS_UNION;
break;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 61dff51..4473c49 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4878,6 +4878,7 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
switch (kind)
{
case CPTK_HAS_NOTHROW_ASSIGN:
+ type1 = strip_array_types (type1);
return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
&& (trait_expr_value (CPTK_HAS_TRIVIAL_ASSIGN, type1, type2)
|| (CLASS_TYPE_P (type1)
@@ -4885,8 +4886,11 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
true))));
case CPTK_HAS_TRIVIAL_ASSIGN:
+ /* ??? The standard seems to be missing the "or array of such a class
+ type" wording for this trait. */
+ type1 = strip_array_types (type1);
return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
- && (pod_type_p (type1)
+ && (trivial_type_p (type1)
|| (CLASS_TYPE_P (type1)
&& TYPE_HAS_TRIVIAL_ASSIGN_REF (type1))));
@@ -4899,21 +4903,25 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
type1 = strip_array_types (type1);
- return (pod_type_p (type1)
+ return (trivial_type_p (type1)
|| (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
case CPTK_HAS_NOTHROW_COPY:
+ type1 = strip_array_types (type1);
return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
|| (CLASS_TYPE_P (type1)
&& classtype_has_nothrow_assign_or_copy_p (type1, false)));
case CPTK_HAS_TRIVIAL_COPY:
- return (pod_type_p (type1) || type_code1 == REFERENCE_TYPE
+ /* ??? The standard seems to be missing the "or array of such a class
+ type" wording for this trait. */
+ type1 = strip_array_types (type1);
+ return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
|| (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_INIT_REF (type1)));
case CPTK_HAS_TRIVIAL_DESTRUCTOR:
type1 = strip_array_types (type1);
- return (pod_type_p (type1) || type_code1 == REFERENCE_TYPE
+ return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
|| (CLASS_TYPE_P (type1)
&& TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
@@ -4947,6 +4955,12 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_POLYMORPHIC:
return (CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1));
+ case CPTK_IS_STD_LAYOUT:
+ return (std_layout_type_p (type1));
+
+ case CPTK_IS_TRIVIAL:
+ return (trivial_type_p (type1));
+
case CPTK_IS_UNION:
return (type_code1 == UNION_TYPE);
@@ -4995,6 +5009,8 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
|| kind == CPTK_IS_ENUM
|| kind == CPTK_IS_POD
|| kind == CPTK_IS_POLYMORPHIC
+ || kind == CPTK_IS_STD_LAYOUT
+ || kind == CPTK_IS_TRIVIAL
|| kind == CPTK_IS_UNION);
if (kind == CPTK_IS_CONVERTIBLE_TO)
@@ -5036,6 +5052,8 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_EMPTY:
case CPTK_IS_POD:
case CPTK_IS_POLYMORPHIC:
+ case CPTK_IS_STD_LAYOUT:
+ case CPTK_IS_TRIVIAL:
if (!check_trait_type (type1))
{
error ("incomplete type %qT not allowed", type1);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a003b44..255a297 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2238,36 +2238,108 @@ is_dummy_object (const_tree ob)
&& TREE_OPERAND (ob, 0) == void_zero_node);
}
+/* Returns 1 iff type T is something we want to treat as a scalar type for
+ the purpose of deciding whether it is trivial/POD/standard-layout. */
+
+static bool
+scalarish_type_p (const_tree t)
+{
+ if (t == error_mark_node)
+ return 1;
+
+ return (SCALAR_TYPE_P (t)
+ || TREE_CODE (t) == VECTOR_TYPE);
+}
+
+/* Returns true iff T requires non-trivial default initialization. */
+
+bool
+type_has_nontrivial_default_init (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return TYPE_HAS_COMPLEX_DFLT (t);
+ else
+ return 0;
+}
+
+/* Returns true iff copying an object of type T is non-trivial. */
+
+bool
+type_has_nontrivial_copy_init (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return TYPE_HAS_COMPLEX_INIT_REF (t);
+ else
+ return 0;
+}
+
+/* Returns 1 iff type T is a trivial type, as defined in [basic.types]. */
+
+bool
+trivial_type_p (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return !(TYPE_HAS_COMPLEX_DFLT (t)
+ || TYPE_HAS_COMPLEX_INIT_REF (t)
+ || TYPE_HAS_COMPLEX_ASSIGN_REF (t)
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t));
+ else
+ return scalarish_type_p (t);
+}
+
/* Returns 1 iff type T is a POD type, as defined in [basic.types]. */
-int
+bool
pod_type_p (const_tree t)
{
/* This CONST_CAST is okay because strip_array_types returns its
argument unmodified and we assign it to a const_tree. */
t = strip_array_types (CONST_CAST_TREE(t));
- if (t == error_mark_node)
- return 1;
- if (INTEGRAL_OR_ENUMERATION_TYPE_P (t))
- return 1; /* integral, character or enumeral type */
- if (FLOAT_TYPE_P (t))
- return 1;
- if (TYPE_PTR_P (t))
- return 1; /* pointer to non-member */
- if (TYPE_PTR_TO_MEMBER_P (t))
- return 1; /* pointer to member */
-
- if (TREE_CODE (t) == VECTOR_TYPE)
- return 1; /* vectors are (small) arrays of scalars */
-
- if (! RECORD_OR_UNION_CODE_P (TREE_CODE (t)))
- return 0; /* other non-class type (reference or function) */
- if (! CLASS_TYPE_P (t))
- return 1; /* struct created by the back end */
- if (CLASSTYPE_NON_POD_P (t))
- return 0;
- return 1;
+ if (CLASS_TYPE_P (t))
+ /* [class]/10: A POD struct is a class that is both a trivial class and a
+ standard-layout class, and has no non-static data members of type
+ non-POD struct, non-POD union (or array of such types).
+
+ We don't need to check individual members because if a member is
+ non-std-layout or non-trivial, the class will be too. */
+ return (std_layout_type_p (t) && trivial_type_p (t));
+ else
+ return scalarish_type_p (t);
+}
+
+/* Returns true iff T is POD for the purpose of layout, as defined in the
+ C++ ABI. */
+
+bool
+layout_pod_type_p (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return !CLASSTYPE_NON_LAYOUT_POD_P (t);
+ else
+ return scalarish_type_p (t);
+}
+
+/* Returns true iff T is a standard-layout type, as defined in
+ [basic.types]. */
+
+bool
+std_layout_type_p (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return !CLASSTYPE_NON_STD_LAYOUT (t);
+ else
+ return scalarish_type_p (t);
}
/* Nonzero iff type T is a class template implicit specialization. */
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 6a4802e..9e49ce5 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2017,7 +2017,7 @@ build_class_member_access_expr (tree object, tree member,
in various testsuite cases where a null object is passed where a
vtable access is required. */
if (null_object_p && warn_invalid_offsetof
- && CLASSTYPE_NON_POD_P (object_type)
+ && CLASSTYPE_NON_STD_LAYOUT (object_type)
&& !DECL_FIELD_IS_BASE (member)
&& cp_unevaluated_operand == 0
&& (complain & tf_warning))
@@ -3134,7 +3134,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
if (fndecl && DECL_BUILT_IN (fndecl)
&& DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
/* Don't do ellipsis conversion for __built_in_constant_p
- as this will result in spurious warnings for non-POD
+ as this will result in spurious errors for non-trivial
types. */
val = require_complete_type (val);
else
diff --git a/gcc/doc/gcc.texi b/gcc/doc/gcc.texi
index 4103175..34b8963 100644
--- a/gcc/doc/gcc.texi
+++ b/gcc/doc/gcc.texi
@@ -134,6 +134,7 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}.
* Invoking GCC:: Command options supported by @samp{gcc}.
* C Implementation:: How GCC implements the ISO C specification.
* C Extensions:: GNU extensions to the C language family.
+* C++ Implementation:: How GCC implements the ISO C++ specification.
* C++ Extensions:: GNU extensions to the C++ language.
* Objective-C:: GNU Objective-C runtime features.
* Compatibility:: Binary Compatibility
@@ -159,6 +160,7 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}.
@include standards.texi
@include invoke.texi
@include implement-c.texi
+@include implement-cxx.texi
@include extend.texi
@include objc.texi
@include compat.texi
diff --git a/gcc/doc/implement-cxx.texi b/gcc/doc/implement-cxx.texi
new file mode 100644
index 0000000..9968f59
--- /dev/null
+++ b/gcc/doc/implement-cxx.texi
@@ -0,0 +1,47 @@
+@c Copyright (C) 2009
+@c Free Software Foundation, Inc.
+@c This is part of the GCC manual.
+@c For copying conditions, see the file gcc.texi.
+
+@node C++ Implementation
+@chapter C++ Implementation-defined behavior
+@cindex implementation-defined behavior, C++ language
+
+A conforming implementation of ISO C++ is required to document its
+choice of behavior in each of the areas that are designated
+``implementation defined''. The following lists all such areas,
+along with the section numbers from the ISO/IEC 14822:1998 and ISO/IEC
+14822:2003 standards. Some areas are only implementation-defined in
+one version of the standard.
+
+Some choices depend on the externally determined ABI for the platform
+(including standard character encodings) which GCC follows; these are
+listed as ``determined by ABI'' below. @xref{Compatibility, , Binary
+Compatibility}, and @uref{http://gcc.gnu.org/readings.html}. Some
+choices are documented in the preprocessor manual.
+@xref{Implementation-defined behavior, , Implementation-defined
+behavior, cpp, The C Preprocessor}. Some choices are documented in
+the corresponding document for the C language. @xref{C
+Implementation}. Some choices are made by the library and operating
+system (or other environment when compiling for a freestanding
+environment); refer to their documentation for details.
+
+@menu
+* Conditionally-supported behavior::
+@end menu
+
+@node Conditionally-supported behavior
+@section Conditionally-supported behavior
+
+@cite{Each implementation shall include documentation that identifies
+all conditionally-supported constructs that it does not support (C++0x
+1.4).}
+
+@itemize @bullet
+@item
+@cite{Whether an argument of class type with a non-trivial copy
+constructor or destructor can be passed to ... (C++0x 5.2.2).}
+
+Such argument passing is not supported.
+
+@end itemize
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 989f577..7ab159a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,21 @@
+2009-07-16 Jason Merrill <jason@redhat.com>
+
+ PR libstdc++/37907
+ * g++.dg/cpp0x/std-layout1.C: New.
+ * g++.dg/ext/has_nothrow_assign.C: Fix.
+ * g++.dg/ext/has_nothrow_copy.C: Fix.
+ * g++.dg/ext/has_trivial_assign.C: Fix.
+ * g++.dg/ext/has_trivial_copy.C: Fix.
+ * g++.dg/ext/is_pod.C: Fix.
+ * g++.dg/other/offsetof3.C: Adjust.
+ * g++.dg/overload/ellipsis1.C: Adjust.
+ * g++.dg/warn/var-args1.C: Adjust.
+ * g++.old-deja/g++.brendan/crash63.C: Adjust.
+ * g++.old-deja/g++.brendan/crash64.C: Adjust.
+ * g++.old-deja/g++.brendan/overload8.C: Adjust.
+ * g++.old-deja/g++.other/vaarg3.C: Adjust.
+ * g++.old-deja/g++.pt/vaarg3.C: Adjust.
+
2009-07-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/torture/builtin-math-5.c: Add more cases.
diff --git a/gcc/testsuite/g++.dg/cpp0x/std-layout1.C b/gcc/testsuite/g++.dg/cpp0x/std-layout1.C
new file mode 100644
index 0000000..bdad82111
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/std-layout1.C
@@ -0,0 +1,91 @@
+// { dg-options "-std=c++0x" }
+
+// [basic.types]/10:
+// Scalar types, standard-layout class types (Clause 9), arrays of such
+// types and cv-qualified versions of these types (3.9.3) are collectively
+// called standard-layout types.
+
+// [class]/7:
+// A standard-layout class is a class that:
+// * has no non-static data members of type non-standard-layout class (or
+// array of such types) or reference,
+// * has no virtual functions (10.3) and no virtual base classes (10.1),
+// * has the same access control (Clause 11) for all non-static data members,
+// * has no non-standard-layout base classes,
+// * either has no non-static data members in the most-derived class and at
+// most one base class with non-static data members, or has no base classes
+// with non-static data members, and
+// * has no base classes of the same type as the first non-static data member.
+
+#include <type_traits>
+
+#define TRY(expr) static_assert (expr, #expr)
+#define YES(type) TRY(std::is_standard_layout<type>::value); \
+ TRY(std::is_standard_layout<type[]>::value); \
+ TRY(std::is_standard_layout<const volatile type>::value);
+#define NO(type) TRY(!std::is_standard_layout<type>::value); \
+ TRY(!std::is_standard_layout<type[]>::value); \
+ TRY(!std::is_standard_layout<const volatile type>::value);
+#define NONPOD(type) TRY(!std::is_pod<type>::value); \
+ TRY(!std::is_pod<type[]>::value); \
+ TRY(!std::is_pod<const volatile type>::value);
+
+struct A;
+
+YES(int);
+YES(__complex int);
+YES(void *);
+YES(int A::*);
+typedef int (A::*pmf)();
+YES(pmf);
+
+struct A { ~A(); };
+YES(A);
+NONPOD(A);
+struct F: public A { int i; };
+YES(F);
+NONPOD(F);
+struct G: public A { A a; };
+NO(G);
+struct M { A a; };
+YES(M);
+
+class B
+{
+ int i;
+ __complex int c;
+ void *p;
+ double ar[4];
+ int A::* pm;
+ int (A::*pmf)();
+};
+YES(B);
+struct D: public B { };
+YES(D);
+struct E: public B { int q; };
+NO(E);
+struct D2: public B { };
+YES(D2);
+struct I: public D, public D2 { };
+NO(I);
+
+struct C
+{
+ int i;
+private:
+ int j;
+};
+NO(C);
+struct H: public C { };
+NO(H);
+struct N { C c; };
+NO(N);
+
+struct J { virtual void f(); };
+struct J2: J { };
+NO(J);
+NO(J2);
+struct K { };
+struct L: virtual K {};
+YES(K);
+NO(L);
diff --git a/gcc/testsuite/g++.dg/cpp0x/trivial1.C b/gcc/testsuite/g++.dg/cpp0x/trivial1.C
new file mode 100644
index 0000000..62173ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/trivial1.C
@@ -0,0 +1,82 @@
+// { dg-options "-std=c++0x" }
+
+// [basic.types]/10:
+// Scalar types, trivial class types (Clause 9), arrays of such types and
+// cv-qualified versions of these types (3.9.3) are collectively called
+// trivial types.
+
+// [class]/6:
+// A trivially copyable class is a class that:
+// * has no non-trivial copy constructors (12.8),
+// * has no non-trivial copy assignment operators (13.5.3, 12.8), and
+// * has a trivial destructor (12.4).
+// A trivial class is a class that has a trivial default constructor (12.1)
+// and is trivially copyable.
+
+#include <type_traits>
+
+#define TRY(expr) static_assert (expr, #expr)
+#define YES(type) TRY(std::is_trivial<type>::value); \
+ TRY(std::is_trivial<type[]>::value); \
+ TRY(std::is_trivial<const volatile type>::value);
+#define NO(type) TRY(!std::is_trivial<type>::value); \
+ TRY(!std::is_trivial<type[]>::value); \
+ TRY(!std::is_trivial<const volatile type>::value);
+
+struct A;
+
+YES(int);
+YES(__complex int);
+YES(void *);
+YES(int A::*);
+typedef int (A::*pmf)();
+YES(pmf);
+
+struct A { ~A(); };
+NO(A);
+struct F: public A { int i; };
+NO(F);
+struct G: public A { A a; };
+NO(G);
+struct M { A a; };
+NO(M);
+
+class B
+{
+ int i;
+ __complex int c;
+ void *p;
+ double ar[4];
+ int A::* pm;
+ int (A::*pmf)();
+};
+YES(B);
+struct D: public B { };
+YES(D);
+struct E: public B { int q; };
+YES(E);
+struct D2: public B { };
+YES(D2);
+struct I: public D, public D2 { };
+YES(I);
+
+struct C
+{
+ int i;
+private:
+ int j;
+};
+YES(C);
+struct H: public C { };
+YES(H);
+struct N { C c; };
+YES(N);
+
+struct J { virtual void f(); };
+struct J2: J { };
+NO(J);
+NO(J2);
+struct K { };
+struct L: virtual K {};
+YES(K);
+NO(L);
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C b/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C
index 73a904e..f3b4a8b 100644
--- a/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C
@@ -134,7 +134,7 @@ int main()
assert (PTEST (A));
assert (PTEST (B));
assert (PTEST (C));
- assert (NTEST (C[]));
+ assert (PTEST (C[]));
assert (PTEST (D));
assert (NTEST (E));
assert (NTEST (E1));
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C
index e8507cf..056c9be 100644
--- a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C
@@ -124,7 +124,7 @@ int main()
assert (PTEST (A));
assert (PTEST (B));
assert (PTEST (C));
- assert (NTEST (C[]));
+ assert (PTEST (C[]));
assert (PTEST (D));
assert (NTEST (E));
assert (NTEST (E1));
diff --git a/gcc/testsuite/g++.dg/ext/has_trivial_assign.C b/gcc/testsuite/g++.dg/ext/has_trivial_assign.C
index 97bcbf23..46d8c34 100644
--- a/gcc/testsuite/g++.dg/ext/has_trivial_assign.C
+++ b/gcc/testsuite/g++.dg/ext/has_trivial_assign.C
@@ -96,7 +96,7 @@ int main()
assert (NTEST (C));
assert (NTEST (D));
assert (PTEST (E));
- assert (NTEST (E[]));
+ assert (PTEST (E[]));
assert (PTEST (F));
assert (NTEST (G));
assert (NTEST (const A));
diff --git a/gcc/testsuite/g++.dg/ext/has_trivial_copy.C b/gcc/testsuite/g++.dg/ext/has_trivial_copy.C
index ca2eeec..4b8cc15 100644
--- a/gcc/testsuite/g++.dg/ext/has_trivial_copy.C
+++ b/gcc/testsuite/g++.dg/ext/has_trivial_copy.C
@@ -96,7 +96,7 @@ int main()
assert (NTEST (C));
assert (NTEST (D));
assert (PTEST (E));
- assert (NTEST (E[]));
+ assert (PTEST (E[]));
assert (PTEST (F));
assert (NTEST (G));
assert (PTEST (B&));
diff --git a/gcc/testsuite/g++.dg/ext/is_pod.C b/gcc/testsuite/g++.dg/ext/is_pod.C
index 5c1f0cd..c984283 100644
--- a/gcc/testsuite/g++.dg/ext/is_pod.C
+++ b/gcc/testsuite/g++.dg/ext/is_pod.C
@@ -68,8 +68,8 @@ int main()
assert (PTEST (A));
assert (PTEST (A[]));
assert (NTEST (B));
- assert (NTEST (C));
- assert (NTEST (C[]));
+ assert (PTEST (C));
+ assert (PTEST (C[]));
return 0;
}
diff --git a/gcc/testsuite/g++.dg/other/offsetof3.C b/gcc/testsuite/g++.dg/other/offsetof3.C
index 1e83af9..5946c81 100644
--- a/gcc/testsuite/g++.dg/other/offsetof3.C
+++ b/gcc/testsuite/g++.dg/other/offsetof3.C
@@ -1,16 +1,17 @@
-/* Verify that offsetof warns if given a non-POD */
+/* Verify that offsetof warns if given a non-standard-layout class */
/* Copyright (C) 2003 Free Software Foundation, Inc. */
/* Contributed by Matt Austern <austern@apple.com> 15 May 2003 */
/* { dg-do compile } */
struct X
{
- X() : x(3), y(4) { }
int x, y;
+protected:
+ int z;
};
typedef X* pX;
typedef __SIZE_TYPE__ size_t;
size_t yoff = size_t(&(pX(0)->y)); /* { dg-warning "invalid access" "" } */
-/* { dg-warning "macro was used incorrectly" "macro" { target *-*-* } 15 } */
+/* { dg-warning "macro was used incorrectly" "macro" { target *-*-* } 16 } */
diff --git a/gcc/testsuite/g++.dg/overload/ellipsis1.C b/gcc/testsuite/g++.dg/overload/ellipsis1.C
index bdd3cd2..3dedaa6 100644
--- a/gcc/testsuite/g++.dg/overload/ellipsis1.C
+++ b/gcc/testsuite/g++.dg/overload/ellipsis1.C
@@ -1,9 +1,6 @@
// PR c++/15142
// Bug: We were aborting after giving a warning about passing a non-POD.
-// Suppress the warning about undefined behavior.
-// { dg-options "-w" }
-
struct B {
B() throw() { }
B(const B&) throw() { }
@@ -17,5 +14,5 @@ struct X {
struct S { S(...); };
void SillyFunc() {
- throw S(X());
+ throw S(X()); // { dg-error "copy" }
}
diff --git a/gcc/testsuite/g++.dg/warn/var-args1.C b/gcc/testsuite/g++.dg/warn/var-args1.C
index aadac20..9bd84a7 100644
--- a/gcc/testsuite/g++.dg/warn/var-args1.C
+++ b/gcc/testsuite/g++.dg/warn/var-args1.C
@@ -6,6 +6,6 @@ void foo(int, ...)
{
va_list va;
int i;
- i = va_arg(va, int&); /* { dg-warning "cannot receive objects" } */
+ i = va_arg(va, int&); /* { dg-error "cannot receive objects" } */
}
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash63.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash63.C
index 13f8339..89685fc 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash63.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash63.C
@@ -4,6 +4,7 @@ class String
{
public:
String (const char *str);
+ String (const String&);
};
class UnitList
@@ -12,4 +13,4 @@ class UnitList
UnitList (...);
};
-UnitList unit_list (String("keV")); // { dg-warning "" } cannot pass non-pod
+UnitList unit_list (String("keV")); // { dg-error "" } cannot pass non-pod
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C
index 6046cb1..3c98692 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C
@@ -16,4 +16,4 @@ struct metatype { int base_list; };
static _type_desc _type_metatype("metatype", sizeof(metatype),
(RF_Ptr)0, 0, 1, 1,
- _im_pers_mem_spec( ((size_t)&((( metatype *)0)-> base_list )) , 1)); // { dg-warning "" } cannot pass non-pod
+ _im_pers_mem_spec( ((size_t)&((( metatype *)0)-> base_list )) , 1));
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/overload8.C b/gcc/testsuite/g++.old-deja/g++.brendan/overload8.C
index fc1b23b..bf129b0 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/overload8.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/overload8.C
@@ -6,4 +6,4 @@ class Complex{public:double re,im;
void zxcvbnm(int n,...){n=1;}
int main(){complex c; Complex C;
zxcvbnm(1,c);
-zxcvbnm(1,C);} // { dg-warning "" } cannot pass non pod
+zxcvbnm(1,C);}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/vaarg3.C b/gcc/testsuite/g++.old-deja/g++.other/vaarg3.C
index f852b08..3408a18 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/vaarg3.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/vaarg3.C
@@ -9,14 +9,14 @@
#include <stdarg.h>
struct X {int m;};
-struct Y : X {int m;};
+struct Y { Y(const Y&); };
struct Z; // { dg-error "forward decl" }
void fn1(va_list args)
{
int i = va_arg (args, int);
- Y x = va_arg (args, Y); // { dg-warning "cannot receive" }
- Y y = va_arg (args, struct Y); // { dg-warning "cannot receive" }
- int &r = va_arg (args, int &); // { dg-warning "cannot receive" }
+ Y x = va_arg (args, Y); // { dg-error "cannot receive" }
+ Y y = va_arg (args, struct Y); // { dg-error "cannot receive" }
+ int &r = va_arg (args, int &); // { dg-error "cannot receive" }
Z z1 = va_arg (args, Z); // { dg-error "incomplete" }
const Z &z2 = va_arg (args, Z); // { dg-error "incomplete" }
@@ -25,7 +25,8 @@ void fn1(va_list args)
// { dg-message "should pass" "pass" { target *-*-* } 24 }
// { dg-message "abort" "abort" { target *-*-* } 24 }
va_arg (args, int []); // { dg-error "array with unspecified bounds" } promote
- va_arg (args, int ()); // { dg-warning "non-POD" } promote
+ va_arg (args, int ()); // { dg-warning "promoted" } promote
+ // { dg-message "abort" "abort" { target *-*-* } 28 }
va_arg (args, bool); // { dg-warning "promote" "promote" }
- // { dg-message "abort" "abort" { target *-*-* } 29 }
+ // { dg-message "abort" "abort" { target *-*-* } 30 }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/vaarg3.C b/gcc/testsuite/g++.old-deja/g++.pt/vaarg3.C
index dced89d..07fb18d 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/vaarg3.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/vaarg3.C
@@ -14,14 +14,14 @@ void PrintArgs (Type somearg, ...)
va_list argp;
va_start (argp, somearg);
Type value;
-value = va_arg (argp, Type); // { dg-warning "non-POD" } cannot pass non-POD
+value = va_arg (argp, Type); // { dg-error "cannot receive" } cannot pass non-POD
va_end (argp);
}
int main (void)
{
A dummy;
-PrintArgs (dummy, dummy); // { dg-warning "non-POD" } cannot pass non-POD
+PrintArgs (dummy, dummy); // { dg-error "cannot pass" } cannot pass non-POD
// { dg-message "instantiated" "inst" { target *-*-* } 24 }
return 0;
}