X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fcp%2Fclass.c;h=76e63981a33a3d5f5862f187cd5e55bd771d5ab7;hp=6e67157a290a3c881a9f5533f735bdec7108650a;hb=e50d78371786658ca79b8a4993bcf76fb9f75f41;hpb=ed111d2b116ffa865e970b8a2ec8cec0e76be440 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 6e67157a290..76e63981a33 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1,6 +1,6 @@ /* Functions related to building classes and their related objects. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -284,7 +284,7 @@ build_base_path (enum tree_code code, if (!want_pointer) /* This must happen before the call to save_expr. */ - expr = build_unary_op (ADDR_EXPR, expr, 0); + expr = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error); offset = BINFO_OFFSET (binfo); fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); @@ -293,6 +293,16 @@ build_base_path (enum tree_code code, /* Do we need to look in the vtable for the real offset? */ virtual_access = (v_binfo && fixed_type_p <= 0); + /* Don't bother with the calculations inside sizeof; they'll ICE if the + source type is incomplete and the pointer value doesn't matter. */ + if (skip_evaluation) + { + expr = build_nop (build_pointer_type (target_type), expr); + if (!want_pointer) + expr = build_indirect_ref (EXPR_LOCATION (expr), expr, NULL); + return expr; + } + /* Do we need to check for a null pointer? */ if (want_pointer && !nonnull) { @@ -335,7 +345,7 @@ build_base_path (enum tree_code code, interesting to the optimizers anyway. */ && !has_empty) { - expr = build_indirect_ref (expr, NULL); + expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error); expr = build_simple_base_path (expr, binfo); if (want_pointer) expr = build_address (expr); @@ -360,10 +370,12 @@ build_base_path (enum tree_code code, t = TREE_TYPE (TYPE_VFIELD (current_class_type)); t = build_pointer_type (t); v_offset = convert (t, current_vtt_parm); - v_offset = build_indirect_ref (v_offset, NULL); + v_offset = cp_build_indirect_ref (v_offset, NULL, + tf_warning_or_error); } else - v_offset = build_vfield_ref (build_indirect_ref (expr, NULL), + v_offset = build_vfield_ref (cp_build_indirect_ref (expr, NULL, + tf_warning_or_error), TREE_TYPE (TREE_TYPE (expr))); v_offset = build2 (POINTER_PLUS_EXPR, TREE_TYPE (v_offset), @@ -371,9 +383,8 @@ build_base_path (enum tree_code code, v_offset = build1 (NOP_EXPR, build_pointer_type (ptrdiff_type_node), v_offset); - v_offset = build_indirect_ref (v_offset, NULL); + v_offset = cp_build_indirect_ref (v_offset, NULL, tf_warning_or_error); TREE_CONSTANT (v_offset) = 1; - TREE_INVARIANT (v_offset) = 1; offset = convert_to_integer (ptrdiff_type_node, size_diffop (offset, @@ -415,7 +426,7 @@ build_base_path (enum tree_code code, null_test = NULL; if (!want_pointer) - expr = build_indirect_ref (expr, NULL); + expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error); out: if (null_test) @@ -449,7 +460,7 @@ build_simple_base_path (tree expr, tree binfo) in the back end. */ temp = unary_complex_lvalue (ADDR_EXPR, expr); if (temp) - expr = build_indirect_ref (temp, NULL); + expr = cp_build_indirect_ref (temp, NULL, tf_warning_or_error); return expr; } @@ -541,7 +552,8 @@ convert_to_base_statically (tree expr, tree base) when processing a template because they do not handle C++-specific trees. */ gcc_assert (!processing_template_decl); - expr = build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1); + expr = cp_build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1, + tf_warning_or_error); if (!integer_zerop (BINFO_OFFSET (base))) expr = fold_build2 (POINTER_PLUS_EXPR, pointer_type, expr, fold_convert (sizetype, BINFO_OFFSET (base))); @@ -613,11 +625,9 @@ build_vtbl_ref_1 (tree instance, tree idx) if (!vtbl) vtbl = build_vfield_ref (instance, basetype); - assemble_external (vtbl); - aref = build_array_ref (vtbl, idx); + aref = build_array_ref (vtbl, idx, input_location); TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx); - TREE_INVARIANT (aref) = TREE_CONSTANT (aref); return aref; } @@ -638,13 +648,16 @@ build_vfn_ref (tree instance_ptr, tree idx) { tree aref; - aref = build_vtbl_ref_1 (build_indirect_ref (instance_ptr, 0), idx); + aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, 0, + tf_warning_or_error), + idx); /* When using function descriptors, the address of the vtable entry is treated as a function pointer. */ if (TARGET_VTABLE_USES_DESCRIPTORS) aref = build1 (NOP_EXPR, TREE_TYPE (aref), - build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1)); + cp_build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1, + tf_warning_or_error)); /* Remember this as a method reference, for later devirtualization. */ aref = build3 (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx); @@ -945,7 +958,7 @@ add_method (tree type, tree method, tree using_decl) CLASSTYPE_METHOD_VEC (type) = method_vec; } - /* Maintain TYPE_HAS_CONSTRUCTOR, etc. */ + /* Maintain TYPE_HAS_USER_CONSTRUCTOR, etc. */ grok_special_member_properties (method); /* Constructors and destructors go in special slots. */ @@ -1030,6 +1043,8 @@ add_method (tree type, tree method, tree using_decl) coming from the using class in overload resolution. */ if (! DECL_STATIC_FUNCTION_P (fn) && ! DECL_STATIC_FUNCTION_P (method) + && TREE_TYPE (TREE_VALUE (parms1)) != error_mark_node + && TREE_TYPE (TREE_VALUE (parms2)) != error_mark_node && (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1))) != TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2))))) continue; @@ -1423,23 +1438,24 @@ determine_primary_bases (tree t) BINFO_VIRTUALS (type_binfo) = BINFO_VIRTUALS (primary); } } - -/* Set memoizing fields and bits of T (and its variants) for later - use. */ -static void -finish_struct_bits (tree t) +/* Update the variant types of T. */ + +void +fixup_type_variants (tree t) { tree variants; - /* Fix up variants (if any). */ + if (!t) + return; + for (variants = TYPE_NEXT_VARIANT (t); variants; variants = TYPE_NEXT_VARIANT (variants)) { /* These fields are in the _TYPE part of the node, not in the TYPE_LANG_SPECIFIC component, so they are not shared. */ - TYPE_HAS_CONSTRUCTOR (variants) = TYPE_HAS_CONSTRUCTOR (t); + TYPE_HAS_USER_CONSTRUCTOR (variants) = TYPE_HAS_USER_CONSTRUCTOR (t); TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t); TYPE_HAS_NONTRIVIAL_DESTRUCTOR (variants) = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t); @@ -1456,6 +1472,17 @@ finish_struct_bits (tree t) /* All variants of a class have the same attributes. */ TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (t); } +} + + +/* Set memoizing fields and bits of T (and its variants) for later + use. */ + +static void +finish_struct_bits (tree t) +{ + /* Fix up variants (if any). */ + fixup_type_variants (t); if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t)) /* For a class w/o baseclasses, 'finish_struct' has set @@ -1478,7 +1505,7 @@ finish_struct_bits (tree t) DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode; for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants)) { - TYPE_MODE (variants) = BLKmode; + SET_TYPE_MODE (variants, BLKmode); TREE_ADDRESSABLE (variants) = 1; } } @@ -1584,7 +1611,8 @@ maybe_warn_about_overly_private_class (tree t) return; } - if (TYPE_HAS_CONSTRUCTOR (t) + /* Warn about classes that have private constructors and no friends. */ + if (TYPE_HAS_USER_CONSTRUCTOR (t) /* Implicitly generated constructors are always public. */ && (!CLASSTYPE_LAZY_DEFAULT_CTOR (t) || !CLASSTYPE_LAZY_COPY_CTOR (t))) @@ -2480,27 +2508,27 @@ finish_struct_anon (tree t) if (TREE_CODE (elt) != FIELD_DECL) { if (is_union) - pedwarn ("%q+#D invalid; an anonymous union can " - "only have non-static data members", elt); + permerror (input_location, "%q+#D invalid; an anonymous union can " + "only have non-static data members", elt); else - pedwarn ("%q+#D invalid; an anonymous struct can " - "only have non-static data members", elt); + permerror (input_location, "%q+#D invalid; an anonymous struct can " + "only have non-static data members", elt); continue; } if (TREE_PRIVATE (elt)) { if (is_union) - pedwarn ("private member %q+#D in anonymous union", elt); + permerror (input_location, "private member %q+#D in anonymous union", elt); else - pedwarn ("private member %q+#D in anonymous struct", elt); + permerror (input_location, "private member %q+#D in anonymous struct", elt); } else if (TREE_PROTECTED (elt)) { if (is_union) - pedwarn ("protected member %q+#D in anonymous union", elt); + permerror (input_location, "protected member %q+#D in anonymous union", elt); else - pedwarn ("protected member %q+#D in anonymous struct", elt); + permerror (input_location, "protected member %q+#D in anonymous struct", elt); } TREE_PRIVATE (elt) = TREE_PRIVATE (field); @@ -2590,20 +2618,25 @@ add_implicitly_declared_members (tree t, } } - /* Default constructor. */ - if (! TYPE_HAS_CONSTRUCTOR (t)) + /* [class.ctor] + + If there is no user-declared constructor for a class, a default + constructor is implicitly declared. */ + if (! TYPE_HAS_USER_CONSTRUCTOR (t)) { TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1; CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1; } - /* Copy constructor. */ + /* [class.ctor] + + If a class definition does not explicitly declare a copy + constructor, one is declared implicitly. */ if (! TYPE_HAS_INIT_REF (t) && ! TYPE_FOR_JAVA (t)) { TYPE_HAS_INIT_REF (t) = 1; TYPE_HAS_CONST_INIT_REF (t) = !cant_have_const_cctor; CLASSTYPE_LAZY_COPY_CTOR (t) = 1; - TYPE_HAS_CONSTRUCTOR (t) = 1; } /* If there is no assignment operator, one will be created if and @@ -2706,10 +2739,11 @@ check_bitfield_decl (tree field) warning (0, "width of %q+D exceeds its type", field); else if (TREE_CODE (type) == ENUMERAL_TYPE && (0 > compare_tree_int (w, - min_precision (TYPE_MIN_VALUE (type), - TYPE_UNSIGNED (type))) + tree_int_cst_min_precision + (TYPE_MIN_VALUE (type), + TYPE_UNSIGNED (type))) || 0 > compare_tree_int (w, - min_precision + tree_int_cst_min_precision (TYPE_MAX_VALUE (type), TYPE_UNSIGNED (type))))) warning (0, "%q+D is too small to hold all values of %q#T", field, type); @@ -2925,8 +2959,7 @@ check_field_decls (tree t, tree *access_decls, if (TREE_PRIVATE (x) || TREE_PROTECTED (x)) CLASSTYPE_NON_AGGREGATE (t) = 1; - /* If this is of reference type, check if it needs an init. - Also do a little ANSI jig if necessary. */ + /* If this is of reference type, check if it needs an init. */ if (TREE_CODE (type) == REFERENCE_TYPE) { CLASSTYPE_NON_POD_P (t) = 1; @@ -2938,10 +2971,6 @@ check_field_decls (tree t, tree *access_decls, only way to initialize nonstatic const and reference members. */ TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; - - if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t) - && extra_warnings) - warning (OPT_Wextra, "non-static reference %q+#D in class without a constructor", x); } type = strip_array_types (type); @@ -2956,7 +2985,8 @@ check_field_decls (tree t, tree *access_decls, x); cant_pack = 1; } - else if (TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT) + else if (DECL_C_BIT_FIELD (x) + || TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT) DECL_PACKED (x) = 1; } @@ -3016,10 +3046,6 @@ check_field_decls (tree t, tree *access_decls, only way to initialize nonstatic const and reference members. */ TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; - - if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t) - && extra_warnings) - warning (OPT_Wextra, "non-static const member %q+#D in class without a constructor", x); } /* A field that is pseudo-const makes the structure likewise. */ else if (CLASS_TYPE_P (type)) @@ -3032,9 +3058,10 @@ check_field_decls (tree t, tree *access_decls, /* Core issue 80: A nonstatic data member is required to have a different name from the class iff the class has a - user-defined constructor. */ - if (constructor_name_p (DECL_NAME (x), t) && TYPE_HAS_CONSTRUCTOR (t)) - pedwarn ("field %q+#D with same name as class", x); + user-declared constructor. */ + if (constructor_name_p (DECL_NAME (x), t) + && TYPE_HAS_USER_CONSTRUCTOR (t)) + permerror (input_location, "field %q+#D with same name as class", x); /* We set DECL_C_BIT_FIELD in grokbitfield. If the type and width are valid, we'll also set DECL_BIT_FIELD. */ @@ -3061,7 +3088,7 @@ check_field_decls (tree t, tree *access_decls, This seems enough for practical purposes. */ if (warn_ecpp && has_pointers - && TYPE_HAS_CONSTRUCTOR (t) + && TYPE_HAS_USER_CONSTRUCTOR (t) && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) && !(TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t))) { @@ -3753,8 +3780,8 @@ check_methods (tree t) if (DECL_PURE_VIRTUAL_P (x)) VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x); } - /* All user-declared destructors are non-trivial. */ - if (DECL_DESTRUCTOR_P (x)) + /* All user-provided destructors are non-trivial. */ + if (DECL_DESTRUCTOR_P (x) && !DECL_DEFAULTED_FN (x)) TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1; } } @@ -4029,6 +4056,120 @@ clone_constructors_and_destructors (tree t) clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1); } +/* Returns true iff class T has a user-defined constructor other than + the default constructor. */ + +bool +type_has_user_nondefault_constructor (tree t) +{ + tree fns; + + if (!TYPE_HAS_USER_CONSTRUCTOR (t)) + return false; + + for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns)) + { + tree fn = OVL_CURRENT (fns); + if (!DECL_ARTIFICIAL (fn) + && (TREE_CODE (fn) == TEMPLATE_DECL + || (skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn)) + != NULL_TREE))) + return true; + } + + return false; +} + +/* Returns true iff FN is a user-provided function, i.e. user-declared + and not defaulted at its first declaration. */ + +static bool +user_provided_p (tree fn) +{ + if (TREE_CODE (fn) == TEMPLATE_DECL) + return true; + else + return (!DECL_ARTIFICIAL (fn) + && !(DECL_DEFAULTED_FN (fn) + && DECL_INITIALIZED_IN_CLASS_P (fn))); +} + +/* Returns true iff class T has a user-provided constructor. */ + +bool +type_has_user_provided_constructor (tree t) +{ + tree fns; + + if (!CLASS_TYPE_P (t)) + return false; + + if (!TYPE_HAS_USER_CONSTRUCTOR (t)) + return false; + + /* This can happen in error cases; avoid crashing. */ + if (!CLASSTYPE_METHOD_VEC (t)) + return false; + + for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns)) + if (user_provided_p (OVL_CURRENT (fns))) + return true; + + return false; +} + +/* Returns true iff class T has a user-provided default constructor. */ + +bool +type_has_user_provided_default_constructor (tree t) +{ + tree fns, args; + + if (!TYPE_HAS_USER_CONSTRUCTOR (t)) + return false; + + for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns)) + { + tree fn = OVL_CURRENT (fns); + if (TREE_CODE (fn) == FUNCTION_DECL + && user_provided_p (fn)) + { + args = FUNCTION_FIRST_USER_PARMTYPE (fn); + while (args && TREE_PURPOSE (args)) + args = TREE_CHAIN (args); + if (!args || args == void_list_node) + return true; + } + } + + return false; +} + +/* Returns true if FN can be explicitly defaulted. */ + +bool +defaultable_fn_p (tree fn) +{ + if (DECL_CONSTRUCTOR_P (fn)) + { + if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node) + return true; + else if (copy_fn_p (fn) > 0 + && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn)) + == void_list_node)) + return true; + else + return false; + } + else if (DECL_DESTRUCTOR_P (fn)) + return true; + else if (DECL_ASSIGNMENT_OPERATOR_P (fn) + && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR) + return copy_fn_p (fn); + else + return false; +} + /* Remove all zero-width bit-fields from T. */ static void @@ -4089,6 +4230,10 @@ type_requires_array_cookie (tree type) second_parm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))); if (second_parm == void_list_node) return false; + /* Do not consider this function if its second argument is an + ellipsis. */ + if (!second_parm) + continue; /* Otherwise, if we have a two-argument function and the second argument is `size_t', it will be the usual deallocation function -- unless there is one-argument function, too. */ @@ -4116,6 +4261,8 @@ check_bases_and_members (tree t) should take a non-const reference argument. */ int no_const_asn_ref; tree access_decls; + bool saved_complex_asn_ref; + bool saved_nontrivial_dtor; /* By default, we use const reference arguments and generate default constructors. */ @@ -4129,6 +4276,12 @@ check_bases_and_members (tree t) /* Check all the method declarations. */ check_methods (t); + /* Save the initial values of these flags which only indicate whether + or not the class has user-provided functions. As we analyze the + bases and members we can set these flags for other reasons. */ + saved_complex_asn_ref = TYPE_HAS_COMPLEX_ASSIGN_REF (t); + saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t); + /* Check all the data member declarations. We cannot call check_field_decls until we have called check_bases check_methods, as check_field_decls depends on TYPE_HAS_NONTRIVIAL_DESTRUCTOR @@ -4144,20 +4297,60 @@ check_bases_and_members (tree t) /* Do some bookkeeping that will guide the generation of implicitly declared member functions. */ - TYPE_HAS_COMPLEX_INIT_REF (t) - |= (TYPE_HAS_INIT_REF (t) || TYPE_CONTAINS_VPTR_P (t)); + TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_CONTAINS_VPTR_P (t); + /* We need to call a constructor for this class if it has a + user-provided constructor, or if the default constructor is going + to initialize the vptr. (This is not an if-and-only-if; + TYPE_NEEDS_CONSTRUCTING is set elsewhere if bases or members + themselves need constructing.) */ TYPE_NEEDS_CONSTRUCTING (t) - |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t)); + |= (type_has_user_provided_constructor (t) || TYPE_CONTAINS_VPTR_P (t)); + /* [dcl.init.aggr] + + An aggregate is an array or a class with no user-provided + constructors ... and no virtual functions. + + Again, other conditions for being an aggregate are checked + elsewhere. */ CLASSTYPE_NON_AGGREGATE (t) - |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_POLYMORPHIC_P (t)); + |= (type_has_user_provided_constructor (t) || TYPE_POLYMORPHIC_P (t)); CLASSTYPE_NON_POD_P (t) |= (CLASSTYPE_NON_AGGREGATE (t) - || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) - || TYPE_HAS_ASSIGN_REF (t)); - TYPE_HAS_COMPLEX_ASSIGN_REF (t) - |= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t); - TYPE_HAS_COMPLEX_DFLT (t) - |= (TYPE_HAS_DEFAULT_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t)); + || saved_nontrivial_dtor || saved_complex_asn_ref); + TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_CONTAINS_VPTR_P (t); + TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t); + + /* If the class has no user-declared constructor, but does have + non-static const or reference data members that can never be + initialized, issue a warning. */ + if (warn_uninitialized + /* Classes with user-declared constructors are presumed to + initialize these members. */ + && !TYPE_HAS_USER_CONSTRUCTOR (t) + /* Aggregates can be initialized with brace-enclosed + initializers. */ + && CLASSTYPE_NON_AGGREGATE (t)) + { + tree field; + + for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + { + tree type; + + if (TREE_CODE (field) != FIELD_DECL) + continue; + + type = TREE_TYPE (field); + if (TREE_CODE (type) == REFERENCE_TYPE) + warning (OPT_Wuninitialized, "non-static reference %q+#D " + "in class without a constructor", field); + else if (CP_TYPE_CONST_P (type) + && (!CLASS_TYPE_P (type) + || !TYPE_HAS_DEFAULT_CONSTRUCTOR (type))) + warning (OPT_Wuninitialized, "non-static const member %q+#D " + "in class without a constructor", field); + } + } /* Synthesize any needed methods. */ add_implicitly_declared_members (t, @@ -4795,14 +4988,18 @@ layout_class_type (tree t, tree *virtuals_p) must be converted to the type given the bitfield here. */ if (DECL_C_BIT_FIELD (field)) { - tree ftype; unsigned HOST_WIDE_INT width; - ftype = TREE_TYPE (field); + tree ftype = TREE_TYPE (field); width = tree_low_cst (DECL_SIZE (field), /*unsignedp=*/1); if (width != TYPE_PRECISION (ftype)) - TREE_TYPE (field) - = c_build_bitfield_integer_type (width, - TYPE_UNSIGNED (ftype)); + { + TREE_TYPE (field) + = c_build_bitfield_integer_type (width, + TYPE_UNSIGNED (ftype)); + TREE_TYPE (field) + = cp_build_qualified_type (TREE_TYPE (field), + TYPE_QUALS (ftype)); + } } /* If we needed additional padding after this field, add it @@ -4846,7 +5043,7 @@ layout_class_type (tree t, tree *virtuals_p) remove_zero_width_bit_fields (t); /* Create the version of T used for virtual bases. We do not use - make_aggr_type for this version; this is an artificial type. For + 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)) { @@ -5006,7 +5203,7 @@ finish_struct_1 (tree t) if (COMPLETE_TYPE_P (t)) { - gcc_assert (IS_AGGR_TYPE (t)); + gcc_assert (MAYBE_CLASS_TYPE_P (t)); error ("redefinition of %q#T", t); popclass (); return; @@ -5325,8 +5522,7 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp) return NULL_TREE; - case NOP_EXPR: - case CONVERT_EXPR: + CASE_CONVERT: return RECUR (TREE_OPERAND (instance, 0)); case ADDR_EXPR: @@ -5352,7 +5548,7 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp) case VAR_DECL: case FIELD_DECL: if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE - && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (instance)))) + && MAYBE_CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (instance)))) { if (nonnull) *nonnull = 1; @@ -5362,7 +5558,7 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp) case TARGET_EXPR: case PARM_DECL: case RESULT_DECL: - if (IS_AGGR_TYPE (TREE_TYPE (instance))) + if (MAYBE_CLASS_TYPE_P (TREE_TYPE (instance))) { if (nonnull) *nonnull = 1; @@ -5602,6 +5798,9 @@ currently_open_class (tree t) { int i; + if (!CLASS_TYPE_P (t)) + return false; + /* We start looking from 1 because entry 0 is from global scope, and has no type. */ for (i = current_class_depth; i > 0; --i) @@ -5744,9 +5943,13 @@ pop_lang_context (void) control of FLAGS. Permit pointers to member function if FLAGS permits. If TEMPLATE_ONLY, the name of the overloaded function was a template-id, and EXPLICIT_TARGS are the explicitly provided - template arguments. If OVERLOAD is for one or more member - functions, then ACCESS_PATH is the base path used to reference - those member functions. */ + template arguments. + + If OVERLOAD is for one or more member functions, then ACCESS_PATH + is the base path used to reference those member functions. If + TF_NO_ACCESS_CONTROL is not set in FLAGS, and the address is + resolved to a member function, access checks will be performed and + errors issued if appropriate. */ static tree resolve_address_of_overloaded_function (tree target_type, @@ -5960,25 +6163,33 @@ resolve_address_of_overloaded_function (tree target_type, } else if (TREE_CHAIN (matches)) { - /* There were too many matches. */ + /* There were too many matches. First check if they're all + the same function. */ + tree match; - if (flags & tf_error) + fn = TREE_PURPOSE (matches); + for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match)) + if (!decls_match (fn, TREE_PURPOSE (matches))) + break; + + if (match) { - tree match; + if (flags & tf_error) + { + error ("converting overloaded function %qD to type %q#T is ambiguous", + DECL_NAME (OVL_FUNCTION (overload)), + target_type); - error ("converting overloaded function %qD to type %q#T is ambiguous", - DECL_NAME (OVL_FUNCTION (overload)), - target_type); + /* Since print_candidates expects the functions in the + TREE_VALUE slot, we flip them here. */ + for (match = matches; match; match = TREE_CHAIN (match)) + TREE_VALUE (match) = TREE_PURPOSE (match); - /* Since print_candidates expects the functions in the - TREE_VALUE slot, we flip them here. */ - for (match = matches; match; match = TREE_CHAIN (match)) - TREE_VALUE (match) = TREE_PURPOSE (match); + print_candidates (matches); + } - print_candidates (matches); + return error_mark_node; } - - return error_mark_node; } /* Good, exactly one match. Now, convert it to the correct type. */ @@ -5992,10 +6203,10 @@ resolve_address_of_overloaded_function (tree target_type, if (!(flags & tf_error)) return error_mark_node; - pedwarn ("assuming pointer to member %qD", fn); + permerror (input_location, "assuming pointer to member %qD", fn); if (!explained) { - pedwarn ("(a pointer to member can only be formed with %<&%E%>)", fn); + inform (input_location, "(a pointer to member can only be formed with %<&%E%>)", fn); explained = 1; } } @@ -6006,22 +6217,28 @@ resolve_address_of_overloaded_function (tree target_type, function will be marked as used at this point. */ if (!(flags & tf_conv)) { + /* Make =delete work with SFINAE. */ + if (DECL_DELETED_FN (fn) && !(flags & tf_error)) + return error_mark_node; + mark_used (fn); - /* We could not check access when this expression was originally - created since we did not know at that time to which function - the expression referred. */ - if (DECL_FUNCTION_MEMBER_P (fn)) - { - gcc_assert (access_path); - perform_or_defer_access_check (access_path, fn, fn); - } + } + + /* We could not check access to member functions when this + expression was originally created since we did not know at that + time to which function the expression referred. */ + if (!(flags & tf_no_access_control) + && DECL_FUNCTION_MEMBER_P (fn)) + { + gcc_assert (access_path); + perform_or_defer_access_check (access_path, fn, fn); } if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type)) - return build_unary_op (ADDR_EXPR, fn, 0); + return cp_build_unary_op (ADDR_EXPR, fn, 0, flags); else { - /* The target must be a REFERENCE_TYPE. Above, build_unary_op + /* The target must be a REFERENCE_TYPE. Above, cp_build_unary_op will mark the function as addressed, but here we must do it explicitly. */ cxx_mark_addressable (fn); @@ -6263,7 +6480,7 @@ is_empty_class (tree type) if (type == error_mark_node) return 0; - if (! IS_AGGR_TYPE (type)) + if (! CLASS_TYPE_P (type)) return 0; /* In G++ 3.2, whether or not a class was empty was determined by @@ -6303,6 +6520,37 @@ contains_empty_class_p (tree type) return false; } +/* Returns true if TYPE contains no actual data, just various + possible combinations of empty classes. */ + +bool +is_really_empty_class (tree type) +{ + if (is_empty_class (type)) + return true; + if (CLASS_TYPE_P (type)) + { + tree field; + tree binfo; + tree base_binfo; + int i; + + for (binfo = TYPE_BINFO (type), i = 0; + BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) + if (!is_really_empty_class (BINFO_TYPE (base_binfo))) + return false; + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL + && !DECL_ARTIFICIAL (field) + && !is_really_empty_class (TREE_TYPE (field))) + return false; + return true; + } + else if (TREE_CODE (type) == ARRAY_TYPE) + return is_really_empty_class (TREE_TYPE (type)); + return false; +} + /* Note that NAME was looked up while the current class was being defined and that the result of that lookup was DECL. */ @@ -6355,8 +6603,8 @@ note_name_declared_in_class (tree name, tree decl) A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. */ - pedwarn ("declaration of %q#D", decl); - pedwarn ("changes meaning of %qD from %q+#D", + permerror (input_location, "declaration of %q#D", decl); + permerror (input_location, "changes meaning of %qD from %q+#D", DECL_NAME (OVL_CURRENT (decl)), (tree) n->value); } } @@ -7297,7 +7545,7 @@ build_vtbl_initializer (tree binfo, We first check this in update_vtable_entry_for_fn, so we handle restored primary bases properly; we also need to do it here so we - zero out unused slots in ctor vtables, rather than filling themff + zero out unused slots in ctor vtables, rather than filling them with erroneous values (though harmless, apart from relocation costs). */ for (b = binfo; ; b = get_primary_binfo (b)) @@ -7362,7 +7610,6 @@ build_vtbl_initializer (tree binfo, TREE_OPERAND (init, 0), build_int_cst (NULL_TREE, i)); TREE_CONSTANT (fdesc) = 1; - TREE_INVARIANT (fdesc) = 1; vfun_inits = tree_cons (NULL_TREE, fdesc, vfun_inits); }