X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gcc%2Fcp%2Fdecl.c;h=d883da6b6406a84fc85990ef784f5ea63995cd92;hb=305c089a9f8347470aa79f7dabed0252c9f83cfa;hp=26e9847f4fd0ebdf0d0086cf888d83dde36d6236;hpb=14a3430e4f2c0266216d904b51c65d299abeb0c9;p=gcc.git diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 26e9847f4fd..d883da6b640 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1,6 +1,6 @@ /* Process declarations and variables for C++ compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -71,7 +71,7 @@ static void require_complete_types_for_parms (tree); static int ambi_op_p (enum tree_code); static int unary_op_p (enum tree_code); static void push_local_name (tree); -static tree grok_reference_init (tree, tree, tree, tree *, int); +static tree grok_reference_init (tree, tree, tree, int); static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *, int, int, tree); static int check_static_variable_definition (tree, tree); @@ -91,7 +91,7 @@ static tree lookup_and_check_tag (enum tag_types, tree, tag_scope, bool); static int walk_namespaces_r (tree, walk_namespaces_fn, void *); static void maybe_deduce_size_from_array_init (tree, tree); static void layout_var_decl (tree); -static tree check_initializer (tree, tree, int, tree *); +static tree check_initializer (tree, tree, int, VEC(tree,gc) **); static void make_rtl_for_nonlocal_decl (tree, tree, const char *); static void save_function_data (tree); static void copy_type_enum (tree , tree); @@ -952,12 +952,15 @@ decls_match (tree newdecl, tree olddecl) interested in their types. */ return 0; + gcc_assert (DECL_P (newdecl)); + if (TREE_CODE (newdecl) == FUNCTION_DECL) { tree f1 = TREE_TYPE (newdecl); tree f2 = TREE_TYPE (olddecl); tree p1 = TYPE_ARG_TYPES (f1); tree p2 = TYPE_ARG_TYPES (f2); + tree r2; /* Specializations of different templates are different functions even if they have the same type. */ @@ -986,7 +989,14 @@ decls_match (tree newdecl, tree olddecl) if (TREE_CODE (f1) != TREE_CODE (f2)) return 0; - if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2))) + /* A declaration with deduced return type should use its pre-deduction + type for declaration matching. */ + if (FNDECL_USED_AUTO (olddecl)) + r2 = DECL_STRUCT_FUNCTION (olddecl)->language->x_auto_return_pattern; + else + r2 = TREE_TYPE (f2); + + if (same_type_p (TREE_TYPE (f1), r2)) { if (!prototype_p (f2) && DECL_EXTERN_C_P (olddecl) && (DECL_BUILT_IN (olddecl) @@ -1203,6 +1213,21 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) || TREE_TYPE (olddecl) == error_mark_node) return error_mark_node; + if (UDLIT_OPER_P (DECL_NAME (newdecl)) + && UDLIT_OPER_P (DECL_NAME (olddecl))) + { + if (TREE_CODE (newdecl) == TEMPLATE_DECL + && TREE_CODE (olddecl) != TEMPLATE_DECL + && check_raw_literal_operator (olddecl)) + error ("literal operator template %q+D conflicts with" + " raw literal operator %qD", newdecl, olddecl); + else if (TREE_CODE (newdecl) != TEMPLATE_DECL + && TREE_CODE (olddecl) == TEMPLATE_DECL + && check_raw_literal_operator (newdecl)) + error ("raw literal operator %q+D conflicts with" + " literal operator template %qD", newdecl, olddecl); + } + if (DECL_P (olddecl) && TREE_CODE (newdecl) == FUNCTION_DECL && TREE_CODE (olddecl) == FUNCTION_DECL @@ -1469,7 +1494,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) { error ("new declaration %q#D", newdecl); - error ("ambiguates old declaration %q+#D", olddecl); + if (FNDECL_USED_AUTO (olddecl)) + error_at (DECL_SOURCE_LOCATION (olddecl), "ambiguates old " + "declaration with deduced return type"); + else + error ("ambiguates old declaration %q+#D", olddecl); return error_mark_node; } else @@ -1683,7 +1712,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* Don't warn about extern decl followed by definition. */ && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)) /* Don't warn about friends, let add_friend take care of it. */ - && ! (newdecl_is_friend || DECL_FRIEND_P (olddecl))) + && ! (newdecl_is_friend || DECL_FRIEND_P (olddecl)) + /* Don't warn about declaration followed by specialization. */ + && (! DECL_TEMPLATE_SPECIALIZATION (newdecl) + || DECL_TEMPLATE_SPECIALIZATION (olddecl))) { warning (OPT_Wredundant_decls, "redundant redeclaration of %qD in same scope", newdecl); warning (OPT_Wredundant_decls, "previous declaration of %q+D", olddecl); @@ -2194,7 +2226,12 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) SET_DECL_INIT_PRIORITY (olddecl, DECL_INIT_PRIORITY (newdecl)); DECL_HAS_INIT_PRIORITY_P (olddecl) = 1; } - /* Likewise for DECL_USER_ALIGN and DECL_PACKED. */ + /* Likewise for DECL_ALIGN, DECL_USER_ALIGN and DECL_PACKED. */ + if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl)) + { + DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); + DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl); + } DECL_USER_ALIGN (olddecl) = DECL_USER_ALIGN (newdecl); if (TREE_CODE (newdecl) == FIELD_DECL) DECL_PACKED (olddecl) = DECL_PACKED (newdecl); @@ -2922,9 +2959,9 @@ tree define_label (location_t location, tree name) { tree ret; - timevar_start (TV_NAME_LOOKUP); + bool running = timevar_cond_start (TV_NAME_LOOKUP); ret = define_label_1 (location, name); - timevar_stop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, running); return ret; } @@ -3255,7 +3292,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, return error_mark_node; } - if (want_template && !DECL_CLASS_TEMPLATE_P (t)) + if (want_template && !DECL_TYPE_TEMPLATE_P (t)) { if (complain & tf_error) error ("% names %q#T, which is not a class template", @@ -3323,7 +3360,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list, if (tmpl && TREE_CODE (tmpl) == TYPE_DECL) tmpl = maybe_get_template_decl_from_type_decl (tmpl); - if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) + if (!tmpl || !DECL_TYPE_TEMPLATE_P (tmpl)) { if (complain & tf_error) error ("no class template named %q#T in %q#T", name, context); @@ -3619,10 +3656,6 @@ cxx_init_decl_processing (void) init_list_type_node = make_node (LANG_TYPE); record_unknown_type (init_list_type_node, "init list"); - dependent_lambda_return_type_node = make_node (LANG_TYPE); - record_unknown_type (dependent_lambda_return_type_node, - "undeduced lambda return type"); - { /* Make sure we get a unique function type, so we can give its pointer type a name. (This wins for gdb.) */ @@ -3986,6 +4019,8 @@ push_cp_library_fn (enum tree_code operator_code, tree type) operator_code, type); pushdecl (fn); + if (flag_tm) + apply_tm_attr (fn, get_identifier ("transaction_safe")); return fn; } @@ -4094,8 +4129,8 @@ fixup_anonymous_aggr (tree t) tree check_tag_decl (cp_decl_specifier_seq *declspecs) { - int saw_friend = declspecs->specs[(int)ds_friend] != 0; - int saw_typedef = declspecs->specs[(int)ds_typedef] != 0; + int saw_friend = decl_spec_seq_has_spec_p (declspecs, ds_friend); + int saw_typedef = decl_spec_seq_has_spec_p (declspecs, ds_typedef); /* If a class, struct, or enum type is declared by the DECLSPECS (i.e, if a class-specifier, enum-specifier, or non-typename elaborated-type-specifier appears in the DECLSPECS), @@ -4108,7 +4143,8 @@ check_tag_decl (cp_decl_specifier_seq *declspecs) else if (declspecs->redefined_builtin_type) { if (!in_system_header) - permerror (input_location, "redeclaration of C++ built-in type %qT", + permerror (declspecs->locations[ds_redefined_builtin_type_spec], + "redeclaration of C++ built-in type %qT", declspecs->redefined_builtin_type); return NULL_TREE; } @@ -4123,6 +4159,12 @@ check_tag_decl (cp_decl_specifier_seq *declspecs) error_p = true; if (declared_type == NULL_TREE && ! saw_friend && !error_p) permerror (input_location, "declaration does not declare anything"); + else if (declared_type != NULL_TREE && type_uses_auto (declared_type)) + { + error ("% can only be specified for variables " + "or function declarations"); + return error_mark_node; + } /* Check for an anonymous union. */ else if (declared_type && RECORD_OR_UNION_CODE_P (TREE_CODE (declared_type)) && TYPE_ANONYMOUS_P (declared_type)) @@ -4152,37 +4194,54 @@ check_tag_decl (cp_decl_specifier_seq *declspecs) SET_ANON_AGGR_TYPE_P (declared_type); if (TREE_CODE (declared_type) != UNION_TYPE && !in_system_header) - pedwarn (input_location, OPT_pedantic, "ISO C++ prohibits anonymous structs"); + pedwarn (input_location, OPT_Wpedantic, "ISO C++ prohibits anonymous structs"); } else { - if (declspecs->specs[(int)ds_inline] - || declspecs->specs[(int)ds_virtual]) + if (decl_spec_seq_has_spec_p (declspecs, ds_inline) + || decl_spec_seq_has_spec_p (declspecs, ds_virtual)) error ("%qs can only be specified for functions", - declspecs->specs[(int)ds_inline] + decl_spec_seq_has_spec_p (declspecs, ds_inline) ? "inline" : "virtual"); else if (saw_friend && (!current_class_type || current_scope () != current_class_type)) error ("% can only be specified inside a class"); - else if (declspecs->specs[(int)ds_explicit]) + else if (decl_spec_seq_has_spec_p (declspecs, ds_explicit)) error ("% can only be specified for constructors"); else if (declspecs->storage_class) error ("a storage class can only be specified for objects " "and functions"); - else if (declspecs->specs[(int)ds_const] - || declspecs->specs[(int)ds_volatile] - || declspecs->specs[(int)ds_restrict] - || declspecs->specs[(int)ds_thread]) + else if (decl_spec_seq_has_spec_p (declspecs, ds_const) + || decl_spec_seq_has_spec_p (declspecs, ds_volatile) + || decl_spec_seq_has_spec_p (declspecs, ds_restrict) + || decl_spec_seq_has_spec_p (declspecs, ds_thread)) error ("qualifiers can only be specified for objects " "and functions"); else if (saw_typedef) warning (0, "% was ignored in this declaration"); - else if (declspecs->specs[(int) ds_constexpr]) + else if (decl_spec_seq_has_spec_p (declspecs, ds_constexpr)) error ("% cannot be used for type declarations"); } + if (declspecs->attributes && warn_attributes && declared_type) + { + location_t loc; + if (!CLASS_TYPE_P (declared_type) + || !CLASSTYPE_TEMPLATE_INSTANTIATION (declared_type)) + /* For a non-template class, use the name location. */ + loc = location_of (declared_type); + else + /* For a template class (an explicit instantiation), use the + current location. */ + loc = input_location; + warning_at (loc, OPT_Wattributes, "attribute ignored in declaration " + "of %q#T", declared_type); + inform (loc, "attribute for %q#T must follow the %qs keyword", + declared_type, class_key_or_enum_as_string (declared_type)); + } + return declared_type; } @@ -4207,14 +4266,6 @@ shadow_tag (cp_decl_specifier_seq *declspecs) if (!t) return NULL_TREE; - if (declspecs->attributes) - { - warning (0, "attribute ignored in declaration of %q+#T", t); - warning (0, "attribute for %q+#T must follow the %qs keyword", - t, class_key_or_enum_as_string (t)); - - } - if (maybe_process_partial_specialization (t) == error_mark_node) return NULL_TREE; @@ -4280,8 +4331,11 @@ groktypename (cp_decl_specifier_seq *type_specifiers, deleted function, but 0 (SD_UNINITIALIZED) if this is a variable implicitly initialized via a default constructor. ATTRIBUTES and PREFIX_ATTRIBUTES are GNU attributes associated with this declaration. - *PUSHED_SCOPE_P is set to the scope entered in this function, if any; if - set, the caller is responsible for calling pop_scope. */ + + The scope represented by the context of the returned DECL is pushed + (if it is not the global namespace) and is assigned to + *PUSHED_SCOPE_P. The caller is then responsible for calling + pop_scope on *PUSHED_SCOPE_P if it is set. */ tree start_decl (const cp_declarator *declarator, @@ -4378,7 +4432,8 @@ start_decl (const cp_declarator *declarator, } /* If #pragma weak was used, mark the decl weak now. */ - maybe_apply_pragma_weak (decl); + if (!processing_template_decl) + maybe_apply_pragma_weak (decl); if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl) @@ -4418,7 +4473,7 @@ start_decl (const cp_declarator *declarator, error ("duplicate initialization of %qD", decl); if (duplicate_decls (decl, field, /*newdecl_is_friend=*/false)) decl = field; - if (declspecs->specs[(int) ds_constexpr] + if (decl_spec_seq_has_spec_p (declspecs, ds_constexpr) && !DECL_DECLARED_CONSTEXPR_P (field)) error ("%qD declared % outside its class", field); } @@ -4596,11 +4651,8 @@ start_decl_1 (tree decl, bool initialized) Quotes on semantics can be found in ARM 8.4.3. */ static tree -grok_reference_init (tree decl, tree type, tree init, tree *cleanup, - int flags) +grok_reference_init (tree decl, tree type, tree init, int flags) { - tree tmp; - if (init == NULL_TREE) { if ((DECL_LANG_SPECIFIC (decl) == 0 @@ -4617,7 +4669,7 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup, if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE) /* Note: default conversion is only called in very special cases. */ - init = decay_conversion (init); + init = decay_conversion (init, tf_warning_or_error); /* Convert INIT to the reference type TYPE. This may involve the creation of a temporary, whose lifetime must be the same as that @@ -4626,62 +4678,8 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup, DECL_INITIAL for local references (instead assigning to them explicitly); we need to allow the temporary to be initialized first. */ - tmp = initialize_reference (type, init, decl, cleanup, flags, - tf_warning_or_error); - if (DECL_DECLARED_CONSTEXPR_P (decl)) - { - tmp = cxx_constant_value (tmp); - DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) - = reduced_constant_expression_p (tmp); - } - - if (tmp == error_mark_node) - return NULL_TREE; - else if (tmp == NULL_TREE) - { - error ("cannot initialize %qT from %qT", type, TREE_TYPE (init)); - return NULL_TREE; - } - - if (TREE_STATIC (decl) && !TREE_CONSTANT (tmp)) - return tmp; - - DECL_INITIAL (decl) = tmp; - - return NULL_TREE; -} - -/* Subroutine of check_initializer. We're initializing a DECL of - std::initializer_list TYPE from a braced-init-list INIT, and need to - extend the lifetime of the underlying array to match that of the decl, - just like for reference initialization. CLEANUP is as for - grok_reference_init. */ - -static tree -build_init_list_var_init (tree decl, tree type, tree init, tree *array_init, - tree *cleanup) -{ - tree aggr_init, array, arrtype; - init = perform_implicit_conversion (type, init, tf_warning_or_error); - if (error_operand_p (init)) - return error_mark_node; - - aggr_init = TARGET_EXPR_INITIAL (init); - array = CONSTRUCTOR_ELT (aggr_init, 0)->value; - arrtype = TREE_TYPE (array); - STRIP_NOPS (array); - gcc_assert (TREE_CODE (array) == ADDR_EXPR); - array = TREE_OPERAND (array, 0); - /* If the array is constant, finish_compound_literal already made it a - static variable and we don't need to do anything here. */ - if (decl && TREE_CODE (array) == TARGET_EXPR) - { - tree var = set_up_extended_ref_temp (decl, array, cleanup, array_init); - var = build_address (var); - var = convert (arrtype, var); - CONSTRUCTOR_ELT (aggr_init, 0)->value = var; - } - return init; + return initialize_reference (type, init, flags, + tf_warning_or_error); } /* Designated initializers in arrays are not supported in GNU C++. @@ -5115,7 +5113,19 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p, /* Handle designated initializers, as an extension. */ if (d->cur->index) { - field = lookup_field_1 (type, d->cur->index, /*want_type=*/false); + if (TREE_CODE (d->cur->index) == INTEGER_CST) + { + if (complain & tf_error) + error ("%<[%E] =%> used in a GNU-style designated initializer" + " for class %qT", d->cur->index, type); + return error_mark_node; + } + + if (TREE_CODE (d->cur->index) == FIELD_DECL) + /* We already reshaped this. */ + gcc_assert (d->cur->index == field); + else + field = lookup_field_1 (type, d->cur->index, /*want_type=*/false); if (!field || TREE_CODE (field) != FIELD_DECL) { @@ -5151,6 +5161,24 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p, return new_init; } +/* Subroutine of reshape_init_r. We're in a context where C99 initializer + designators are not valid; either complain or return true to indicate + that reshape_init_r should return error_mark_node. */ + +static bool +has_designator_problem (reshape_iter *d, tsubst_flags_t complain) +{ + if (d->cur->index) + { + if (complain & tf_error) + error ("C99 designator %qE outside aggregate initializer", + d->cur->index); + else + return true; + } + return false; +} + /* Subroutine of reshape_init, which processes a single initializer (part of a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the iterator within the CONSTRUCTOR which points to the initializer to process. @@ -5166,6 +5194,10 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, if (error_operand_p (init)) return error_mark_node; + if (first_initializer_p && !CP_AGGREGATE_TYPE_P (type) + && has_designator_problem (d, complain)) + return error_mark_node; + if (TREE_CODE (type) == COMPLEX_TYPE) { /* A complex type can be initialized from one or two initializers, @@ -5186,6 +5218,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, VEC(constructor_elt, gc) *v = 0; CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, d->cur->value); + if (has_designator_problem (d, complain)) + return error_mark_node; d->cur++; init = build_constructor (init_list_type_node, v); } @@ -5233,7 +5267,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, valid aggregate initialization. */ && !first_initializer_p && (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init)) - || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL))) + || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL, + complain))) { d->cur++; return init; @@ -5265,6 +5300,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, array types (one value per array element). */ if (TREE_CODE (str_init) == STRING_CST) { + if (has_designator_problem (d, complain)) + return error_mark_node; d->cur++; return str_init; } @@ -5404,17 +5441,8 @@ static tree build_aggr_init_full_exprs (tree decl, tree init, int flags) { - int saved_stmts_are_full_exprs_p = 0; - if (building_stmt_list_p ()) - { - saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); - current_stmt_tree ()->stmts_are_full_exprs_p = 1; - } - init = build_aggr_init (decl, init, flags, tf_warning_or_error); - if (building_stmt_list_p ()) - current_stmt_tree ()->stmts_are_full_exprs_p = - saved_stmts_are_full_exprs_p; - return init; + gcc_assert (stmts_are_full_exprs_p ()); + return build_aggr_init (decl, init, flags, tf_warning_or_error); } /* Verify INIT (the initializer for DECL), and record the @@ -5425,7 +5453,7 @@ build_aggr_init_full_exprs (tree decl, tree init, int flags) evaluated dynamically to initialize DECL. */ static tree -check_initializer (tree decl, tree init, int flags, tree *cleanup) +check_initializer (tree decl, tree init, int flags, VEC(tree,gc) **cleanups) { tree type = TREE_TYPE (decl); tree init_code = NULL; @@ -5455,7 +5483,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) } else if (!COMPLETE_TYPE_P (type)) { - error ("%qD has incomplete type", decl); + error ("%q#D has incomplete type", decl); TREE_TYPE (decl) = error_mark_node; return NULL_TREE; } @@ -5494,19 +5522,26 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) } else if (!init && DECL_REALLY_EXTERN (decl)) ; - else if (TREE_CODE (type) == REFERENCE_TYPE) - init = grok_reference_init (decl, type, init, cleanup, flags); - else if (init || type_build_ctor_call (type)) + else if (init || type_build_ctor_call (type) + || TREE_CODE (type) == REFERENCE_TYPE) { - if (!init) + if (TREE_CODE (type) == REFERENCE_TYPE) + { + init = grok_reference_init (decl, type, init, flags); + flags |= LOOKUP_ALREADY_DIGESTED; + } + else if (!init) check_for_uninitialized_const_var (decl); /* Do not reshape constructors of vectors (they don't need to be reshaped. */ else if (BRACE_ENCLOSED_INITIALIZER_P (init)) { if (is_std_init_list (type)) - init = build_init_list_var_init (decl, type, init, - &extra_init, cleanup); + { + init = perform_implicit_conversion (type, init, + tf_warning_or_error); + flags |= LOOKUP_ALREADY_DIGESTED; + } else if (TYPE_NON_AGGREGATE_CLASS (type)) { /* Don't reshape if the class has constructors. */ @@ -5523,7 +5558,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) else { init = reshape_init (type, init, tf_warning_or_error); - if (cxx_dialect >= cxx0x && SCALAR_TYPE_P (type)) + if (SCALAR_TYPE_P (type)) check_narrowing (type, init); } } @@ -5535,9 +5570,10 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) if (type == error_mark_node) return NULL_TREE; - if (type_build_ctor_call (type) - || (CLASS_TYPE_P (type) - && !(init && BRACE_ENCLOSED_INITIALIZER_P (init)))) + if ((type_build_ctor_call (type) || CLASS_TYPE_P (type)) + && !(flags & LOOKUP_ALREADY_DIGESTED) + && !(init && BRACE_ENCLOSED_INITIALIZER_P (init) + && CP_AGGREGATE_TYPE_P (type))) { init_code = build_aggr_init_full_exprs (decl, init, flags); @@ -5579,7 +5615,13 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) if (init && TREE_CODE (init) != TREE_VEC) { - init_code = store_init_value (decl, init, flags); + /* In aggregate initialization of a variable, each element + initialization is a full-expression because there is no + enclosing expression. */ + gcc_assert (stmts_are_full_exprs_p ()); + + init_code = store_init_value (decl, init, cleanups, flags); + if (pedantic && TREE_CODE (type) == ARRAY_TYPE && DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST @@ -5941,7 +5983,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, tree asmspec_tree, int flags) { tree type; - tree cleanup; + VEC(tree,gc) *cleanups = NULL; const char *asmspec = NULL; int was_readonly = 0; bool var_definition_p = false; @@ -5964,9 +6006,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (type == error_mark_node) return; - /* Assume no cleanup is required. */ - cleanup = NULL_TREE; - /* If a name was specified, get the string. */ if (at_namespace_scope_p ()) asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree); @@ -5980,8 +6019,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, && (DECL_INITIAL (decl) || init)) DECL_INITIALIZED_IN_CLASS_P (decl) = 1; - auto_node = type_uses_auto (type); - if (auto_node) + if (TREE_CODE (decl) != FUNCTION_DECL + && (auto_node = type_uses_auto (type))) { tree d_init; if (init == NULL_TREE) @@ -6086,9 +6125,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, /* This variable seems to be a non-dependent constant, so process its initializer. If check_initializer returns non-null the initialization wasn't constant after all. */ - tree init_code = check_initializer (decl, init, flags, &cleanup); + tree init_code; + cleanups = make_tree_vector (); + init_code = check_initializer (decl, init, flags, &cleanups); if (init_code == NULL_TREE) init = NULL_TREE; + release_tree_vector (cleanups); } else if (!DECL_PRETTY_FUNCTION_P (decl)) /* Deduce array size even if the initializer is dependent. */ @@ -6187,7 +6229,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, error ("Java object %qD not allocated with %", decl); init = NULL_TREE; } - init = check_initializer (decl, init, flags, &cleanup); + cleanups = make_tree_vector (); + init = check_initializer (decl, init, flags, &cleanups); /* Thread-local storage cannot be dynamically initialized. */ if (DECL_THREAD_LOCAL_P (decl) && init) { @@ -6352,8 +6395,13 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, /* If a CLEANUP_STMT was created to destroy a temporary bound to a reference, insert it in the statement-tree now. */ - if (cleanup) - push_cleanup (decl, cleanup, false); + if (cleanups) + { + unsigned i; tree t; + FOR_EACH_VEC_ELT (tree, cleanups, i, t) + push_cleanup (decl, t, false); + release_tree_vector (cleanups); + } if (was_readonly) TREE_READONLY (decl) = 1; @@ -6489,7 +6537,7 @@ get_atexit_node (void) atexit_fndecl = build_library_fn_ptr (name, fn_type); mark_used (atexit_fndecl); pop_lang_context (); - atexit_node = decay_conversion (atexit_fndecl); + atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error); return atexit_node; } @@ -7345,6 +7393,47 @@ grokfndecl (tree ctype, if (IDENTIFIER_OPNAME_P (DECL_NAME (decl)) && !grok_op_properties (decl, /*complain=*/true)) return NULL_TREE; + else if (UDLIT_OPER_P (DECL_NAME (decl))) + { + bool long_long_unsigned_p; + bool long_double_p; + const char *suffix = NULL; + /* [over.literal]/6: Literal operators shall not have C linkage. */ + if (DECL_LANGUAGE (decl) == lang_c) + { + error ("literal operator with C linkage"); + return NULL_TREE; + } + + if (DECL_NAMESPACE_SCOPE_P (decl)) + { + if (!check_literal_operator_args (decl, &long_long_unsigned_p, + &long_double_p)) + { + error ("%qD has invalid argument list", decl); + return NULL_TREE; + } + + suffix = UDLIT_OP_SUFFIX (DECL_NAME (decl)); + if (long_long_unsigned_p) + { + if (cpp_interpret_int_suffix (suffix, strlen (suffix))) + warning (0, "integer suffix %<%s%>" + " shadowed by implementation", suffix); + } + else if (long_double_p) + { + if (cpp_interpret_float_suffix (suffix, strlen (suffix))) + warning (0, "floating point suffix %<%s%>" + " shadowed by implementation", suffix); + } + } + else + { + error ("%qD must be a non-member function", decl); + return NULL_TREE; + } + } if (funcdef_flag) /* Make the init_value nonzero so pushdecl knows this is not @@ -7361,6 +7450,13 @@ grokfndecl (tree ctype, if (ctype != NULL_TREE) grokclassfn (ctype, decl, flags); + /* 12.4/3 */ + if (cxx_dialect >= cxx0x + && DECL_DESTRUCTOR_P (decl) + && !TYPE_BEING_DEFINED (DECL_CONTEXT (decl)) + && !processing_template_decl) + deduce_noexcept_on_destructor (decl); + decl = check_explicit_specialization (orig_declarator, decl, template_count, 2 * funcdef_flag + @@ -7587,7 +7683,7 @@ grokvardecl (tree type, TREE_PUBLIC (decl) = DECL_EXTERNAL (decl); } - if (declspecs->specs[(int)ds_thread]) + if (decl_spec_seq_has_spec_p (declspecs, ds_thread)) DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); /* If the type of the decl has no linkage, make sure that we'll @@ -7752,7 +7848,10 @@ check_static_variable_definition (tree decl, tree type) return 0; else if (cxx_dialect >= cxx0x && !INTEGRAL_OR_ENUMERATION_TYPE_P (type)) { - if (literal_type_p (type)) + if (!COMPLETE_TYPE_P (type)) + error ("in-class initialization of static data member %q#D of " + "incomplete type", decl); + else if (literal_type_p (type)) permerror (input_location, "% needed for in-class initialization of " "static data member %q#D of non-integral type", decl); @@ -7780,7 +7879,7 @@ check_static_variable_definition (tree decl, tree type) "static member %qD", decl); else if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type)) - pedwarn (input_location, OPT_pedantic, "ISO C++ forbids initialization of member constant " + pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids initialization of member constant " "%qD of non-integral type %qT", decl, type); return 0; @@ -7953,9 +8052,9 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) else if (in_system_header) /* Allow them in system headers because glibc uses them. */; else if (name) - pedwarn (input_location, OPT_pedantic, "ISO C++ forbids zero-size array %qD", name); + pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array %qD", name); else - pedwarn (input_location, OPT_pedantic, "ISO C++ forbids zero-size array"); + pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array"); } } else if (TREE_CONSTANT (size) @@ -8081,7 +8180,7 @@ create_array_type_for_decl (tree name, tree type, tree size) /* 8.3.4/1: If the type of the identifier of D contains the auto type-specifier, the program is ill-formed. */ if (pedantic && type_uses_auto (type)) - pedwarn (input_location, OPT_pedantic, + pedwarn (input_location, OPT_Wpedantic, "declaration of %qD as array of %", name); /* If there are some types which cannot be array elements, @@ -8338,16 +8437,16 @@ grokdeclarator (const cp_declarator *declarator, bool parameter_pack_p = declarator? declarator->parameter_pack_p : false; bool template_type_arg = false; bool template_parm_flag = false; - bool constexpr_p = declspecs->specs[(int) ds_constexpr]; + bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr); const char *errmsg; - signed_p = declspecs->specs[(int)ds_signed]; - unsigned_p = declspecs->specs[(int)ds_unsigned]; - short_p = declspecs->specs[(int)ds_short]; - long_p = declspecs->specs[(int)ds_long]; - longlong = declspecs->specs[(int)ds_long] >= 2; + signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed); + unsigned_p = decl_spec_seq_has_spec_p (declspecs, ds_unsigned); + short_p = decl_spec_seq_has_spec_p (declspecs, ds_short); + long_p = decl_spec_seq_has_spec_p (declspecs, ds_long); + longlong = decl_spec_seq_has_spec_p (declspecs, ds_long_long); explicit_int128 = declspecs->explicit_int128_p; - thread_p = declspecs->specs[(int)ds_thread]; + thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread); if (decl_context == FUNCDEF) funcdef_flag = true, decl_context = NORMAL; @@ -8537,9 +8636,18 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } + if (dname + && TREE_CODE (dname) == IDENTIFIER_NODE + && UDLIT_OPER_P (dname) + && innermost_code != cdk_function) + { + error ("declaration of %qD as non-function", dname); + return error_mark_node; + } + if (dname && IDENTIFIER_OPNAME_P (dname)) { - if (declspecs->specs[(int)ds_typedef]) + if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)) { error ("declaration of %qD as %", dname); return error_mark_node; @@ -8577,7 +8685,7 @@ grokdeclarator (const cp_declarator *declarator, if (name == NULL) name = decl_context == PARM ? "parameter" : "type name"; - if (constexpr_p && declspecs->specs[(int)ds_typedef]) + if (constexpr_p && decl_spec_seq_has_spec_p (declspecs, ds_typedef)) { error ("% cannot appear in a typedef declaration"); return error_mark_node; @@ -8667,7 +8775,7 @@ grokdeclarator (const cp_declarator *declarator, else if (! is_main) permerror (input_location, "ISO C++ forbids declaration of %qs with no type", name); else if (pedantic) - pedwarn (input_location, OPT_pedantic, + pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids declaration of %qs with no type", name); else warning (OPT_Wreturn_type, @@ -8686,7 +8794,7 @@ grokdeclarator (const cp_declarator *declarator, explicit_int128 = false; } else if (pedantic && ! in_system_header) - pedwarn (input_location, OPT_pedantic, + pedwarn (input_location, OPT_Wpedantic, "ISO C++ does not support %<__int128%> for %qs", name); } @@ -8737,7 +8845,7 @@ grokdeclarator (const cp_declarator *declarator, ok = 1; if (!explicit_int && !defaulted_int && !explicit_char && !explicit_int128 && pedantic) { - pedwarn (input_location, OPT_pedantic, + pedwarn (input_location, OPT_Wpedantic, "long, short, signed or unsigned used invalidly for %qs", name); if (flag_pedantic_errors) @@ -8803,7 +8911,7 @@ grokdeclarator (const cp_declarator *declarator, else if (short_p) type = short_integer_type_node; - if (declspecs->specs[(int)ds_complex]) + if (decl_spec_seq_has_spec_p (declspecs, ds_complex)) { if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE) error ("complex invalid for %qs", name); @@ -8827,16 +8935,27 @@ grokdeclarator (const cp_declarator *declarator, } type_quals = TYPE_UNQUALIFIED; - if (declspecs->specs[(int)ds_const]) + if (decl_spec_seq_has_spec_p (declspecs, ds_const)) type_quals |= TYPE_QUAL_CONST; - if (declspecs->specs[(int)ds_volatile]) + if (decl_spec_seq_has_spec_p (declspecs, ds_volatile)) type_quals |= TYPE_QUAL_VOLATILE; - if (declspecs->specs[(int)ds_restrict]) + if (decl_spec_seq_has_spec_p (declspecs, ds_restrict)) type_quals |= TYPE_QUAL_RESTRICT; if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED) error ("qualifiers are not allowed on declaration of %", ctor_return_type); + /* If we're using the injected-class-name to form a compound type or a + declaration, replace it with the underlying class so we don't get + redundant typedefs in the debug output. But if we are returning the + type unchanged, leave it alone so that it's available to + maybe_get_template_decl_from_type_decl. */ + if (CLASS_TYPE_P (type) + && DECL_SELF_REFERENCE_P (TYPE_NAME (type)) + && type == TREE_TYPE (TYPE_NAME (type)) + && (declarator || type_quals)) + type = DECL_ORIGINAL_TYPE (TYPE_NAME (type)); + type_quals |= cp_type_quals (type); type = cp_build_qualified_type_real (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl) @@ -8845,9 +8964,9 @@ grokdeclarator (const cp_declarator *declarator, type_quals = cp_type_quals (type); staticp = 0; - inlinep = !! declspecs->specs[(int)ds_inline]; - virtualp = !! declspecs->specs[(int)ds_virtual]; - explicitp = !! declspecs->specs[(int)ds_explicit]; + inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline); + virtualp = decl_spec_seq_has_spec_p (declspecs, ds_virtual); + explicitp = decl_spec_seq_has_spec_p (declspecs, ds_explicit); storage_class = declspecs->storage_class; if (storage_class == sc_static) @@ -8859,7 +8978,7 @@ grokdeclarator (const cp_declarator *declarator, storage_class = sc_none; staticp = 0; } - friendp = !! declspecs->specs[(int)ds_friend]; + friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend); if (dependent_name && !friendp) { @@ -8870,7 +8989,7 @@ grokdeclarator (const cp_declarator *declarator, /* Issue errors about use of storage classes for parameters. */ if (decl_context == PARM) { - if (declspecs->specs[(int)ds_typedef]) + if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)) { error ("typedef declaration invalid in parameter declaration"); return error_mark_node; @@ -8914,7 +9033,7 @@ grokdeclarator (const cp_declarator *declarator, && ((storage_class && storage_class != sc_extern && storage_class != sc_static) - || declspecs->specs[(int)ds_typedef])) + || decl_spec_seq_has_spec_p (declspecs, ds_typedef))) { error ("multiple storage classes in declaration of %qs", name); thread_p = false; @@ -8928,7 +9047,7 @@ grokdeclarator (const cp_declarator *declarator, && (storage_class == sc_register || storage_class == sc_auto)) ; - else if (declspecs->specs[(int)ds_typedef]) + else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)) ; else if (decl_context == FIELD /* C++ allows static class elements. */ @@ -9075,6 +9194,11 @@ grokdeclarator (const cp_declarator *declarator, error ("%qs declared as function returning an array", name); return error_mark_node; } + /* When decl_context == NORMAL we emit a better error message + later in abstract_virtuals_error. */ + if (decl_context == TYPENAME && ABSTRACT_CLASS_TYPE_P (type)) + error ("%qs declared as function returning an abstract " + "class type", name); /* Pick up type qualifiers which should be applied to `this'. */ memfn_quals = declarator->u.function.qualifiers; @@ -9098,13 +9222,17 @@ grokdeclarator (const cp_declarator *declarator, { if (!declarator->u.function.late_return_type) { - error ("%qs function uses % type specifier without" - " late return type", name); - return error_mark_node; + if (current_class_type + && LAMBDA_TYPE_P (current_class_type)) + /* OK for C++11 lambdas. */; + else if (cxx_dialect < cxx1y) + pedwarn (input_location, 0, "%qs function uses " + "% type specifier without trailing " + "return type", name); } else if (!is_auto (type)) { - error ("%qs function with late return type has" + error ("%qs function with trailing return type has" " %qT as its type rather than plain %", name, type); return error_mark_node; @@ -9112,8 +9240,14 @@ grokdeclarator (const cp_declarator *declarator, } else if (declarator->u.function.late_return_type) { - error ("%qs function with late return type not declared" - " with % type specifier", name); + if (cxx_dialect < cxx0x) + /* Not using maybe_warn_cpp0x because this should + always be an error. */ + error ("trailing return type only available with " + "-std=c++11 or -std=gnu++11"); + else + error ("%qs function with trailing return type not " + "declared with % type specifier", name); return error_mark_node; } } @@ -9512,7 +9646,7 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } } - else if (declspecs->specs[(int)ds_typedef] + else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef) && current_class_type) { error ("cannot declare member %<%T::%s%> within %qT", @@ -9544,12 +9678,12 @@ grokdeclarator (const cp_declarator *declarator, error ("non-parameter %qs cannot be a parameter pack", name); } - /* Did array size calculations overflow? */ - + /* Did array size calculations overflow or does the array cover more + than half of the address-space? */ if (TREE_CODE (type) == ARRAY_TYPE && COMPLETE_TYPE_P (type) && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST - && TREE_OVERFLOW (TYPE_SIZE_UNIT (type))) + && ! valid_constant_size_p (TYPE_SIZE_UNIT (type))) { error ("size of array %qs is too large", name); /* If we proceed with the array type as it is, we'll eventually @@ -9583,7 +9717,8 @@ grokdeclarator (const cp_declarator *declarator, error ("non-member %qs cannot be declared %", name); storage_class = sc_none; } - else if (decl_context == TYPENAME || declspecs->specs[(int)ds_typedef]) + else if (decl_context == TYPENAME + || decl_spec_seq_has_spec_p (declspecs, ds_typedef)) { error ("non-object member %qs cannot be declared %", name); storage_class = sc_none; @@ -9613,7 +9748,7 @@ grokdeclarator (const cp_declarator *declarator, } /* If this is declaring a typedef name, return a TYPE_DECL. */ - if (declspecs->specs[(int)ds_typedef] && decl_context != TYPENAME) + if (decl_spec_seq_has_spec_p (declspecs, ds_typedef) && decl_context != TYPENAME) { tree decl; @@ -9725,6 +9860,11 @@ grokdeclarator (const cp_declarator *declarator, memfn_quals != TYPE_UNQUALIFIED, inlinep, friendp, raises != NULL_TREE); + if (decl_spec_seq_has_spec_p (declspecs, ds_alias)) + /* Acknowledge that this was written: + `using analias = atype;'. */ + TYPE_DECL_ALIAS_P (decl) = 1; + return decl; } @@ -9928,6 +10068,13 @@ grokdeclarator (const cp_declarator *declarator, } else if (decl_context == FIELD) { + if (!staticp && TREE_CODE (type) != METHOD_TYPE + && type_uses_auto (type)) + { + error ("non-static data member declared %"); + type = error_mark_node; + } + /* The C99 flexible array extension. */ if (!staticp && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE) @@ -10127,7 +10274,8 @@ grokdeclarator (const cp_declarator *declarator, { /* C++ allows static class members. All other work for this is done by grokfield. */ - decl = build_lang_decl (VAR_DECL, unqualified_id, type); + decl = build_lang_decl_loc (declarator->id_loc, + VAR_DECL, unqualified_id, type); set_linkage_for_static_data_member (decl); /* Even if there is an in-class initialization, DECL is considered undefined until an out-of-class @@ -10165,9 +10313,17 @@ grokdeclarator (const cp_declarator *declarator, } if (initialized) - /* An attempt is being made to initialize a non-static - member. This is new in C++11. */ - maybe_warn_cpp0x (CPP0X_NSDMI); + { + /* An attempt is being made to initialize a non-static + member. This is new in C++11. */ + maybe_warn_cpp0x (CPP0X_NSDMI); + + /* If this has been parsed with static storage class, but + errors forced staticp to be cleared, ensure NSDMI is + not present. */ + if (declspecs->storage_class == sc_static) + DECL_INITIAL (decl) = error_mark_node; + } } bad_specifiers (decl, BSP_FIELD, virtualp, @@ -10203,15 +10359,15 @@ grokdeclarator (const cp_declarator *declarator, and `extern' makes no difference. */ if (! toplevel_bindings_p () && (storage_class == sc_static - || declspecs->specs[(int)ds_inline]) + || decl_spec_seq_has_spec_p (declspecs, ds_inline)) && pedantic) { if (storage_class == sc_static) - pedwarn (input_location, OPT_pedantic, + pedwarn (input_location, OPT_Wpedantic, "% specified invalid for function %qs " "declared out of global scope", name); else - pedwarn (input_location, OPT_pedantic, + pedwarn (input_location, OPT_Wpedantic, "% specifier invalid for function %qs " "declared out of global scope", name); } @@ -10305,7 +10461,7 @@ grokdeclarator (const cp_declarator *declarator, } if (storage_class == sc_extern && pedantic) { - pedwarn (input_location, OPT_pedantic, + pedwarn (input_location, OPT_Wpedantic, "cannot explicitly declare member %q#D to have " "extern linkage", decl); storage_class = sc_none; @@ -10407,7 +10563,9 @@ static tree local_variable_p_walkfn (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) { - if (local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp)) + /* Check DECL_NAME to avoid including temporaries. We don't check + DECL_ARTIFICIAL because we do want to complain about 'this'. */ + if (local_variable_p (*tp) && DECL_NAME (*tp)) return *tp; else if (TYPE_P (*tp)) *walk_subtrees = 0; @@ -10415,7 +10573,6 @@ local_variable_p_walkfn (tree *tp, int *walk_subtrees, return NULL_TREE; } - /* Check that ARG, which is a default-argument expression for a parameter DECL, is valid. Returns ARG, or ERROR_MARK_NODE, if something goes wrong. DECL may also be a _TYPE node, rather than a @@ -10454,7 +10611,8 @@ check_default_argument (tree decl, tree arg) A default argument expression is implicitly converted to the parameter type. */ if (!TREE_TYPE (arg) - || !can_convert_arg (decl_type, TREE_TYPE (arg), arg, LOOKUP_NORMAL)) + || !can_convert_arg (decl_type, TREE_TYPE (arg), arg, LOOKUP_NORMAL, + tf_warning_or_error)) { if (decl) error ("default argument for %q#D has type %qT", @@ -10466,6 +10624,17 @@ check_default_argument (tree decl, tree arg) return error_mark_node; } + if (warn_zero_as_null_pointer_constant + && c_inhibit_evaluation_warnings == 0 + && TYPE_PTR_OR_PTRMEM_P (decl_type) + && null_ptr_cst_p (arg) + && !NULLPTR_TYPE_P (TREE_TYPE (arg))) + { + warning (OPT_Wzero_as_null_pointer_constant, + "zero as null pointer constant"); + return nullptr_node; + } + /* [dcl.fct.default] Local variables shall not be used in default argument @@ -10476,7 +10645,10 @@ check_default_argument (tree decl, tree arg) var = cp_walk_tree_without_duplicates (&arg, local_variable_p_walkfn, NULL); if (var) { - error ("default argument %qE uses local variable %qD", arg, var); + if (DECL_NAME (var) == this_identifier) + permerror (input_location, "default argument %qE uses %qD", arg, var); + else + error ("default argument %qE uses local variable %qD", arg, var); return error_mark_node; } @@ -11256,7 +11428,7 @@ grok_op_properties (tree decl, bool complain) if (operator_code == POSTINCREMENT_EXPR || operator_code == POSTDECREMENT_EXPR) { - pedwarn (input_location, OPT_pedantic, "%qD cannot have default arguments", + pedwarn (input_location, OPT_Wpedantic, "%qD cannot have default arguments", decl); } else @@ -11304,6 +11476,9 @@ check_elaborated_type_specifier (enum tag_types tag_code, { tree type; + if (decl == error_mark_node) + return error_mark_node; + /* In the case of: struct S { struct S *p; }; @@ -11323,10 +11498,15 @@ check_elaborated_type_specifier (enum tag_types tag_code, type, tag_name (tag_code)); return error_mark_node; } + /* Accept bound template template parameters. */ + else if (allow_template_p + && TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM) + ; /* [dcl.type.elab] - If the identifier resolves to a typedef-name or a template - type-parameter, the elaborated-type-specifier is ill-formed. + If the identifier resolves to a typedef-name or the + simple-template-id resolves to an alias template + specialization, the elaborated-type-specifier is ill-formed. In other words, the only legitimate declaration to use in the elaborated type specifier is the implicit typedef created when @@ -11335,8 +11515,13 @@ check_elaborated_type_specifier (enum tag_types tag_code, && !DECL_SELF_REFERENCE_P (decl) && tag_code != typename_type) { - error ("using typedef-name %qD after %qs", decl, tag_name (tag_code)); - error ("%q+D has a previous declaration here", decl); + if (alias_template_specialization_p (type)) + error ("using alias template specialization %qT after %qs", + type, tag_name (tag_code)); + else + error ("using typedef-name %qD after %qs", decl, tag_name (tag_code)); + inform (DECL_SOURCE_LOCATION (decl), + "%qD has a previous declaration here", decl); return error_mark_node; } else if (TREE_CODE (type) != RECORD_TYPE @@ -11761,7 +11946,7 @@ xref_basetypes (tree ref, tree base_list) TYPE_FOR_JAVA (ref) = 1; base_binfo = NULL_TREE; - if (CLASS_TYPE_P (basetype) && !dependent_type_p (basetype)) + if (CLASS_TYPE_P (basetype) && !dependent_scope_p (basetype)) { base_binfo = TYPE_BINFO (basetype); /* The original basetype could have been a typedef'd type. */ @@ -11806,8 +11991,8 @@ xref_basetypes (tree ref, tree base_list) BINFO_BASE_ACCESS_APPEND (binfo, access); } - if (VEC_space (tree, CLASSTYPE_VBASECLASSES (ref), 1)) - /* If we have space in the vbase vector, we must have shared at + if (VEC_length (tree, CLASSTYPE_VBASECLASSES (ref)) < max_vbases) + /* If we didn't get max_vbases vbases, we must have shared at least one of them, and are therefore diamond shaped. */ CLASSTYPE_DIAMOND_SHAPED_P (ref) = 1; @@ -11846,15 +12031,19 @@ xref_basetypes (tree ref, tree base_list) static void copy_type_enum (tree dst, tree src) { - TYPE_MIN_VALUE (dst) = TYPE_MIN_VALUE (src); - TYPE_MAX_VALUE (dst) = TYPE_MAX_VALUE (src); - TYPE_SIZE (dst) = TYPE_SIZE (src); - TYPE_SIZE_UNIT (dst) = TYPE_SIZE_UNIT (src); - SET_TYPE_MODE (dst, TYPE_MODE (src)); - TYPE_PRECISION (dst) = TYPE_PRECISION (src); - TYPE_ALIGN (dst) = TYPE_ALIGN (src); - TYPE_USER_ALIGN (dst) = TYPE_USER_ALIGN (src); - TYPE_UNSIGNED (dst) = TYPE_UNSIGNED (src); + tree t; + for (t = dst; t; t = TYPE_NEXT_VARIANT (t)) + { + TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (src); + TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (src); + TYPE_SIZE (t) = TYPE_SIZE (src); + TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (src); + SET_TYPE_MODE (dst, TYPE_MODE (src)); + TYPE_PRECISION (t) = TYPE_PRECISION (src); + TYPE_ALIGN (t) = TYPE_ALIGN (src); + TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (src); + TYPE_UNSIGNED (t) = TYPE_UNSIGNED (src); + } } /* Begin compiling the definition of an enumeration type. @@ -11956,8 +12145,23 @@ start_enum (tree name, tree enumtype, tree underlying_type, *is_new = true; } prevtype = enumtype; - enumtype = cxx_make_type (ENUMERAL_TYPE); - enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current); + + /* Do not push the decl more than once, unless we need to + compare underlying types at instantiation time */ + if (!enumtype + || TREE_CODE (enumtype) != ENUMERAL_TYPE + || (underlying_type + && dependent_type_p (underlying_type)) + || (ENUM_UNDERLYING_TYPE (enumtype) + && dependent_type_p (ENUM_UNDERLYING_TYPE (enumtype)))) + { + enumtype = cxx_make_type (ENUMERAL_TYPE); + enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current); + } + else + enumtype = xref_tag (enum_type, name, /*tag_scope=*/ts_current, + false); + if (enumtype == error_mark_node) return error_mark_node; @@ -12209,9 +12413,12 @@ finish_enum (tree enumtype) return; } - /* Here there should not be any variants of this type. */ + /* If this is a forward declaration, there should not be any variants, + though we can get a variant in the middle of an enum-specifier with + wacky code like 'enum E { e = sizeof(const E*) };' */ gcc_assert (enumtype == TYPE_MAIN_VARIANT (enumtype) - && !TYPE_NEXT_VARIANT (enumtype)); + && (TYPE_VALUES (enumtype) + || !TYPE_NEXT_VARIANT (enumtype))); } /* Build and install a CONST_DECL for an enumeration constant of the @@ -12242,14 +12449,11 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc) { value = cxx_constant_value (value); - if (TREE_CODE (value) == INTEGER_CST - && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (value))) - { - value = perform_integral_promotions (value); - } - else + if (TREE_CODE (value) != INTEGER_CST + || ! INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (value))) { - error ("enumerator value for %qD is not an integer constant", name); + error ("enumerator value for %qD is not an integer constant", + name); value = NULL_TREE; } } @@ -12419,7 +12623,8 @@ check_function_type (tree decl, tree current_function_parms) /* In a function definition, arg types must be complete. */ require_complete_types_for_parms (current_function_parms); - if (dependent_type_p (return_type)) + if (dependent_type_p (return_type) + || type_uses_auto (return_type)) return; if (!COMPLETE_OR_VOID_TYPE_P (return_type) || (TYPE_FOR_JAVA (return_type) && MAYBE_CLASS_TYPE_P (return_type))) @@ -12590,6 +12795,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) /* Build the return declaration for the function. */ restype = TREE_TYPE (fntype); + if (DECL_RESULT (decl1) == NULL_TREE) { tree resdecl; @@ -12698,6 +12904,12 @@ start_preparsed_function (tree decl1, tree attrs, int flags) current_stmt_tree ()->stmts_are_full_exprs_p = 1; current_binding_level = bl; + if (!processing_template_decl && type_uses_auto (restype)) + { + FNDECL_USED_AUTO (decl1) = true; + current_function_auto_return_pattern = restype; + } + /* Start the statement-tree, start the tree now. */ DECL_SAVED_TREE (decl1) = push_stmt_list (); @@ -12999,6 +13211,7 @@ save_function_data (tree decl) f->base.x_stmt_tree.x_cur_stmt_list = NULL; f->bindings = NULL; f->x_local_names = NULL; + f->base.local_typedefs = NULL; } @@ -13311,6 +13524,24 @@ finish_function (int flags) of curly braces for a function. */ gcc_assert (stmts_are_full_exprs_p ()); + /* If there are no return statements in a function with auto return type, + the return type is void. But if the declared type is something like + auto*, this is an error. */ + if (!processing_template_decl && FNDECL_USED_AUTO (fndecl) + && TREE_TYPE (fntype) == current_function_auto_return_pattern) + { + if (!is_auto (current_function_auto_return_pattern) + && !current_function_returns_value && !current_function_returns_null) + { + error ("no return statements in function returning %qT", + current_function_auto_return_pattern); + inform (input_location, "only plain % return type can be " + "deduced to %"); + } + apply_deduced_return_type (fndecl, void_type_node); + fntype = TREE_TYPE (fndecl); + } + /* Save constexpr function body before it gets munged by the NRV transformation. */ maybe_save_function_definition (fndecl); @@ -13677,8 +13908,17 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain) cleanup = call; } + /* build_delete sets the location of the destructor call to the + current location, even though the destructor is going to be + called later, at the end of the current scope. This can lead to + a "jumpy" behaviour for users of debuggers when they step around + the end of the block. So let's unset the location of the + destructor call instead. */ + if (cleanup != NULL && EXPR_P (cleanup)) + SET_EXPR_LOCATION (cleanup, UNKNOWN_LOCATION); return cleanup; } + /* When a stmt has been parsed, this function is called. */ @@ -13754,6 +13994,7 @@ cp_tree_node_structure (union lang_tree_node * t) case TRAIT_EXPR: return TS_CP_TRAIT_EXPR; case LAMBDA_EXPR: return TS_CP_LAMBDA_EXPR; case TEMPLATE_INFO: return TS_CP_TEMPLATE_INFO; + case USERDEF_LITERAL: return TS_CP_USERDEF_LITERAL; default: return TS_CP_GENERIC; } }