diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-19 18:19:39 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-19 18:19:39 +0000 |
commit | e56043cd2c207982e812ce6fcecb7353dea58363 (patch) | |
tree | 01a6f37ad5a9ae6b18bdc20f052b04e19b4255c0 /gcc/cp | |
parent | 2e02a1a4548f2ee1ea519c88e68b20621ad16fcc (diff) | |
download | gcc-e56043cd2c207982e812ce6fcecb7353dea58363.tar.gz |
2010-09-19 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 164348, with some improvements
in gcc/melt-runtime.[ch]
2010-09-19 Basile Starynkevitch <basile@starynkevitch.net>
[[merged with trunk rev.164348, so improved MELT runtime!]]
* gcc/melt-runtime.h: improved comments.
(melt_debug_garbcoll, melt_debuggc_eprintf): Moved from melt-runtime.c.
(melt_obmag_string): New declaration.
(struct meltobject_st, struct meltclosure_st, struct
meltroutine_st, struct meltmixbigint_st, struct meltstring_st):
using GTY variable_size and @@MELTGTY@@ comment.
(melt_mark_special): added debug print.
* gcc/melt-runtime.c: Improved comments.
Include bversion.h, realmpfr.h, gimple-pretty-print.h.
(ggc_force_collect) Declared external.
(melt_forward_counter): Added.
(melt_obmag_string): New function.
(melt_alptr_1, melt_alptr_2, melt_break_alptr_1_at)
(melt_break_alptr_2_at, melt_break_alptr_1,melt_break_alptr_1)
(melt_allocate_young_gc_zone, melt_free_young_gc_zone): New.
(delete_special, meltgc_make_special): Improved debug printf and
use melt_break_alptr_1...
(ggc_alloc_*) macros defined for backport to GCC 4.5
(melt_forwarded_copy): Don't clear the new destination zone in old
GGC heap.
(meltgc_add_out_raw_len): Use ggc_alloc_atomic.
(meltgc_raw_new_mappointers, meltgc_raw_put_mappointers)
(meltgc_raw_remove_mappointers): Corrected length argument to
ggc_alloc_cleared_vec_entrypointermelt_st.
(melt_really_initialize): Call melt_allocate_young_gc_zone.
(melt_initialize): Set flag_plugin_added.
(melt_val2passflag): TODO_verify_loops only in GCC 4.5
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@164424 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
40 files changed, 9145 insertions, 3403 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 59b0e40b000..c412f0c9ece 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,2007 @@ +2010-09-15 Jason Merrill <jason@redhat.com> + + * semantics.c (finish_id_expression): Diagnose use of function + parms in evaluated context outside function body. + + * decl2.c (grokbitfield): Diagnose non-integral width. + + * call.c (convert_like_real): Use the underlying type of the + reference for the temporary. + +2010-09-15 Jakub Jelinek <jakub@redhat.com> + + PR c++/45635 + * class.c (build_vtbl_initializer): Use fn instead of init's operand + as first argument to FDESC_EXPR. + +2010-09-15 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/45665 + * decl.c (grokdeclarator): Check build_memfn_type return value + for error_mark_node. + +2010-09-13 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com> + + * semantics.c (finish_for_stmt): Always test flag_new_for_scope. + (begin_range_for_stmt): Likewise. + +2010-09-11 Rodrigo Rivas <rodrigorivascosta@gmail.com> + + Implement range-based for-statements. + * cp-tree.def (RANGE_FOR_STMT): New. + * cp-tree.h (RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY): New. + (cp_convert_range_for): Declare. + * pt.c (tsubst_expr): Add RANGE_FOR_STMT. + (tsubst_copy_and_build): perform_koenig_lookup takes extra argument. + * semantics.c (begin_range_for_stmt): New. + (finish_range_for_decl): New. + (finish_for_stmt): Accept also RANGE_FOR_STMT. + (perform_koenig_lookup): Add extra argument include_std. + * parser.c (cp_parser_c_for): New with code from + cp_parser_iteration_statement(). + (cp_parser_range_for): New. + (cp_convert_range_for): New. + (cp_parser_iteration_statement): Add range-for support. + (cp_parser_condition): Adjust comment. + (cp_parser_postfix_expression): perform_koenig_lookup takes extra + argument. + * dump.c (cp_dump_tree): Add RANGE_FOR_STMT. + * cxx-pretty-print.c: Likewise. + * lex.c (cxx_init): Likewise. + * name-lookup.c (lookup_function_nonclass): Add extra argument + include_std. + (lookup_arg_dependent): Likewise. + * name-lookup.h: Likewise. + +2010-09-10 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com> + + PR c++/43824 + * error.c (maybe_warn_cpp0x): Add new warning + CPP0X_INLINE_NAMESPACES. + * parser.c (cp_parser_namespace_definition): Likewise. + * cp-tree.h (cpp0x_warn_str): Likewise. + +2010-09-10 Richard Guenther <rguenther@suse.de> + + * decl.c (reshape_init_vector): For VECTOR_TYPEs, use + TYPE_VECTOR_SUBPARTS instead of TYPE_DEBUG_REPRESENTATION_TYPE. + +2010-09-10 Jan Hubicka <jh@suse.cz> + + PR tree-optimization/45605 + * cp/class.c (build_vtbl_initializer): Avoid wrong type conversion in + ADDR_EXPR. + +2010-09-08 Jakub Jelinek <jakub@redhat.com> + + PR c++/45588 + * pt.c (tsubst) <case INTEGER_TYPE>: Call mark_rvalue_use + before calling fold_decl_constant_value. + +2010-09-07 Arnaud Charlet <charlet@adacore.com> + + * cp-tree.h (build_enumerator): Add new location_t parameter. + (build_lang_decl_loc): New function. + * decl.c (build_enumerator): New parameter loc. Use it when calling + build_decl. Replace build_lang_decl with build_lang_decl_loc. + * pt.c (tsubst_enum): Adjust call to build_enumerator. + * parser.c (cp_parser_enumerator_definition): Ditto. + * lex.c (build_lang_decl_loc): New function. + +2010-09-06 Dodji Seketeli <dodji@redhat.com> + + PR c++/45200 + PR c++/45293 + PR c++/45558 + * tree.c (strip_typedefs): Strip typedefs from the context of + TYPENAME_TYPEs. + +2010-09-06 Mark Mitchell <mark@codesourcery.com> + + * typeck.c (cp_build_binary_op): Call do_warn_double_promotion. + * call.c (build_conditional_expr): Likewise. + (convert_arg_to_ellipsis): Likewise. + +2010-09-06 Arnaud Charlet <charlet@adacore.com> + + * parser.c (make_pointer_declarator, make_reference_declarator, + make_call_declarator, make_array_declarator): Set declarator->id_loc. + (cp_parser_init_declarator): Adjust location of decl if appropriate. + +2010-09-06 Jason Merrill <jason@redhat.com> + + * call.c (implicit_conversion): Fix value-init of enums. + (convert_like_real): Likewise. + + * decl.c (cp_finish_decl): Don't change init for auto deduction. + + * pt.c (fold_non_dependent_expr_sfinae): Split out from... + (fold_non_dependent_expr): ...here. + (convert_nontype_argument): Use it. Take complain parm. + Use perform_implicit_conversion instead of ocp_convert. + Allow cv-qual changes. + (convert_template_argument): Pass complain down. + (tsubst_template_arg): Suppress constant expression warnings. + Don't fold here. + + * method.c (synthesized_method_walk): In constructors, also check + subobject destructors. + + * semantics.c (finish_compound_literal): Always build a + TARGET_EXPR. + +2010-08-30 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/45043 + * decl.c (grokdeclarator): Use MAIN_NAME_P only on IDENTIFIER_NODEs. + +2010-08-30 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/45423 + * parser.c (cp_parser_omp_atomic): Handle boolean + {PRE,POST}_INCREMENT. + +2010-08-29 Jason Merrill <jason@redhat.com> + + PR c++/44991 + * parser.c (cp_parser_parameter_declaration): Pop parameter decls + after tentative parsing. + +2010-08-22 Joseph Myers <joseph@codesourcery.com> + + * Make-lang.in (g++spec.o): Update dependencies. + * g++spec.c: Include opts.h + (MATH_LIBRARY, LIBSTDCXX): Remove initial "-l". + (lang_specific_driver): Use cl_decoded_option structures. + +2010-08-20 Nathan Froyd <froydnj@codesourcery.com> + + * call.c: Use FOR_EACH_VEC_ELT. + * class.c: Likewise. + * decl.c: Likewise. + * decl2.c: Likewise. + * error.c: Likewise. + * except.c: Likewise. + * mangle.c: Likewise. + * method.c: Likewise. + * name-lookup.c: Likewise. + * parser.c: Likewise. + * pt.c: Likewise. + * repo.c: Likewise. + * semantics.c: Likewise. + * typeck2.c: Likewise. + +2010-08-19 Jason Merrill <jason@redhat.com> + + * call.c (reference_related_p): Check for error_mark_node. + (add_function_candidate): Check it instead of + same_type_ignoring_top_level_qualifiers_p. + + PR c++/45315 + * init.c (build_new_1): Don't use build_value_init in a template. + (build_value_init): Make sure we don't. + + PR c++/45307 + * cp-gimplify.c (cp_gimplify_expr): Also remove assignment + of empty class CONSTRUCTOR. + + * except.c (pending_noexcept, pending_noexcept_checks): New. + (perform_deferred_noexcept_checks): New. + (maybe_noexcept_warning): Split from... + (finish_noexcept_expr): ...here. Adjust. + * decl2.c (cp_write_global_declarations): Call + perform_deferred_noexcept_checks. + * cp-tree.h: And declare it. + +2010-08-18 Nathan Froyd <froydnj@codesourcery.com> + + PR c++/45049 + * name-lookup.c (push_overloaded_decl): Change DECL_CHAIN to + TREE_CHAIN. + +2010-08-17 Kai Tietz <kai.tietz@onevision.com> + + * class.c (note_name_declared_in_class): Make in 'extern "C"' blocks, + or if -fms-extensions is enabled check, check permissive. + +2010-08-09 Jason Merrill <jason@redhat.com> + + PR c++/45236 + * pt.c (lookup_template_class): Don't re-coerce outer parms. + +2010-08-09 Nathan Froyd <froydnj@codesourcery.com> + + * call.c (add_builtin_candidates): Use VECs for local variable + `types'. Adjust remainder of function accordingly. + +2010-08-09 Nathan Froyd <froydnj@codesourcery.com> + + * name-lookup.c (is_associated_namespace): Convert local variables + to be VECs instead of TREE_LISTs. + +2010-08-09 Nathan Froyd <froydnj@codesourcery.com> + + * tree.c (varargs_function_p): Use stdarg_p. + +2010-08-07 Nathan Froyd <froydnj@codesourcery.com> + + * parser.c (cp_default_arg_entry): Declare. Declare a VEC of it. + (cp_unparsed_functions_entry): Declare. Declare a VEC of it. + (cp_parser) [unparsed_functions_queues]: Rename to unparsed_queues. + Change type to a VEC. + (unparsed_funs_with_default_args): Define. + (unparsed_funs_with_definitions): Define. + (push_unparsed_function_queues): New function. + (cp_parser_new): Call it. + (pop_unparsed_function_queues): New function. + (cp_parser_class_specifier): Adjust processing of unparsed functions. + (cp_parser_template_declaration_after_export): Use VEC_safe_push. + (cp_parser_save_member_function_body): Likewise. + (cp_parser_late_parsing_for_member): Call push_unparsed_function_queues + and pop_unparsed_function_queues. + (cp_parser_late_parsing_default_args): Likewise. + (cp_parser_save_default_args): Use VEC_safe_push. + +2010-08-07 Nathan Froyd <froydnj@codesourcery.com> + + * name-lookup.h (cp_label_binding): Declare. Declare a VEC type + containing it. + (cp_binding_level): Convert shadowed_labels and dead_vars_from_for + fields to VECs. + * decl.c (poplevel): Adjust for type changes. + (declare_local_label): Likewise. + +2010-08-06 Jason Merrill <jason@redhat.com> + + * typeck.c (complete_type_or_maybe_complain): Split out from... + (complete_type_or_else): Here. + (build_class_member_access_expr): Call it. + (finish_class_member_access_expr): Likewise. + * call.c (build_special_member_call): Likewise. + * cvt.c (build_expr_type_conversion): Likewise. + * init.c (build_new): Likewise. + * typeck2.c (build_functional_cast): Likewise. + * cp-tree.h: Declare it. + + * init.c (build_value_init): Add complain parm. + (build_value_init_noctor): Likewise. + (perform_member_init): Pass it. + (expand_aggr_init_1): Likewise. + (build_new_1): Likewise. + (build_vec_init): Likewise. + * pt.c (tsubst_expr): Likewise. + * typeck2.c (build_functional_cast): Likewise. + * cp-tree.h: Adjust. + * tree.c (build_target_expr_with_type): Handle error_mark_node. + + * typeck.c (decay_conversion): Any expression with type nullptr_t + decays to nullptr. + +2010-07-30 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + PR c++/45112 + * decl.c (duplicate_decls): Merge DECL_USER_ALIGN and DECL_PACKED. + +2010-07-27 Jason Merrill <jason@redhat.com> + + * pt.c (tsubst_expr) [DECL_EXPR]: Handle getting an AGGR_INIT_EXPR + from build_value_init. + * init.c (build_value_init_noctor): Give error for unknown array + bound. + +2010-07-27 Joseph Myers <joseph@codesourcery.com> + + * cp-objcp-common.h (LANG_HOOKS_MISSING_ARGUMENT): Remove. + +2010-07-27 Joseph Myers <joseph@codesourcery.com> + + * cp-objcp-common.c (cxx_initialize_diagnostics): First call + c_common_initialize_diagnostics. + * cp-objcp-common.h (LANG_HOOKS_OPTION_LANG_MASK, + LANG_HOOKS_COMPLAIN_WRONG_LANG_P): Define. + +2010-07-21 Jason Merrill <jason@redhat.com> + + * tree.c (cp_tree_equal): Fix CONSTRUCTOR handling. + + * parser.c (cp_parser_init_declarator): Pass LOOKUP_NORMAL + to cp_finish_decl. + +2010-07-20 Jeffrey Yasskin <jyasskin@google.com> + + PR c++/44641 + * pt.c (instantiate_class_template): Propagate the template's + location to its instance. + +2010-07-20 Jason Merrill <jason@redhat.com> + + PR c++/44967 + * pt.c (tsubst_copy_and_build): Rework last change. + + PR c++/44967 + * pt.c (tsubst_copy_and_build): Handle partial substitution of + CALL_EXPR. + +2010-07-19 Jason Merrill <jason@redhat.com> + + PR c++/44996 + * semantics.c (finish_decltype_type): Correct decltype + of parenthesized rvalue reference variable. + + PR c++/44969 + * tree.c (cp_tree_equal): Compare type of *CAST_EXPR. + * pt.c (iterative_hash_template_arg): Hash type of *CAST_EXPR. + +2010-07-19 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44969 + * typeck.c (build_x_compound_expr_from_list): Add tsubst_flags_t + parameter. + * cp-tree.h: Adjust declaration. + * init.c (perform_member_init): Adjust caller. + * decl.c (grok_reference_init, cp_finish_decl): Likewise. + * typeck2.c (store_init_value): Likewise. + (build_functional_cast): Pass complain argument to + build_x_compound_expr_from_list. + +2010-07-16 Jason Merrill <jason@redhat.com> + + PR c++/32505 + * pt.c (process_partial_specialization): Diagnose partial + specialization after instantiation. + (most_specialized_class): Add complain parm. + + * ptree.c (cxx_print_xnode): Handle TEMPLATE_INFO. + +2010-07-15 Nathan Froyd <froydnj@codesourcery.com> + + * init.c (build_new_1): Use cp_build_function_call_nary instead of + cp_build_function_call. + +2010-07-15 Jason Merrill <jason@redhat.com> + + PR c++/44909 + * call.c (add_function_candidate): If we're working on an implicit + declaration, don't consider candidates that won't match. + * typeck.c (same_type_ignoring_top_level_qualifiers_p): Now a fn. + * cp-tree.h (same_type_ignoring_top_level_qualifiers_p): Adjust. + + Revert: + * cp-tree.h (struct lang_type_class): Add has_user_opeq. + (TYPE_HAS_USER_OPEQ): New. + * decl.c (grok_special_member_properties): Set it. + * class.c (add_implicitly_declared_members): Don't lazily declare + constructors/operator= if a base or member has a user-declared one. + (check_bases_and_members, check_bases): Adjust. + (check_field_decls, check_field_decl): Adjust. + +2010-07-15 Anatoly Sokolov <aesok@post.ru> + + * decl.c (integer_three_node): Remove. + (cxx_init_decl_processing): Do not initialize the integer_three_node. + * cp-tree.h (integer_three_node): Remove. + +2010-07-15 Nathan Froyd <froydnj@codesourcery.com> + + * cp-tree.h: Carefully replace TREE_CHAIN with DECL_CHAIN. + * call.c: Likewise. + * class.c: Likewise. + * cp-gimplify.c: Likewise. + * decl.c: Likewise. + * decl2.c: Likewise. + * init.c: Likewise. + * mangle.c: Likewise. + * name-lookup.c: Likewise. + * optimize.c: Likewise. + * parser.c: Likewise. + * pt.c: Likewise. + * rtti.c: Likewise. + * search.c: Likewise. + * semantics.c: Likewise. + * typeck.c: Likewise. + * typeck2.c: Likewise. + +2010-07-14 Jason Merrill <jason@redhat.com> + + * init.c (sort_mem_initializers): Rename "field_type" to "ctx". + (build_field_list): Cache field type. + + Implement C++0x unrestricted unions (N2544) + * class.c (check_field_decl): Loosen union handling in C++0x. + * method.c (walk_field_subobs): Split out from... + (synthesized_method_walk): ...here. Set msg before loops. + (process_subob_fn): Check for triviality in union members. + * init.c (sort_mem_initializers): Splice out uninitialized + anonymous unions and union members. + (push_base_cleanups): Don't automatically destroy anonymous unions + and union members. + +2010-07-13 Jason Merrill <jason@redhat.com> + + PR c++/44909 + * cp-tree.h (struct lang_type_class): Add has_user_opeq. + (TYPE_HAS_USER_OPEQ): New. + * decl.c (grok_special_member_properties): Set it. + * class.c (add_implicitly_declared_members): Don't lazily declare + constructors/operator= if a base or member has a user-declared one. + (check_bases_and_members, check_bases): Adjust. + (check_field_decls, check_field_decl): Adjust. + * method.c (synthesized_method_walk): Initialize check_vdtor. + + PR c++/44540 + * mangle.c (write_type): Canonicalize. + (canonicalize_for_substitution): Retain cv-quals on FUNCTION_TYPE. + (write_CV_qualifiers_for_type): Ignore them in abi>=5. + +2010-07-13 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44908 + * call.c (convert_like_real): Adjust convert_ptrmem call, pass + complain argument. + * typeck.c (get_delta_difference): Update prototype, add a + tsubst_flags_t parameter; update get_delta_difference_1 calls and + add checks for error_mark_node. + (get_delta_difference_1): Update prototype, add a tsubst_flags_t + parameter; update lookup_base call. + (build_ptrmemfunc): Update prototype, add a tsubst_flags_t + parameter; update get_delta_difference call and add check for + error_mark_node. + (convert_ptrmem): Update prototype, add a tsubst_flags_t + parameter; update get_delta_difference call and add check for + error_mark_node; update build_ptrmemfunc call. + (build_static_cast_1): Adjust convert_ptrmem call. + (expand_ptrmemfunc_cst): Adjust get_delta_difference call. + (cp_build_unary_op): Adjust build_ptrmemfunc call. + * cvt.c (cp_convert_to_pointer, convert_force): Adjust convert_ptrmem + and build_ptrmemfunc calls. + * cp-tree.h: Update build_ptrmemfunc and convert_ptrmem prototypes. + +2010-07-12 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44907 + * call.c (build_temp): Add tsubst_flags_t complain parameter; + adjust build_special_member_call call, pass complain. + (convert_like_real): Adjust build_temp call, pass complain. + +2010-07-09 Jason Merrill <jason@redhat.com> + + PR c++/43120 + * cp-tree.h (BV_LOST_PRIMARY): New macro. + * class.c (update_vtable_entry_for_fn): Fix covariant thunk logic. + Set BV_LOST_PRIMARY. + (build_vtbl_initializer): Check BV_LOST_PRIMARY. + +2010-07-08 Jason Merrill <jason@redhat.com> + + PR c++/43120 + * class.c (update_vtable_entry_for_fn): Fix handling of dummy + virtual bases for covariant thunks. + +2010-07-08 Manuel López-Ibáñez <manu@gcc.gnu.org> + + * cp-tree.h: Do not include toplev.h. + +2010-07-06 Jason Merrill <jason@redhat.com> + + PR c++/44703 + * call.c (is_std_init_list): Look through typedefs. + + PR c++/44778 + * init.c (build_offset_ref): If scope isn't dependent, + don't exit early. Look at TYPE_MAIN_VARIANT. + * pt.c (tsubst_copy) [OFFSET_REF]: Do substitution. + + * error.c (dump_function_decl): Don't crash on null DECL_NAME. + +2010-07-06 Shujing Zhao <pearly.zhao@oracle.com> + + * cp-tree.h (impl_conv_void): New type. + (convert_to_void): Adjust prototype. + * cvt.c (convert_to_void): Use impl_conv_void, emit and adjust the + diagnostic for easy translation. Change caller. + * typeck.c: Update call to convert_to_void. + * semantics.c: Likewise. + * init.c: Likewise. + +2010-07-05 Nathan Froyd <froydnj@codesourcery.com> + + * decl.c (cp_finish_decl): Call add_local_decl. + * optimize.c (clone_body): Adjust for new type of cfun->local_decls. + +2010-07-05 Paolo Carlini <paolo.carlini@oracle.com> + + * pt.c (tsubst): Early declare code = TREE_CODE (t) and use it + throughout. + +2010-07-05 Shujing Zhao <pearly.zhao@oracle.com> + + PR c++/22138 + * parser.c (cp_parser_primary_expression): Error if local template is + declared. + +2010-07-02 Le-Chun Wu <lcwu@google.com> + + PR/44128 + * name-lookup.c (pushdecl_maybe_friend): Warn when a local decl + (variable or type) shadows another type. + +2010-07-02 Jakub Jelinek <jakub@redhat.com> + + PR c++/44780 + * typeck.c (convert_for_assignment): When converting a convertible + vector type or objc++ types, call mark_rvalue_use. + * typeck2.c (build_m_component_ref): Use return values from + mark_rvalue_use or mark_lvalue_use. + * class.c (build_base_path): Likewise. + * call.c (build_conditional_expr): Likewise. + +2010-07-02 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44039 + * pt.c (tsubst_baselink): Return error_mark_node if lookup_fnfields + returns NULL_TREE. + +2010-07-01 Richard Guenther <rguenther@suse.de> + + * cp-gimplify.c (cp_gimplify_expr): Open-code the rhs + predicate we are looking for, allow non-gimplified + INDIRECT_REFs. + +2010-06-30 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44628 + * typeck.c (cp_build_unary_op): Early return error_mark_node when + arg is NULL_TREE too. + * call.c (convert_class_to_reference): Return error_mark_node when + expr is NULL_TREE. + +2010-06-30 Michael Matz <matz@suse.de> + + * repo.c (finish_repo): Fix typo. + +2010-06-30 Nathan Froyd <froydnj@codesourcery.com> + + * parser.c (cp_parser_omp_for_loop): Use a VEC for for_block. + +2010-06-30 Nathan Froyd <froydnj@codesourcery.com> + + * repo.c (pending_repo): Change type to a VEC. + (finish_repo): Adjust for new type of pending_repo. + (repo_emit_p): Likewise. + +2010-06-30 Manuel López-Ibáñez <manu@gcc.gnu.org> + + * tree.c: Include gimple.h. Do not include tree-flow.h + * decl.c: Do not include tree-flow.h + * Make-lang.in: Adjust dependencies. + +2010-06-29 Nathan Froyd <froydnj@codesourcery.com> + + * decl.c (incomplete_var): Declare. Declare VECs containing them. + (incomplete_vars): Adjust comment. Change type to a VEC. + (maybe_register_incomplete_var): Adjust for new type. + (complete_vars): Adjust iteration over incomplete_vars. + +2010-06-29 Nathan Froyd <froydnj@codesourcery.com> + + * decl.c (struct named_label_entry): Change type of bad_decls field + to a VEC. + (poplevel_named_label_1): Adjust for new type of bad_decls. + (check_goto): Likewise. + +2010-06-29 Jason Merrill <jason@redhat.com> + + Enable implicitly declared move constructor/operator= (N3053). + * class.c (add_implicitly_declared_members): A class with no + explicitly declared copy or move constructor gets both declared + implicitly, and similarly for operator=. + (check_bases): A type with no copy ctor does not inhibit + a const copy ctor in a derived class. It does mean the derived + one is non-trivial. + (check_field_decl): Likewise. + (check_bases_and_members): A nonexistent copy ctor/op= is non-trivial. + * tree.c (type_has_nontrivial_copy_init): Adjust semantics. + (trivially_copyable_p): Likewise. + * call.c (convert_like_real): Use type_has_nontrivial_copy_init. + * class.c (finish_struct_bits): Likewise. + * tree.c (build_target_expr_with_type): Likewise. + * typeck2.c (store_init_value): Likewise. + + Enable implicitly deleted functions (N2346) + * class.c (check_bases_and_members): Adjust lambda flags. + * method.c (implicitly_declare_fn): Set DECL_DELETED_FN if appropriate. + + * decl2.c (mark_used): Adjust error for use of deleted function. + + Machinery to support implicit delete/move. + * cp-tree.h: (struct lang_type_class): Add lazy_move_assign, + has_complex_move_ctor, has_complex_move_assign bitfields. + (CLASSTYPE_LAZY_MOVE_ASSIGN): New. + (TYPE_HAS_COMPLEX_MOVE_ASSIGN): New. + (TYPE_HAS_COMPLEX_MOVE_CTOR): New. + (enum special_function_kind): Add sfk_move_assignment. + (LOOKUP_SPECULATIVE): New. + * call.c (build_over_call): Return early if it's set. + (build_over_call): Use trivial_fn_p. + * class.c (check_bases): If the base has no default constructor, + the derived one is non-trivial. Handle move ctor/op=. + (check_field_decl): Likewise. + (check_bases_and_members): Handle move ctor/op=. + (add_implicitly_declared_members): Handle CLASSTYPE_LAZY_MOVE_ASSIGN. + (type_has_move_constructor, type_has_move_assign): New. + * decl.c (grok_special_member_properties): Handle move ctor/op=. + * method.c (type_has_trivial_fn, type_set_nontrivial_flag): New. + (trivial_fn_p): New. + (do_build_copy_constructor): Use it. + (do_build_assign_ref): Likewise. Handle move assignment. + (build_stub_type, build_stub_object, locate_fn_flags): New. + (locate_ctor): Use locate_fn_flags. + (locate_copy, locate_dtor): Remove. + (get_dtor, get_default_ctor, get_copy_ctor, get_copy_assign): New. + (process_subob_fn, synthesized_method_walk): New. + (maybe_explain_implicit_delete): New. + (implicitly_declare_fn): Use synthesized_method_walk, + type_has_trivial_fn, and type_set_nontrivial_flag. + (defaulted_late_check): Set DECL_DELETED_FN. + (defaultable_fn_check): Handle sfk_move_assignment. + (lazily_declare_fn): Clear CLASSTYPE_LAZY_* early. Don't declare + implicitly deleted move ctor/op=. + * search.c (lookup_fnfields_1): Handle sfk_move_assignment. + (lookup_fnfields_slot): New. + * semantics.c (omp_clause_info_fndecl): Remove. + (cxx_omp_create_clause_info): Use get_default_ctor, get_copy_ctor, + get_copy_assign, trivial_fn_p. + (trait_expr_value): Adjust call to locate_ctor. + * tree.c (special_function_p): Handle sfk_move_assignment. + + * class.c (type_has_virtual_destructor): New. + * cp-tree.h: Declare it. + * semantics.c (trait_expr_value): Use it. + + * call.c (build_over_call): Only give warnings with tf_warning. + + * name-lookup.c (pop_scope): Handle NULL_TREE. + + * cp-tree.h (TYPE_HAS_ASSIGN_REF): Rename to TYPE_HAS_COPY_ASSIGN. + (TYPE_HAS_CONST_ASSIGN_REF): Rename to TYPE_HAS_CONST_COPY_ASSIGN. + (TYPE_HAS_INIT_REF): Rename to TYPE_HAS_COPY_CTOR. + (TYPE_HAS_CONST_INIT_REF): Rename to TYPE_HAS_CONST_COPY_CTOR. + (TYPE_HAS_COMPLEX_ASSIGN_REF): Rename to TYPE_HAS_COMPLEX_COPY_ASSIGN. + (TYPE_HAS_COMPLEX_INIT_REF): Rename to TYPE_HAS_COMPLEX_COPY_CTOR. + (TYPE_HAS_TRIVIAL_ASSIGN_REF): Rename to TYPE_HAS_TRIVIAL_COPY_ASSIGN. + (TYPE_HAS_TRIVIAL_INIT_REF): Rename to TYPE_HAS_TRIVIAL_COPY_CTOR. + (CLASSTYPE_LAZY_ASSIGNMENT_OP): Rename to CLASSTYPE_LAZY_COPY_ASSIGN. + (sfk_assignment_operator): Rename to sfk_copy_assignment. + * decl.c, call.c, class.c, init.c, method.c, pt.c, ptree.c: Adjust. + * search.c, semantics.c, tree.c: Adjust. + + * pt.c (dependent_scope_ref_p): Remove. + (value_dependent_expression_p): Don't call it. + (type_dependent_expression_p): Here either. + * init.c (build_offset_ref): Set TREE_TYPE on a qualified-id + if the scope isn't dependent. + + * pt.c (convert_nontype_argument): Use mark_lvalue_use if we want + a reference. + + PR c++/44587 + * pt.c (has_value_dependent_address): New. + (value_dependent_expression_p): Check it. + (convert_nontype_argument): Likewise. Call decay_conversion before + folding if we want a pointer. + * semantics.c (finish_id_expression): Don't add SCOPE_REF if the + scope is the current instantiation. + +2010-06-28 Jakub Jelinek <jakub@redhat.com> + + PR c++/44682 + * class.c (build_base_path): If want_pointer, call mark_rvalue_use + on expr. + +2010-06-28 Steven Bosscher <steven@gcc.gnu.org> + + * init.c: Do not include except.h. + * decl.c: Likewise. + * expr.c: Likewise. + * cp-lang.c: Likewise. + * pt.c: Likewise. + * semantics.c: Likewise. + * decl2.c: Likewise. + * except.c: Likewise. + (init_exception_processing): Do not set the removed + lang_protect_cleanup_actions here. + (cp_protect_cleanup_actions): Make non-static and remove prototype. + (doing_eh): New, moved from except.c but removed the do_warning flag. + (expand_start_catch_block): Update doing_eh call. + (expand_end_catch_block): Likewise. + (build_throw): Likewise. + * cp-tree.h: Prototype cp_protect_cleanup_actions. + * cp-objcp-common.h: Set LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS to + cp_protect_cleanup_actions. + * Make-lang.in: Update dependencies. + +2010-06-26 Jason Merrill <jason@redhat.com> + + * call.c (add_function_candidate): Set LOOKUP_COPY_PARM for any + constructor called with a single argument that takes a reference + to the constructor's class. + (BAD_CONVERSION_RANK): New. + (compare_ics): Use it to compare bad ICSes. + +2010-06-25 Joseph Myers <joseph@codesourcery.com> + + * lang-specs.h: Remove +e handling. + +2010-06-24 Andi Kleen <ak@linux.intel.com> + + * parser.c: (cp_parser_question_colon_clause): + Switch to use cp_lexer_peek_token. + Call warn_for_omitted_condop. Call pedwarn for omitted + middle operand. + +2010-06-22 Jakub Jelinek <jakub@redhat.com> + + PR c++/44619 + * typeck2.c (build_m_component_ref): Call mark_lvalue_use on + datum and mark_rvalue_use on component. + + PR c++/44627 + * error.c (dump_expr): Don't look at CALL_EXPR_ARG (t, 0) if + the CALL_EXPR has no arguments. + +2010-06-21 Jason Merrill <jason@redhat.com> + + * typeck.c (comp_except_specs): Fix ce_derived with noexcept. + + * semantics.c (check_trait_type): Check COMPLETE_TYPE_P for array + element type. + +2010-06-17 Nathan Froyd <froydnj@codesourcery.com> + + * name-lookup.c (struct arg_lookup): Convert namespaces and + classes fields to VEC. + (arg_assoc_namespace): Adjust for new type of namespaces. + (arg_assoc_class): Adjust for new type of classes. + (lookup_arg_dependent): Use make_tree_vector and + release_tree_vector. + * typeck2.c (build_x_arrow): Use vec_member. + +2010-06-17 Manuel López-Ibáñez <manu@gcc.gnu.org> + + PR c++/44486 + * error.c (dump_decl): Better wording for anonymous namespace. + +2010-06-16 Nathan Froyd <froydnj@codesourcery.com> + + * class.c (build_vtbl_initializer): Adjust computation of new_position + and which entry to add padding for. + +2010-06-16 Jason Merrill <jason@redhat.com> + + * except.c (check_noexcept_r): Return the problematic function. + (finish_noexcept_expr): Give -Wnoexcept warning. Add complain parm. + * pt.c (tsubst_copy_and_build): Pass it. + * parser.c (cp_parser_unary_expression): Likewise. + * cp-tree.h: Adjust prototype. + + * method.c (defaulted_late_check): Give the defaulted method + the same exception specification as the implicit declaration. + +2010-06-15 Jason Merrill <jason@redhat.com> + + * class.c (add_implicitly_declared_members): Implicit assignment + operators can also be virtual overriders. + * method.c (lazily_declare_fn): Likewise. + + * call.c (convert_like_real): Give "initializing argument of" + information for ambiguous conversion. Give source position + of function. + + * call.c (print_z_candidates): Do print viable deleted candidates. + (joust): Don't choose a deleted function just because its worst + conversion is better than another candidate's worst. + + * call.c (convert_like_real): Don't complain about + list-value-initialization from an explicit constructor. + + * decl.c (duplicate_decls): Use DECL_IS_BUILTIN rather than test + DECL_SOURCE_LOCATION directly. + + * class.c (type_has_user_provided_default_constructor): Use + sufficient_parms_p. + + * call.c (is_subseq): Handle ck_aggr, ck_list. + (compare_ics): Treat an aggregate or ambiguous conversion to the + same type as involving the same function. + +2010-06-13 Shujing Zhao <pearly.zhao@oracle.com> + + * typeck.c (convert_for_assignment): Fix comment. Change message + format from %d to %qP. + (convert_for_initialization): Fix comment. + +2010-06-11 Shujing Zhao <pearly.zhao@oracle.com> + + * cp-tree.h (expr_list_kind): New type. + (impl_conv_rhs): New type. + (build_x_compound_expr_from_list, convert_for_initialization): Adjust + prototype. + (typeck.c (convert_arguments): Use impl_conv_rhs and emit the + diagnostics for easy translation. Change caller. + (convert_for_initialization): Use impl_conv_rhs and change caller. + (build_x_compound_expr_from_list): Use expr_list_kind and emit the + diagnostics for easy translation. Change caller. + * decl.c (bad_spec_place): New enum. + (bad_specifiers): Use it and emit the diagnostics for easy + translation. Change caller. + * pt.c (coerce_template_parms): Put the diagnostics in full sentence. + +2010-06-09 Nathan Froyd <froydnj@codesourcery.com> + + * cp-tree.h (struct saved_scope): Change decl_ns_list field type + to a VEC. + * decl2.c (cp_write_global_declarations): Adjust for new type of + decl_namespace_list. + * name-lookup.c (current_decl_namespace): Likewise. + (push_decl_namespace): Likewise. + (pop_decl_namespace): Likewise. + +2010-06-09 Nathan Froyd <froydnj@codesourcery.com> + + * call.c (build_java_interface_fn_ref): Call build_function_type_list + instead of build_function_type. + * decl.c (cxx_init_decl_processing): Likewise. + (declare_global_var): Likewise. + (get_atexit_node): Likewise. + (expand_static_init): Likewise. + * decl2.c (start_objects): Likewise. + (start_static_storage_duration_function): Likewise. + * except.c (init_exception_processing): Likewise. + (build_exc_ptr): Likewise. + (build_throw): Likewise. + * rtti.c (throw_bad_cast): Likewise. + (throw_bad_typeid): Likewise. + (build_dynamic_cast_1): Likewise. + +2010-06-09 Nathan Froyd <froydnj@codesourcery.com> + + * call.c (build_call_n): Call XALLOCAVEC instead of alloca. + (build_op_delete_call): Likewise. + (build_over_call): Likewise. + * cp-gimplify.c (cxx_omp_clause_apply_fn): Likewise. + * pt.c (process_partial_specialization): Likewise. + (tsubst_template_args): Likewise. + * semantics.c (finish_asm_stmt): Likewise. + +2010-06-08 Nathan Sidwell <nathan@codesourcery.com> + + * decl.c (record_key_method_defined): New, broken out of ... + (finish_function): ... here. Call it. + (start_decl): Treat aliases as definitions. + +2010-06-08 Laurynas Biveinis <laurynas.biveinis@gmail.com> + + * typeck2.c (abstract_virtuals_error): Use typed GC allocation. + + * pt.c (maybe_process_partial_specialization): Likewise. + (register_specialization): Likewise. + (add_pending_template): Likewise. + (lookup_template_class): Likewise. + (push_tinst_level): Likewise. + + * parser.c (cp_lexer_new_main): Likewise. + (cp_lexer_new_from_tokens): Likewise. + (cp_token_cache_new): Likewise. + (cp_parser_context_new): Likewise. + (cp_parser_new): Likewise. + (cp_parser_nested_name_specifier_opt): Likewise. + (cp_parser_template_id): Likewise. + + * name-lookup.c (binding_entry_make): Likewise. + (binding_table_construct): Likewise. + (binding_table_new): Likewise. + (cxx_binding_make): Likewise. + (pushdecl_maybe_friend): Likewise. + (begin_scope): Likewise. + (push_to_top_level): Likewise. + + * lex.c (init_reswords): Likewise. + (retrofit_lang_decl): Likewise. + (cxx_dup_lang_specific_decl): Likewise. + (copy_lang_type): Likewise. + (cxx_make_type): Likewise. + + * decl.c (make_label_decl): Likewise. + (check_goto): Likewise. + (start_preparsed_function): Likewise. + (save_function_data): Likewise. + + * cp-tree.h (TYPE_SET_PTRMEMFUNC_TYPE): Likewise. + + * cp-objcp-common.c (decl_shadowed_for_var_insert): Likewise. + + * class.c (finish_struct_1): Likewise. + + * cp-tree.h (struct lang_type): Add variable_size GTY option. + (struct lang_decl): Likewise. + + * parser.c (cp_parser_new): Update comment to not reference + ggc_alloc. + +2010-06-07 Jason Merrill <jason@redhat.com> + + PR c++/44366 + * error.c (dump_parameters): Mask out TFF_SCOPE. + (dump_simple_decl): Don't print the scope of a PARM_DECL. + (dump_scope): Remove no-op mask. + + PR c++/44401 + * parser.c (cp_parser_lookup_name): Fix naming the constructor. + + * cp-tree.h (COMPLETE_OR_OPEN_TYPE_P): New macro. + * init.c (build_offset_ref): Use it. + * pt.c (maybe_process_partial_specialization): Use it. + (instantiate_class_template): Use it. + * search.c (lookup_base): Use it. + +2010-06-07 Jakub Jelinek <jakub@redhat.com> + + PR c++/44444 + * expr.c (mark_exp_read): Handle INDIRECT_REF. + * cvt.c (convert_to_void): Handle INDIRECT_REF like + handled_component_p. + + PR c++/44443 + * decl.c (initialize_local_var): If TREE_USED is set on the type, + set also DECL_READ_P on the decl. + +2010-05-25 Dodji Seketeli <dodji@redhat.com> + + PR c++/44188 + * cp-tree.h (typedef_variant_p): Move this declaration to + gcc/tree.h. + * tree.c (typedef_variant_p): Move this definition to gcc/tree.c. + * decl.c (grokdeclarator): Do not rename debug info of an + anonymous tagged type named by a typedef. + +2010-06-05 Fabien Chêne <fabien@gcc.gnu.org> + + PR c++/44086 + * class.c (check_field_decls): Move the call to + check_bitfield_decl before trying to set the + CLASSTYPE_READONLY_FIELDS_NEED_INIT flag. + +2010-06-05 Steven Bosscher <steven@gcc.gnu.org> + + * typeck.c: Update include path for moved files. + * decl.c: Likewise. + * rtti.c: Likewise. + * cp-gimplify.c: Likewise. + * cp-lang.c: Likewise. + * pt.c: Likewise. + * semantics.c: Likewise. + * cxx-pretty-print.h: Likewise. + * decl2.c: Likewise. + * parser.c: Likewise. + * cp-objcp-common.c: Likewise. + * cp-tree.h: Likewise. + * name-lookup.c: Likewise. + * lex.c: Likewise. + * name-lookup.h: Likewise. + * config-lang.in: Update paths in gtfiles for files in c-family/. + * Make-lang.in: Likewise. + +2010-06-04 Magnus Fromreide <magfr@lysator.liu.se> + + * cvt.c (cp_convert_to_pointer): Use null_ptr_cst_p. + * typeck.c (build_ptrmemfunc): Likewise. + +2010-06-04 Jason Merrill <jason@redhat.com> + + * typeck2.c (merge_exception_specifiers): Adjust merging of + throw() and noexcept(true). + + * pt.c (value_dependent_expression_p) [NOEXCEPT_EXPR]: Avoid + using an uninitialized variable. + + * cxx-pretty-print.c (pp_cxx_unary_expression): Handle NOEXCEPT_EXPR. + (pp_cxx_expression): Likewise. + + Implement noexcept-specification (15.4) + * parser.c (cp_parser_exception_specification_opt): Parse it. + Give -Wdeprecated warning about throw() specs. + * pt.c (tsubst_exception_specification): Handle it. + * error.c (dump_exception_spec): Handle it. + (dump_expr): Handle NOEXCEPT_EXPR. + * cxx-pretty-print.c (pp_cxx_exception_specification): Likewise. + * typeck.c (comp_except_specs): Handle compatibility rules. + Change exact parm to take an enum. + * typeck2.c (merge_exception_specifiers): Handle noexcept. + * except.c (nothrow_spec_p, type_noexcept_p): New fns. + (type_throw_all_p, build_noexcept_spec): New fns. + * cp-tree.h (TYPE_NOTHROW_P, TYPE_NOEXCEPT_P): Use them. + (comp_except_specs): Define ce_derived, ce_normal, ce_exact enums. + (cp_tree_index): Add CPTI_NOEXCEPT_TRUE_SPEC, CPTI_NOEXCEPT_FALSE_SPEC. + (noexcept_true_spec, noexcept_false_spec): New macros. + * name-lookup.c (pushdecl_maybe_friend): Adjust. + * search.c (check_final_overrider): Adjust. + * decl.c (check_redeclaration_exception_specification): Adjust. + (use_eh_spec_block): Use type_throw_all_p. + (cxx_init_decl_processing): Set noexcept_false_spec,noexcept_true_spec. + Give operator new a noexcept-specification in C++0x mode. + * tree.c (build_exception_variant, cxx_type_hash_eq): Adjust. + (cp_build_type_attribute_variant): Don't test TYPE_RAISES_EXCEPTIONS. + + Implement noexcept operator (5.3.7) + * cp-tree.def (NOEXCEPT_EXPR): New. + * except.c (check_noexcept_r, finish_noexcept_expr): New. + * cp-tree.h: Declare finish_noexcept_expr. + * parser.c (cp_parser_unary_expression): Parse noexcept-expression. + * pt.c (tsubst_copy_and_build): And tsubst it. + (type_dependent_expression_p): Handle it. + (value_dependent_expression_p): Handle it. + + * call.c (build_conditional_expr): Never fold in unevaluated context. + * tree.c (build_aggr_init_expr): Propagate TREE_NOTHROW. + * semantics.c (simplify_aggr_init_expr): Likewise. + * typeck.c (merge_types): Call merge_exception_specifiers. + * decl.c (duplicate_decls): Check DECL_SOURCE_LOCATION rather than + DECL_ANTICIPATED for preferring new type. + +2010-06-04 Joseph Myers <joseph@codesourcery.com> + + * g++spec.c (lang_specific_driver): Use GCC-specific formats in + diagnostics. + +2010-06-04 Jakub Jelinek <jakub@redhat.com> + + PR c++/44412 + * typeck.c (build_class_member_access_expr): Call mark_exp_read + on object for static data members. + +2010-06-04 Jakub Jelinek <jakub@redhat.com> + Jason Merrill <jason@redhat.com> + + PR c++/44362 + * call.c (build_conditional_expr): If both arg2 and arg3 are lvalues + with the same type, call mark_lvalue_use on both. + +2010-06-03 Nathan Froyd <froydnj@codesourcery.com> + + * class.c (struct vtbl_init_data_s): Remove last_init field. + (struct secondary_vptr_vtt_init_data_s): Change type of inits field + to a VEC. + (finish_vtbls): Use a VEC rather than a TREE_LIST for the accumulated + initializers. + (build_vtt): Likewise. + (initialize_vtable): Take a VEC instead of a tree. + (build_vtt_inits): Change return type to void. Take a VEC ** + instead of a tree *; accumulate results into said VEC. + (build_ctor_vtbl_group): Use a VEC rather than a TREE_LIST for the + accumulated initializers. Pass the vtable to accumulate_vtbl_inits. + (accumulate_vtbl_inits): Add extra vtable tree parameter; take a VEC + instead of a tree. + (dfs_accumulate_vtbl_inits): Likewise. Change return type to void. + (build_vtbl_initializer): Add VEC parameter; accumulate initializers + into it. + (dfs_build_secondary_vptr_vtt_inits): Use CONSTRUCTOR_APPEND_ELT + rather than tree_cons. + (build_vbase_offset_vtbl_entries): Likewise. + (add_vcall_offset): Likewise. + (build_rtti_vtbl_entries): Likewise. + * cp-tree.h (initialize_artificial_var): Take a VEC instead of a tree. + * decl.c (initialize_artificial_var): Use build_constructor instead + of build_constructor_from_list. + +2010-06-03 H.J. Lu <hongjiu.lu@intel.com> + + PR c++/44294 + * class.c (layout_class_type): Check MAX_FIXED_MODE_SIZE on + bit-field. + +2010-06-02 Jonathan Wakely <jwakely.gcc@gmail.com> + + * parser.c (cp_parser_mem_initializer_list): Change error text. + +2010-06-02 Jakub Jelinek <jakub@redhat.com> + + * cp-objcp-common.c (shadowed_var_for_decl): Change into + tree_decl_map hashtab from tree_map. + (decl_shadowed_for_var_lookup, decl_shadowed_for_var_insert): Adjust. + (init_shadowed_var_for_decl): Adjust initialization. + + PR c++/44361 + * cvt.c (convert_to_void): If implicit is NULL, call mark_rvalue_use + instead of calling mark_exp_read only when not an assignment. + + PR debug/44367 + * semantics.c (finalize_nrv): Don't copy DECL_ARTIFICIAL, DECL_IGNORED_P, + DECL_SOURCE_LOCATION and DECL_ABSTRACT_ORIGIN from var to result. + Set DECL_VALUE_EXPR on var. + +2010-06-02 Jason Merrill <jason@redhat.com> + + * error.c (dump_type): Improve typedef handling. + + PR c++/9726 + PR c++/23594 + PR c++/44333 + * name-lookup.c (same_entity_p): New. + (ambiguous_decl): Multiple declarations of the same entity + are not ambiguous. + +2010-06-01 Jason Merrill <jason@redhat.com> + + DR 990 + * call.c (add_list_candidates): Prefer the default constructor. + (build_aggr_conv): Treat missing initializers like { }. + * typeck2.c (process_init_constructor_record): Likewise. + * init.c (expand_default_init): Use digest_init for + direct aggregate initialization, too. + + * call.c (add_list_candidates): Split out... + (build_user_type_conversion_1): ...from here. + (build_new_method_call): And here. + (implicit_conversion): Propagate LOOKUP_NO_NARROWING. + + PR c++/44358 + * call.c (build_list_conv): Set list-initialization flags properly. + +2010-06-01 Nathan Froyd <froydnj@codesourcery.com> + + * typeck2.c (build_x_arrow): Make types_memoized a VEC. + +2010-06-01 Arnaud Charlet <charlet@adacore.com> + Matthew Gingell <gingell@adacore.com> + + * Make-lang.in (CXX_C_OBJS): Add c-ada-spec.o. + * decl2.c: Include langhooks.h and c-ada-spec.h. + (cpp_check, collect_source_refs, collect_ada_namespace, + collect_all_refs): New functions. + (cp_write_global_declarations): Add handling of -fdump-ada-spec. + * lang-specs.h: Ditto. + +2010-05-29 Nathan Froyd <froydnj@codesourcery.com> + + * cp-tree.h (cp_build_function_call_nary): Declare. + * typeck.c (cp_build_function_call_nary): Define. + * decl.c (register_dtor_fn): Use it instead of + cp_build_function_call. + (cxx_maybe_build_cleanup): Likewise. + * decl2.c (generate_ctor_or_dtor_function): Likewise. + * except.c (do_get_exception_ptr): Likewise. + (do_begin_catch): Likewise. + (do_allocate_exception): Likewise. + (do_free_exception): Likewise. + (build_throw): Likewise. Use cp_build_function_call_vec instead + of cp_build_function_call. + (do_end_catch): Likewise. + +2010-05-29 Nathan Froyd <froydnj@codesourcery.com> + + * cp-tree.h (struct cp_decl_specifier_seq): Move type_location field up. + (struct cp_declarator): Move id_loc field up. + +2010-05-29 Steven Bosscher <steven@gcc.gnu.org> + + * cp-tree.h (ATTRIBUTE_GCC_CXXDIAG): Remove. Require that + this file is included before c-common.h. Define GCC_DIAG_STYLE + before including diagnostic-core.h and toplev.h. + (pedwarn_cxx98): Use ATTRIBUTE_GCC_DIAG. + * pt.c: Include cp-tree.h before c-common.h. + +2010-05-29 Steven Bosscher <steven@gcc.gnu.org> + + * tree.c (c_register_addr_space): Add stub. + +2010-05-28 Joseph Myers <joseph@codesourcery.com> + + * g++spec.c (lang_specific_driver): Use fatal_error instead of + fatal. + +2010-05-28 Dodji Seketeli <dodji@redhat.com> + + Revert fix of PR c++/44188 + * cp-tree.h (typedef_variant_p): Revert moving this declaration to + gcc/tree.h. + * tree.c (typedef_variant_p): Revert moving this definition to + gcc/tree.c. + * decl.c (grokdeclarator): Revert naming typedef handling. + +2010-05-27 Joseph Myers <joseph@codesourcery.com> + + * call.c: Include diagnostic-core.h instead of diagnostic.h. + * cp-lang.c: Don't include diagnostic.h + * name-lookup.c: Include diagnostic-core.h instead of + diagnostic.h. + (cp_emit_debug_info_for_using): Use seen_error. + * optimize.c: Include diagnostic-core.h instead of diagnostic.h. + * parser.c: Include diagnostic-core.h instead of diagnostic.h. + * pt.c (iterative_hash_template_arg): Use seen_error. + * repo.c: Include diagnostic-core.h instead of diagnostic.h. + * typeck2.c: Include diagnostic-core.h instead of diagnostic.h. + * Make-lang.in (cp/cp-lang.o, cp/typeck2.o, cp/call.o, cp/repo.o, + cp/optimize.o, cp/parser.o, cp/name-lookup.o): Update + dependencies. + +2010-05-25 Dodji Seketeli <dodji@redhat.com> + + PR c++/44188 + * cp-tree.h (typedef_variant_p): Move this declaration to + gcc/tree.h. + * tree.c (typedef_variant_p): Move this definition to gcc/tree.c. + * decl.c (grokdeclarator): Do not rename debug info of an + anonymous tagged type named by a typedef. + +2010-05-27 Jason Merrill <jason@redhat.com> + + PR c++/43555 + * decl.c (grokdeclarator) [cdk_pointer et al]: Force evaluation of + anonymous VLA size. + +2010-05-27 Kai Tietz <kai.tietz@onevision.com> + + PR bootstrap/44287 + * rtti.c (emit_support_tinfos): Check for NULL_TREE. + * class.c (layout_class_type): Likewise. + * decl.c (finish_enum): Likewise. + * mangle.c (write_builitin_type): Likewise. + +2010-05-26 Kai Tietz <kai.tietz@onevision.com> + + * cp-tree.h (cp_decl_specifier_seq): Add new bifield + explicit_int128_p. + * decl.c (grokdeclarator): Handle __int128. + * parser.c (cp_lexer_next_token_is_decl_specifier_ke): Likewise. + (cp_parser_simple_type_specifier): Likewise. + * rtti.c (emit_support_tinfos): Add int128 nodes for rtti. + * typeck.c (cp_common_type): Handle __int128. + * mangle.c (integer_type_codes): Add itk_int128 and + itk_unsigned_int128. + +2010-05-26 Jason Merrill <jason@redhat.com> + + PR c++/43382 + * pt.c (tsubst_pack_expansion): Don't get confused by recursive + unification. + +2010-05-26 Steven Bosscher <steven@gcc.gnu.org> + + * cp-lang.c: Do not include expr.h. + +2010-05-26 Steven Bosscher <steven@gcc.gnu.org> + + * decl.c: Do not include rtl.h + * semantics.c: Likewise. + +2010-05-25 Steven Bosscher <steven@gcc.gnu.org> + + * cp-tree.h: Do not include splay-tree.h. + (struct prtmem_cst): Remove unused field and false comment. + * typeck.c: Do not include rtl.h, expr.h, and tm_p.h. + * optimize.c: Do not inclde rtl.h, insn-config.h, and integrate.h. + * init.c: Do not include rtl.h and expr.h. + * class.c: Do not include rtl.h. Include splay-tree.h. + (build_clone): Use plain NULL instead of NULL_RTX. + * decl.c: Do not include expr.h. Explain why rtl.h has to be + included. Include splay-tree.h. + * method.c: Do not include rtl.h and expr.h. + (use_thunk): Use plain NULL instead of NULL_RTX. + * except.c: Do not include rtl.h, expr.h, and libfuncs.h. + * tree.c: Do not include rtl.h, insn-config.h, integrate.h, + and target.h. Include splay-tree.h. + * expr.c: Do not include rtl.h and expr.h. + * pt.c: Do not include obstack.h and rtl.h. + (tsubst_friend_function): Use plain NULL instead of NULL_RTX. + (tsubst_decl): Likewise. + (instantiate_decl): Likewise. + * semantics.c: Do not include exprt.h and debug.h. Explain why + rtl.h has to be included. + * decl2.c: Do not include rtl.h and expr.h. Include splay-tree.h. + * call.c: Do not include rtl.h and expr.h. + * search.c: Do not include obstack.h and rtl.h. + * friend.c: Do not include rtl.h and expr.h. + * Make-lang.in: Update dependencies. + +2010-05-25 Jakub Jelinek <jakub@redhat.com> + + PR c++/18249 + * parser.c (non_integral_constant): Add NIC_NONE. + (required_token): Add RT_NONE. + (cp_parser_unary_expression): Initialize non_constant_p + to NIC_NONE. + (cp_parser_asm_definition): Initialize missing to RT_NONE. + (cp_parser_primary_expression, cp_parser_postfix_expression, + cp_parser_cast_expression, cp_parser_binary_expression, + cp_parser_functional_cast): Fix formatting. + +2010-05-25 Shujing Zhao <pearly.zhao@oracle.com> + + PR c++/18249 + * parser.c: Remove inclusion of dyn-string.h. + (non_integral_constant): New enum. + (name_lookup_error): New enum. + (required_token): New enum. + (cp_parser_required_error): New function. + (cp_parser_require): Change the type of variable token_desc to + required_token and use cp_parser_required_error. + (cp_parser_require_keyword): Likewise. + (cp_parser_error): Use gmsgid as parameter. + (cp_parser_name_lookup_error): Change the type of variable desired to + name_lookup_error and put the diagnostic in the full sentences. Change + caller. + (cp_parser_non_integral_constant_expression): Change the type of the + variable thing to non_integral_constant and put the diagnostics in + full sentences. Change caller. + +2010-05-24 Eric Botcazou <ebotcazou@adacore.com> + + PR middle-end/44100 + * typeck.c (cp_build_unary_op): Fold offsetof-like computations. + +2010-05-24 Joseph Myers <joseph@codesourcery.com> + + * error.c (cp_diagnostic_starter): Update call to + diagnostic_build_prefix. + (cp_print_error_function, + print_instantiation_partial_context_line): Check show_column flag + in context. + +2010-05-24 Jason Merrill <jason@redhat.com> + + PR c++/41510 + * decl.c (check_initializer): Don't wrap an init-list in a + TREE_LIST. + * init.c (build_aggr_init): Don't assume copy-initialization if + init has CONSTRUCTOR_IS_DIRECT_INIT. + * call.c (build_new_method_call): Sanity check. + +2010-05-24 Nathan Froyd <froydnj@codesourcery.com> + + * rtti.c (tinfo_base_init): Use build_constructor instead of + build_constructor_from_list. Don't cons a tree node for + returning. + (generic_initializer): Use build_constructor_single instead of + build_constructor_from_list. + (ptr_initializer): Use build_constructor instead of + build_constructor_from_list + (ptm_initializer): Likewise. + (class_initializer): Likewise. Take varargs instead of TRAIL. + (get_pseudo_ti_init): Adjust calls to class_initializer. Use + build_constructor instead of build_constructor_from_list. + +2010-05-22 Steven Bosscher <steven@gcc.gnu.org> + + * semantics.c: Include bitmap.h. + * Make-lang.in: Update dependencies. + +2010-05-22 Jan Hubicka <jh@suse.cz> + + * decl2.c (maybe_emit_vtables): Produce same comdat group when outputting + comdat vtables. + (cxx_callgraph_analyze_expr): Remove code marking vtables needed. + +2010-05-21 Joseph Myers <joseph@codesourcery.com> + + * cxx-pretty-print.c: Correct merge error. + +2010-05-21 Joseph Myers <joseph@codesourcery.com> + + * error.c: Include tree-diagnostic.h and tree-pretty-print.h. + (cp_print_error_function): Use diagnostic_abstract_origin macro. + (cp_printer): Handle %K here using percent_K_format. + * cxx-pretty-print.c: Include tree-pretty-print.h. + * Make-lang.in (cp/error.o, cp/cxx-pretty-print.o): Update + dependencies. + +2010-05-21 Steven Bosscher <steven@gcc.gnu.org> + + * error.c, tree.c, typeck2.c, cxx-pretty-print.c, mangle.c: + Clean up redundant includes. + +2010-05-20 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/30298 + * decl.c (xref_basetypes): Return false in case of ill-formed + redefinition. + +2010-05-19 Jason Merrill <jason@redhat.com> + + * call.c (reference_binding): Use cp_build_qualified_type_real + and cp_type_quals consistently. + (add_function_candidate): Likewise. + (build_conditional_expr): Likewise. + (convert_like_real): Likewise. + (type_passed_as): Likewise. + * class.c (add_method): Likewise. + (same_signature_p): Likewise. + (layout_class_type): Likewise. + * decl.c (cxx_init_decl_processing): Likewise. + (cp_fname_init): Likewise. + (grokdeclarator): Likewise. + * decl2.c (cp_reconstruct_complex_type): Likewise. + * init.c (build_new_1): Likewise. + * method.c (do_build_copy_constructor): Likewise. + (implicitly_declare_fn): Likewise. + * pt.c (tsubst_aggr_type): Likewise. + (tsubst): Likewise. + * rtti.c (init_rtti_processing): Likewise. + (build_headof): Likewise. + (build_dynamic_cast_1): Likewise. + (tinfo_base_init): Likewise. + (emit_support_tinfos): Likewise. + * semantics.c (capture_decltype): Likewise. + * tree.c (cv_unqualified): Likewise. + * typeck.c (composite_pointer_type): Likewise. + (string_conv_p): Likewise. + + * mangle.c (write_CV_qualifiers_for_type): Tweak. + + * call.c (initialize_reference): Use CP_TYPE_CONST_P. + * decl.c (start_decl): Likewise. + * semantics.c (finish_compound_literal): Likewise. + * typeck.c (check_return_expr): Use CP_TYPE_VOLATILE_P. + (cp_type_readonly): Remove. + * cp-tree.h: Remove declaration. + + * typeck.c (merge_types): Preserve memfn quals. + + * decl.c (grokdeclarator): Don't check quals on fn type. + * typeck.c (cp_apply_type_quals_to_decl): Likewise. + * tree.c (cp_build_qualified_type_real): Simplify qualifier checking. + + PR c++/44193 + * typeck.c (type_memfn_quals): New fn. + (apply_memfn_quals): New fn. + (cp_type_quals): Return TYPE_UNQUALIFIED for FUNCTION_TYPE. + (cp_type_readonly): Use cp_type_quals. + * cp-tree.h: Add declarations. + * tree.c (cp_build_qualified_type_real): Don't set, but do + preserve, quals on FUNCTION_TYPE. + (strip_typedefs): Use apply_memfn_quals and type_memfn_quals. + * decl.c (build_ptrmem_type): Likewise. + (grokdeclarator): Likewise. + (static_fn_type): Likewise. + * decl2.c (change_return_type): Likewise. + (cp_reconstruct_complex_type): Likewise. + * pt.c (tsubst_function_type): Likewise. + (unify): Likewise. + (tsubst): Likewise. Drop special FUNCTION_TYPE substitution code. + +2010-05-18 Nathan Froyd <froydnj@codesourcery.com> + + * tree.c (build_min_non_dep_call_vec): Update comment. + +2010-05-17 Jason Merrill <jason@redhat.com> + + * call.c (struct z_candidate): Add explicit_targs field. + (add_template_candidate_real): Set it. + (build_over_call): Use it to control init-list warning. + + PR c++/44157 + * call.c (build_over_call): Limit init-list deduction warning to + cases where the argument is actually an init-list. + + PR c++/44158 + * call.c (build_over_call): Don't do bitwise copy for move ctor. + +2010-05-17 Dodji Seketeli <dodji@redhat.com> + Jason Merrill <jason@redhat.com> + + PR c++/44108 + * decl.c (compute_array_index_type): Call mark_rvalue_use. + +2010-05-15 Jason Merrill <jason@redhat.com> + + * cp-tree.h (TYPE_NOEXCEPT_P): New macro. + * except.c (begin_eh_spec_block): Use MUST_NOT_THROW_EXPR if + TYPE_NOEXCEPT_P. + (finish_eh_spec_block): Adjust. + +2010-05-15 Jakub Jelinek <jakub@redhat.com> + + PR c++/44148 + * pt.c (tsubst): Unshare template argument. + +2010-05-15 Steven Bosscher <steven@gcc.gnu.org> + + * decl.c: Include tree-iterator.h, as fixup for tree-inline.h changes. + * Make-lang.in: Fix dependencies accordingly. + +2010-05-14 Jason Merrill <jason@redhat.com> + + C++ DR 475 + * except.c (build_throw): Simplify, adjust for DR 475. + + PR c++/44127 + * except.c (dtor_nothrow): Return nonzero for type with + trivial destructor. + + PR c++/44127 + * cp-gimplify.c (gimplify_must_not_throw_expr): Use + gimple_build_eh_must_not_throw. + +2010-05-14 Martin Jambor <mjambor@suse.cz> + + * cp-lang.c (LANG_HOOKS_FOLD_OBJ_TYPE_REF): Remove both its undef + and define. + +2010-05-14 Jonathan Wakely <jwakely.gcc@gmail.com> + + * call.c (build_new_method_call): Change warning text. + * typeck2.c (build_functional_cast): Change error text. + +2010-05-14 Shujing Zhao <pearly.zhao@oracle.com> + + PR c++/30566 + * name-lookup.c (pushdecl_maybe_friend): Avoid the warnings about + shadowing the outer parameter or variables by the declaration of + nested function in nested structure or class. Warn the shadowing by + the declaration of nested lambda expression. + +2010-05-13 Jason Merrill <jason@redhat.com> + + * typeck.c (cp_build_array_ref): Factor out from... + (build_array_ref): ...here. Drop complain parm. + (build_new_op): Adjust. + * class.c (build_vtbl_ref_1): Adjust. + * decl2.c (grok_array_decl): Adjust. + * cp-tree.h: Adjust prototypes. + +2010-05-13 Jan Hubicka <jh@suse.cz> + + * decl.c (cp_finish_decl): Do not worry about used attribute. + +2010-05-12 Jason Merrill <jason@redhat.com> + + * typeck.c (build_array_ref): Take complain parm. + * cp-tree.h: Add it to prototype. + * call.c (build_new_op): Pass it. + * class.c (build_vtbl_ref): Pass it. + * decl2.c (grok_array_decl): Pass it. + + PR bootstrap/44048 + PR target/44099 + * cp-tree.def (NULLPTR_TYPE): Remove. + * cp-tree.h (NULLPTR_TYPE_P): New. + (SCALAR_TYPE_P): Use it. + (nullptr_type_node): New. + (cp_tree_index): Add CPTI_NULLPTR_TYPE. + * decl.c (cxx_init_decl_processing): Call record_builtin_type on + nullptr_type_node. + * cvt.c (ocp_convert): Use NULLPTR_TYPE_P instead of NULLPTR_TYPE. + * cxx-pretty-print.c (pp_cxx_constant): Likewise. + * error.c (dump_type, dump_type_prefix, dump_type_suffix): Likewise. + * mangle.c (write_type): Likewise. + * name-lookup.c (arg_assoc_type): Likewise. + * typeck.c (build_reinterpret_cast_1): Likewise. + * rtti.c (typeinfo_in_lib_p): Likewise. + (emit_support_tinfos): Remove local nullptr_type_node. + + * cp-tree.h (UNKNOWN_TYPE): Remove. + * decl.c (cxx_init_decl_processing): Use LANG_TYPE instead. + * error.c (dumy_type, dump_type_prefix, dump_type_suffix): Likewise. + * typeck2.c (cxx_incomplete_type_diagnostic): Likewise. + * class.c (instantiate_type): Check unknown_type_node rather than + UNKNOWN_TYPE. + * name-lookup.c (maybe_push_decl): Likewise. + * rtti.c (get_tinfo_decl_dynamic): Likewise. + (get_typeid): Likewise. + * semantics.c (finish_offsetof): Likewise. + + PR c++/20669 + * call.c (add_template_candidate_real): If deduction fails, still + add the template as a non-viable candidate. + (equal_functions): Handle template candidates. + (print_z_candidate): Likewise. + (print_z_candidates): Likewise. + (build_new_function_call): Likewise. + + * cp-tree.h (LOOKUP_LIST_ONLY): New. + * call.c (add_candidates): Enforce it. + (build_new_method_call): Try non-list ctor if no viable list ctor. + (build_user_type_conversion_1): Likewise. + + * call.c (add_candidates): Distinguish between type(x) and + x.operator type(). + (convert_class_to_reference): Set LOOKUP_NO_CONVERSION. + (build_new_method_call): Give better error for conversion op. + + * call.c (add_candidates): Add first_arg and return_type parms. + Add special constructor/conversion op handling. + (convert_class_to_reference): Use it. + (build_user_type_conversion_1): Likewise. + (build_op_call): Likewise. + (build_new_method_call): Likewise. + (build_new_op): Adjust. + (perform_overload_resolution): Adjust. + +2010-05-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/34272 + PR c++/43630 + PR c++/34491 + * pt.c (process_partial_specialization): Return error_mark_node + in case of unused template parameters in partial specialization. + +2010-05-11 Jakub Jelinek <jakub@redhat.com> + + PR c++/44062 + * semantics.c (finish_expr_stmt): Don't call mark_exp_read here... + * cvt.c (convert_to_void): ... but here. If expr is a COMPOUND_EXPR, + look at its second operand. + +2010-05-10 Jason Merrill <jason@redhat.com> + + PR c++/44017 + * semantics.c (baselink_for_fns): Revert earlier change. + + PR c++/44045 + * typeck.c (cp_build_modify_expr): Complain about assignment to + array from init list. + +2010-05-10 Fabien Chêne <fabien.chene@gmail.com> + + PR c++/43719 + * decl.c (check_initializer): strip array type before checking for + uninitialized const or ref members. + +2010-05-07 Fabien Chêne <fabien.chene@gmail.com> + + PR c++/43951 + * init.c (diagnose_uninitialized_cst_or_ref_member_1): Returns the + error count. Emit errors only if compain is true. + (build_new_1): Do not return error_mark_node if + diagnose_uninitialized_cst_or_ref_member_1 does not diagnose any + errors. Delay the check for user-provided constructor. + (perform_member_init): Adjust. + * cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Change the + prototype. + +2010-05-06 Magnus Fromreide <magfr@lysator.liu.se> + Jason Merrill <jason@redhat.com> + + Add support for C++0x nullptr. + * cp-tree.def: Add NULLPTR_TYPE. + * cp-tree.h: Add nullptr_node. + (cp_tree_index): Add CPTI_NULLPTR. + (SCALAR_TYPE_P): Add NULLPTR_TYPE. + * call.c (null_ptr_cst_p): Handle nullptr. + (standard_conversion): Likewise. + (convert_arg_to_ellipsis): Likewise. + * mangle.c (write_type): Likewise. + * name-lookup.c (arg_assoc_type): Likewise. + * parser.c (cp_parser_primary_expression): Likewise. + * typeck.c (cp_build_binary_op): Likewise. + (build_reinterpret_cast_1): Likewise. + * error.c (dump_type): Likewise. + (dump_type_prefix, dump_type_suffix): Likewise. + * decl.c (cxx_init_decl_processing): Likewise. + * cxx-pretty-print.c (pp_cxx_constant): Likewise. + * cvt.c (ocp_convert): Likewise. + * rtti.c (typeinfo_in_lib_p, emit_support_tinfos): Put + nullptr_t tinfo in libsupc++. + +2010-05-06 Jason Merrill <jason@redhat.com> + + * semantics.c (simplify_aggr_init_expr): Use INIT_EXPR. + +2010-04-22 Jakub Jelinek <jakub@redhat.com> + Dodji Seketeli <dodji@redhat.com> + + PR c/18624 + * cp-tree.h (mark_exp_read, rvalue_use, lvalue_use, type_use): + Declare ... + * expr.c (mark_exp_read, rvalue_use, lvalue_use, type_use): ... new fns. + * typeck.c (cxx_sizeof_expr, cxx_alignof_expr): Call type_use. + (decay_conversion, perform_integral_promotions): Call rvalue_use. + (cp_build_unary_op): Call lvalue_use. + * decl.c (unused_but_set_errorcount): New variable. + (poplevel): Issue -Wunused-but-set-variable diagnostics. + (duplicate_decls): Merge DECL_READ_P flags. + (start_cleanup_fn): Set DECL_READ_P flag. + (finish_function): Issue -Wunused-but-set-parameter diagnostics. + * tree.c (rvalue): Call rvalue_use. + * pt.c (convert_nontype_argument): Likewise. + * semantics.c (finish_expr_stmt, finish_asm_stmt, finish_typeof, + finish_decltype_type): Likewise. + * call.c (convert_like_real) <ck_identity, ck_user>: Call rvalue use. + (build_x_va_arg, build_new_method_call, build_over_call): Call lvalue_use + or rvalue_use depending on the expr. + * init.c (build_new, build_delete): Likewise. + * rtti.c (build_typeid, build_dynamic_cast_1): Likewise. + +2010-05-05 Jason Merrill <jason@redhat.com> + + PR c++/43787 + * cp-gimplify.c (cp_gimplify_expr): Remove copies of empty classes. + * call.c (build_over_call): Don't try to avoid INIT_EXPR copies here. + +2010-05-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/43028 + * pt.c (unify): Check each elt for error_mark_node. + +2010-05-04 Jason Merrill <jason@redhat.com> + + PR c++/38064 + * typeck.c (cp_build_binary_op): Allow enums for <> as well. + +2010-05-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/43705 + * call.c (build_new_method_call): Return error_mark_node if fns is + NULL_TREE. + +2010-05-03 Dodji Seketeli <dodji@redhat.com> + + PR c++/43953 + * pt.c (most_specialized_class): Pretend we are processing + a template decl during the call to coerce_template_parms. + +2010-05-03 Jason Merrill <jason@redhat.com> + + PR c++/42810 + PR c++/43680 + * decl.c (finish_enum): Use the TYPE_MIN_VALUE and TYPE_MAX_VALUE + from the selected underlying type unless -fstrict-enums. Set + ENUM_UNDERLYING_TYPE to have the restricted range. + * cvt.c (type_promotes_to): Use ENUM_UNDERLYING_TYPE. + * class.c (check_bitfield_decl): Likewise. + +2010-05-01 H.J. Lu <hongjiu.lu@intel.com> + + PR c++/43951 + * init.c (build_new_1): Revert the accidental checkin in + revision 158918. + +2010-04-30 Jason Merrill <jason@redhat.com> + + PR c++/43868 + * cxx-pretty-print.c (pp_cxx_decl_specifier_seq): Move pmf handling... + (pp_cxx_type_specifier_seq): ...here. + +2010-04-30 Steven Bosscher <steven@gcc.gnu.org> + + * optimize.c, parser.c, mangle.c, cp-tree.h: Do not include varray.h. + * Make-lang.in: Don't include varray.h dependency in CXX_TREE_H. + +2010-04-30 Shujing Zhao <pearly.zhao@oracle.com> + + PR c++/43779 + * typeck.c (warn_args_num): New function. + (convert_arguments): Use warn_args_num to print the diagnostic + messages. + +2010-04-29 Fabien Chêne <fabien.chene@gmail.com> + + PR c++/43890 + * init.c (diagnose_uninitialized_cst_or_ref_member): check for + user-provided constructor while recursing. + +2010-04-28 Manuel López-Ibáñez <manu@gcc.gnu.org> + + PR c++/9335 + * error.c (print_instantiation_partial_context_line): Handle + recursive instantiation. + (print_instantiation_partial_context): Likewise. + +2010-04-27 Jason Merrill <jason@redhat.com> + + * init.c (perform_member_init): Check CLASS_TYPE_P. + +2010-04-27 Fabien Chêne <fabien.chene@gmail.com> + + PR c++/29043 + * init.c (perform_member_init): check for uninitialized const or + reference members, including array types. + +2010-04-24 Jason Merrill <jason@redhat.com> + + * tree.c (get_fns): Split out from get_first_fn. + * cp-tree.h: Declare it. + * search.c (shared_member_p): Use it. + * semantics.c (finish_qualified_id_expr): Simplify. + (finish_id_expression): Simplify. + + * semantics.c (finish_non_static_data_member): Call maybe_dummy_object + whenever object is NULL_TREE. Don't do 'this' capture here. + (finish_qualified_id_expr): Pass NULL_TREE. + (finish_id_expression): Likewise. + (lambda_expr_this_capture): Likewise. + + * semantics.c (finish_qualified_id_expr): Use maybe_dummy_object + rather than checking current_class_ref directly. + (finish_call_expr): Likewise. + + PR c++/43856 + * name-lookup.c (qualify_lookup): Disqualify lambda op(). + * class.c (current_nonlambda_class_type): New fn. + * semantics.c (nonlambda_method_basetype): New. + * cp-tree.h: Declare them. + * tree.c (maybe_dummy_object): Handle implicit 'this' capture. + + * semantics.c (baselink_for_fns): Correct BASELINK_BINFO. + + PR c++/43875 + * semantics.c (lambda_return_type): Complain about + braced-init-list. + + PR c++/43790 + * tree.c (cv_unqualified): Handle error_mark_node. + + PR c++/41468 + * call.c (convert_like_real) [ck_ambig]: Just return error_mark_node + if we don't want errors. + + PR c++/41468 + * class.c (convert_to_base): Add complain parameter. Pass + ba_quiet to lookup_base if we don't want errors. + (build_vfield_ref): Pass complain to convert_to_base. + * call.c (convert_like_real): Likewise. + (initialize_reference): Likewise. + (perform_direct_initialization_if_possible): Pass complain to + convert_like_real. + * cp-tree.h: Adjust. + +2010-04-27 Fabien Chêne <fabien.chene@gmail.com> + Jason Merrill <jason@redhat.com> + + PR c++/42844 + * decl.c (check_for_uninitialized_const_var): Handle classes that need + constructing, too. + (check_initializer): Call it for classes that need constructing, too. + * class.c (in_class_defaulted_default_constructor): New. + * cp-tree.h: Declare it. + +2010-04-20 Jason Merrill <jason@redhat.com> + + PR c++/9335 + * init.c (constant_value_1): Treat error_mark_node as a constant + if DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P is set. + * cvt.c (ocp_convert): Handle getting error_mark_node from + integral_constant_value. + * decl.c (compute_array_index_type): Likewise. + +2010-04-20 Dodji Seketeli <dodji@redhat.com> + + PR c++/43800 + PR c++/43704 + * typeck.c (incompatible_dependent_types_p): If one of the + compared types if not a typedef then honour their main variant + equivalence. + +2010-04-20 Jakub Jelinek <jakub@redhat.com> + + * cp-tree.h (TYPE_REF_IS_RVALUE): Remove. + +2010-04-19 Dodji Seketeli <dodji@redhat.com> + + PR c++/43704 + * typeck.c (structural_comptypes): Test dependent typedefs + incompatibility before testing for their main variant based + equivalence. + +2010-04-19 Jakub Jelinek <jakub@redhat.com> + + * cp-tree.h (SCOPED_ENUM_P, UNSCOPED_ENUM_P, SET_SCOPED_ENUM_P): Use + ENUM_IS_SCOPED bit instead of TYPE_LANG_FLAG_5. + +2010-04-18 Eric Botcazou <ebotcazou@adacore.com> + + * decl.c (cxx_init_decl_processing): Remove second argument in call to + build_common_tree_nodes. + +2010-04-14 Jason Merrill <jason@redhat.com> + + PR c++/36625 + * parser.c (cp_parser_parenthesized_expression_list): Change + is_attribute_list parm to int to indicate whether or not to + handle initial identifier specially. + (cp_parser_attribute_list): Use attribute_takes_identifier_p. + +2010-04-13 Jason Merrill <jason@redhat.com> + + * call.c (type_decays_to): Check MAYBE_CLASS_TYPE_P instead of + CLASS_TYPE_P. + * parser.c (cp_parser_lambda_expression): Complain about lambda in + unevaluated context. + * pt.c (iterative_hash_template_arg): Don't crash on lambda. + +2010-04-12 Jason Merrill <jason@redhat.com> + + PR c++/43641 + * semantics.c (maybe_add_lambda_conv_op): Use build_call_a and tweak + return value directly. + + * call.c (type_decays_to): Call cv_unqualified for non-class type. + +2010-04-12 Fabien Chene <fabien.chene@gmail.com> + + PR c++/25811 + * cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Declare. + * init.c (build_new_1): Check for uninitialized const members and + uninitialized reference members, when using new without + new-initializer. Call diagnose_uninitialized_cst_or_ref_member. + (diagnose_uninitialized_cst_or_ref_member): Define, call + diagnose_uninitialized_cst_or_ref_member_1. + (diagnose_uninitialized_cst_or_ref_member_1): New function. + +2010-04-12 Richard Guenther <rguenther@suse.de> + + PR c++/43611 + * semantics.c (expand_or_defer_fn_1): Do not keep extern + template inline functions. + +2010-04-09 Manuel López-Ibáñez <manu@gcc.gnu.org> + + PR c++/28584 + * typeck.c (cp_build_c_cast): Warn for casting integer to larger + pointer type. + +2010-04-07 Jason Merrill <jason@redhat.com> + + PR c++/43016 + * decl.c (start_preparsed_function): Do defer nested functions. + + PR c++/11094, DR 408 + * cp-tree.h (VAR_HAD_UNKNOWN_BOUND, SET_VAR_HAD_UNKNOWN_BOUND): New. + * decl2.c (finish_static_data_member_decl): Set it. + * decl.c (duplicate_decls): Propagate it. + * pt.c (tsubst_decl): Don't substitute the domain of an array + VAR_DECL if it's set. + (regenerate_decl_from_template): Substitute it here. + (type_dependent_expression_p): Return true if it's set. + * semantics.c (finish_decltype_type): Instantiate such a variable. + * typeck.c (cxx_sizeof_expr): Likewise. + (strip_array_domain): New. + + PR c++/43145 + * name-lookup.c (current_decl_namespace): Non-static. + (pop_nested_namespace): Sanity check. + * cp-tree.h: Declare current_decl_namespace. + * decl.c (grokvardecl): Use it instead of current_namespace. + (grokfndecl): Likewise. + + PR c++/38392 + * pt.c (tsubst_friend_function): Instatiate a friend that has already + been used. + + * pt.c (print_template_statistics): New. + * cp-tree.h: Declare it. + * tree.c (cxx_print_statistics): Call it. + + PR c++/41970 + * decl.c (grokvardecl): Tweak warning message. + (grokfndecl): Likewise. + +2010-04-07 Dodji Seketeli <dodji@redhat.com> + + PR c++/42697 + *pt.c (tsubst_decl): Get the arguments of a specialization from + the specialization template, not from the most general template. + +2010-04-07 Dodji Seketeli <dodji@redhat.com> + + PR c++/40239 + * typeck2.c (process_init_constructor_record): + value-initialize members that are are not explicitely + initialized. + +2010-04-07 Jie Zhang <jie@codesourcery.com> + + PR c++/42556 + * typeck2.c (split_nonconstant_init_1): Drop empty CONSTRUCTOR + when all of its elements are non-constant and have been split out. + +2010-04-06 Taras Glek <taras@mozilla.com> + Jason Merrill <jason@redhat.com> + + * parser.c (cp_parser_class_specifier): Set class location to that + of IDENTIFIER_NODE instead of '{' when possible. + * semantics.c (begin_class_definition): Do not overide locations + with less precise ones. + 2010-04-06 Jason Merrill <jason@redhat.com> PR c++/43648 @@ -570,3 +2574,4 @@ Copyright (C) 2010 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. + diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 83e1b2b5f44..a2d34e3c3f3 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -53,7 +53,8 @@ c++: cc1plus$(exeext) # Tell GNU make to ignore these if they exist. .PHONY: c++ -g++spec.o: $(srcdir)/cp/g++spec.c $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) $(CONFIG_H) +g++spec.o: $(srcdir)/cp/g++spec.c $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) \ + $(CONFIG_H) opts.h (SHLIB_LINK='$(SHLIB_LINK)'; \ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \ $(INCLUDES) $(srcdir)/cp/g++spec.c) @@ -71,10 +72,8 @@ g++-cross$(exeext): g++$(exeext) # The compiler itself. # Shared with C front end: -CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \ - c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \ - incpath.o c-ppoutput.o c-cppbuiltin.o prefix.o \ - c-gimplify.o c-omp.o +CXX_C_OBJS = attribs.o incpath.o prefix.o \ + $(C_COMMON_OBJS) $(CXX_TARGET_OBJS) # Language-specific object files for C++ and Objective C++. CXX_AND_OBJCXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \ @@ -85,7 +84,7 @@ CXX_AND_OBJCXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \ cp/cp-gimplify.o tree-mudflap.o $(CXX_C_OBJS) # Language-specific object files for C++. -CXX_OBJS = cp/cp-lang.o stub-objc.o $(CXX_AND_OBJCXX_OBJS) +CXX_OBJS = cp/cp-lang.o c-family/stub-objc.o $(CXX_AND_OBJCXX_OBJS) c++_OBJS = $(CXX_OBJS) dummy-checksum.o cc1plus-checksum.o cp/g++spec.o @@ -241,9 +240,9 @@ c++.stagefeedback: stagefeedback-start # # .o: .h dependencies. CXX_TREE_H = $(TREE_H) cp/name-lookup.h cp/cp-tree.h $(C_COMMON_H) \ - $(FUNCTION_H) $(VARRAY_H) \ + $(FUNCTION_H) \ $(SYSTEM_H) coretypes.h $(CONFIG_H) $(TARGET_H) $(GGC_H) \ - $(srcdir)/../include/hashtab.h $(srcdir)/../include/splay-tree.h + $(srcdir)/../include/hashtab.h CXX_PRETTY_PRINT_H = cp/cxx-pretty-print.h $(C_PRETTY_PRINT_H) @@ -251,72 +250,73 @@ cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ $(C_PRAGMA_H) toplev.h output.h input.h cp/operators.def $(TM_P_H) cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h debug.h langhooks.h \ $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-cp.h gt-cp-cp-lang.h \ - $(DIAGNOSTIC_H) cp/cp-objcp-common.h $(EXPR_H) $(EXCEPT_H) + cp/cp-objcp-common.h $(EXPR_H) cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \ - output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \ + output.h toplev.h $(HASHTAB_H) $(RTL_H) \ cp/operators.def $(TM_P_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(C_PRAGMA_H) \ - debug.h gt-cp-decl.h $(TIMEVAR_H) $(TREE_FLOW_H) $(TARGET_H) $(PLUGIN_H) \ - intl.h -cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h $(EXPR_H) \ - output.h except.h toplev.h $(RTL_H) $(C_COMMON_H) gt-cp-decl2.h $(CGRAPH_H) \ - $(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H) $(GIMPLE_H) $(POINTER_SET_H) + debug.h gt-cp-decl.h $(TIMEVAR_H) $(TARGET_H) $(PLUGIN_H) \ + intl.h tree-iterator.h $(SPLAY_TREE_H) +cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \ + output.h toplev.h $(C_COMMON_H) gt-cp-decl2.h $(CGRAPH_H) \ + $(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H) $(GIMPLE_H) $(POINTER_SET_H) \ + $(SPLAY_TREE_H) c-family/c-ada-spec.h cp/cp-objcp-common.o : cp/cp-objcp-common.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) $(CXX_TREE_H) $(C_COMMON_H) toplev.h \ langhooks.h $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) debug.h \ $(CXX_PRETTY_PRINT_H) cp/cp-objcp-common.h gt-cp-cp-objcp-common.h cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h output.h \ - $(TM_P_H) $(DIAGNOSTIC_H) gt-cp-typeck2.h $(REAL_H) intl.h -cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(RTL_H) $(EXPR_H) \ - toplev.h $(DIAGNOSTIC_H) convert.h $(C_COMMON_H) $(TARGET_H) -cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(RTL_H) \ - $(TARGET_H) convert.h $(CGRAPH_H) $(TREE_DUMP_H) gt-cp-class.h -cp/call.o: cp/call.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(RTL_H) \ - $(EXPR_H) $(DIAGNOSTIC_H) intl.h gt-cp-call.h convert.h $(TARGET_H) langhooks.h -cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(RTL_H) toplev.h \ - $(EXPR_H) -cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(RTL_H) $(EXPR_H) \ - toplev.h except.h $(TARGET_H) -cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_H) \ + $(TM_P_H) $(DIAGNOSTIC_CORE_H) gt-cp-typeck2.h $(REAL_H) intl.h +cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ + toplev.h $(DIAGNOSTIC_H) convert.h $(C_COMMON_H) $(TARGET_H) \ + output.h toplev.h +cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h \ + $(TARGET_H) convert.h $(CGRAPH_H) $(TREE_DUMP_H) gt-cp-class.h \ + $(SPLAY_TREE_H) +cp/call.o: cp/call.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h \ + $(DIAGNOSTIC_CORE_H) intl.h gt-cp-call.h convert.h $(TARGET_H) langhooks.h +cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h +cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ + toplev.h $(EXCEPT_H) $(TARGET_H) +cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h \ $(TM_P_H) $(TARGET_H) $(DIAGNOSTIC_H) gt-cp-method.h $(GIMPLE_H) cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h $(FLAGS_H) toplev.h \ convert.h $(TARGET_H) intl.h -cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(RTL_H) \ +cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h \ intl.h -cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(RTL_H) \ - insn-config.h $(INTEGRATE_H) $(TREE_INLINE_H) $(REAL_H) gt-cp-tree.h \ - $(TARGET_H) debug.h $(TREE_FLOW_H) $(CGRAPH_H) +cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h \ + $(TREE_INLINE_H) $(REAL_H) gt-cp-tree.h \ + $(TARGET_H) debug.h $(CGRAPH_H) $(SPLAY_TREE_H) $(GIMPLE_H) cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(TM_H) cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h convert.h \ $(TARGET_H) $(C_PRAGMA_H) gt-cp-rtti.h intl.h -cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(RTL_H) except.h \ - toplev.h cp/cfns.h $(EXPR_H) libfuncs.h $(TREE_INLINE_H) $(TARGET_H) -cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) $(FLAGS_H) $(EXPR_H) \ - toplev.h except.h $(TM_P_H) +cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ + toplev.h cp/cfns.h $(TREE_INLINE_H) $(TARGET_H) +cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(TM_P_H) cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/cp-objcp-common.h \ - toplev.h $(RTL_H) except.h $(TREE_INLINE_H) pointer-set.h gt-cp-pt.h \ - vecprim.h intl.h + toplev.h $(TREE_INLINE_H) pointer-set.h gt-cp-pt.h vecprim.h intl.h cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) \ - $(FLAGS_H) $(REAL_H) $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H) -cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) \ + $(FLAGS_H) $(REAL_H) $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H) \ + tree-diagnostic.h tree-pretty-print.h +cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_CORE_H) \ gt-cp-repo.h -cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) except.h toplev.h \ - $(FLAGS_H) debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \ +cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) toplev.h \ + $(FLAGS_H) output.h $(RTL_H) $(TIMEVAR_H) \ $(TREE_INLINE_H) $(CGRAPH_H) $(TARGET_H) $(C_COMMON_H) $(GIMPLE_H) \ - gt-cp-semantics.h + bitmap.h gt-cp-semantics.h cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) $(TREE_DUMP_H) -cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h $(INTEGRATE_H) \ - insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(GIMPLE_H) \ - $(TARGET_H) tree-iterator.h $(CGRAPH_H) +cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) \ + input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(GIMPLE_H) \ + $(TARGET_H) tree-iterator.h $(CGRAPH_H) $(DIAGNOSTIC_CORE_H) cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h $(REAL_H) \ gt-cp-mangle.h $(TARGET_H) $(TM_P_H) $(CGRAPH_H) -cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) gt-cp-parser.h \ - output.h $(TARGET_H) $(PLUGIN_H) intl.h +cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_CORE_H) \ + gt-cp-parser.h output.h $(TARGET_H) $(PLUGIN_H) intl.h cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) toplev.h $(C_COMMON_H) \ $(TM_H) coretypes.h pointer-set.h tree-iterator.h cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(CXX_TREE_H) $(TIMEVAR_H) gt-cp-name-lookup.h toplev.h \ - $(DIAGNOSTIC_H) $(FLAGS_H) debug.h + $(DIAGNOSTIC_CORE_H) $(FLAGS_H) debug.h cp/cxx-pretty-print.o: cp/cxx-pretty-print.c $(CXX_PRETTY_PRINT_H) \ - $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h $(CXX_TREE_H) + $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h $(CXX_TREE_H) tree-pretty-print.h diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 5a32b3b67d9..2b9b848a730 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1,6 +1,6 @@ /* Functions related to invoking methods and overloaded functions. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) and modified by Brendan Kehoe (brendan@cygnus.com). @@ -32,10 +32,8 @@ along with GCC; see the file COPYING3. If not see #include "cp-tree.h" #include "output.h" #include "flags.h" -#include "rtl.h" #include "toplev.h" -#include "expr.h" -#include "diagnostic.h" +#include "diagnostic-core.h" #include "intl.h" #include "target.h" #include "convert.h" @@ -124,6 +122,11 @@ struct conversion { : (NODE)->user_conv_p ? cr_user \ : (NODE)->rank) +#define BAD_CONVERSION_RANK(NODE) \ + ((NODE)->ellipsis_p ? cr_ellipsis \ + : (NODE)->user_conv_p ? cr_user \ + : (NODE)->rank) + static struct obstack conversion_obstack; static bool conversion_obstack_initialized; @@ -197,11 +200,11 @@ static bool promoted_arithmetic_type_p (tree); static conversion *conditional_conversion (tree, tree); static char *name_as_c_string (tree, tree, bool *); static tree prep_operand (tree); -static void add_candidates (tree, const VEC(tree,gc) *, tree, bool, tree, tree, - int, struct z_candidate **); +static void add_candidates (tree, tree, const VEC(tree,gc) *, tree, tree, bool, + tree, tree, int, struct z_candidate **); static conversion *merge_conversion_sequences (conversion *, conversion *); static bool magic_varargs_p (tree); -static tree build_temp (tree, tree, int, diagnostic_t *); +static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t); /* Returns nonzero iff the destructor name specified in NAME matches BASETYPE. NAME can take many forms... */ @@ -284,7 +287,7 @@ build_call_n (tree function, int n, ...) return build_call_a (function, 0, NULL); else { - tree *argarray = (tree *) alloca (n * sizeof (tree)); + tree *argarray = XALLOCAVEC (tree, n); va_list ap; int i; @@ -447,6 +450,7 @@ struct z_candidate { indicated by the CONVERSION_PATH. */ tree conversion_path; tree template_decl; + tree explicit_targs; candidate_warning *warnings; z_candidate *next; }; @@ -460,9 +464,11 @@ null_ptr_cst_p (tree t) /* [conv.ptr] A null pointer constant is an integral constant expression - (_expr.const_) rvalue of integer type that evaluates to zero. */ + (_expr.const_) rvalue of integer type that evaluates to zero or + an rvalue of type std::nullptr_t. */ t = integral_constant_value (t); - if (t == null_node) + if (t == null_node + || NULLPTR_TYPE_P (TREE_TYPE (t))) return true; if (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t)) { @@ -588,6 +594,12 @@ build_list_conv (tree type, tree ctor, int flags) unsigned i; tree val; + /* Within a list-initialization we can have more user-defined + conversions. */ + flags &= ~LOOKUP_NO_CONVERSION; + /* But no narrowing conversions. */ + flags |= LOOKUP_NO_NARROWING; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val) { conversion *sub @@ -627,8 +639,9 @@ build_aggr_conv (tree type, tree ctor, int flags) unsigned HOST_WIDE_INT i = 0; conversion *c; tree field = next_initializable_field (TYPE_FIELDS (type)); + tree empty_ctor = NULL_TREE; - for (; field; field = next_initializable_field (TREE_CHAIN (field))) + for (; field; field = next_initializable_field (DECL_CHAIN (field))) { if (i < CONSTRUCTOR_NELTS (ctor)) { @@ -640,8 +653,14 @@ build_aggr_conv (tree type, tree ctor, int flags) if (TREE_CODE (type) == UNION_TYPE) break; } - else if (build_value_init (TREE_TYPE (field)) == error_mark_node) - return NULL; + else + { + if (empty_ctor == NULL_TREE) + empty_ctor = build_constructor (init_list_type_node, NULL); + if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (empty_ctor), + empty_ctor, flags)) + return NULL; + } } if (i < CONSTRUCTOR_NELTS (ctor)) @@ -776,7 +795,12 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, if (same_type_p (from, to)) return conv; - if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to)) + /* [conv.ptr] + A null pointer constant can be converted to a pointer type; ... A + null pointer constant of integral type can be converted to an + rvalue of type std::nullptr_t. */ + if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to) + || NULLPTR_TYPE_P (to)) && expr && null_ptr_cst_p (expr)) conv = build_conv (ck_std, to, conv); else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE) @@ -911,17 +935,20 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, An rvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to an rvalue of type - bool. */ + bool. ... An rvalue of type std::nullptr_t can be converted + to an rvalue of type bool; */ if (ARITHMETIC_TYPE_P (from) || UNSCOPED_ENUM_P (from) || fcode == POINTER_TYPE - || TYPE_PTR_TO_MEMBER_P (from)) + || TYPE_PTR_TO_MEMBER_P (from) + || NULLPTR_TYPE_P (from)) { conv = build_conv (ck_std, to, conv); if (fcode == POINTER_TYPE || TYPE_PTRMEM_P (from) || (TYPE_PTRMEMFUNC_P (from) - && conv->rank < cr_pbool)) + && conv->rank < cr_pbool) + || NULLPTR_TYPE_P (from)) conv->rank = cr_pbool; return conv; } @@ -972,6 +999,9 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, bool reference_related_p (tree t1, tree t2) { + if (t1 == error_mark_node || t2 == error_mark_node) + return false; + t1 = TYPE_MAIN_VARIANT (t1); t2 = TYPE_MAIN_VARIANT (t2); @@ -1013,6 +1043,9 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) struct z_candidate *cand; bool any_viable_p; + if (!expr) + return NULL; + conversions = lookup_conversions (s, /*lookup_template_convs_p=*/true); if (!conversions) return NULL; @@ -1043,60 +1076,35 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) t = TREE_TYPE (reference_type); + /* We're performing a user-defined conversion to a desired type, so set + this for the benefit of add_candidates. */ + flags |= LOOKUP_NO_CONVERSION; + for (; conversions; conversions = TREE_CHAIN (conversions)) { tree fns = TREE_VALUE (conversions); + tree binfo = TREE_PURPOSE (conversions); + struct z_candidate *old_candidates = candidates;; - for (; fns; fns = OVL_NEXT (fns)) + add_candidates (fns, first_arg, NULL, reference_type, + NULL_TREE, false, + binfo, TYPE_BINFO (s), + flags, &candidates); + + for (cand = candidates; cand != old_candidates; cand = cand->next) { - tree f = OVL_CURRENT (fns); + /* Now, see if the conversion function really returns + an lvalue of the appropriate type. From the + point of view of unification, simply returning an + rvalue of the right type is good enough. */ + tree f = cand->fn; tree t2 = TREE_TYPE (TREE_TYPE (f)); - - if (DECL_NONCONVERTING_P (f) - && (flags & LOOKUP_ONLYCONVERTING)) - continue; - - cand = NULL; - - /* If this is a template function, try to get an exact - match. */ - if (TREE_CODE (f) == TEMPLATE_DECL) + if (TREE_CODE (t2) != REFERENCE_TYPE + || !reference_compatible_p (t, TREE_TYPE (t2))) { - cand = add_template_candidate (&candidates, - f, s, - NULL_TREE, - first_arg, - NULL, - reference_type, - TYPE_BINFO (s), - TREE_PURPOSE (conversions), - LOOKUP_NORMAL, - DEDUCE_CONV); - - if (cand) - { - /* Now, see if the conversion function really returns - an lvalue of the appropriate type. From the - point of view of unification, simply returning an - rvalue of the right type is good enough. */ - f = cand->fn; - t2 = TREE_TYPE (TREE_TYPE (f)); - if (TREE_CODE (t2) != REFERENCE_TYPE - || !reference_compatible_p (t, TREE_TYPE (t2))) - { - candidates = candidates->next; - cand = NULL; - } - } + cand->viable = 0; } - else if (TREE_CODE (t2) == REFERENCE_TYPE - && reference_compatible_p (t, TREE_TYPE (t2))) - cand = add_function_candidate (&candidates, f, s, first_arg, - NULL, TYPE_BINFO (s), - TREE_PURPOSE (conversions), - LOOKUP_NORMAL); - - if (cand) + else { conversion *identity_conv; /* Build a standard conversion sequence indicating the @@ -1260,7 +1268,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) type, so that we can later do a const_cast to the desired type. */ if (related_p && c_cast_p && !at_least_as_qualified_p (to, tfrom)) - to = build_qualified_type (to, cp_type_quals (tfrom)); + to = cp_build_qualified_type (to, cp_type_quals (tfrom)); compatible_p = reference_compatible_p (to, tfrom); /* Directly bind reference when target expression's type is compatible with @@ -1389,9 +1397,12 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) conversion operator). */ flags |= LOOKUP_NO_TEMP_BIND; - /* Temporaries are copy-initialized, except for this hack to allow - explicit conversion ops to the copy ctor. See also - add_function_candidate. */ + /* Core issue 899: When [copy-]initializing a temporary to be bound + to the first parameter of a copy constructor (12.8) called with + a single argument in the context of direct-initialization, + explicit conversion functions are also considered. + + So don't set LOOKUP_ONLYCONVERTING in that case. */ if (!(flags & LOOKUP_COPY_PARM)) flags |= LOOKUP_ONLYCONVERTING; @@ -1446,7 +1457,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, tree elt; if (nelts == 0) - elt = integer_zero_node; + elt = build_value_init (to, tf_none); else if (nelts == 1) elt = CONSTRUCTOR_ELT (expr, 0)->value; else @@ -1471,7 +1482,8 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, && (flags & LOOKUP_NO_CONVERSION) == 0) { struct z_candidate *cand; - int convflags = (flags & (LOOKUP_NO_TEMP_BIND|LOOKUP_ONLYCONVERTING)); + int convflags = (flags & (LOOKUP_NO_TEMP_BIND|LOOKUP_ONLYCONVERTING + |LOOKUP_NO_NARROWING)); if (CLASS_TYPE_P (to) && !CLASSTYPE_NON_AGGREGATE (complete_type (to)) @@ -1587,6 +1599,29 @@ add_function_candidate (struct z_candidate **candidates, else if (!sufficient_parms_p (parmnode)) viable = 0; + /* Kludge: When looking for a function from a subobject while generating + an implicit copy/move constructor/operator=, don't consider anything + that takes (a reference to) an unrelated type. See c++/44909. */ + else if ((flags & LOOKUP_SPECULATIVE) + || (current_function_decl + && DECL_DEFAULTED_FN (current_function_decl))) + { + if (DECL_CONSTRUCTOR_P (fn)) + i = 1; + else if (DECL_ASSIGNMENT_OPERATOR_P (fn) + && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR) + i = 2; + else + i = 0; + if (i && len == i) + { + parmnode = chain_index (i-1, parmlist); + if (!reference_related_p (non_reference (TREE_VALUE (parmnode)), + ctype)) + viable = 0; + } + } + if (! viable) goto out; @@ -1620,6 +1655,8 @@ add_function_candidate (struct z_candidate **candidates, tree parmtype = TREE_VALUE (parmnode); int lflags = flags; + parmnode = TREE_CHAIN (parmnode); + /* The type of the implicit object parameter ('this') for overload resolution is not always the same as for the function itself; conversion functions are considered to @@ -1631,19 +1668,30 @@ add_function_candidate (struct z_candidate **candidates, parameter, we can just change the parm type. */ if (ctype && is_this) { - parmtype - = build_qualified_type (ctype, - TYPE_QUALS (TREE_TYPE (parmtype))); + parmtype = cp_build_qualified_type + (ctype, cp_type_quals (TREE_TYPE (parmtype))); parmtype = build_pointer_type (parmtype); } - if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn) - && (len-skip == 1)) + /* Core issue 899: When [copy-]initializing a temporary to be bound + to the first parameter of a copy constructor (12.8) called with + a single argument in the context of direct-initialization, + explicit conversion functions are also considered. + + So set LOOKUP_COPY_PARM to let reference_binding know that + it's being called in that context. We generalize the above + to handle move constructors and template constructors as well; + the standardese should soon be updated similarly. */ + if (ctype && i == 0 && (len-skip == 1) + && !(flags & LOOKUP_ONLYCONVERTING) + && DECL_CONSTRUCTOR_P (fn) + && parmtype != error_mark_node + && (same_type_ignoring_top_level_qualifiers_p + (non_reference (parmtype), ctype))) { - /* Hack: Direct-initialize copy parm (i.e. suppress - LOOKUP_ONLYCONVERTING) to make explicit conversion ops - work. See also reference_binding. */ lflags |= LOOKUP_COPY_PARM; + /* We allow user-defined conversions within init-lists, but + not for the copy constructor. */ if (flags & LOOKUP_NO_COPY_CTOR_CONVERSION) lflags |= LOOKUP_NO_CONVERSION; } @@ -1671,9 +1719,6 @@ add_function_candidate (struct z_candidate **candidates, if (t->bad_p) viable = -1; - - if (parmnode) - parmnode = TREE_CHAIN (parmnode); } out: @@ -2263,6 +2308,8 @@ type_decays_to (tree type) return build_pointer_type (TREE_TYPE (type)); if (TREE_CODE (type) == FUNCTION_TYPE) return build_pointer_type (type); + if (!MAYBE_CLASS_TYPE_P (type)) + type = cv_unqualified (type); return type; } @@ -2286,12 +2333,11 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, { int ref1, i; int enum_p = 0; - tree type, argtypes[3]; + tree type, argtypes[3], t; /* TYPES[i] is the set of possible builtin-operator parameter types - we will consider for the Ith argument. These are represented as - a TREE_LIST; the TREE_VALUE of each node is the potential - parameter type. */ - tree types[2]; + we will consider for the Ith argument. */ + VEC(tree,gc) *types[2]; + unsigned ix; for (i = 0; i < 3; ++i) { @@ -2353,7 +2399,8 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, ref1 = 0; } - types[0] = types[1] = NULL_TREE; + types[0] = make_tree_vector (); + types[1] = make_tree_vector (); for (i = 0; i < 2; ++i) { @@ -2372,11 +2419,11 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, if (code == COND_EXPR) { if (real_lvalue_p (args[i])) - types[i] = tree_cons - (NULL_TREE, build_reference_type (argtypes[i]), types[i]); + VEC_safe_push (tree, gc, types[i], + build_reference_type (argtypes[i])); - types[i] = tree_cons - (NULL_TREE, TYPE_MAIN_VARIANT (argtypes[i]), types[i]); + VEC_safe_push (tree, gc, types[i], + TYPE_MAIN_VARIANT (argtypes[i])); } else if (! convs) @@ -2392,54 +2439,60 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, continue; if (code == COND_EXPR && TREE_CODE (type) == REFERENCE_TYPE) - types[i] = tree_cons (NULL_TREE, type, types[i]); + VEC_safe_push (tree, gc, types[i], type); type = non_reference (type); if (i != 0 || ! ref1) { type = TYPE_MAIN_VARIANT (type_decays_to (type)); if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE) - types[i] = tree_cons (NULL_TREE, type, types[i]); + VEC_safe_push (tree, gc, types[i], type); if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type)) type = type_promotes_to (type); } - if (! value_member (type, types[i])) - types[i] = tree_cons (NULL_TREE, type, types[i]); + if (! vec_member (type, types[i])) + VEC_safe_push (tree, gc, types[i], type); } } else { if (code == COND_EXPR && real_lvalue_p (args[i])) - types[i] = tree_cons - (NULL_TREE, build_reference_type (argtypes[i]), types[i]); + VEC_safe_push (tree, gc, types[i], + build_reference_type (argtypes[i])); type = non_reference (argtypes[i]); if (i != 0 || ! ref1) { type = TYPE_MAIN_VARIANT (type_decays_to (type)); if (enum_p && UNSCOPED_ENUM_P (type)) - types[i] = tree_cons (NULL_TREE, type, types[i]); + VEC_safe_push (tree, gc, types[i], type); if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type)) type = type_promotes_to (type); } - types[i] = tree_cons (NULL_TREE, type, types[i]); + VEC_safe_push (tree, gc, types[i], type); } } /* Run through the possible parameter types of both arguments, creating candidates with those parameter types. */ - for (; types[0]; types[0] = TREE_CHAIN (types[0])) + FOR_EACH_VEC_ELT_REVERSE (tree, types[0], ix, t) { - if (types[1]) - for (type = types[1]; type; type = TREE_CHAIN (type)) + unsigned jx; + tree u; + + if (!VEC_empty (tree, types[1])) + FOR_EACH_VEC_ELT_REVERSE (tree, types[1], jx, u) add_builtin_candidate - (candidates, code, code2, fnname, TREE_VALUE (types[0]), - TREE_VALUE (type), args, argtypes, flags); + (candidates, code, code2, fnname, t, + u, args, argtypes, flags); else add_builtin_candidate - (candidates, code, code2, fnname, TREE_VALUE (types[0]), + (candidates, code, code2, fnname, t, NULL_TREE, args, argtypes, flags); } + + release_tree_vector (types[0]); + release_tree_vector (types[1]); } @@ -2521,11 +2574,11 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, return_type, strict, flags); if (i != 0) - return NULL; + goto fail; fn = instantiate_template (tmpl, targs, tf_none); if (fn == error_mark_node) - return NULL; + goto fail; /* In [class.copy]: @@ -2554,7 +2607,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn); if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)), ctype)) - return NULL; + goto fail; } if (obj != NULL_TREE) @@ -2586,8 +2639,12 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, cand->template_decl = build_template_info (tmpl, targs); else cand->template_decl = DECL_TEMPLATE_INFO (fn); + cand->explicit_targs = explicit_targs; return cand; + fail: + return add_candidate (candidates, tmpl, first_arg, arglist, nargs, NULL, + access_path, conversion_path, 0); } @@ -2620,10 +2677,10 @@ add_template_conv_candidate (struct z_candidate **candidates, tree tmpl, } /* The CANDS are the set of candidates that were considered for - overload resolution. Return the set of viable candidates. If none - of the candidates were viable, set *ANY_VIABLE_P to true. STRICT_P - is true if a candidate should be considered viable only if it is - strictly viable. */ + overload resolution. Return the set of viable candidates, or CANDS + if none are viable. If any of the candidates were viable, set + *ANY_VIABLE_P to true. STRICT_P is true if a candidate should be + considered viable only if it is strictly viable. */ static struct z_candidate* splice_viable (struct z_candidate *cands, @@ -2688,6 +2745,10 @@ build_this (tree obj) static inline int equal_functions (tree fn1, tree fn2) { + if (TREE_CODE (fn1) != TREE_CODE (fn2)) + return 0; + if (TREE_CODE (fn1) == TEMPLATE_DECL) + return fn1 == fn2; if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2) || DECL_EXTERN_C_FUNCTION_P (fn1)) return decls_match (fn1, fn2); @@ -2723,7 +2784,7 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate) inform (input_location, "%s %T <conversion>", msgstr, candidate->fn); else if (candidate->viable == -1) inform (input_location, "%s %+#D <near match>", msgstr, candidate->fn); - else if (DECL_DELETED_FN (candidate->fn)) + else if (DECL_DELETED_FN (STRIP_TEMPLATE (candidate->fn))) inform (input_location, "%s %+#D <deleted>", msgstr, candidate->fn); else inform (input_location, "%s %+#D", msgstr, candidate->fn); @@ -2740,11 +2801,12 @@ print_z_candidates (struct z_candidate *candidates) if (!candidates) return; - /* Remove deleted candidates. */ + /* Remove non-viable deleted candidates. */ cand1 = candidates; for (cand2 = &cand1; *cand2; ) { if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL + && !(*cand2)->viable && DECL_DELETED_FN ((*cand2)->fn)) *cand2 = (*cand2)->next; else @@ -2763,12 +2825,12 @@ print_z_candidates (struct z_candidate *candidates) { tree fn = cand1->fn; /* Skip builtin candidates and conversion functions. */ - if (TREE_CODE (fn) != FUNCTION_DECL) + if (!DECL_P (fn)) continue; cand2 = &cand1->next; while (*cand2) { - if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL + if (DECL_P ((*cand2)->fn) && equal_functions (fn, (*cand2)->fn)) *cand2 = (*cand2)->next; else @@ -2814,6 +2876,65 @@ merge_conversion_sequences (conversion *user_seq, conversion *std_seq) return std_seq; } +/* Handle overload resolution for initializing an object of class type from + an initializer list. First we look for a suitable constructor that + takes a std::initializer_list; if we don't find one, we then look for a + non-list constructor. + + Parameters are as for add_candidates, except that the arguments are in + the form of a CONSTRUCTOR (the initializer list) rather than a VEC, and + the RETURN_TYPE parameter is replaced by TOTYPE, the desired type. */ + +static void +add_list_candidates (tree fns, tree first_arg, + tree init_list, tree totype, + tree explicit_targs, bool template_only, + tree conversion_path, tree access_path, + int flags, + struct z_candidate **candidates) +{ + VEC(tree,gc) *args; + + gcc_assert (*candidates == NULL); + + /* For list-initialization we consider explicit constructors, but + give an error if one is selected. */ + flags &= ~LOOKUP_ONLYCONVERTING; + /* And we don't allow narrowing conversions. We also use this flag to + avoid the copy constructor call for copy-list-initialization. */ + flags |= LOOKUP_NO_NARROWING; + + /* Always use the default constructor if the list is empty (DR 990). */ + if (CONSTRUCTOR_NELTS (init_list) == 0 + && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype)) + ; + /* If the class has a list ctor, try passing the list as a single + argument first, but only consider list ctors. */ + else if (TYPE_HAS_LIST_CTOR (totype)) + { + flags |= LOOKUP_LIST_ONLY; + args = make_tree_vector_single (init_list); + add_candidates (fns, first_arg, args, NULL_TREE, + explicit_targs, template_only, conversion_path, + access_path, flags, candidates); + if (any_strictly_viable (*candidates)) + return; + } + + args = ctor_to_vec (init_list); + + /* We aren't looking for list-ctors anymore. */ + flags &= ~LOOKUP_LIST_ONLY; + /* We allow more user-defined conversions within an init-list. */ + flags &= ~LOOKUP_NO_CONVERSION; + /* But not for the copy ctor. */ + flags |= LOOKUP_NO_COPY_CTOR_CONVERSION; + + add_candidates (fns, first_arg, args, NULL_TREE, + explicit_targs, template_only, conversion_path, + access_path, flags, candidates); +} + /* Returns the best overload candidate to perform the requested conversion. This function is used for three the overloading situations described in [over.match.copy], [over.match.conv], and [over.match.ref]. @@ -2862,6 +2983,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) candidates = 0; flags |= LOOKUP_NO_CONVERSION; + if (BRACE_ENCLOSED_INITIALIZER_P (expr)) + flags |= LOOKUP_NO_NARROWING; /* It's OK to bind a temporary for converting constructor arguments, but not in converting the return value of a conversion operator. */ @@ -2870,48 +2993,32 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) if (ctors) { + int ctorflags = flags; ctors = BASELINK_FUNCTIONS (ctors); first_arg = build_int_cst (build_pointer_type (totype), 0); - if (BRACE_ENCLOSED_INITIALIZER_P (expr) - && !TYPE_HAS_LIST_CTOR (totype)) - { - args = ctor_to_vec (expr); - /* We still allow more conversions within an init-list. */ - flags = ((flags & ~LOOKUP_NO_CONVERSION) - /* But not for the copy ctor. */ - |LOOKUP_NO_COPY_CTOR_CONVERSION - |LOOKUP_NO_NARROWING); - } - else - args = make_tree_vector_single (expr); /* We should never try to call the abstract or base constructor from here. */ gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors)) && !DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors))); - } - for (; ctors; ctors = OVL_NEXT (ctors)) - { - tree ctor = OVL_CURRENT (ctors); - if (DECL_NONCONVERTING_P (ctor) - && !BRACE_ENCLOSED_INITIALIZER_P (expr)) - continue; - if (TREE_CODE (ctor) == TEMPLATE_DECL) - cand = add_template_candidate (&candidates, ctor, totype, - NULL_TREE, first_arg, args, NULL_TREE, - TYPE_BINFO (totype), - TYPE_BINFO (totype), - flags, - DEDUCE_CALL); + if (BRACE_ENCLOSED_INITIALIZER_P (expr)) + { + /* List-initialization. */ + add_list_candidates (ctors, first_arg, expr, totype, NULL_TREE, + false, TYPE_BINFO (totype), TYPE_BINFO (totype), + ctorflags, &candidates); + } else - cand = add_function_candidate (&candidates, ctor, totype, - first_arg, args, TYPE_BINFO (totype), - TYPE_BINFO (totype), - flags); + { + args = make_tree_vector_single (expr); + add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false, + TYPE_BINFO (totype), TYPE_BINFO (totype), + ctorflags, &candidates); + } - if (cand) + for (cand = candidates; cand; cand = cand->next) { cand->second_conv = build_identity_conv (totype, NULL_TREE); @@ -2935,8 +3042,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) for (; conv_fns; conv_fns = TREE_CHAIN (conv_fns)) { - tree fns; tree conversion_path = TREE_PURPOSE (conv_fns); + struct z_candidate *old_candidates; /* If we are called to convert to a reference type, we are trying to find an lvalue binding, so don't even consider temporaries. If @@ -2945,65 +3052,40 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) if (TREE_CODE (totype) == REFERENCE_TYPE) convflags |= LOOKUP_NO_TEMP_BIND; - for (fns = TREE_VALUE (conv_fns); fns; fns = OVL_NEXT (fns)) + old_candidates = candidates; + add_candidates (TREE_VALUE (conv_fns), first_arg, NULL, totype, + NULL_TREE, false, + conversion_path, TYPE_BINFO (fromtype), + flags, &candidates); + + for (cand = candidates; cand != old_candidates; cand = cand->next) { - tree fn = OVL_CURRENT (fns); - - if (DECL_NONCONVERTING_P (fn) - && (flags & LOOKUP_ONLYCONVERTING)) - continue; - - /* [over.match.funcs] For conversion functions, the function - is considered to be a member of the class of the implicit - object argument for the purpose of defining the type of - the implicit object parameter. - - So we pass fromtype as CTYPE to add_*_candidate. */ - - if (TREE_CODE (fn) == TEMPLATE_DECL) - cand = add_template_candidate (&candidates, fn, fromtype, - NULL_TREE, - first_arg, NULL, totype, - TYPE_BINFO (fromtype), - conversion_path, - flags, - DEDUCE_CONV); - else - cand = add_function_candidate (&candidates, fn, fromtype, - first_arg, NULL, - TYPE_BINFO (fromtype), - conversion_path, - flags); + conversion *ics + = implicit_conversion (totype, + TREE_TYPE (TREE_TYPE (cand->fn)), + 0, + /*c_cast_p=*/false, convflags); - if (cand) - { - conversion *ics - = implicit_conversion (totype, - TREE_TYPE (TREE_TYPE (cand->fn)), - 0, - /*c_cast_p=*/false, convflags); - - /* If LOOKUP_NO_TEMP_BIND isn't set, then this is - copy-initialization. In that case, "The result of the - call is then used to direct-initialize the object that is - the destination of the copy-initialization." [dcl.init] - - We represent this in the conversion sequence with an - rvalue conversion, which means a constructor call. But - don't add a second rvalue conversion if there's already - one there. Which there really shouldn't be, but it's - harmless since we'd add it here anyway. */ - if (ics && MAYBE_CLASS_TYPE_P (totype) && ics->kind != ck_rvalue - && !(convflags & LOOKUP_NO_TEMP_BIND)) - ics = build_conv (ck_rvalue, totype, ics); - - cand->second_conv = ics; - - if (!ics) - cand->viable = 0; - else if (candidates->viable == 1 && ics->bad_p) - cand->viable = -1; - } + /* If LOOKUP_NO_TEMP_BIND isn't set, then this is + copy-initialization. In that case, "The result of the + call is then used to direct-initialize the object that is + the destination of the copy-initialization." [dcl.init] + + We represent this in the conversion sequence with an + rvalue conversion, which means a constructor call. But + don't add a second rvalue conversion if there's already + one there. Which there really shouldn't be, but it's + harmless since we'd add it here anyway. */ + if (ics && MAYBE_CLASS_TYPE_P (totype) && ics->kind != ck_rvalue + && !(convflags & LOOKUP_NO_TEMP_BIND)) + ics = build_conv (ck_rvalue, totype, ics); + + cand->second_conv = ics; + + if (!ics) + cand->viable = 0; + else if (cand->viable == 1 && ics->bad_p) + cand->viable = -1; } } @@ -3079,7 +3161,7 @@ resolve_args (VEC(tree,gc) *args) unsigned int ix; tree arg; - for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix) + FOR_EACH_VEC_ELT (tree, args, ix, arg) { if (error_operand_p (arg)) return NULL; @@ -3133,7 +3215,8 @@ perform_overload_resolution (tree fn, } /* Add the various candidate functions. */ - add_candidates (fn, args, explicit_targs, template_only, + add_candidates (fn, NULL_TREE, args, NULL_TREE, + explicit_targs, template_only, /*conversion_path=*/NULL_TREE, /*access_path=*/NULL_TREE, LOOKUP_NORMAL, @@ -3194,7 +3277,8 @@ build_new_function_call (tree fn, VEC(tree,gc) **args, bool koenig_p, { if (complain & tf_error) { - if (!any_viable_p && candidates && ! candidates->next) + if (!any_viable_p && candidates && ! candidates->next + && (TREE_CODE (candidates->fn) == FUNCTION_DECL)) return cp_build_function_call_vec (candidates->fn, args, complain); if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) fn = TREE_OPERAND (fn, 0); @@ -3371,24 +3455,13 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain) if (fns) { - tree base = BINFO_TYPE (BASELINK_BINFO (fns)); first_mem_arg = build_this (obj); - for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns)) - { - tree fn = OVL_CURRENT (fns); - - if (TREE_CODE (fn) == TEMPLATE_DECL) - add_template_candidate (&candidates, fn, base, NULL_TREE, - first_mem_arg, *args, NULL_TREE, - TYPE_BINFO (type), - TYPE_BINFO (type), - LOOKUP_NORMAL, DEDUCE_CALL); - else - add_function_candidate - (&candidates, fn, base, first_mem_arg, *args, TYPE_BINFO (type), - TYPE_BINFO (type), LOOKUP_NORMAL); - } + add_candidates (BASELINK_FUNCTIONS (fns), + first_mem_arg, *args, NULL_TREE, + NULL_TREE, false, + BASELINK_BINFO (fns), BASELINK_ACCESS_BINFO (fns), + LOOKUP_NORMAL, &candidates); } convs = lookup_conversions (type, /*lookup_template_convs_p=*/true); @@ -3613,7 +3686,6 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, tree arg2_type; tree arg3_type; tree result = NULL_TREE; - tree result_save; tree result_type = NULL_TREE; bool lvalue_p = true; struct z_candidate *candidates = 0; @@ -3805,11 +3877,11 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, the type of the other. */ if ((conv2 || conv3) && CLASS_TYPE_P (arg2_type) - && TYPE_QUALS (arg2_type) != TYPE_QUALS (arg3_type)) + && cp_type_quals (arg2_type) != cp_type_quals (arg3_type)) arg2_type = arg3_type = cp_build_qualified_type (arg2_type, - TYPE_QUALS (arg2_type) - | TYPE_QUALS (arg3_type)); + cp_type_quals (arg2_type) + | cp_type_quals (arg3_type)); } /* [expr.cond] @@ -3821,6 +3893,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, && same_type_p (arg2_type, arg3_type)) { result_type = arg2_type; + arg2 = mark_lvalue_use (arg2); + arg3 = mark_lvalue_use (arg3); goto valid_operands; } @@ -3935,6 +4009,10 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, /* In this case, there is always a common type. */ result_type = type_after_usual_arithmetic_conversions (arg2_type, arg3_type); + do_warn_double_promotion (result_type, arg2_type, arg3_type, + "implicit conversion from %qT to %qT to " + "match other result of conditional", + input_location); if (TREE_CODE (arg2_type) == ENUMERAL_TYPE && TREE_CODE (arg3_type) == ENUMERAL_TYPE) @@ -4000,12 +4078,10 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, } valid_operands: - result_save = build3 (COND_EXPR, result_type, arg1, arg2, arg3); - result = fold_if_not_in_template (result_save); - - if (cp_unevaluated_operand && TREE_CODE (result) == CALL_EXPR) - /* Avoid folding to a CALL_EXPR within decltype (c++/42013). */ - result = result_save; + result = build3 (COND_EXPR, result_type, arg1, arg2, arg3); + if (!cp_unevaluated_operand) + /* Avoid folding within decltype (c++/42013) and noexcept. */ + result = fold_if_not_in_template (result); /* We can't use result_type below, as fold might have returned a throw_expr. */ @@ -4046,53 +4122,101 @@ prep_operand (tree operand) /* Add each of the viable functions in FNS (a FUNCTION_DECL or OVERLOAD) to the CANDIDATES, returning an updated list of - CANDIDATES. The ARGS are the arguments provided to the call, - without any implicit object parameter. This may change ARGS. The + CANDIDATES. The ARGS are the arguments provided to the call; + if FIRST_ARG is non-null it is the implicit object argument, + otherwise the first element of ARGS is used if needed. The EXPLICIT_TARGS are explicit template arguments provided. TEMPLATE_ONLY is true if only template functions should be considered. CONVERSION_PATH, ACCESS_PATH, and FLAGS are as for add_function_candidate. */ static void -add_candidates (tree fns, const VEC(tree,gc) *args, +add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args, + tree return_type, tree explicit_targs, bool template_only, tree conversion_path, tree access_path, int flags, struct z_candidate **candidates) { tree ctype; - VEC(tree,gc) *non_static_args; - tree first_arg; + const VEC(tree,gc) *non_static_args; + bool check_list_ctor; + bool check_converting; + unification_kind_t strict; + tree fn; + + if (!fns) + return; + + /* Precalculate special handling of constructors and conversion ops. */ + fn = OVL_CURRENT (fns); + if (DECL_CONV_FN_P (fn)) + { + check_list_ctor = false; + check_converting = !!(flags & LOOKUP_ONLYCONVERTING); + if (flags & LOOKUP_NO_CONVERSION) + /* We're doing return_type(x). */ + strict = DEDUCE_CONV; + else + /* We're doing x.operator return_type(). */ + strict = DEDUCE_EXACT; + /* [over.match.funcs] For conversion functions, the function + is considered to be a member of the class of the implicit + object argument for the purpose of defining the type of + the implicit object parameter. */ + ctype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (first_arg))); + } + else + { + if (DECL_CONSTRUCTOR_P (fn)) + { + check_list_ctor = !!(flags & LOOKUP_LIST_ONLY); + check_converting = !!(flags & LOOKUP_ONLYCONVERTING); + } + else + { + check_list_ctor = false; + check_converting = false; + } + strict = DEDUCE_CALL; + ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE; + } - ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE; - /* Delay creating the implicit this parameter until it is needed. */ - non_static_args = NULL; - first_arg = NULL_TREE; + if (first_arg) + non_static_args = args; + else + /* Delay creating the implicit this parameter until it is needed. */ + non_static_args = NULL; - while (fns) + for (; fns; fns = OVL_NEXT (fns)) { - tree fn; tree fn_first_arg; const VEC(tree,gc) *fn_args; fn = OVL_CURRENT (fns); + + if (check_converting && DECL_NONCONVERTING_P (fn)) + continue; + if (check_list_ctor && !is_list_ctor (fn)) + continue; + /* Figure out which set of arguments to use. */ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) { - /* If this function is a non-static member, prepend the implicit - object parameter. */ - if (non_static_args == NULL) + /* If this function is a non-static member and we didn't get an + implicit object argument, move it out of args. */ + if (first_arg == NULL_TREE) { unsigned int ix; tree arg; - - non_static_args = VEC_alloc (tree, gc, - VEC_length (tree, args) - 1); + VEC(tree,gc) *tempvec + = VEC_alloc (tree, gc, VEC_length (tree, args) - 1); for (ix = 1; VEC_iterate (tree, args, ix, arg); ++ix) - VEC_quick_push (tree, non_static_args, arg); + VEC_quick_push (tree, tempvec, arg); + non_static_args = tempvec; + first_arg = build_this (VEC_index (tree, args, 0)); } - if (first_arg == NULL_TREE) - first_arg = build_this (VEC_index (tree, args, 0)); + fn_first_arg = first_arg; fn_args = non_static_args; } @@ -4110,11 +4234,11 @@ add_candidates (tree fns, const VEC(tree,gc) *args, explicit_targs, fn_first_arg, fn_args, - NULL_TREE, + return_type, access_path, conversion_path, flags, - DEDUCE_CALL); + strict); else if (!template_only) add_function_candidate (candidates, fn, @@ -4124,7 +4248,6 @@ add_candidates (tree fns, const VEC(tree,gc) *args, access_path, conversion_path, flags); - fns = OVL_NEXT (fns); } } @@ -4235,7 +4358,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, /* Add namespace-scope operators to the list of functions to consider. */ add_candidates (lookup_function_nonclass (fnname, arglist, /*block_p=*/true), - arglist, NULL_TREE, false, NULL_TREE, NULL_TREE, + NULL_TREE, arglist, NULL_TREE, + NULL_TREE, false, NULL_TREE, NULL_TREE, flags, &candidates); /* Add class-member operators to the candidate set. */ if (CLASS_TYPE_P (TREE_TYPE (arg1))) @@ -4249,10 +4373,11 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, goto user_defined_result_ready; } if (fns) - add_candidates (BASELINK_FUNCTIONS (fns), arglist, + add_candidates (BASELINK_FUNCTIONS (fns), + NULL_TREE, arglist, NULL_TREE, NULL_TREE, false, BASELINK_BINFO (fns), - TYPE_BINFO (TREE_TYPE (arg1)), + BASELINK_ACCESS_BINFO (fns), flags, &candidates); } @@ -4498,7 +4623,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, return cp_build_unary_op (code, arg1, candidates != 0, complain); case ARRAY_REF: - return build_array_ref (input_location, arg1, arg2); + return cp_build_array_ref (input_location, arg1, arg2, complain); case MEMBER_REF: return build_m_component_ref (cp_build_indirect_ref (arg1, RO_NULL, @@ -4690,7 +4815,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, /* The placement args might not be suitable for overload resolution at this point, so build the call directly. */ int nargs = call_expr_nargs (placement); - tree *argarray = (tree *) alloca (nargs * sizeof (tree)); + tree *argarray = XALLOCAVEC (tree, nargs); int i; argarray[0] = addr; for (i = 1; i < nargs; i++) @@ -4762,7 +4887,7 @@ enforce_access (tree basetype_path, tree decl, tree diag_decl) static tree build_temp (tree expr, tree type, int flags, - diagnostic_t *diagnostic_kind) + diagnostic_t *diagnostic_kind, tsubst_flags_t complain) { int savew, savee; VEC(tree,gc) *args; @@ -4770,7 +4895,7 @@ build_temp (tree expr, tree type, int flags, savew = warningcount, savee = errorcount; args = make_tree_vector_single (expr); expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, - &args, type, flags, tf_warning_or_error); + &args, type, flags, complain); release_tree_vector (args); if (warningcount > savew) *diagnostic_kind = DK_WARNING; @@ -4867,7 +4992,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, { permerror (input_location, "invalid conversion from %qT to %qT", TREE_TYPE (expr), totype); if (fn) - permerror (input_location, " initializing argument %P of %qD", argnum, fn); + permerror (DECL_SOURCE_LOCATION (fn), + " initializing argument %P of %qD", argnum, fn); } else return error_mark_node; @@ -4886,9 +5012,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, tree convfn = cand->fn; unsigned i; + expr = mark_rvalue_use (expr); + /* When converting from an init list we consider explicit constructors, but actually trying to call one is an error. */ - if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)) + if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn) + /* Unless we're calling it for value-initialization from an + empty list, since that is handled separately in 8.5.4. */ + && cand->num_convs > 0) { if (complain & tf_error) error ("converting to %qT from initializer list would use " @@ -4918,11 +5049,12 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, return expr; } case ck_identity: + expr = mark_rvalue_use (expr); if (BRACE_ENCLOSED_INITIALIZER_P (expr)) { int nelts = CONSTRUCTOR_NELTS (expr); if (nelts == 0) - expr = integer_zero_node; + expr = build_value_init (totype, tf_warning_or_error); else if (nelts == 1) expr = CONSTRUCTOR_ELT (expr, 0)->value; else @@ -4945,9 +5077,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, } return expr; case ck_ambig: - /* Call build_user_type_conversion again for the error. */ - return build_user_type_conversion - (totype, convs->u.expr, LOOKUP_NORMAL); + if (complain & tf_error) + { + /* Call build_user_type_conversion again for the error. */ + build_user_type_conversion (totype, convs->u.expr, LOOKUP_NORMAL); + if (fn) + error (" initializing argument %P of %q+D", argnum, fn); + } + return error_mark_node; case ck_list: { @@ -4971,7 +5108,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, } /* Build up the array. */ elttype = cp_build_qualified_type - (elttype, TYPE_QUALS (elttype) | TYPE_QUAL_CONST); + (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); array = build_array_of_n_type (elttype, len); array = finish_compound_literal (array, new_ctor); @@ -5017,7 +5154,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, /* Build an expression for `*((base*) &expr)'. */ expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain); expr = convert_to_base (expr, build_pointer_type (totype), - !c_cast_p, /*nonnull=*/true); + !c_cast_p, /*nonnull=*/true, complain); expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain); return expr; } @@ -5031,11 +5168,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, conversion (i.e. the second step of copy-initialization), so don't allow any more. */ flags |= LOOKUP_NO_CONVERSION; - expr = build_temp (expr, totype, flags, &diag_kind); + expr = build_temp (expr, totype, flags, &diag_kind, complain); if (diag_kind && fn) { if ((complain & tf_error)) - emit_diagnostic (diag_kind, input_location, 0, + emit_diagnostic (diag_kind, DECL_SOURCE_LOCATION (fn), 0, " initializing argument %P of %qD", argnum, fn); else if (diag_kind == DK_ERROR) return error_mark_node; @@ -5070,10 +5207,16 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, || TREE_CODE (expr) == CONSTRUCTOR || TREE_CODE (expr) == VA_ARG_EXPR) { - tree type = convs->u.next->type; + /* Otherwise, a temporary of type "cv1 T1" is created and + initialized from the initializer expression using the rules + for a non-reference copy-initialization (8.5). */ + + tree type = TREE_TYPE (ref_type); cp_lvalue_kind lvalue = real_lvalue_p (expr); - if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)) + gcc_assert (same_type_ignoring_top_level_qualifiers_p + (type, convs->u.next->type)); + if (!CP_TYPE_CONST_NON_VOLATILE_P (type) && !TYPE_REF_IS_RVALUE (ref_type)) { if (complain & tf_error) @@ -5099,7 +5242,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, OK. */ if ((lvalue & clk_packed) && CLASS_TYPE_P (type) - && !TYPE_HAS_TRIVIAL_INIT_REF (type)) + && type_has_nontrivial_copy_init (type)) { if (complain & tf_error) error ("cannot bind packed field %qE to %qT", @@ -5140,12 +5283,12 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, case ck_ptr: if (convs->base_p) expr = convert_to_base (expr, totype, !c_cast_p, - /*nonnull=*/false); + /*nonnull=*/false, complain); return build_nop (totype, expr); case ck_pmem: return convert_ptrmem (totype, expr, /*allow_inverse_p=*/false, - c_cast_p); + c_cast_p, complain); default: break; @@ -5168,11 +5311,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, tree convert_arg_to_ellipsis (tree arg) { + tree arg_type; + /* [expr.call] The lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are performed. */ arg = decay_conversion (arg); + arg_type = TREE_TYPE (arg); /* [expr.call] If the argument has integral or enumeration type that is subject @@ -5180,19 +5326,29 @@ convert_arg_to_ellipsis (tree arg) type that is subject to the floating point promotion (_conv.fpprom_), the value of the argument is converted to the promoted type before the call. */ - if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE - && (TYPE_PRECISION (TREE_TYPE (arg)) + if (TREE_CODE (arg_type) == REAL_TYPE + && (TYPE_PRECISION (arg_type) < TYPE_PRECISION (double_type_node)) - && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (arg)))) - arg = convert_to_real (double_type_node, arg); - else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg))) + && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (arg_type))) + { + if (warn_double_promotion && !c_inhibit_evaluation_warnings) + warning (OPT_Wdouble_promotion, + "implicit conversion from %qT to %qT when passing " + "argument to function", + arg_type, double_type_node); + arg = convert_to_real (double_type_node, arg); + } + else if (NULLPTR_TYPE_P (arg_type)) + arg = null_pointer_node; + else if (INTEGRAL_OR_ENUMERATION_TYPE_P (arg_type)) arg = perform_integral_promotions (arg); arg = require_complete_type (arg); + arg_type = TREE_TYPE (arg); if (arg != error_mark_node - && (type_has_nontrivial_copy_init (TREE_TYPE (arg)) - || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (arg)))) + && (type_has_nontrivial_copy_init (arg_type) + || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (arg_type))) { /* [expr.call] 5.2.2/7: Passing a potentially-evaluated argument of class type (Clause 9) @@ -5207,7 +5363,7 @@ convert_arg_to_ellipsis (tree arg) it is not potentially-evaluated. */ if (cp_unevaluated_operand == 0) error ("cannot pass objects of non-trivially-copyable " - "type %q#T through %<...%>", TREE_TYPE (arg)); + "type %q#T through %<...%>", arg_type); } return arg; @@ -5226,6 +5382,8 @@ build_x_va_arg (tree expr, tree type) if (expr == error_mark_node || !type) return error_mark_node; + expr = mark_lvalue_use (expr); + if (type_has_nontrivial_copy_init (type) || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) || TREE_CODE (type) == REFERENCE_TYPE) @@ -5286,7 +5444,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) } /* Detect recursion. */ - for (i = 0; VEC_iterate (tree, default_arg_context, i, t); ++i) + FOR_EACH_VEC_ELT (tree, default_arg_context, i, t) if (t == fn) { error ("recursive evaluation of default argument for %q#D", fn); @@ -5312,7 +5470,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) { arg = digest_init (type, arg); arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, - "default argument", fn, parmnum, + ICR_DEFAULT_ARGUMENT, fn, parmnum, tf_warning_or_error); } else @@ -5326,7 +5484,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) if (!CONSTANT_CLASS_P (arg)) arg = unshare_expr (arg); arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, - "default argument", fn, parmnum, + ICR_DEFAULT_ARGUMENT, fn, parmnum, tf_warning_or_error); arg = convert_for_arg_passing (type, arg); } @@ -5348,7 +5506,7 @@ type_passed_as (tree type) { type = build_reference_type (type); /* There are no other pointers to this temporary. */ - type = build_qualified_type (type, TYPE_QUAL_RESTRICT); + type = cp_build_qualified_type (type, TYPE_QUAL_RESTRICT); } else if (targetm.calls.promote_prototypes (type) && INTEGRAL_TYPE_P (type) @@ -5483,7 +5641,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ++nargs; alcarray = XALLOCAVEC (tree, nargs); alcarray[0] = first_arg; - for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix) + FOR_EACH_VEC_ELT (tree, args, ix, arg) alcarray[ix + 1] = arg; argarray = alcarray; } @@ -5498,7 +5656,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) } /* Give any warnings we noticed during overload resolution. */ - if (cand->warnings) + if (cand->warnings && (complain & tf_warning)) { struct candidate_warning *w; for (w = cand->warnings; w; w = w->next) @@ -5511,6 +5669,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) if (DECL_FUNCTION_MEMBER_P (fn)) { + tree access_fn; /* If FN is a template function, two cases must be considered. For example: @@ -5538,10 +5697,41 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) different access. */ if (DECL_TEMPLATE_INFO (fn) && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (fn))) - perform_or_defer_access_check (cand->access_path, - DECL_TI_TEMPLATE (fn), fn); + access_fn = DECL_TI_TEMPLATE (fn); + else + access_fn = fn; + if (flags & LOOKUP_SPECULATIVE) + { + /* If we're checking for implicit delete, we don't want access + control errors. */ + if (!accessible_p (cand->access_path, access_fn, true)) + { + /* Unless we're under maybe_explain_implicit_delete. */ + if (flags & LOOKUP_COMPLAIN) + enforce_access (cand->access_path, access_fn, fn); + return error_mark_node; + } + } else - perform_or_defer_access_check (cand->access_path, fn, fn); + perform_or_defer_access_check (cand->access_path, access_fn, fn); + } + + /* If we're checking for implicit delete, don't bother with argument + conversions. */ + if (flags & LOOKUP_SPECULATIVE) + { + if (DECL_DELETED_FN (fn)) + { + if (flags & LOOKUP_COMPLAIN) + mark_used (fn); + return error_mark_node; + } + if (cand->viable == 1) + return fn; + else if (!(flags & LOOKUP_COMPLAIN)) + /* Reject bad conversions now. */ + return error_mark_node; + /* else continue to get conversion error. */ } /* Find maximum size of vector to hold converted arguments. */ @@ -5549,7 +5739,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) nargs = VEC_length (tree, args) + (first_arg != NULL_TREE ? 1 : 0); if (parmlen > nargs) nargs = parmlen; - argarray = (tree *) alloca (nargs * sizeof (tree)); + argarray = XALLOCAVEC (tree, nargs); /* The implicit parameters to a constructor are not considered by overload resolution, and must be of the proper type. */ @@ -5638,6 +5828,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) parm = TREE_CHAIN (parm), ++arg_index, ++i) { tree type = TREE_VALUE (parm); + tree arg = VEC_index (tree, args, arg_index); conv = convs[i]; @@ -5652,7 +5843,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) if (cxx_dialect > cxx98 && flag_deduce_init_list && cand->template_decl - && is_std_init_list (non_reference (type))) + && is_std_init_list (non_reference (type)) + && BRACE_ENCLOSED_INITIALIZER_P (arg)) { tree tmpl = TI_TEMPLATE (cand->template_decl); tree realparm = chain_index (j, DECL_ARGUMENTS (cand->fn)); @@ -5662,7 +5854,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) pattype = PACK_EXPANSION_PATTERN (pattype); pattype = non_reference (pattype); - if (!is_std_init_list (pattype)) + if (TREE_CODE (pattype) == TEMPLATE_TYPE_PARM + && (cand->explicit_targs == NULL_TREE + || (TREE_VEC_LENGTH (cand->explicit_targs) + <= TEMPLATE_TYPE_IDX (pattype)))) { pedwarn (input_location, 0, "deducing %qT as %qT", non_reference (TREE_TYPE (patparm)), @@ -5673,9 +5868,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) } } - val = convert_like_with_context - (conv, VEC_index (tree, args, arg_index), fn, i - is_method, - complain); + val = convert_like_with_context (conv, arg, fn, i-is_method, complain); val = convert_for_arg_passing (type, val); if (val == error_mark_node) @@ -5694,7 +5887,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) { tree a = VEC_index (tree, args, arg_index); if (magic_varargs_p (fn)) - /* Do no conversions for magic varargs. */; + /* Do no conversions for magic varargs. */ + a = mark_type_use (a); else a = convert_arg_to_ellipsis (a); argarray[j++] = a; @@ -5718,6 +5912,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) tree targ; tree arg = argarray[num_artificial_parms_for (fn)]; tree fa; + bool trivial = trivial_fn_p (fn); /* Pull out the real argument, disregarding const-correctness. */ targ = arg; @@ -5742,12 +5937,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) if (TREE_CODE (arg) == TARGET_EXPR && TARGET_EXPR_LIST_INIT_P (arg)) { - /* Copy-list-initialization doesn't require the copy constructor + /* Copy-list-initialization doesn't require the constructor to be defined. */ } /* [class.copy]: the copy constructor is implicitly defined even if the implementation elided its use. */ - else if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn))) + else if (!trivial) { mark_used (fn); already_used = true; @@ -5765,35 +5960,20 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) { if (TREE_CODE (arg) == TARGET_EXPR) return arg; - else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))) - return build_target_expr_with_type (arg, DECL_CONTEXT (fn)); + else if (trivial) + return force_target_expr (DECL_CONTEXT (fn), arg); } - else if (TREE_CODE (arg) == TARGET_EXPR - || (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)) - && !move_fn_p (fn))) + else if (TREE_CODE (arg) == TARGET_EXPR || trivial) { tree to = stabilize_reference (cp_build_indirect_ref (fa, RO_NULL, complain)); - tree type = TREE_TYPE (to); - if (TREE_CODE (arg) != TARGET_EXPR - && TREE_CODE (arg) != AGGR_INIT_EXPR - && is_really_empty_class (type)) - { - /* Avoid copying empty classes. */ - val = build2 (COMPOUND_EXPR, void_type_node, to, arg); - TREE_NO_WARNING (val) = 1; - val = build2 (COMPOUND_EXPR, type, val, to); - TREE_NO_WARNING (val) = 1; - } - else - val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg); + val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg); return val; } } else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR - && copy_fn_p (fn) - && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn))) + && trivial_fn_p (fn)) { tree to = stabilize_reference (cp_build_indirect_ref (argarray[0], RO_NULL, complain)); @@ -5939,14 +6119,11 @@ build_java_interface_fn_ref (tree fn, tree instance) if (!java_iface_lookup_fn) { - tree endlink = build_void_list_node (); - tree t = tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, java_int_type_node, - endlink))); + tree ftype = build_function_type_list (ptr_type_node, + ptr_type_node, ptr_type_node, + java_int_type_node, NULL_TREE); java_iface_lookup_fn - = add_builtin_function ("_Jv_LookupInterfaceMethodIdx", - build_function_type (ptr_type_node, t), + = add_builtin_function ("_Jv_LookupInterfaceMethodIdx", ftype, 0, NOT_BUILT_IN, NULL, NULL_TREE); } @@ -5971,7 +6148,7 @@ build_java_interface_fn_ref (tree fn, tree instance) /* Determine the itable index of FN. */ i = 1; - for (method = TYPE_METHODS (iface); method; method = TREE_CHAIN (method)) + for (method = TYPE_METHODS (iface); method; method = DECL_CHAIN (method)) { if (!DECL_VIRTUAL_P (method)) continue; @@ -6044,7 +6221,7 @@ build_special_member_call (tree instance, tree name, VEC(tree,gc) **args, if (TYPE_P (binfo)) { /* Resolve the name. */ - if (!complete_type_or_else (binfo, NULL_TREE)) + if (!complete_type_or_maybe_complain (binfo, NULL_TREE, complain)) return error_mark_node; binfo = TYPE_BINFO (binfo); @@ -6103,7 +6280,7 @@ build_special_member_call (tree instance, tree name, VEC(tree,gc) **args, /* If the current function is a complete object constructor or destructor, then we fetch the VTT directly. Otherwise, we look it up using the VTT we were given. */ - vtt = TREE_CHAIN (CLASSTYPE_VTABLES (current_class_type)); + vtt = DECL_CHAIN (CLASSTYPE_VTABLES (current_class_type)); vtt = decay_conversion (vtt); vtt = build3 (COND_EXPR, TREE_TYPE (vtt), build2 (EQ_EXPR, boolean_type_node, @@ -6200,7 +6377,6 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args, VEC(tree,gc) *user_args; tree call; tree fn; - tree class_type; int template_only = 0; bool any_viable_p; tree orig_instance; @@ -6215,7 +6391,7 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args, *fn_p = NULL_TREE; if (error_operand_p (instance) - || error_operand_p (fns)) + || !fns || error_operand_p (fns)) return error_mark_node; if (!BASELINK_P (fns)) @@ -6318,68 +6494,43 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args, if (DECL_DESTRUCTOR_P (fn)) name = complete_dtor_identifier; - /* If CONSTRUCTOR_IS_DIRECT_INIT is set, this was a T{ } form - initializer, not T({ }). If the type doesn't have a list ctor, - break apart the list into separate ctor args. */ - if (DECL_CONSTRUCTOR_P (fn) && args != NULL && !VEC_empty (tree, *args) - && BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *args, 0)) - && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *args, 0)) - && !TYPE_HAS_LIST_CTOR (basetype)) - { - gcc_assert (VEC_length (tree, *args) == 1); - *args = ctor_to_vec (VEC_index (tree, *args, 0)); - } - - class_type = (conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE); first_mem_arg = instance_ptr; /* Get the high-water mark for the CONVERSION_OBSTACK. */ p = conversion_obstack_alloc (0); - for (fn = fns; fn; fn = OVL_NEXT (fn)) + /* If CONSTRUCTOR_IS_DIRECT_INIT is set, this was a T{ } form + initializer, not T({ }). */ + if (DECL_CONSTRUCTOR_P (fn) && args != NULL && !VEC_empty (tree, *args) + && BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *args, 0)) + && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *args, 0))) { - tree t = OVL_CURRENT (fn); - tree this_first_arg; + gcc_assert (VEC_length (tree, *args) == 1 + && !(flags & LOOKUP_ONLYCONVERTING)); - /* We can end up here for copy-init of same or base class. */ - if ((flags & LOOKUP_ONLYCONVERTING) - && DECL_NONCONVERTING_P (t)) - continue; - - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t)) - this_first_arg = first_mem_arg; - else - this_first_arg = NULL_TREE; - - if (TREE_CODE (t) == TEMPLATE_DECL) - /* A member template. */ - add_template_candidate (&candidates, t, - class_type, - explicit_targs, - this_first_arg, - args == NULL ? NULL : *args, - optype, - access_binfo, - conversion_path, - flags, - DEDUCE_CALL); - else if (! template_only) - add_function_candidate (&candidates, t, - class_type, - this_first_arg, - args == NULL ? NULL : *args, - access_binfo, - conversion_path, - flags); + add_list_candidates (fns, first_mem_arg, VEC_index (tree, *args, 0), + basetype, explicit_targs, template_only, + conversion_path, access_binfo, flags, &candidates); } - + else + { + add_candidates (fns, first_mem_arg, user_args, optype, + explicit_targs, template_only, conversion_path, + access_binfo, flags, &candidates); + } + any_viable_p = false; candidates = splice_viable (candidates, pedantic, &any_viable_p); + if (!any_viable_p) { if (complain & tf_error) { if (!COMPLETE_TYPE_P (basetype)) cxx_incomplete_type_error (instance_ptr, basetype); + else if (optype) + error ("no matching function for call to %<%T::operator %T(%A)%#V%>", + basetype, optype, build_tree_list_vec (user_args), + TREE_TYPE (TREE_TYPE (instance_ptr))); else { char *pretty_name; @@ -6436,8 +6587,8 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args, /* This is not an error, it is runtime undefined behavior. */ warning (0, (DECL_CONSTRUCTOR_P (current_function_decl) ? - "abstract virtual %q#D called from constructor" - : "abstract virtual %q#D called from destructor"), + "pure virtual %q#D called from constructor" + : "pure virtual %q#D called from destructor"), fn); if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE @@ -6538,6 +6689,8 @@ is_subseq (conversion *ics1, conversion *ics2) if (ics2->kind == ck_user || ics2->kind == ck_ambig + || ics2->kind == ck_aggr + || ics2->kind == ck_list || ics2->kind == ck_identity) /* At this point, ICS1 cannot be a proper subsequence of ICS2. We can get a USER_CONV when we are comparing the @@ -6691,14 +6844,16 @@ compare_ics (conversion *ics1, conversion *ics2) if (rank1 == cr_bad) { - /* XXX Isn't this an extension? */ - /* Both ICS are bad. We try to make a decision based on what - would have happened if they'd been good. */ - if (ics1->user_conv_p > ics2->user_conv_p - || ics1->rank > ics2->rank) + /* Both ICS are bad. We try to make a decision based on what would + have happened if they'd been good. This is not an extension, + we'll still give an error when we build up the call; this just + helps us give a more helpful error message. */ + rank1 = BAD_CONVERSION_RANK (ics1); + rank2 = BAD_CONVERSION_RANK (ics2); + + if (rank1 > rank2) return -1; - else if (ics1->user_conv_p < ics2->user_conv_p - || ics1->rank < ics2->rank) + else if (rank1 < rank2) return 1; /* We couldn't make up our minds; try to figure it out below. */ @@ -6722,13 +6877,25 @@ compare_ics (conversion *ics1, conversion *ics2) for (t1 = ics1; t1->kind != ck_user; t1 = t1->u.next) if (t1->kind == ck_ambig || t1->kind == ck_aggr) - return 0; + break; for (t2 = ics2; t2->kind != ck_user; t2 = t2->u.next) if (t2->kind == ck_ambig || t2->kind == ck_aggr) - return 0; + break; - if (t1->cand->fn != t2->cand->fn) + if (t1->kind != t2->kind) return 0; + else if (t1->kind == ck_user) + { + if (t1->cand->fn != t2->cand->fn) + return 0; + } + else + { + /* For ambiguous or aggregate conversions, use the target type as + a proxy for the conversion function. */ + if (!same_type_ignoring_top_level_qualifiers_p (t1->type, t2->type)) + return 0; + } /* We can just fall through here, after setting up FROM_TYPE1 and FROM_TYPE2. */ @@ -6790,9 +6957,8 @@ compare_ics (conversion *ics1, conversion *ics2) Two conversion sequences with the same rank are indistinguishable unless one of the following rules applies: - --A conversion that is not a conversion of a pointer, or pointer - to member, to bool is better than another conversion that is such - a conversion. + --A conversion that does not a convert a pointer, pointer to member, + or std::nullptr_t to bool is better than one that does. The ICS_STD_RANK automatically handles the pointer-to-bool rule, so that we do not have to check it explicitly. */ @@ -7351,6 +7517,9 @@ tweak: winner = -1, w = cand2, l = cand1; if (winner) { + /* Don't choose a deleted function over ambiguity. */ + if (DECL_P (w->fn) && DECL_DELETED_FN (w->fn)) + return 0; if (warn) { pedwarn (input_location, 0, @@ -7582,7 +7751,7 @@ perform_direct_initialization_if_possible (tree type, expr = convert_like_real (conv, expr, NULL_TREE, 0, 0, /*issue_conversion_warnings=*/false, c_cast_p, - tf_warning_or_error); + complain); /* Free all the conversions we allocated. */ obstack_free (&conversion_obstack, p); @@ -7722,7 +7891,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup, { if (complain & tf_error) { - if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST) + if (!CP_TYPE_CONST_P (TREE_TYPE (type)) && !TYPE_REF_IS_RVALUE (type) && !real_lvalue_p (expr)) error ("invalid initialization of non-const reference of " @@ -7808,7 +7977,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup, expr = convert_to_base (expr, build_pointer_type (base_conv_type), /*check_access=*/true, - /*nonnull=*/true); + /*nonnull=*/true, complain); expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr); } else @@ -7837,6 +8006,10 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup, bool is_std_init_list (tree type) { + /* Look through typedefs. */ + if (!TYPE_P (type)) + return false; + type = TYPE_MAIN_VARIANT (type); return (CLASS_TYPE_P (type) && CP_TYPE_CONTEXT (type) == std_node && strcmp (TYPE_NAME_STRING (type), "initializer_list") == 0); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 1bab07dd42c..c594d6add33 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, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -30,13 +30,13 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "cp-tree.h" #include "flags.h" -#include "rtl.h" #include "output.h" #include "toplev.h" #include "target.h" #include "convert.h" #include "cgraph.h" #include "tree-dump.h" +#include "splay-tree.h" /* The number of nested classes being processed. If we are not in the scope of any class, this is zero. */ @@ -77,9 +77,7 @@ typedef struct vtbl_init_data_s tree rtti_binfo; /* The negative-index vtable initializers built up so far. These are in order from least negative index to most negative index. */ - tree inits; - /* The last (i.e., most negative) entry in INITS. */ - tree* last_init; + VEC(constructor_elt,gc) *inits; /* The binfo for the virtual base for which we're building vcall offset initializers. */ tree vbase; @@ -136,7 +134,8 @@ static void add_implicitly_declared_members (tree, int, int); static tree fixed_type_or_null (tree, int *, int *); static tree build_simple_base_path (tree expr, tree binfo); static tree build_vtbl_ref_1 (tree, tree); -static tree build_vtbl_initializer (tree, tree, tree, tree, int *); +static void build_vtbl_initializer (tree, tree, tree, tree, int *, + VEC(constructor_elt,gc) **); static int count_fields (tree); static int add_fields_to_record_type (tree, struct sorted_fields_type*, int); static bool check_bitfield_decl (tree); @@ -173,14 +172,15 @@ static void dump_vtable (tree, tree, tree); static void dump_vtt (tree, tree); static void dump_thunk (FILE *, int, tree); static tree build_vtable (tree, tree, tree); -static void initialize_vtable (tree, tree); +static void initialize_vtable (tree, VEC(constructor_elt,gc) *); static void layout_nonempty_base_or_field (record_layout_info, tree, tree, splay_tree); static tree end_of_class (tree, int); static bool layout_empty_base (record_layout_info, tree, tree, splay_tree); -static void accumulate_vtbl_inits (tree, tree, tree, tree, tree); -static tree dfs_accumulate_vtbl_inits (tree, tree, tree, tree, - tree); +static void accumulate_vtbl_inits (tree, tree, tree, tree, tree, + VEC(constructor_elt,gc) **); +static void dfs_accumulate_vtbl_inits (tree, tree, tree, tree, tree, + VEC(constructor_elt,gc) **); static void build_rtti_vtbl_entries (tree, vtbl_init_data *); static void build_vcall_and_vbase_vtbl_entries (tree, vtbl_init_data *); static void clone_constructors_and_destructors (tree); @@ -189,7 +189,7 @@ static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned); static void build_ctor_vtbl_group (tree, tree); static void build_vtt (tree); static tree binfo_ctor_vtable (tree); -static tree *build_vtt_inits (tree, tree, tree *, tree *); +static void build_vtt_inits (tree, tree, VEC(constructor_elt,gc) **, tree *); static tree dfs_build_secondary_vptr_vtt_inits (tree, void *); static tree dfs_fixup_binfo_vtbls (tree, void *); static int record_subobject_offset (tree, tree, splay_tree); @@ -283,6 +283,8 @@ build_base_path (enum tree_code code, if (!want_pointer) /* This must happen before the call to save_expr. */ expr = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error); + else + expr = mark_rvalue_use (expr); offset = BINFO_OFFSET (binfo); fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); @@ -467,7 +469,7 @@ build_simple_base_path (tree expr, tree binfo) expr = build_simple_base_path (expr, d_binfo); for (field = TYPE_FIELDS (BINFO_TYPE (d_binfo)); - field; field = TREE_CHAIN (field)) + field; field = DECL_CHAIN (field)) /* Is this the base field created by build_base_field? */ if (TREE_CODE (field) == FIELD_DECL && DECL_FIELD_IS_BASE (field) @@ -506,10 +508,12 @@ build_simple_base_path (tree expr, tree binfo) assumed to be non-NULL. */ tree -convert_to_base (tree object, tree type, bool check_access, bool nonnull) +convert_to_base (tree object, tree type, bool check_access, bool nonnull, + tsubst_flags_t complain) { tree binfo; tree object_type; + base_access access; if (TYPE_PTR_P (TREE_TYPE (object))) { @@ -519,8 +523,11 @@ convert_to_base (tree object, tree type, bool check_access, bool nonnull) else object_type = TREE_TYPE (object); + access = check_access ? ba_check : ba_unique; + if (!(complain & tf_error)) + access |= ba_quiet; binfo = lookup_base (object_type, type, - check_access ? ba_check : ba_unique, + access, NULL); if (!binfo || binfo == error_mark_node) return error_mark_node; @@ -575,7 +582,7 @@ build_vfield_ref (tree datum, tree type) /* First, convert to the requested type. */ if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type)) datum = convert_to_base (datum, type, /*check_access=*/false, - /*nonnull=*/true); + /*nonnull=*/true, tf_warning_or_error); /* Second, the requested type may not be the owner of its own vptr. If not, convert to the base class that owns it. We cannot use @@ -1043,8 +1050,8 @@ add_method (tree type, tree method, tree using_decl) && ! 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))))) + && (cp_type_quals (TREE_TYPE (TREE_VALUE (parms1))) + != cp_type_quals (TREE_TYPE (TREE_VALUE (parms2))))) continue; /* For templates, the return type and template parameters @@ -1253,7 +1260,7 @@ check_bases (tree t, seen_non_virtual_nearly_empty_base_p = 0; if (!CLASSTYPE_NON_STD_LAYOUT (t)) - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL) break; @@ -1275,10 +1282,11 @@ check_bases (tree t, assignment operators that take const references, then the derived class cannot have such a member automatically generated. */ - if (! TYPE_HAS_CONST_INIT_REF (basetype)) + if (TYPE_HAS_COPY_CTOR (basetype) + && ! TYPE_HAS_CONST_COPY_CTOR (basetype)) *cant_have_const_ctor_p = 1; - if (TYPE_HAS_ASSIGN_REF (basetype) - && !TYPE_HAS_CONST_ASSIGN_REF (basetype)) + if (TYPE_HAS_COPY_ASSIGN (basetype) + && !TYPE_HAS_CONST_COPY_ASSIGN (basetype)) *no_const_asn_ref_p = 1; if (BINFO_VIRTUAL_P (base_binfo)) @@ -1304,13 +1312,19 @@ check_bases (tree t, TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype); TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype); - TYPE_HAS_COMPLEX_ASSIGN_REF (t) - |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype); - TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype); + TYPE_HAS_COMPLEX_COPY_ASSIGN (t) + |= (TYPE_HAS_COMPLEX_COPY_ASSIGN (basetype) + || !TYPE_HAS_COPY_ASSIGN (basetype)); + TYPE_HAS_COMPLEX_COPY_CTOR (t) |= (TYPE_HAS_COMPLEX_COPY_CTOR (basetype) + || !TYPE_HAS_COPY_CTOR (basetype)); + TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) + |= TYPE_HAS_COMPLEX_MOVE_ASSIGN (basetype); + TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_HAS_COMPLEX_MOVE_CTOR (basetype); TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype); CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) |= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype); - TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_HAS_COMPLEX_DFLT (basetype); + TYPE_HAS_COMPLEX_DFLT (t) |= (!TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype) + || TYPE_HAS_COMPLEX_DFLT (basetype)); /* A standard-layout class is a class that: ... @@ -1331,7 +1345,7 @@ check_bases (tree t, members, or has no base classes with non-static data members */ for (basefield = TYPE_FIELDS (basetype); basefield; - basefield = TREE_CHAIN (basefield)) + basefield = DECL_CHAIN (basefield)) if (TREE_CODE (basefield) == FIELD_DECL) { if (field) @@ -1534,7 +1548,8 @@ finish_struct_bits (tree t) mode to be BLKmode, and force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to be passed by invisible reference and prevent it from being returned in a register. */ - if (! TYPE_HAS_TRIVIAL_INIT_REF (t) || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)) + if (type_has_nontrivial_copy_init (t) + || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)) { tree variants; DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode; @@ -1588,7 +1603,7 @@ maybe_warn_about_overly_private_class (tree t) functions are private. (Since there are no friends or non-private statics, we can't ever call any of the private member functions.) */ - for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) + for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) /* We're not interested in compiler-generated methods; they don't provide any way to call private members. */ if (!DECL_ARTIFICIAL (fn)) @@ -1661,10 +1676,10 @@ maybe_warn_about_overly_private_class (tree t) template <class T> class C { private: C(); }; - To avoid this asymmetry, we check TYPE_HAS_INIT_REF. All + To avoid this asymmetry, we check TYPE_HAS_COPY_CTOR. All complete non-template or fully instantiated classes have this flag set. */ - if (!TYPE_HAS_INIT_REF (t)) + if (!TYPE_HAS_COPY_CTOR (t)) nonprivate_ctor = 1; else for (fn = CLASSTYPE_CONSTRUCTORS (t); fn; fn = OVL_NEXT (fn)) @@ -1793,7 +1808,7 @@ finish_struct_methods (tree t) /* Clear DECL_IN_AGGR_P for all functions. */ for (fn_fields = TYPE_METHODS (t); fn_fields; - fn_fields = TREE_CHAIN (fn_fields)) + fn_fields = DECL_CHAIN (fn_fields)) DECL_IN_AGGR_P (fn_fields) = 0; /* Issue warnings about private constructors and such. If there are @@ -1863,8 +1878,8 @@ same_signature_p (const_tree fndecl, const_tree base_fndecl) tree types, base_types; types = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl)); - if ((TYPE_QUALS (TREE_TYPE (TREE_VALUE (base_types))) - == TYPE_QUALS (TREE_TYPE (TREE_VALUE (types)))) + if ((cp_type_quals (TREE_TYPE (TREE_VALUE (base_types))) + == cp_type_quals (TREE_TYPE (TREE_VALUE (types)))) && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types))) return 1; } @@ -2033,7 +2048,7 @@ get_vcall_index (tree fn, tree type) tree_pair_p p; unsigned ix; - for (ix = 0; VEC_iterate (tree_pair_s, indices, ix, p); ix++) + FOR_EACH_VEC_ELT (tree_pair_s, indices, ix, p) if ((DECL_DESTRUCTOR_P (fn) && DECL_DESTRUCTOR_P (p->purpose)) || same_signature_p (fn, p->purpose)) return p->value; @@ -2043,8 +2058,9 @@ get_vcall_index (tree fn, tree type) } /* Update an entry in the vtable for BINFO, which is in the hierarchy - dominated by T. FN has been overridden in BINFO; VIRTUALS points to the - corresponding position in the BINFO_VIRTUALS list. */ + dominated by T. FN is the old function; VIRTUALS points to the + corresponding position in the new BINFO_VIRTUALS list. IX is the index + of that entry in the list. */ static void update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, @@ -2189,6 +2205,40 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, gcc_assert (DECL_INVALID_OVERRIDER_P (overrider_target) || !DECL_THUNK_P (fn)); + /* If we need a covariant thunk, then we may need to adjust first_defn. + The ABI specifies that the thunks emitted with a function are + determined by which bases the function overrides, so we need to be + sure that we're using a thunk for some overridden base; even if we + know that the necessary this adjustment is zero, there may not be an + appropriate zero-this-adjusment thunk for us to use since thunks for + overriding virtual bases always use the vcall offset. + + Furthermore, just choosing any base that overrides this function isn't + quite right, as this slot won't be used for calls through a type that + puts a covariant thunk here. Calling the function through such a type + will use a different slot, and that slot is the one that determines + the thunk emitted for that base. + + So, keep looking until we find the base that we're really overriding + in this slot: the nearest primary base that doesn't use a covariant + thunk in this slot. */ + if (overrider_target != overrider_fn) + { + if (BINFO_TYPE (b) == DECL_CONTEXT (overrider_target)) + /* We already know that the overrider needs a covariant thunk. */ + b = get_primary_binfo (b); + for (; ; b = get_primary_binfo (b)) + { + tree main_binfo = TYPE_BINFO (BINFO_TYPE (b)); + tree bv = chain_index (ix, BINFO_VIRTUALS (main_binfo)); + if (BINFO_LOST_PRIMARY_P (b)) + lost = true; + if (!DECL_THUNK_P (TREE_VALUE (bv))) + break; + } + first_defn = b; + } + /* Assume that we will produce a thunk that convert all the way to the final overrider, and not to an intermediate virtual base. */ virtual_base = NULL_TREE; @@ -2213,36 +2263,6 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, } } - if (overrider_fn != overrider_target && !virtual_base) - { - /* The ABI specifies that a covariant thunk includes a mangling - for a this pointer adjustment. This-adjusting thunks that - override a function from a virtual base have a vcall - adjustment. When the virtual base in question is a primary - virtual base, we know the adjustments are zero, (and in the - non-covariant case, we would not use the thunk). - Unfortunately we didn't notice this could happen, when - designing the ABI and so never mandated that such a covariant - thunk should be emitted. Because we must use the ABI mandated - name, we must continue searching from the binfo where we - found the most recent definition of the function, towards the - primary binfo which first introduced the function into the - vtable. If that enters a virtual base, we must use a vcall - this-adjusting thunk. Bleah! */ - tree probe = first_defn; - - while ((probe = get_primary_binfo (probe)) - && (unsigned) list_length (BINFO_VIRTUALS (probe)) > ix) - if (BINFO_VIRTUAL_P (probe)) - virtual_base = probe; - - if (virtual_base) - /* Even if we find a virtual base, the correct delta is - between the overrider and the binfo we're building a vtable - for. */ - goto virtual_covariant; - } - /* Compute the constant adjustment to the `this' pointer. The `this' pointer, when this function is called, will point at BINFO (or one of its primary bases, which are at the same offset). */ @@ -2262,7 +2282,6 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, /* The `this' pointer needs to be adjusted from pointing to BINFO to pointing at the base where the final overrider appears. */ - virtual_covariant: delta = size_diffop_loc (input_location, convert (ssizetype, BINFO_OFFSET (TREE_VALUE (overrider))), @@ -2275,6 +2294,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, = get_vcall_index (overrider_target, BINFO_TYPE (virtual_base)); else BV_VCALL_INDEX (*virtuals) = NULL_TREE; + + if (lost) + BV_LOST_PRIMARY (*virtuals) = true; } /* Called from modify_all_vtables via dfs_walk. */ @@ -2517,7 +2539,7 @@ finish_struct_anon (tree t) { tree field; - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) { if (TREE_STATIC (field)) continue; @@ -2529,7 +2551,7 @@ finish_struct_anon (tree t) { bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE; tree elt = TYPE_FIELDS (TREE_TYPE (field)); - for (; elt; elt = TREE_CHAIN (elt)) + for (; elt; elt = DECL_CHAIN (elt)) { /* We're generally only interested in entities the user declared, but we also find nested classes by noticing @@ -2613,47 +2635,13 @@ add_implicitly_declared_members (tree t, { /* In general, we create destructors lazily. */ CLASSTYPE_LAZY_DESTRUCTOR (t) = 1; - /* However, if the implicit destructor is non-trivial - destructor, we sometimes have to create it at this point. */ - if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)) - { - bool lazy_p = true; - - if (TYPE_FOR_JAVA (t)) - /* If this a Java class, any non-trivial destructor is - invalid, even if compiler-generated. Therefore, if the - destructor is non-trivial we create it now. */ - lazy_p = false; - else - { - tree binfo; - tree base_binfo; - int ix; - - /* If the implicit destructor will be virtual, then we must - generate it now because (unfortunately) we do not - generate virtual tables lazily. */ - binfo = TYPE_BINFO (t); - for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++) - { - tree base_type; - tree dtor; - - base_type = BINFO_TYPE (base_binfo); - dtor = CLASSTYPE_DESTRUCTORS (base_type); - if (dtor && DECL_VIRTUAL_P (dtor)) - { - lazy_p = false; - break; - } - } - } - /* If we can't get away with being lazy, generate the destructor - now. */ - if (!lazy_p) - lazily_declare_fn (sfk_destructor, t); - } + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) + && TYPE_FOR_JAVA (t)) + /* But if this is a Java class, any non-trivial destructor is + invalid, even if compiler-generated. Therefore, if the + destructor is non-trivial we create it now. */ + lazily_declare_fn (sfk_destructor, t); } /* [class.ctor] @@ -2670,27 +2658,59 @@ add_implicitly_declared_members (tree t, 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)) + if (! TYPE_HAS_COPY_CTOR (t) && ! TYPE_FOR_JAVA (t) + && !type_has_move_constructor (t)) { - TYPE_HAS_INIT_REF (t) = 1; - TYPE_HAS_CONST_INIT_REF (t) = !cant_have_const_cctor; + TYPE_HAS_COPY_CTOR (t) = 1; + TYPE_HAS_CONST_COPY_CTOR (t) = !cant_have_const_cctor; CLASSTYPE_LAZY_COPY_CTOR (t) = 1; + if (cxx_dialect >= cxx0x) + CLASSTYPE_LAZY_MOVE_CTOR (t) = 1; } - /* Currently only lambdas get a lazy move ctor, but N2987 adds them for - other classes. */ - if (LAMBDA_TYPE_P (t)) - CLASSTYPE_LAZY_MOVE_CTOR (t) = 1; - /* If there is no assignment operator, one will be created if and when it is needed. For now, just record whether or not the type of the parameter to the assignment operator will be a const or non-const reference. */ - if (!TYPE_HAS_ASSIGN_REF (t) && !TYPE_FOR_JAVA (t)) + if (!TYPE_HAS_COPY_ASSIGN (t) && !TYPE_FOR_JAVA (t) + && !type_has_move_assign (t)) + { + TYPE_HAS_COPY_ASSIGN (t) = 1; + TYPE_HAS_CONST_COPY_ASSIGN (t) = !cant_have_const_assignment; + CLASSTYPE_LAZY_COPY_ASSIGN (t) = 1; + if (cxx_dialect >= cxx0x) + CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 1; + } + + /* We can't be lazy about declaring functions that might override + a virtual function from a base class. */ + if (TYPE_POLYMORPHIC_P (t) + && (CLASSTYPE_LAZY_COPY_ASSIGN (t) + || CLASSTYPE_LAZY_MOVE_ASSIGN (t) + || CLASSTYPE_LAZY_DESTRUCTOR (t))) { - TYPE_HAS_ASSIGN_REF (t) = 1; - TYPE_HAS_CONST_ASSIGN_REF (t) = !cant_have_const_assignment; - CLASSTYPE_LAZY_ASSIGNMENT_OP (t) = 1; + tree binfo = TYPE_BINFO (t); + tree base_binfo; + int ix; + tree opname = ansi_assopname (NOP_EXPR); + for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ++ix) + { + tree bv; + for (bv = BINFO_VIRTUALS (base_binfo); bv; bv = TREE_CHAIN (bv)) + { + tree fn = BV_FN (bv); + if (DECL_NAME (fn) == opname) + { + if (CLASSTYPE_LAZY_COPY_ASSIGN (t)) + lazily_declare_fn (sfk_copy_assignment, t); + if (CLASSTYPE_LAZY_MOVE_ASSIGN (t)) + lazily_declare_fn (sfk_move_assignment, t); + } + else if (DECL_DESTRUCTOR_P (fn) + && CLASSTYPE_LAZY_DESTRUCTOR (t)) + lazily_declare_fn (sfk_destructor, t); + } + } } } @@ -2702,7 +2722,7 @@ count_fields (tree fields) { tree x; int n_fields = 0; - for (x = fields; x; x = TREE_CHAIN (x)) + for (x = fields; x; x = DECL_CHAIN (x)) { if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x))) n_fields += count_fields (TYPE_FIELDS (TREE_TYPE (x))); @@ -2719,7 +2739,7 @@ static int add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, int idx) { tree x; - for (x = fields; x; x = TREE_CHAIN (x)) + for (x = fields; x; x = DECL_CHAIN (x)) { if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x))) idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx); @@ -2781,14 +2801,8 @@ check_bitfield_decl (tree field) && TREE_CODE (type) != BOOLEAN_TYPE) warning (0, "width of %q+D exceeds its type", field); else if (TREE_CODE (type) == ENUMERAL_TYPE - && (0 > compare_tree_int (w, - tree_int_cst_min_precision - (TYPE_MIN_VALUE (type), - TYPE_UNSIGNED (type))) - || 0 > compare_tree_int (w, - tree_int_cst_min_precision - (TYPE_MAX_VALUE (type), - TYPE_UNSIGNED (type))))) + && (0 > (compare_tree_int + (w, TYPE_PRECISION (ENUM_UNDERLYING_TYPE (type)))))) warning (0, "%q+D is too small to hold all values of %q#T", field, type); } @@ -2820,17 +2834,17 @@ check_field_decl (tree field, { tree type = strip_array_types (TREE_TYPE (field)); - /* An anonymous union cannot contain any fields which would change + /* In C++98 an anonymous union cannot contain any fields which would change the settings of CANT_HAVE_CONST_CTOR and friends. */ - if (ANON_UNION_TYPE_P (type)) + if (ANON_UNION_TYPE_P (type) && cxx_dialect < cxx0x) ; - /* And, we don't set TYPE_HAS_CONST_INIT_REF, etc., for anonymous + /* And, we don't set TYPE_HAS_CONST_COPY_CTOR, etc., for anonymous structs. So, we recurse through their fields here. */ else if (ANON_AGGR_TYPE_P (type)) { tree fields; - for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) + for (fields = TYPE_FIELDS (type); fields; fields = DECL_CHAIN (fields)) if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field)) check_field_decl (fields, t, cant_have_const_ctor, no_const_asn_ref, any_default_members); @@ -2843,31 +2857,47 @@ check_field_decl (tree field, make it through without complaint. */ abstract_virtuals_error (field, type); - if (TREE_CODE (t) == UNION_TYPE) + if (TREE_CODE (t) == UNION_TYPE && cxx_dialect < cxx0x) { + static bool warned; + int oldcount = errorcount; if (TYPE_NEEDS_CONSTRUCTING (type)) error ("member %q+#D with constructor not allowed in union", field); if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) error ("member %q+#D with destructor not allowed in union", field); - if (TYPE_HAS_COMPLEX_ASSIGN_REF (type)) + if (TYPE_HAS_COMPLEX_COPY_ASSIGN (type)) error ("member %q+#D with copy assignment operator not allowed in union", field); + if (!warned && errorcount > oldcount) + { + inform (DECL_SOURCE_LOCATION (field), "unrestricted unions " + "only available with -std=c++0x or -std=gnu++0x"); + warned = true; + } } else { TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type); TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type); - TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (type); - TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (type); - TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_HAS_COMPLEX_DFLT (type); + TYPE_HAS_COMPLEX_COPY_ASSIGN (t) + |= (TYPE_HAS_COMPLEX_COPY_ASSIGN (type) + || !TYPE_HAS_COPY_ASSIGN (type)); + TYPE_HAS_COMPLEX_COPY_CTOR (t) |= (TYPE_HAS_COMPLEX_COPY_CTOR (type) + || !TYPE_HAS_COPY_CTOR (type)); + TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_HAS_COMPLEX_MOVE_ASSIGN (type); + TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_HAS_COMPLEX_MOVE_CTOR (type); + TYPE_HAS_COMPLEX_DFLT (t) |= (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type) + || TYPE_HAS_COMPLEX_DFLT (type)); } - if (!TYPE_HAS_CONST_INIT_REF (type)) + if (TYPE_HAS_COPY_CTOR (type) + && !TYPE_HAS_CONST_COPY_CTOR (type)) *cant_have_const_ctor = 1; - if (!TYPE_HAS_CONST_ASSIGN_REF (type)) + if (TYPE_HAS_COPY_ASSIGN (type) + && !TYPE_HAS_CONST_COPY_ASSIGN (type)) *no_const_asn_ref = 1; } if (DECL_INITIAL (field) != NULL_TREE) @@ -2931,12 +2961,12 @@ check_field_decls (tree t, tree *access_decls, tree type = TREE_TYPE (x); int this_field_access; - next = &TREE_CHAIN (x); + next = &DECL_CHAIN (x); if (TREE_CODE (x) == USING_DECL) { /* Prune the access declaration from the list of fields. */ - *field = TREE_CHAIN (x); + *field = DECL_CHAIN (x); /* Save the access declarations for our caller. */ *access_decls = tree_cons (NULL_TREE, x, *access_decls); @@ -3026,7 +3056,8 @@ check_field_decls (tree t, tree *access_decls, aggregate, initialization by a brace-enclosed list) is the only way to initialize nonstatic const and reference members. */ - TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; + TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1; + TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1; } type = strip_array_types (type); @@ -3093,6 +3124,14 @@ check_field_decls (tree t, tree *access_decls, if (! zero_init_p (type)) CLASSTYPE_NON_ZERO_INIT_P (t) = 1; + /* We set DECL_C_BIT_FIELD in grokbitfield. + If the type and width are valid, we'll also set DECL_BIT_FIELD. */ + if (! DECL_C_BIT_FIELD (x) || ! check_bitfield_decl (x)) + check_field_decl (x, t, + cant_have_const_ctor_p, + no_const_asn_ref_p, + &any_default_members); + /* If any field is const, the structure type is pseudo-const. */ if (CP_TYPE_CONST_P (type)) { @@ -3104,7 +3143,8 @@ check_field_decls (tree t, tree *access_decls, aggregate, initialization by a brace-enclosed list) is the only way to initialize nonstatic const and reference members. */ - TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; + TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1; + TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1; } /* A field that is pseudo-const makes the structure likewise. */ else if (CLASS_TYPE_P (type)) @@ -3121,14 +3161,6 @@ check_field_decls (tree t, tree *access_decls, 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. */ - if (! DECL_C_BIT_FIELD (x) || ! check_bitfield_decl (x)) - check_field_decl (x, t, - cant_have_const_ctor_p, - no_const_asn_ref_p, - &any_default_members); } /* Effective C++ rule 11: if a class has dynamic memory held by pointers, @@ -3149,18 +3181,18 @@ check_field_decls (tree t, tree *access_decls, && has_pointers && TYPE_HAS_USER_CONSTRUCTOR (t) && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) - && !(TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t))) + && !(TYPE_HAS_COPY_CTOR (t) && TYPE_HAS_COPY_ASSIGN (t))) { warning (OPT_Weffc__, "%q#T has pointer data members", t); - if (! TYPE_HAS_INIT_REF (t)) + if (! TYPE_HAS_COPY_CTOR (t)) { warning (OPT_Weffc__, " but does not override %<%T(const %T&)%>", t, t); - if (!TYPE_HAS_ASSIGN_REF (t)) + if (!TYPE_HAS_COPY_ASSIGN (t)) warning (OPT_Weffc__, " or %<operator=(const %T&)%>", t); } - else if (! TYPE_HAS_ASSIGN_REF (t)) + else if (! TYPE_HAS_COPY_ASSIGN (t)) warning (OPT_Weffc__, " but does not override %<operator=(const %T&)%>", t); } @@ -3367,7 +3399,7 @@ walk_subobject_offsets (tree type, } /* Iterate through the fields of TYPE. */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL && !DECL_ARTIFICIAL (field)) { tree field_offset; @@ -3716,9 +3748,9 @@ build_base_field (record_layout_info rli, tree binfo, objects of the same type at the same address. */ layout_nonempty_base_or_field (rli, decl, binfo, offsets); /* Add the new FIELD_DECL to the list of fields for T. */ - TREE_CHAIN (decl) = *next_field; + DECL_CHAIN (decl) = *next_field; *next_field = decl; - next_field = &TREE_CHAIN (decl); + next_field = &DECL_CHAIN (decl); } } else @@ -3830,7 +3862,7 @@ check_methods (tree t) { tree x; - for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) + for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x)) { check_for_override (x, t); if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x)) @@ -3843,7 +3875,9 @@ check_methods (tree t) if (DECL_PURE_VIRTUAL_P (x)) VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x); } - /* All user-provided destructors are non-trivial. */ + /* All user-provided destructors are non-trivial. + Constructors and assignment ops are handled in + grok_special_member_properties. */ if (DECL_DESTRUCTOR_P (x) && user_provided_p (x)) TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1; } @@ -3867,8 +3901,8 @@ build_clone (tree fn, tree name) /* Remember where this function came from. */ DECL_ABSTRACT_ORIGIN (clone) = fn; /* Make it easy to find the CLONE given the FN. */ - TREE_CHAIN (clone) = TREE_CHAIN (fn); - TREE_CHAIN (fn) = clone; + DECL_CHAIN (clone) = DECL_CHAIN (fn); + DECL_CHAIN (fn) = clone; /* If this is a template, do the rest on the DECL_TEMPLATE_RESULT. */ if (TREE_CODE (clone) == TEMPLATE_DECL) @@ -3932,8 +3966,8 @@ build_clone (tree fn, tree name) /* Remove the in-charge parameter. */ if (DECL_HAS_IN_CHARGE_PARM_P (clone)) { - TREE_CHAIN (DECL_ARGUMENTS (clone)) - = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone))); + DECL_CHAIN (DECL_ARGUMENTS (clone)) + = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))); DECL_HAS_IN_CHARGE_PARM_P (clone) = 0; } /* And the VTT parm, in a complete [cd]tor. */ @@ -3943,20 +3977,20 @@ build_clone (tree fn, tree name) DECL_HAS_VTT_PARM_P (clone) = 1; else { - TREE_CHAIN (DECL_ARGUMENTS (clone)) - = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone))); + DECL_CHAIN (DECL_ARGUMENTS (clone)) + = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))); DECL_HAS_VTT_PARM_P (clone) = 0; } } - for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms)) + for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms)) { DECL_CONTEXT (parms) = clone; cxx_dup_lang_specific_decl (parms); } /* Create the RTL for this function. */ - SET_DECL_RTL (clone, NULL_RTX); + SET_DECL_RTL (clone, NULL); rest_of_decl_compilation (clone, /*top_level=*/1, at_eof); if (pch_file) @@ -4012,8 +4046,8 @@ clone_function_decl (tree fn, int update_method_vec_p) tree clone; /* Avoid inappropriate cloning. */ - if (TREE_CHAIN (fn) - && DECL_CLONED_FUNCTION_P (TREE_CHAIN (fn))) + if (DECL_CHAIN (fn) + && DECL_CLONED_FUNCTION_P (DECL_CHAIN (fn))) return; if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)) @@ -4070,8 +4104,8 @@ adjust_clone_args (tree decl) { tree clone; - for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone); - clone = TREE_CHAIN (clone)) + for (clone = DECL_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone); + clone = DECL_CHAIN (clone)) { tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone)); tree orig_decl_parms = TYPE_ARG_TYPES (TREE_TYPE (decl)); @@ -4177,6 +4211,34 @@ type_has_user_nondefault_constructor (tree t) return false; } +/* Returns the defaulted constructor if T has one. Otherwise, returns + NULL_TREE. */ + +tree +in_class_defaulted_default_constructor (tree t) +{ + tree fns, args; + + if (!TYPE_HAS_USER_CONSTRUCTOR (t)) + return NULL_TREE; + + for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns)) + { + tree fn = OVL_CURRENT (fns); + + if (DECL_DEFAULTED_IN_CLASS_P (fn)) + { + args = FUNCTION_FIRST_USER_PARMTYPE (fn); + while (args && TREE_PURPOSE (args)) + args = TREE_CHAIN (args); + if (!args || args == void_list_node) + return fn; + } + } + + return NULL_TREE; +} + /* Returns true iff FN is a user-provided function, i.e. user-declared and not defaulted at its first declaration; or explicit, private, protected, or non-const. */ @@ -4220,7 +4282,7 @@ type_has_user_provided_constructor (tree t) bool type_has_user_provided_default_constructor (tree t) { - tree fns, args; + tree fns; if (!TYPE_HAS_USER_CONSTRUCTOR (t)) return false; @@ -4229,19 +4291,73 @@ type_has_user_provided_default_constructor (tree t) { 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; - } + && user_provided_p (fn) + && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn))) + return true; } return false; } +/* Returns true iff class TYPE has a virtual destructor. */ + +bool +type_has_virtual_destructor (tree type) +{ + tree dtor; + + if (!CLASS_TYPE_P (type)) + return false; + + gcc_assert (COMPLETE_TYPE_P (type)); + dtor = CLASSTYPE_DESTRUCTORS (type); + return (dtor && DECL_VIRTUAL_P (dtor)); +} + +/* Returns true iff class T has a move constructor. */ + +bool +type_has_move_constructor (tree t) +{ + tree fns; + + if (CLASSTYPE_LAZY_MOVE_CTOR (t)) + { + gcc_assert (COMPLETE_TYPE_P (t)); + lazily_declare_fn (sfk_move_constructor, t); + } + + if (!CLASSTYPE_METHOD_VEC (t)) + return false; + + for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns)) + if (move_fn_p (OVL_CURRENT (fns))) + return true; + + return false; +} + +/* Returns true iff class T has a move assignment operator. */ + +bool +type_has_move_assign (tree t) +{ + tree fns; + + if (CLASSTYPE_LAZY_MOVE_ASSIGN (t)) + { + gcc_assert (COMPLETE_TYPE_P (t)); + lazily_declare_fn (sfk_move_assignment, t); + } + + for (fns = lookup_fnfields_slot (t, ansi_assopname (NOP_EXPR)); + fns; fns = OVL_NEXT (fns)) + if (move_fn_p (OVL_CURRENT (fns))) + return true; + + return false; +} + /* Remove all zero-width bit-fields from T. */ static void @@ -4260,9 +4376,9 @@ remove_zero_width_bit_fields (tree t) check_bitfield_decl eventually sets DECL_SIZE (*fieldsp) to that width. */ && integer_zerop (DECL_SIZE (*fieldsp))) - *fieldsp = TREE_CHAIN (*fieldsp); + *fieldsp = DECL_CHAIN (*fieldsp); else - fieldsp = &TREE_CHAIN (*fieldsp); + fieldsp = &DECL_CHAIN (*fieldsp); } } @@ -4357,7 +4473,7 @@ check_bases_and_members (tree 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_complex_asn_ref = TYPE_HAS_COMPLEX_COPY_ASSIGN (t); saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t); /* Check all the data member declarations. We cannot call @@ -4375,7 +4491,8 @@ 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_CONTAINS_VPTR_P (t); + TYPE_HAS_COMPLEX_COPY_CTOR (t) |= TYPE_CONTAINS_VPTR_P (t); + TYPE_HAS_COMPLEX_MOVE_CTOR (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; @@ -4398,7 +4515,8 @@ check_bases_and_members (tree 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_COPY_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t); + TYPE_HAS_COMPLEX_MOVE_ASSIGN (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 @@ -4414,7 +4532,7 @@ check_bases_and_members (tree t) { tree field; - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) { tree type; @@ -4440,7 +4558,7 @@ check_bases_and_members (tree t) /* Check defaulted declarations here so we have cant_have_const_ctor and don't need to worry about clones. */ - for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) + for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) if (DECL_DEFAULTED_IN_CLASS_P (fn)) { int copy = copy_fn_p (fn); @@ -4468,10 +4586,9 @@ check_bases_and_members (tree t) /* "The closure type associated with a lambda-expression has a deleted default constructor and a deleted copy assignment operator." */ TYPE_NEEDS_CONSTRUCTING (t) = 1; - TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0; - CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 0; - TYPE_HAS_ASSIGN_REF (t) = 0; - CLASSTYPE_LAZY_ASSIGNMENT_OP (t) = 0; + TYPE_HAS_COMPLEX_DFLT (t) = 1; + TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1; + CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 0; /* "This class type is not an aggregate." */ CLASSTYPE_NON_AGGREGATE (t) = 1; @@ -4507,7 +4624,7 @@ create_vtable_ptr (tree t, tree* virtuals_p) tree fn; /* Collect the virtual functions declared in T. */ - for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) + for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn) && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST) { @@ -4642,7 +4759,7 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets) bases will go after the last extant field to date. */ next_field = &TYPE_FIELDS (t); while (*next_field) - next_field = &TREE_CHAIN (*next_field); + next_field = &DECL_CHAIN (*next_field); /* Go through the virtual bases, allocating space for each virtual base that is not already a primary base class. These are @@ -4883,9 +5000,9 @@ layout_class_type (tree t, tree *virtuals_p) /* The vptr is always the first thing in the class. */ if (vptr) { - TREE_CHAIN (vptr) = TYPE_FIELDS (t); + DECL_CHAIN (vptr) = TYPE_FIELDS (t); TYPE_FIELDS (t) = vptr; - next_field = &TREE_CHAIN (vptr); + next_field = &DECL_CHAIN (vptr); place_field (rli, vptr); } else @@ -4897,7 +5014,7 @@ layout_class_type (tree t, tree *virtuals_p) build_base_fields (rli, empty_base_offsets, next_field); /* Layout the non-static data members. */ - for (field = non_static_data_members; field; field = TREE_CHAIN (field)) + for (field = non_static_data_members; field; field = DECL_CHAIN (field)) { tree type; tree padding; @@ -4948,14 +5065,21 @@ layout_class_type (tree t, tree *virtuals_p) of the field. Then, we are supposed to use the left over bits as additional padding. */ for (itk = itk_char; itk != itk_none; ++itk) - if (INT_CST_LT (DECL_SIZE (field), - TYPE_SIZE (integer_types[itk]))) + if (integer_types[itk] != NULL_TREE + && (INT_CST_LT (size_int (MAX_FIXED_MODE_SIZE), + TYPE_SIZE (integer_types[itk])) + || INT_CST_LT (DECL_SIZE (field), + TYPE_SIZE (integer_types[itk])))) break; /* ITK now indicates a type that is too large for the field. We have to back up by one to find the largest type that fits. */ - integer_type = integer_types[itk - 1]; + do + { + --itk; + integer_type = integer_types[itk]; + } while (itk > 0 && integer_type == NULL_TREE); /* Figure out how much additional padding is required. GCC 3.2 always created a padding field, even if it had zero @@ -5075,7 +5199,7 @@ layout_class_type (tree t, tree *virtuals_p) TYPE_UNSIGNED (ftype)); TREE_TYPE (field) = cp_build_qualified_type (TREE_TYPE (field), - TYPE_QUALS (ftype)); + cp_type_quals (ftype)); } } @@ -5171,7 +5295,7 @@ layout_class_type (tree t, tree *virtuals_p) /* Copy the fields from T. */ next_field = &TYPE_FIELDS (base_t); - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL) { *next_field = build_decl (input_location, @@ -5184,7 +5308,7 @@ layout_class_type (tree t, tree *virtuals_p) = DECL_FIELD_BIT_OFFSET (field); DECL_SIZE (*next_field) = DECL_SIZE (field); DECL_MODE (*next_field) = DECL_MODE (field); - next_field = &TREE_CHAIN (*next_field); + next_field = &DECL_CHAIN (*next_field); } /* Record the base version of the type. */ @@ -5231,7 +5355,7 @@ layout_class_type (tree t, tree *virtuals_p) warn_about_ambiguous_bases (t); /* Now that we're done with layout, give the base fields the real types. */ - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) if (DECL_ARTIFICIAL (field) && IS_FAKE_BASE_TYPE (TREE_TYPE (field))) TREE_TYPE (field) = TYPE_CONTEXT (TREE_TYPE (field)); @@ -5263,7 +5387,7 @@ determine_key_method (tree type) key function may not be inline; those targets should not call this function until the end of the translation unit. */ for (method = TYPE_METHODS (type); method != NULL_TREE; - method = TREE_CHAIN (method)) + method = DECL_CHAIN (method)) if (DECL_VINDEX (method) != NULL_TREE && ! DECL_DECLARED_INLINE_P (method) && ! DECL_PURE_VIRTUAL_P (method)) @@ -5387,7 +5511,7 @@ finish_struct_1 (tree t) /* Complete the rtl for any static member objects of the type we're working on. */ - for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x)) + for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x)) if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x) && TREE_TYPE (x) != error_mark_node && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t)) @@ -5403,9 +5527,8 @@ finish_struct_1 (tree t) n_fields = count_fields (TYPE_FIELDS (t)); if (n_fields > 7) { - struct sorted_fields_type *field_vec = GGC_NEWVAR - (struct sorted_fields_type, - sizeof (struct sorted_fields_type) + n_fields * sizeof (tree)); + struct sorted_fields_type *field_vec = ggc_alloc_sorted_fields_type + (sizeof (struct sorted_fields_type) + n_fields * sizeof (tree)); field_vec->len = n_fields; add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0); qsort (field_vec->elts, n_fields, sizeof (tree), @@ -5485,13 +5608,13 @@ unreverse_member_declarations (tree t) x && TREE_CODE (x) != TYPE_DECL; x = next) { - next = TREE_CHAIN (x); - TREE_CHAIN (x) = prev; + next = DECL_CHAIN (x); + DECL_CHAIN (x) = prev; prev = x; } if (prev) { - TREE_CHAIN (TYPE_FIELDS (t)) = x; + DECL_CHAIN (TYPE_FIELDS (t)) = x; if (prev) TYPE_FIELDS (t) = prev; } @@ -5528,7 +5651,7 @@ finish_struct (tree t, tree attributes) CLASSTYPE_PURE_VIRTUALS contains the list of the inline friends (see CLASSTYPE_INLINE_FRIENDS) so we need to clear it. */ CLASSTYPE_PURE_VIRTUALS (t) = NULL; - for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) + for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x)) if (DECL_PURE_VIRTUAL_P (x)) VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x); complete_vars (t); @@ -5938,6 +6061,34 @@ currently_open_derived_class (tree t) return NULL_TREE; } +/* Returns the innermost class type which is not a lambda closure type. */ + +tree +current_nonlambda_class_type (void) +{ + int i; + + /* We start looking from 1 because entry 0 is from global scope, + and has no type. */ + for (i = current_class_depth; i > 0; --i) + { + tree c; + if (i == current_class_depth) + c = current_class_type; + else + { + if (current_class_stack[i].hidden) + break; + c = current_class_stack[i].type; + } + if (!c) + continue; + if (!LAMBDA_TYPE_P (c)) + return c; + } + return NULL_TREE; +} + /* When entering a class scope, all enclosing class scopes' names with static meaning (static variables, static functions, types and enumerators) have to be visible. This recursive function calls @@ -6343,7 +6494,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags) flags &= ~tf_ptrmem_ok; - if (TREE_CODE (lhstype) == UNKNOWN_TYPE) + if (lhstype == unknown_type_node) { if (flags & tf_error) error ("not enough type information"); @@ -6600,7 +6751,7 @@ is_really_empty_class (tree type) 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)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL && !DECL_ARTIFICIAL (field) && !is_really_empty_class (TREE_TYPE (field))) @@ -6656,7 +6807,13 @@ note_name_declared_in_class (tree name, tree decl) = current_class_stack[current_class_depth - 1].names_used; if (!names_used) return; - + /* The C language allows members to be declared with a type of the same + name, and the C++ standard says this diagnostic is not required. So + allow it in extern "C" blocks unless predantic is specified. + Allow it in all cases if -ms-extensions is specified. */ + if ((!pedantic && current_lang_name == lang_name_c) + || flag_ms_extensions) + return; n = splay_tree_lookup (names_used, (splay_tree_key) name); if (n) { @@ -6980,36 +7137,36 @@ debug_thunks (tree fn) static void finish_vtbls (tree t) { - tree list; tree vbase; + VEC(constructor_elt,gc) *v = NULL; + tree vtable = BINFO_VTABLE (TYPE_BINFO (t)); /* We lay out the primary and secondary vtables in one contiguous vtable. The primary vtable is first, followed by the non-virtual secondary vtables in inheritance graph order. */ - list = build_tree_list (BINFO_VTABLE (TYPE_BINFO (t)), NULL_TREE); - accumulate_vtbl_inits (TYPE_BINFO (t), TYPE_BINFO (t), - TYPE_BINFO (t), t, list); + accumulate_vtbl_inits (TYPE_BINFO (t), TYPE_BINFO (t), TYPE_BINFO (t), + vtable, t, &v); /* Then come the virtual bases, also in inheritance graph order. */ for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase)) { if (!BINFO_VIRTUAL_P (vbase)) continue; - accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), t, list); + accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), vtable, t, &v); } if (BINFO_VTABLE (TYPE_BINFO (t))) - initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list)); + initialize_vtable (TYPE_BINFO (t), v); } /* Initialize the vtable for BINFO with the INITS. */ static void -initialize_vtable (tree binfo, tree inits) +initialize_vtable (tree binfo, VEC(constructor_elt,gc) *inits) { tree decl; - layout_vtable_decl (binfo, list_length (inits)); + layout_vtable_decl (binfo, VEC_length (constructor_elt, inits)); decl = get_vtbl_decl_for_binfo (binfo); initialize_artificial_var (decl, inits); dump_vtable (BINFO_TYPE (binfo), binfo, decl); @@ -7031,13 +7188,13 @@ initialize_vtable (tree binfo, tree inits) static void build_vtt (tree t) { - tree inits; tree type; tree vtt; tree index; + VEC(constructor_elt,gc) *inits; /* Build up the initializers for the VTT. */ - inits = NULL_TREE; + inits = NULL; index = size_zero_node; build_vtt_inits (TYPE_BINFO (t), t, &inits, &index); @@ -7046,15 +7203,15 @@ build_vtt (tree t) return; /* Figure out the type of the VTT. */ - type = build_index_type (size_int (list_length (inits) - 1)); + type = build_index_type (size_int (VEC_length (constructor_elt, inits) - 1)); type = build_cplus_array_type (const_ptr_type_node, type); /* Now, build the VTT object itself. */ vtt = build_vtable (t, mangle_vtt_for_type (t), type); initialize_artificial_var (vtt, inits); /* Add the VTT to the vtables list. */ - TREE_CHAIN (vtt) = TREE_CHAIN (CLASSTYPE_VTABLES (t)); - TREE_CHAIN (CLASSTYPE_VTABLES (t)) = vtt; + DECL_CHAIN (vtt) = DECL_CHAIN (CLASSTYPE_VTABLES (t)); + DECL_CHAIN (CLASSTYPE_VTABLES (t)) = vtt; dump_vtt (t, vtt); } @@ -7092,8 +7249,8 @@ typedef struct secondary_vptr_vtt_init_data_s /* Current index into the VTT. */ tree index; - /* TREE_LIST of initializers built up. */ - tree inits; + /* Vector of initializers built up. */ + VEC(constructor_elt,gc) *inits; /* The type being constructed by this secondary VTT. */ tree type_being_constructed; @@ -7107,19 +7264,18 @@ typedef struct secondary_vptr_vtt_init_data_s for virtual bases of T. When it is not so, we build the constructor vtables for the BINFO-in-T variant. */ -static tree * -build_vtt_inits (tree binfo, tree t, tree *inits, tree *index) +static void +build_vtt_inits (tree binfo, tree t, VEC(constructor_elt,gc) **inits, tree *index) { int i; tree b; tree init; - tree secondary_vptrs; secondary_vptr_vtt_init_data data; int top_level_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t); /* We only need VTTs for subobjects with virtual bases. */ if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))) - return inits; + return; /* We need to use a construction vtable if this is not the primary VTT. */ @@ -7133,8 +7289,7 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index) /* Add the address of the primary vtable for the complete object. */ init = binfo_ctor_vtable (binfo); - *inits = build_tree_list (NULL_TREE, init); - inits = &TREE_CHAIN (*inits); + CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init); if (top_level_p) { gcc_assert (!BINFO_VPTR_INDEX (binfo)); @@ -7145,30 +7300,23 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index) /* Recursively add the secondary VTTs for non-virtual bases. */ for (i = 0; BINFO_BASE_ITERATE (binfo, i, b); ++i) if (!BINFO_VIRTUAL_P (b)) - inits = build_vtt_inits (b, t, inits, index); + build_vtt_inits (b, t, inits, index); /* Add secondary virtual pointers for all subobjects of BINFO with either virtual bases or reachable along a virtual path, except subobjects that are non-virtual primary bases. */ data.top_level_p = top_level_p; data.index = *index; - data.inits = NULL; + data.inits = *inits; data.type_being_constructed = BINFO_TYPE (binfo); dfs_walk_once (binfo, dfs_build_secondary_vptr_vtt_inits, NULL, &data); *index = data.index; - /* The secondary vptrs come back in reverse order. After we reverse - them, and add the INITS, the last init will be the first element - of the chain. */ - secondary_vptrs = data.inits; - if (secondary_vptrs) - { - *inits = nreverse (secondary_vptrs); - inits = &TREE_CHAIN (secondary_vptrs); - gcc_assert (*inits == NULL_TREE); - } + /* data.inits might have grown as we added secondary virtual pointers. + Make sure our caller knows about the new vector. */ + *inits = data.inits; if (top_level_p) /* Add the secondary VTTs for virtual bases in inheritance graph @@ -7178,13 +7326,11 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index) if (!BINFO_VIRTUAL_P (b)) continue; - inits = build_vtt_inits (b, t, inits, index); + build_vtt_inits (b, t, inits, index); } else /* Remove the ctor vtables we created. */ dfs_walk_all (binfo, dfs_fixup_binfo_vtbls, NULL, binfo); - - return inits; } /* Called from build_vtt_inits via dfs_walk. BINFO is the binfo for the base @@ -7232,7 +7378,7 @@ dfs_build_secondary_vptr_vtt_inits (tree binfo, void *data_) } /* Add the initializer for the secondary vptr itself. */ - data->inits = tree_cons (NULL_TREE, binfo_ctor_vtable (binfo), data->inits); + CONSTRUCTOR_APPEND_ELT (data->inits, NULL_TREE, binfo_ctor_vtable (binfo)); /* Advance the vtt index. */ data->index = size_binop (PLUS_EXPR, data->index, @@ -7275,12 +7421,11 @@ dfs_fixup_binfo_vtbls (tree binfo, void* data) static void build_ctor_vtbl_group (tree binfo, tree t) { - tree list; tree type; tree vtbl; - tree inits; tree id; tree vbase; + VEC(constructor_elt,gc) *v; /* See if we've already created this construction vtable group. */ id = mangle_ctor_vtbl_for_type (t, binfo); @@ -7293,9 +7438,10 @@ build_ctor_vtbl_group (tree binfo, tree t) construction vtable group. */ vtbl = build_vtable (t, id, ptr_type_node); DECL_CONSTRUCTION_VTABLE_P (vtbl) = 1; - list = build_tree_list (vtbl, NULL_TREE); + + v = NULL; accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)), - binfo, t, list); + binfo, vtbl, t, &v); /* Add the vtables for each of our virtual bases using the vbase in T binfo. */ @@ -7309,12 +7455,11 @@ build_ctor_vtbl_group (tree binfo, tree t) continue; b = copied_binfo (vbase, binfo); - accumulate_vtbl_inits (b, vbase, binfo, t, list); + accumulate_vtbl_inits (b, vbase, binfo, vtbl, t, &v); } - inits = TREE_VALUE (list); /* Figure out the type of the construction vtable. */ - type = build_index_type (size_int (list_length (inits) - 1)); + type = build_index_type (size_int (VEC_length (constructor_elt, v) - 1)); type = build_cplus_array_type (vtable_entry_type, type); layout_type (type); TREE_TYPE (vtbl) = type; @@ -7323,7 +7468,7 @@ build_ctor_vtbl_group (tree binfo, tree t) /* Initialize the construction vtable. */ CLASSTYPE_VTABLES (t) = chainon (CLASSTYPE_VTABLES (t), vtbl); - initialize_artificial_var (vtbl, inits); + initialize_artificial_var (vtbl, v); dump_vtable (t, binfo, vtbl); } @@ -7341,8 +7486,9 @@ static void accumulate_vtbl_inits (tree binfo, tree orig_binfo, tree rtti_binfo, + tree vtbl, tree t, - tree inits) + VEC(constructor_elt,gc) **inits) { int i; tree base_binfo; @@ -7362,10 +7508,7 @@ accumulate_vtbl_inits (tree binfo, return; /* Build the initializers for the BINFO-in-T vtable. */ - TREE_VALUE (inits) - = chainon (TREE_VALUE (inits), - dfs_accumulate_vtbl_inits (binfo, orig_binfo, - rtti_binfo, t, inits)); + dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, vtbl, t, inits); /* Walk the BINFO and its bases. We walk in preorder so that as we initialize each vtable we can figure out at what offset the @@ -7379,24 +7522,25 @@ accumulate_vtbl_inits (tree binfo, continue; accumulate_vtbl_inits (base_binfo, BINFO_BASE_BINFO (orig_binfo, i), - rtti_binfo, t, + rtti_binfo, vtbl, t, inits); } } -/* Called from accumulate_vtbl_inits. Returns the initializers for - the BINFO vtable. */ +/* Called from accumulate_vtbl_inits. Adds the initializers for the + BINFO vtable to L. */ -static tree +static void dfs_accumulate_vtbl_inits (tree binfo, tree orig_binfo, tree rtti_binfo, + tree orig_vtbl, tree t, - tree l) + VEC(constructor_elt,gc) **l) { - tree inits = NULL_TREE; tree vtbl = NULL_TREE; int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t); + int n_inits; if (ctor_vtbl_p && BINFO_VIRTUAL_P (orig_binfo) && BINFO_PRIMARY_P (orig_binfo)) @@ -7450,23 +7594,24 @@ dfs_accumulate_vtbl_inits (tree binfo, /* Otherwise, this is case 3 and we get our own. */ } else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo)) - return inits; + return; + + n_inits = VEC_length (constructor_elt, *l); if (!vtbl) { tree index; int non_fn_entries; - /* Compute the initializer for this vtable. */ - inits = build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, - &non_fn_entries); + /* Add the initializer for this vtable. */ + build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, + &non_fn_entries, l); /* Figure out the position to which the VPTR should point. */ - vtbl = TREE_PURPOSE (l); - vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, vtbl); + vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, orig_vtbl); index = size_binop (PLUS_EXPR, size_int (non_fn_entries), - size_int (list_length (TREE_VALUE (l)))); + size_int (n_inits)); index = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (vtable_entry_type), index); @@ -7479,12 +7624,11 @@ dfs_accumulate_vtbl_inits (tree binfo, straighten this out. */ BINFO_VTABLE (binfo) = tree_cons (rtti_binfo, vtbl, BINFO_VTABLE (binfo)); else if (BINFO_PRIMARY_P (binfo) && BINFO_VIRTUAL_P (binfo)) - inits = NULL_TREE; + /* Throw away any unneeded intializers. */ + VEC_truncate (constructor_elt, *l, n_inits); else /* For an ordinary vtable, set BINFO_VTABLE. */ BINFO_VTABLE (binfo) = vtbl; - - return inits; } static GTY(()) tree abort_fndecl_addr; @@ -7512,26 +7656,26 @@ static GTY(()) tree abort_fndecl_addr; primary bases; we need these while the primary base is being constructed. */ -static tree +static void build_vtbl_initializer (tree binfo, tree orig_binfo, tree t, tree rtti_binfo, - int* non_fn_entries_p) + int* non_fn_entries_p, + VEC(constructor_elt,gc) **inits) { - tree v, b; - tree vfun_inits; + tree v; vtbl_init_data vid; - unsigned ix; + unsigned ix, jx; tree vbinfo; VEC(tree,gc) *vbases; + constructor_elt *e; /* Initialize VID. */ memset (&vid, 0, sizeof (vid)); vid.binfo = binfo; vid.derived = t; vid.rtti_binfo = rtti_binfo; - vid.last_init = &vid.inits; vid.primary_vtbl_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t); vid.ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t); vid.generate_vcall_entries = true; @@ -7557,28 +7701,52 @@ build_vtbl_initializer (tree binfo, /* If the target requires padding between data entries, add that now. */ if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1) { - tree cur, *prev; + int n_entries = VEC_length (constructor_elt, vid.inits); + + VEC_safe_grow (constructor_elt, gc, vid.inits, + TARGET_VTABLE_DATA_ENTRY_DISTANCE * n_entries); - for (prev = &vid.inits; (cur = *prev); prev = &TREE_CHAIN (cur)) + /* Move data entries into their new positions and add padding + after the new positions. Iterate backwards so we don't + overwrite entries that we would need to process later. */ + for (ix = n_entries - 1; + VEC_iterate (constructor_elt, vid.inits, ix, e); + ix--) { - tree add = cur; - int i; + int j; + int new_position = (TARGET_VTABLE_DATA_ENTRY_DISTANCE * ix + + (TARGET_VTABLE_DATA_ENTRY_DISTANCE - 1)); - for (i = 1; i < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++i) - add = tree_cons (NULL_TREE, - build1 (NOP_EXPR, vtable_entry_type, - null_pointer_node), - add); - *prev = add; + VEC_replace (constructor_elt, vid.inits, new_position, e); + + for (j = 1; j < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++j) + { + constructor_elt *f = VEC_index (constructor_elt, vid.inits, + new_position - j); + f->index = NULL_TREE; + f->value = build1 (NOP_EXPR, vtable_entry_type, + null_pointer_node); + } } } if (non_fn_entries_p) - *non_fn_entries_p = list_length (vid.inits); + *non_fn_entries_p = VEC_length (constructor_elt, vid.inits); + + /* The initializers for virtual functions were built up in reverse + order. Straighten them out and add them to the running list in one + step. */ + jx = VEC_length (constructor_elt, *inits); + VEC_safe_grow (constructor_elt, gc, *inits, + (jx + VEC_length (constructor_elt, vid.inits))); + + for (ix = VEC_length (constructor_elt, vid.inits) - 1; + VEC_iterate (constructor_elt, vid.inits, ix, e); + ix--, jx++) + VEC_replace (constructor_elt, *inits, jx, e); /* Go through all the ordinary virtual functions, building up initializers. */ - vfun_inits = NULL_TREE; for (v = BINFO_VIRTUALS (orig_binfo); v; v = TREE_CHAIN (v)) { tree delta; @@ -7610,20 +7778,8 @@ build_vtbl_initializer (tree binfo, 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)) - { - /* We found a defn before a lost primary; go ahead as normal. */ - if (look_for_overrides_here (BINFO_TYPE (b), fn_original)) - break; - - /* The nearest definition is from a lost primary; clear the - slot. */ - if (BINFO_LOST_PRIMARY_P (b)) - { - init = size_zero_node; - break; - } - } + if (BV_LOST_PRIMARY (v)) + init = size_zero_node; if (! init) { @@ -7640,9 +7796,14 @@ build_vtbl_initializer (tree binfo, if (DECL_PURE_VIRTUAL_P (fn_original)) { fn = abort_fndecl; - if (abort_fndecl_addr == NULL) - abort_fndecl_addr = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn); - init = abort_fndecl_addr; + if (!TARGET_VTABLE_USES_DESCRIPTORS) + { + if (abort_fndecl_addr == NULL) + abort_fndecl_addr + = fold_convert (vfunc_ptr_type_node, + build_fold_addr_expr (fn)); + init = abort_fndecl_addr; + } } else { @@ -7654,7 +7815,9 @@ build_vtbl_initializer (tree binfo, } /* Take the address of the function, considering it to be of an appropriate generic type. */ - init = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn); + if (!TARGET_VTABLE_USES_DESCRIPTORS) + init = fold_convert (vfunc_ptr_type_node, + build_fold_addr_expr (fn)); } } @@ -7664,31 +7827,20 @@ build_vtbl_initializer (tree binfo, int i; if (init == size_zero_node) for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i) - vfun_inits = tree_cons (NULL_TREE, init, vfun_inits); + CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init); else for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i) { tree fdesc = build2 (FDESC_EXPR, vfunc_ptr_type_node, - TREE_OPERAND (init, 0), - build_int_cst (NULL_TREE, i)); + fn, build_int_cst (NULL_TREE, i)); TREE_CONSTANT (fdesc) = 1; - vfun_inits = tree_cons (NULL_TREE, fdesc, vfun_inits); + CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, fdesc); } } else - vfun_inits = tree_cons (NULL_TREE, init, vfun_inits); + CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init); } - - /* The initializers for virtual functions were built up in reverse - order; straighten them out now. */ - vfun_inits = nreverse (vfun_inits); - - /* The negative offset initializers are also in reverse order. */ - vid.inits = nreverse (vid.inits); - - /* Chain the two together. */ - return chainon (vid.inits, vfun_inits); } /* Adds to vid->inits the initializers for the vbase and vcall @@ -7798,12 +7950,9 @@ build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid) delta = size_diffop_loc (input_location, BINFO_OFFSET (b), BINFO_OFFSET (non_primary_binfo)); - *vid->last_init - = build_tree_list (NULL_TREE, - fold_build1_loc (input_location, NOP_EXPR, - vtable_entry_type, - delta)); - vid->last_init = &TREE_CHAIN (*vid->last_init); + CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, + fold_build1_loc (input_location, NOP_EXPR, + vtable_entry_type, delta)); } } @@ -7898,7 +8047,7 @@ add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid) order. G++ 3.2 used the order in the vtable. */ for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo)); orig_fn; - orig_fn = TREE_CHAIN (orig_fn)) + orig_fn = DECL_CHAIN (orig_fn)) if (DECL_VINDEX (orig_fn)) add_vcall_offset (orig_fn, binfo, vid); } @@ -7982,7 +8131,7 @@ add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid) signature as FN, then we do not need a second vcall offset. Check the list of functions already present in the derived class vtable. */ - for (i = 0; VEC_iterate (tree, vid->fns, i, derived_entry); ++i) + FOR_EACH_VEC_ELT (tree, vid->fns, i, derived_entry) { if (same_signature_p (derived_entry, orig_fn) /* We only use one vcall offset for virtual destructors, @@ -8038,8 +8187,7 @@ add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid) vcall_offset); } /* Add the initializer to the vtable. */ - *vid->last_init = build_tree_list (NULL_TREE, vcall_offset); - vid->last_init = &TREE_CHAIN (*vid->last_init); + CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, vcall_offset); } } @@ -8083,15 +8231,13 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid) /* Convert the declaration to a type that can be stored in the vtable. */ init = build_nop (vfunc_ptr_type_node, decl); - *vid->last_init = build_tree_list (NULL_TREE, init); - vid->last_init = &TREE_CHAIN (*vid->last_init); + CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init); /* Add the offset-to-top entry. It comes earlier in the vtable than the typeinfo entry. Convert the offset to look like a function pointer, so that we can put it in the vtable. */ init = build_nop (vfunc_ptr_type_node, offset); - *vid->last_init = build_tree_list (NULL_TREE, init); - vid->last_init = &TREE_CHAIN (*vid->last_init); + CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init); } /* Fold a OBJ_TYPE_REF expression to the address of a function. diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in index c6d7b38b31f..a15c7e24705 100644 --- a/gcc/cp/config-lang.in +++ b/gcc/cp/config-lang.in @@ -30,4 +30,4 @@ compilers="cc1plus\$(exeext)" target_libs="target-libstdc++-v3" -gtfiles="\$(srcdir)/cp/rtti.c \$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/cp/typeck2.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-lex.c \$(srcdir)/c-pragma.h \$(srcdir)/c-pragma.c \$(srcdir)/cp/class.c \$(srcdir)/cp/cp-objcp-common.c \$(srcdir)/cp/cp-lang.c" +gtfiles="\$(srcdir)/cp/rtti.c \$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/cp/typeck2.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-lex.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/cp/class.c \$(srcdir)/cp/cp-objcp-common.c \$(srcdir)/cp/cp-lang.c" diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 533d2d18384..e5a7f265958 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tree.h" #include "cp-tree.h" -#include "c-common.h" +#include "c-family/c-common.h" #include "toplev.h" #include "tree-iterator.h" #include "gimple.h" @@ -51,7 +51,7 @@ static tree begin_bc_block (enum bc_t bc) { tree label = create_artificial_label (input_location); - TREE_CHAIN (label) = bc_label[bc]; + DECL_CHAIN (label) = bc_label[bc]; bc_label[bc] = label; return label; } @@ -73,8 +73,8 @@ finish_bc_block (enum bc_t bc, tree label, gimple_seq body) gimple_seq_add_stmt (&body, gimple_build_label (label)); } - bc_label[bc] = TREE_CHAIN (label); - TREE_CHAIN (label) = NULL_TREE; + bc_label[bc] = DECL_CHAIN (label); + DECL_CHAIN (label) = NULL_TREE; return body; } @@ -480,11 +480,16 @@ gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p) tree stmt = *expr_p; tree temp = voidify_wrapper_expr (stmt, NULL); tree body = TREE_OPERAND (stmt, 0); + gimple_seq try_ = NULL; + gimple_seq catch_ = NULL; + gimple mnt; - stmt = build_gimple_eh_filter_tree (body, NULL_TREE, - build_call_n (terminate_node, 0)); + gimplify_and_add (body, &try_); + mnt = gimple_build_eh_must_not_throw (terminate_node); + gimplify_seq_add_stmt (&catch_, mnt); + mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH); - gimplify_and_add (stmt, pre_p); + gimplify_seq_add_stmt (pre_p, mnt); if (temp) { *expr_p = temp; @@ -569,6 +574,29 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0))) TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (op0), op1); + + else if ((is_gimple_lvalue (op1) || INDIRECT_REF_P (op1) + || (TREE_CODE (op1) == CONSTRUCTOR + && CONSTRUCTOR_NELTS (op1) == 0) + || (TREE_CODE (op1) == CALL_EXPR + && !CALL_EXPR_RETURN_SLOT_OPT (op1))) + && is_really_empty_class (TREE_TYPE (op0))) + { + /* Remove any copies of empty classes. We check that the RHS + has a simple form so that TARGET_EXPRs and non-empty + CONSTRUCTORs get reduced properly, and we leave the return + slot optimization alone because it isn't a copy (FIXME so it + shouldn't be represented as one). + + Also drop volatile variables on the RHS to avoid infinite + recursion from gimplify_expr trying to load the value. */ + if (!TREE_SIDE_EFFECTS (op1) + || (DECL_P (op1) && TREE_THIS_VOLATILE (op1))) + *expr_p = op0; + else + *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p), + op0, op1); + } } ret = GS_OK; break; @@ -868,7 +896,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) IMPORTED_DECL_ASSOCIATED_DECL (using_directive) = TREE_OPERAND (stmt, 0); - TREE_CHAIN (using_directive) = BLOCK_VARS (block); + DECL_CHAIN (using_directive) = BLOCK_VARS (block); BLOCK_VARS (block) = using_directive; } /* The USING_STMT won't appear in GENERIC. */ @@ -896,7 +924,7 @@ cp_genericize (tree fndecl) struct cp_genericize_data wtd; /* Fix up the types of parms passed by invisible reference. */ - for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t)) + for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t)) if (TREE_ADDRESSABLE (TREE_TYPE (t))) { /* If a function's arguments are copied to create a thunk, @@ -956,7 +984,7 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2) return NULL; nargs = list_length (DECL_ARGUMENTS (fn)); - argarray = (tree *) alloca (nargs * sizeof (tree)); + argarray = XALLOCAVEC (tree, nargs); defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))); if (arg2) @@ -1153,7 +1181,7 @@ cxx_omp_predetermined_sharing (tree decl) tree var; if (outer) - for (var = BLOCK_VARS (outer); var; var = TREE_CHAIN (var)) + for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) if (DECL_NAME (decl) == DECL_NAME (var) && (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (var)))) diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index 6cae7b632ae..fb687b81685 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -1,5 +1,6 @@ /* Language-dependent hooks for C++. - Copyright 2001, 2002, 2004, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright 2001, 2002, 2004, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. Contributed by Alexandre Oliva <aoliva@redhat.com> This file is part of GCC. @@ -24,16 +25,13 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tree.h" #include "cp-tree.h" -#include "c-common.h" +#include "c-family/c-common.h" #include "toplev.h" #include "langhooks.h" #include "langhooks-def.h" -#include "diagnostic.h" #include "debug.h" #include "cp-objcp-common.h" #include "hashtab.h" -#include "except.h" -#include "expr.h" enum c_language_kind c_language = clk_cxx; static void cp_init_ts (void); @@ -77,8 +75,6 @@ static tree cp_eh_personality (void); #define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name #undef LANG_HOOKS_DWARF_NAME #define LANG_HOOKS_DWARF_NAME cxx_dwarf_name -#undef LANG_HOOKS_FOLD_OBJ_TYPE_REF -#define LANG_HOOKS_FOLD_OBJ_TYPE_REF cp_fold_obj_type_ref #undef LANG_HOOKS_INIT_TS #define LANG_HOOKS_INIT_TS cp_init_ts #undef LANG_HOOKS_EH_PERSONALITY diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index 460f32fe13d..0fdb87a4cc4 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -1,5 +1,5 @@ /* Some code common to C++ and ObjC++ front ends. - Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Ziemowit Laski <zlaski@apple.com> This file is part of GCC. @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tree.h" #include "cp-tree.h" -#include "c-common.h" +#include "c-family/c-common.h" #include "toplev.h" #include "langhooks.h" #include "langhooks-def.h" @@ -129,8 +129,13 @@ cp_var_mod_type_p (tree type, tree fn) void cxx_initialize_diagnostics (diagnostic_context *context) { - pretty_printer *base = context->printer; - cxx_pretty_printer *pp = XNEW (cxx_pretty_printer); + pretty_printer *base; + cxx_pretty_printer *pp; + + c_common_initialize_diagnostics (context); + + base = context->printer; + pp = XNEW (cxx_pretty_printer); memcpy (pp_base (pp), base, sizeof (pretty_printer)); pp_cxx_pretty_printer_init (pp); context->printer = (pretty_printer *) pp; @@ -177,7 +182,7 @@ has_c_linkage (const_tree decl) return DECL_EXTERN_C_P (decl); } -static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) +static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_map))) htab_t shadowed_var_for_decl; /* Lookup a shadowed var for FROM, and return it if we find one. */ @@ -185,11 +190,11 @@ static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) tree decl_shadowed_for_var_lookup (tree from) { - struct tree_map *h, in; + struct tree_decl_map *h, in; in.base.from = from; - h = (struct tree_map *) htab_find_with_hash (shadowed_var_for_decl, &in, - htab_hash_pointer (from)); + h = (struct tree_decl_map *) + htab_find_with_hash (shadowed_var_for_decl, &in, DECL_UID (from)); if (h) return h->to; return NULL_TREE; @@ -200,22 +205,22 @@ decl_shadowed_for_var_lookup (tree from) void decl_shadowed_for_var_insert (tree from, tree to) { - struct tree_map *h; + struct tree_decl_map *h; void **loc; - h = GGC_NEW (struct tree_map); - h->hash = htab_hash_pointer (from); + h = ggc_alloc_tree_decl_map (); h->base.from = from; h->to = to; - loc = htab_find_slot_with_hash (shadowed_var_for_decl, h, h->hash, INSERT); - *(struct tree_map **) loc = h; + loc = htab_find_slot_with_hash (shadowed_var_for_decl, h, DECL_UID (from), + INSERT); + *(struct tree_decl_map **) loc = h; } void init_shadowed_var_for_decl (void) { - shadowed_var_for_decl = htab_create_ggc (512, tree_map_hash, - tree_map_eq, 0); + shadowed_var_for_decl = htab_create_ggc (512, tree_decl_map_hash, + tree_decl_map_eq, 0); } diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h index 1a97ad2b119..2391faf2239 100644 --- a/gcc/cp/cp-objcp-common.h +++ b/gcc/cp/cp-objcp-common.h @@ -1,5 +1,6 @@ /* Language hooks common to C++ and ObjC++ front ends. - Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. Contributed by Ziemowit Laski <zlaski@apple.com> This file is part of GCC. @@ -40,6 +41,10 @@ extern bool cp_function_decl_explicit_p (tree decl); #define LANG_HOOKS_FINISH cxx_finish #undef LANG_HOOKS_CLEAR_BINDING_STACK #define LANG_HOOKS_CLEAR_BINDING_STACK pop_everything +#undef LANG_HOOKS_OPTION_LANG_MASK +#define LANG_HOOKS_OPTION_LANG_MASK c_common_option_lang_mask +#undef LANG_HOOKS_COMPLAIN_WRONG_LANG_P +#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P c_common_complain_wrong_lang_p #undef LANG_HOOKS_INIT_OPTIONS #define LANG_HOOKS_INIT_OPTIONS c_common_init_options #undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS @@ -48,8 +53,6 @@ extern bool cp_function_decl_explicit_p (tree decl); #define LANG_HOOKS_HANDLE_OPTION c_common_handle_option #undef LANG_HOOKS_HANDLE_FILENAME #define LANG_HOOKS_HANDLE_FILENAME c_common_handle_filename -#undef LANG_HOOKS_MISSING_ARGUMENT -#define LANG_HOOKS_MISSING_ARGUMENT c_common_missing_argument #undef LANG_HOOKS_POST_OPTIONS #define LANG_HOOKS_POST_OPTIONS c_common_post_options #undef LANG_HOOKS_GET_ALIAS_SET @@ -143,4 +146,7 @@ extern bool cp_function_decl_explicit_p (tree decl); #undef LANG_HOOKS_EH_USE_CXA_END_CLEANUP #define LANG_HOOKS_EH_USE_CXA_END_CLEANUP true +#undef LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS +#define LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS cp_protect_cleanup_actions + #endif /* GCC_CP_OBJCP_COMMON */ diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index c71f94caa61..1eb25c31a7d 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -247,6 +247,7 @@ DEFTREECODE (STATIC_CAST_EXPR, "static_cast_expr", tcc_unary, 1) DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", tcc_unary, 1) DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", tcc_expression, 2) DEFTREECODE (TYPEID_EXPR, "typeid_expr", tcc_expression, 1) +DEFTREECODE (NOEXCEPT_EXPR, "noexcept_expr", tcc_unary, 1) /* A placeholder for an expression that is not type-dependent, but does occur in a template. When an expression that is not @@ -292,6 +293,11 @@ DEFTREECODE (IF_STMT, "if_stmt", tcc_statement, 3) FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */ DEFTREECODE (FOR_STMT, "for_stmt", tcc_statement, 4) +/* Used to represent a range-based `for' statement. The operands are + RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY, respectively. Only used + in templates. */ +DEFTREECODE (RANGE_FOR_STMT, "range_for_stmt", tcc_statement, 3) + /* Used to represent a 'while' statement. The operands are WHILE_COND and WHILE_BODY, respectively. */ DEFTREECODE (WHILE_STMT, "while_stmt", tcc_statement, 2) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 63346736cf6..c78beb7c2f1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1,6 +1,6 @@ /* Definitions for C++ parsing and type checking. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -26,31 +26,25 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "function.h" #include "hashtab.h" -#include "splay-tree.h" #include "vec.h" -#include "varray.h" -#include "c-common.h" -#include "name-lookup.h" /* In order for the format checking to accept the C++ front end diagnostic framework extensions, you must include this file before - toplev.h, not after. We override the definition of GCC_DIAG_STYLE + diagnostic-core.h, not after. We override the definition of GCC_DIAG_STYLE in c-common.h. */ #undef GCC_DIAG_STYLE #define GCC_DIAG_STYLE __gcc_cxxdiag__ -#if GCC_VERSION >= 4001 -#define ATTRIBUTE_GCC_CXXDIAG(m, n) __attribute__ ((__format__ (GCC_DIAG_STYLE, m, n))) ATTRIBUTE_NONNULL(m) -#else -#define ATTRIBUTE_GCC_CXXDIAG(m, n) ATTRIBUTE_NONNULL(m) -#endif -#ifdef GCC_TOPLEV_H +#if defined(GCC_DIAGNOSTIC_CORE_H) || defined (GCC_C_COMMON_H) #error \ In order for the format checking to accept the C++ front end diagnostic \ -framework extensions, you must include this file before toplev.h, not after. +framework extensions, you must include this file before diagnostic-core.h and \ +c-common.h, not after. #endif -#include "toplev.h" +#include "c-family/c-common.h" #include "diagnostic.h" +#include "name-lookup.h" + /* Usage of TREE_LANG_FLAG_?: 0: IDENTIFIER_MARKED (IDENTIFIER_NODEs) NEW_EXPR_USE_GLOBAL (in NEW_EXPR). @@ -74,7 +68,6 @@ framework extensions, you must include this file before toplev.h, not after. BASELINK_QUALIFIED_P (in BASELINK) TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR) TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX) - TYPE_REF_IS_RVALUE (in REFERENCE_TYPE) ATTR_IS_DEPENDENT (in the TREE_LIST for an attribute) CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR) LAMBDA_EXPR_CAPTURES_THIS_P (in LAMBDA_EXPR) @@ -121,7 +114,6 @@ framework extensions, you must include this file before toplev.h, not after. 3: TYPE_FOR_JAVA. 4: TYPE_HAS_NONTRIVIAL_DESTRUCTOR 5: CLASS_TYPE_P (in RECORD_TYPE and UNION_TYPE) - SCOPED_ENUM_P (in ENUMERAL_TYPE) 6: TYPE_DEPENDENT_P_VALID Usage of DECL_LANG_FLAG_?: @@ -176,6 +168,9 @@ framework extensions, you must include this file before toplev.h, not after. The BV_FN is the declaration for the virtual function itself. + If BV_LOST_PRIMARY is set, it means that this entry is for a lost + primary virtual base and can be left null in the vtable. + BINFO_VTABLE This is an expression with POINTER_TYPE that gives the value to which the vptr should be initialized. Use get_vtbl_decl_for_binfo @@ -247,9 +242,6 @@ typedef struct template_parm_index_s template_parm_index; struct GTY(()) ptrmem_cst { struct tree_common common; - /* This isn't used, but the middle-end expects all constants to have - this field. */ - rtx rtl; tree member; }; typedef struct ptrmem_cst * ptrmem_cst_t; @@ -297,11 +289,6 @@ typedef struct ptrmem_cst * ptrmem_cst_t; #define same_type_p(TYPE1, TYPE2) \ comptypes ((TYPE1), (TYPE2), COMPARE_STRICT) -/* Returns nonzero iff TYPE1 and TYPE2 are the same type, ignoring - top-level qualifiers. */ -#define same_type_ignoring_top_level_qualifiers_p(TYPE1, TYPE2) \ - same_type_p (TYPE_MAIN_VARIANT (TYPE1), TYPE_MAIN_VARIANT (TYPE2)) - /* Nonzero if we are presently building a statement tree, rather than expanding each statement as we encounter it. */ #define building_stmt_tree() (cur_stmt_list != NULL_TREE) @@ -400,7 +387,9 @@ typedef enum cpp0x_warn_str /* scoped enums */ CPP0X_SCOPED_ENUMS, /* defaulted and deleted functions */ - CPP0X_DEFAULTED_DELETED + CPP0X_DEFAULTED_DELETED, + /* inline namespaces */ + CPP0X_INLINE_NAMESPACES } cpp0x_warn_str; /* The various kinds of operation used by composite_pointer_type. */ @@ -428,6 +417,34 @@ typedef enum readonly_error_kind REK_DECREMENT } readonly_error_kind; +/* Possible cases of expression list used by build_x_compound_expr_from_list. */ +typedef enum expr_list_kind { + ELK_INIT, /* initializer */ + ELK_MEM_INIT, /* member initializer */ + ELK_FUNC_CAST /* functional cast */ +} expr_list_kind; + +/* Possible cases of implicit bad rhs conversions. */ +typedef enum impl_conv_rhs { + ICR_DEFAULT_ARGUMENT, /* default argument */ + ICR_CONVERTING, /* converting */ + ICR_INIT, /* initialization */ + ICR_ARGPASS, /* argument passing */ + ICR_RETURN, /* return */ + ICR_ASSIGN /* assignment */ +} impl_conv_rhs; + +/* Possible cases of implicit or explicit bad conversions to void. */ +typedef enum impl_conv_void { + ICV_CAST, /* (explicit) conversion to void */ + ICV_SECOND_OF_COND, /* second operand of conditional expression */ + ICV_THIRD_OF_COND, /* third operand of conditional expression */ + ICV_RIGHT_OF_COMMA, /* right operand of comma operator */ + ICV_LEFT_OF_COMMA, /* left operand of comma operator */ + ICV_STATEMENT, /* statement */ + ICV_THIRD_IN_FOR /* for increment expression */ +} impl_conv_void; + /* Macros for access to language-specific slots in an identifier. */ #define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \ @@ -768,6 +785,8 @@ enum cp_tree_index CPTI_LANG_NAME_JAVA, CPTI_EMPTY_EXCEPT_SPEC, + CPTI_NOEXCEPT_TRUE_SPEC, + CPTI_NOEXCEPT_FALSE_SPEC, CPTI_JCLASS, CPTI_TERMINATE, CPTI_CALL_UNEXPECTED, @@ -778,6 +797,9 @@ enum cp_tree_index CPTI_KEYED_CLASSES, + CPTI_NULLPTR, + CPTI_NULLPTR_TYPE, + CPTI_MAX }; @@ -812,6 +834,8 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; #define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL] #define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL] #define current_aggr cp_global_trees[CPTI_AGGR_TAG] +#define nullptr_node cp_global_trees[CPTI_NULLPTR] +#define nullptr_type_node cp_global_trees[CPTI_NULLPTR_TYPE] /* We cache these tree nodes so as to call get_identifier less frequently. */ @@ -852,6 +876,8 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; /* Exception specifier used for throw(). */ #define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC] +#define noexcept_true_spec cp_global_trees[CPTI_NOEXCEPT_TRUE_SPEC] +#define noexcept_false_spec cp_global_trees[CPTI_NOEXCEPT_FALSE_SPEC] /* If non-NULL, a POINTER_TYPE equivalent to (java::lang::Class*). */ #define jclass_node cp_global_trees[CPTI_JCLASS] @@ -897,7 +923,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; struct GTY(()) saved_scope { VEC(cxx_saved_binding,gc) *old_bindings; tree old_namespace; - tree decl_ns_list; + VEC(tree,gc) *decl_ns_list; tree class_name; tree class_type; tree access_specifier; @@ -1223,11 +1249,11 @@ struct GTY(()) lang_type_header { BOOL_BITFIELD is_lang_type_class : 1; BOOL_BITFIELD has_type_conversion : 1; - BOOL_BITFIELD has_init_ref : 1; + BOOL_BITFIELD has_copy_ctor : 1; BOOL_BITFIELD has_default_ctor : 1; BOOL_BITFIELD const_needs_init : 1; BOOL_BITFIELD ref_needs_init : 1; - BOOL_BITFIELD has_const_assign_ref : 1; + BOOL_BITFIELD has_const_copy_assign : 1; BOOL_BITFIELD spare : 1; }; @@ -1255,7 +1281,7 @@ struct GTY(()) lang_type_class { unsigned non_pod_class : 1; unsigned nearly_empty_p : 1; unsigned user_align : 1; - unsigned has_assign_ref : 1; + unsigned has_copy_assign : 1; unsigned has_new : 1; unsigned has_array_new : 1; @@ -1281,19 +1307,23 @@ struct GTY(()) lang_type_class { unsigned was_anonymous : 1; unsigned lazy_default_ctor : 1; unsigned lazy_copy_ctor : 1; - unsigned lazy_assignment_op : 1; + unsigned lazy_copy_assign : 1; unsigned lazy_destructor : 1; - unsigned has_const_init_ref : 1; - unsigned has_complex_init_ref : 1; - unsigned has_complex_assign_ref : 1; + unsigned has_const_copy_ctor : 1; + unsigned has_complex_copy_ctor : 1; + unsigned has_complex_copy_assign : 1; unsigned non_aggregate : 1; unsigned has_complex_dflt : 1; unsigned has_list_ctor : 1; unsigned non_std_layout : 1; - unsigned lazy_move_ctor : 1; unsigned is_literal : 1; + unsigned lazy_move_ctor : 1; + unsigned lazy_move_assign : 1; + unsigned has_complex_move_ctor : 1; + unsigned has_complex_move_assign : 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 so, make sure to copy it in instantiate_class_template! */ @@ -1301,7 +1331,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 : 7; + unsigned dummy : 4; tree primary_base; VEC(tree_pair_s,gc) *vcall_indices; @@ -1334,7 +1364,7 @@ struct GTY(()) lang_type_ptrmem { tree record; }; -struct GTY(()) lang_type { +struct GTY((variable_size)) lang_type { union lang_type_u { struct lang_type_header GTY((skip (""))) h; @@ -1396,8 +1426,13 @@ struct GTY(()) lang_type { /* Nonzero means that NODE (a class type) has an assignment operator -- but that it has not yet been declared. */ -#define CLASSTYPE_LAZY_ASSIGNMENT_OP(NODE) \ - (LANG_TYPE_CLASS_CHECK (NODE)->lazy_assignment_op) +#define CLASSTYPE_LAZY_COPY_ASSIGN(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->lazy_copy_assign) + +/* Nonzero means that NODE (a class type) has an assignment operator + -- but that it has not yet been declared. */ +#define CLASSTYPE_LAZY_MOVE_ASSIGN(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->lazy_move_assign) /* Nonzero means that NODE (a class type) has a destructor -- but that it has not yet been declared. */ @@ -1405,17 +1440,17 @@ struct GTY(()) lang_type { (LANG_TYPE_CLASS_CHECK (NODE)->lazy_destructor) /* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */ -#define TYPE_HAS_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_assign_ref) +#define TYPE_HAS_COPY_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_copy_assign) /* True iff the class type NODE has an "operator =" whose parameter has a parameter of type "const X&". */ -#define TYPE_HAS_CONST_ASSIGN_REF(NODE) \ - (LANG_TYPE_CLASS_CHECK (NODE)->h.has_const_assign_ref) +#define TYPE_HAS_CONST_COPY_ASSIGN(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->h.has_const_copy_assign) /* Nonzero means that this _CLASSTYPE node has an X(X&) constructor. */ -#define TYPE_HAS_INIT_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->h.has_init_ref) -#define TYPE_HAS_CONST_INIT_REF(NODE) \ - (LANG_TYPE_CLASS_CHECK (NODE)->has_const_init_ref) +#define TYPE_HAS_COPY_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->h.has_copy_ctor) +#define TYPE_HAS_CONST_COPY_CTOR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->has_const_copy_ctor) /* Nonzero if this class has an X(initializer_list<T>) constructor. */ #define TYPE_HAS_LIST_CTOR(NODE) \ @@ -1434,6 +1469,11 @@ struct GTY(()) lang_type { starting the definition of this type has been seen. */ #define TYPE_BEING_DEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->being_defined) +/* Nonzero means that this type is either complete or being defined, so we + can do lookup in it. */ +#define COMPLETE_OR_OPEN_TYPE_P(NODE) \ + (COMPLETE_TYPE_P (NODE) || (CLASS_TYPE_P (NODE) && TYPE_BEING_DEFINED (NODE))) + /* Mark bits for repeated base checks. */ #define TYPE_MARKED_P(NODE) TREE_LANG_FLAG_6 (TYPE_CHECK (NODE)) @@ -1727,17 +1767,24 @@ struct GTY(()) lang_type { /* The function to call. */ #define BV_FN(NODE) (TREE_VALUE (NODE)) +/* Whether or not this entry is for a lost primary virtual base. */ +#define BV_LOST_PRIMARY(NODE) (TREE_LANG_FLAG_0 (NODE)) /* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE will be NULL_TREE to indicate a throw specification of `()', or - no exceptions allowed. */ + no exceptions allowed. For a noexcept specification, TREE_VALUE + is NULL_TREE and TREE_PURPOSE is the constant-expression. */ #define TYPE_RAISES_EXCEPTIONS(NODE) TYPE_LANG_SLOT_1 (NODE) -/* For FUNCTION_TYPE or METHOD_TYPE, return 1 iff it is declared `throw()'. */ -#define TYPE_NOTHROW_P(NODE) \ - (TYPE_RAISES_EXCEPTIONS (NODE) \ - && TREE_VALUE (TYPE_RAISES_EXCEPTIONS (NODE)) == NULL_TREE) +/* For FUNCTION_TYPE or METHOD_TYPE, return 1 iff it is declared `throw()' + or noexcept(true). */ +#define TYPE_NOTHROW_P(NODE) nothrow_spec_p (TYPE_RAISES_EXCEPTIONS (NODE)) + +/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE is noexcept. This is the + case for things declared noexcept(true) and, with -fnothrow-opt, for + throw() functions. */ +#define TYPE_NOEXCEPT_P(NODE) type_noexcept_p (NODE) /* The binding level associated with the namespace. */ #define NAMESPACE_LEVEL(NODE) \ @@ -1758,7 +1805,7 @@ struct GTY(()) lang_decl_base { unsigned threadprivate_or_deleted_p : 1; /* var or fn */ unsigned anticipated_p : 1; /* fn or type */ unsigned friend_attr : 1; /* fn or type */ - unsigned template_conv_p : 1; /* template only? */ + unsigned template_conv_p : 1; /* var or template */ unsigned odr_used : 1; /* var or fn */ unsigned u2sel : 1; /* 1 spare bit */ @@ -1875,7 +1922,7 @@ struct GTY(()) lang_decl_parm { union rather than a struct containing a union as its only field, but tree.h declares it as a struct. */ -struct GTY(()) lang_decl { +struct GTY((variable_size)) lang_decl { union GTY((desc ("%h.base.selector"))) lang_decl_u { struct lang_decl_base GTY ((default)) base; struct lang_decl_min GTY((tag ("0"))) min; @@ -2041,9 +2088,9 @@ struct GTY(()) lang_decl { if (TREE_CODE (FN) == FUNCTION_DECL \ && (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (FN) \ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (FN))) \ - for (CLONE = TREE_CHAIN (FN); \ + for (CLONE = DECL_CHAIN (FN); \ CLONE && DECL_CLONED_FUNCTION_P (CLONE); \ - CLONE = TREE_CHAIN (CLONE)) + CLONE = DECL_CHAIN (CLONE)) /* Nonzero if NODE has DECL_DISCRIMINATOR and not DECL_ACCESS. */ #define DECL_DISCRIMINATOR_P(NODE) \ @@ -2088,6 +2135,15 @@ struct GTY(()) lang_decl { #define DECL_TEMPLATE_CONV_FN_P(NODE) \ (DECL_LANG_SPECIFIC (TEMPLATE_DECL_CHECK (NODE))->u.base.template_conv_p) +/* Nonzero if NODE, a static data member, was declared in its class as an + array of unknown bound. */ +#define VAR_HAD_UNKNOWN_BOUND(NODE) \ + (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE)) \ + ? DECL_LANG_SPECIFIC (NODE)->u.base.template_conv_p \ + : false) +#define SET_VAR_HAD_UNKNOWN_BOUND(NODE) \ + (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.template_conv_p = true) + /* Set the overloaded operator code for NODE to CODE. */ #define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \ (LANG_DECL_FN_CHECK (NODE)->operator_code = (CODE)) @@ -2993,10 +3049,16 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) || TREE_CODE (TYPE) == REAL_TYPE \ || TREE_CODE (TYPE) == COMPLEX_TYPE) +/* True iff TYPE is cv decltype(nullptr). */ +#define NULLPTR_TYPE_P(TYPE) \ + (TREE_CODE (TYPE) == LANG_TYPE \ + && TYPE_MAIN_VARIANT (TYPE) == nullptr_type_node) + /* [basic.types] - Arithmetic types, enumeration types, pointer types, and - pointer-to-member types, are collectively called scalar types. + Arithmetic types, enumeration types, pointer types, + pointer-to-member types, and std::nullptr_t are collectively called + scalar types. Keep these checks in ascending code order. */ #define SCALAR_TYPE_P(TYPE) \ @@ -3004,7 +3066,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) || TREE_CODE (TYPE) == ENUMERAL_TYPE \ || ARITHMETIC_TYPE_P (TYPE) \ || TYPE_PTR_P (TYPE) \ - || TYPE_PTRMEMFUNC_P (TYPE)) + || TYPE_PTRMEMFUNC_P (TYPE) \ + || NULLPTR_TYPE_P (TYPE)) /* Determines whether this type is a C++0x scoped enumeration type. Scoped enumerations types are introduced via "enum class" or @@ -3027,17 +3090,17 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) - The underlying type of the enum is well-defined. */ #define SCOPED_ENUM_P(TYPE) \ - (TREE_CODE (TYPE) == ENUMERAL_TYPE && TYPE_LANG_FLAG_5 (TYPE)) + (TREE_CODE (TYPE) == ENUMERAL_TYPE && ENUM_IS_SCOPED (TYPE)) /* Determine whether this is an unscoped enumeration type. */ #define UNSCOPED_ENUM_P(TYPE) \ - (TREE_CODE (TYPE) == ENUMERAL_TYPE && !TYPE_LANG_FLAG_5 (TYPE)) + (TREE_CODE (TYPE) == ENUMERAL_TYPE && !ENUM_IS_SCOPED (TYPE)) /* Set the flag indicating whether an ENUMERAL_TYPE is a C++0x scoped enumeration type (1) or a normal (unscoped) enumeration type (0). */ #define SET_SCOPED_ENUM_P(TYPE, VAL) \ - (TYPE_LANG_FLAG_5 (ENUMERAL_TYPE_CHECK (TYPE)) = (VAL)) + (ENUM_IS_SCOPED (TYPE) = (VAL)) /* Returns the underlying type of the given enumeration type. The underlying type is determined in different ways, depending on the @@ -3117,13 +3180,19 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define TYPE_NON_AGGREGATE_CLASS(NODE) \ (CLASS_TYPE_P (NODE) && CLASSTYPE_NON_AGGREGATE (NODE)) -/* Nonzero if there is a user-defined X::op=(x&) for this class. */ -#define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_assign_ref) +/* Nonzero if there is a non-trivial X::op=(cv X&) for this class. */ +#define TYPE_HAS_COMPLEX_COPY_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_copy_assign) -/* Nonzero if there is a user-defined X::X(x&) for this class. */ -#define TYPE_HAS_COMPLEX_INIT_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_init_ref) +/* Nonzero if there is a non-trivial X::X(cv X&) for this class. */ +#define TYPE_HAS_COMPLEX_COPY_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_copy_ctor) -/* Nonzero if there is a user-defined default constructor for this class. */ +/* Nonzero if there is a non-trivial X::op=(X&&) for this class. */ +#define TYPE_HAS_COMPLEX_MOVE_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_move_assign) + +/* Nonzero if there is a non-trivial X::X(X&&) for this class. */ +#define TYPE_HAS_COMPLEX_MOVE_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_move_ctor) + +/* Nonzero if there is a non-trivial default constructor for this class. */ #define TYPE_HAS_COMPLEX_DFLT(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_dflt) /* Nonzero if TYPE has a trivial destructor. From [class.dtor]: @@ -3153,13 +3222,13 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) /* Nonzero for class type means that copy initialization of this type can use a bitwise copy. */ -#define TYPE_HAS_TRIVIAL_INIT_REF(NODE) \ - (TYPE_HAS_INIT_REF (NODE) && ! TYPE_HAS_COMPLEX_INIT_REF (NODE)) +#define TYPE_HAS_TRIVIAL_COPY_CTOR(NODE) \ + (TYPE_HAS_COPY_CTOR (NODE) && ! TYPE_HAS_COMPLEX_COPY_CTOR (NODE)) /* Nonzero for class type means that assignment of this type can use a bitwise copy. */ -#define TYPE_HAS_TRIVIAL_ASSIGN_REF(NODE) \ - (TYPE_HAS_ASSIGN_REF (NODE) && ! TYPE_HAS_COMPLEX_ASSIGN_REF (NODE)) +#define TYPE_HAS_TRIVIAL_COPY_ASSIGN(NODE) \ + (TYPE_HAS_COPY_ASSIGN (NODE) && ! TYPE_HAS_COMPLEX_COPY_ASSIGN (NODE)) /* Returns true if NODE is a pointer-to-data-member. */ #define TYPE_PTRMEM_P(NODE) \ @@ -3192,10 +3261,6 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define TYPE_REF_OBJ_P(NODE) \ (TREE_CODE (NODE) == REFERENCE_TYPE && TYPE_OBJ_P (TREE_TYPE (NODE))) -/* True if reference type NODE is an rvalue reference */ -#define TYPE_REF_IS_RVALUE(NODE) \ - TREE_LANG_FLAG_0 (REFERENCE_TYPE_CHECK (NODE)) - /* Returns true if NODE is a pointer to an object, or a pointer to void. Keep these checks in ascending tree code order. */ #define TYPE_PTROBV_P(NODE) \ @@ -3250,8 +3315,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) do { \ if (TYPE_LANG_SPECIFIC (NODE) == NULL) \ { \ - TYPE_LANG_SPECIFIC (NODE) = GGC_CNEWVAR \ - (struct lang_type, sizeof (struct lang_type_ptrmem)); \ + TYPE_LANG_SPECIFIC (NODE) = ggc_alloc_cleared_lang_type \ + (sizeof (struct lang_type_ptrmem)); \ TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.h.is_lang_type_class = 0; \ } \ TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.record = (VALUE); \ @@ -3337,8 +3402,6 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define ANON_UNION_TYPE_P(NODE) \ (TREE_CODE (NODE) == UNION_TYPE && ANON_AGGR_TYPE_P (NODE)) -#define UNKNOWN_TYPE LANG_TYPE - /* Define fields and accessors for nodes representing declared names. */ #define TYPE_WAS_ANONYMOUS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->was_anonymous) @@ -3738,6 +3801,12 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define FOR_EXPR(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 2) #define FOR_BODY(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 3) +/* RANGE_FOR_STMT accessors. These give access to the declarator, + expression and body of the statement, respectively. */ +#define RANGE_FOR_DECL(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 0) +#define RANGE_FOR_EXPR(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 1) +#define RANGE_FOR_BODY(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 2) + #define SWITCH_STMT_COND(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0) #define SWITCH_STMT_BODY(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1) #define SWITCH_STMT_TYPE(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 2) @@ -3831,7 +3900,8 @@ typedef enum special_function_kind { sfk_constructor, /* A constructor. */ sfk_copy_constructor, /* A copy constructor. */ sfk_move_constructor, /* A move constructor. */ - sfk_assignment_operator, /* An assignment operator. */ + sfk_copy_assignment, /* A copy assignment operator. */ + sfk_move_assignment, /* A move assignment operator. */ sfk_destructor, /* A destructor. */ sfk_complete_destructor, /* A destructor for complete objects. */ sfk_base_destructor, /* A destructor for base subobjects. */ @@ -3934,7 +4004,6 @@ typedef enum base_kind { /* For building calls to `delete'. */ extern GTY(()) tree integer_two_node; -extern GTY(()) tree integer_three_node; /* The number of function bodies which we are currently processing. (Zero if we are at namespace scope, one inside the body of a @@ -3948,6 +4017,7 @@ extern int function_depth; sizeof can be nested. */ extern int cp_unevaluated_operand; +extern tree cp_convert_range_for (tree, tree, tree); /* in pt.c */ @@ -4102,8 +4172,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; have already generated a temporary, such as reference initialization and the catch parameter. */ #define DIRECT_BIND (1 << 4) -/* User-defined conversions are not permitted. (Built-in conversions - are permitted.) */ +/* We're performing a user-defined conversion, so more user-defined + conversions are not permitted (only built-in conversions). */ #define LOOKUP_NO_CONVERSION (1 << 5) /* The user has explicitly called a destructor. (Therefore, we do not need to check that the object is non-NULL before calling the @@ -4126,10 +4196,21 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; /* We're inside an init-list, so narrowing conversions are ill-formed. */ #define LOOKUP_NO_NARROWING (LOOKUP_PREFER_RVALUE << 1) /* Avoid user-defined conversions for the first parameter of a copy - constructor. */ + constructor (or move constructor). */ #define LOOKUP_NO_COPY_CTOR_CONVERSION (LOOKUP_NO_NARROWING << 1) /* This is the first parameter of a copy constructor. */ #define LOOKUP_COPY_PARM (LOOKUP_NO_COPY_CTOR_CONVERSION << 1) +/* We only want to consider list constructors. */ +#define LOOKUP_LIST_ONLY (LOOKUP_COPY_PARM << 1) +/* Return after determining which function to call and checking access. + Used by sythesized_method_walk to determine which functions will + be called to initialize subobjects, in order to determine exception + specification and possible implicit delete. + This is kind of a hack, but since access control doesn't respect SFINAE + we can't just use tf_none to avoid access control errors, we need + another mechanism. Exiting early also avoids problems with trying + to perform argument conversions when the class isn't complete yet. */ +#define LOOKUP_SPECULATIVE (LOOKUP_LIST_ONLY << 1) #define LOOKUP_NAMESPACES_ONLY(F) \ (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES)) @@ -4355,14 +4436,14 @@ typedef enum cp_decl_spec { typedef struct cp_decl_specifier_seq { /* The number of times each of the keywords has been seen. */ unsigned specs[(int) ds_last]; + /* The location of the primary type. Mainly used for error + reporting. */ + location_t type_location; /* The primary type, if any, given by the decl-specifier-seq. Modifiers, like "short", "const", and "unsigned" are not reflected here. This field will be a TYPE, unless a typedef-name was used, in which case it will be a TYPE_DECL. */ tree type; - /* The location of the primary type. Mainly used for error - reporting. */ - location_t type_location; /* The attributes, if any, provided with the specifier sequence. */ tree attributes; /* If non-NULL, a built-in type that the user attempted to redefine @@ -4386,6 +4467,8 @@ typedef struct cp_decl_specifier_seq { BOOL_BITFIELD any_type_specifiers_p : 1; /* True iff "int" was explicitly provided. */ BOOL_BITFIELD explicit_int_p : 1; + /* True iff "__int128" was explicitly provided. */ + BOOL_BITFIELD explicit_int128_p : 1; /* True iff "char" was explicitly provided. */ BOOL_BITFIELD explicit_char_p : 1; } cp_decl_specifier_seq; @@ -4430,12 +4513,12 @@ struct cp_declarator { /* Whether we parsed an ellipsis (`...') just before the declarator, to indicate this is a parameter pack. */ BOOL_BITFIELD parameter_pack_p : 1; + location_t id_loc; /* Currently only set for cdk_id and cdk_function. */ /* Attributes that apply to this declarator. */ tree attributes; /* For all but cdk_id and cdk_error, the contained declarator. For cdk_id and cdk_error, guaranteed to be NULL. */ cp_declarator *declarator; - location_t id_loc; /* Currently only set for cdk_id and cdk_function. */ union { /* For identifiers. */ struct { @@ -4566,7 +4649,8 @@ extern void validate_conversion_obstack (void); extern tree build_vfield_ref (tree, tree); extern tree build_base_path (enum tree_code, tree, tree, int); -extern tree convert_to_base (tree, tree, bool, bool); +extern tree convert_to_base (tree, tree, bool, bool, + tsubst_flags_t); extern tree convert_to_base_statically (tree, tree); extern tree build_vtbl_ref (tree, tree); extern tree build_vfn_ref (tree, tree); @@ -4576,6 +4660,7 @@ extern void resort_type_method_vec (void *, void *, extern bool add_method (tree, tree, tree); extern bool currently_open_class (tree); extern tree currently_open_derived_class (tree); +extern tree current_nonlambda_class_type (void); extern tree finish_struct (tree, tree); extern void finish_struct_1 (tree); extern int resolves_to_fixed_type_p (tree, int *); @@ -4608,9 +4693,13 @@ extern void check_for_override (tree, tree); extern void push_class_stack (void); extern void pop_class_stack (void); extern bool type_has_user_nondefault_constructor (tree); +extern tree in_class_defaulted_default_constructor (tree); extern bool user_provided_p (tree); extern bool type_has_user_provided_constructor (tree); extern bool type_has_user_provided_default_constructor (tree); +extern bool type_has_virtual_destructor (tree); +extern bool type_has_move_constructor (tree); +extern bool type_has_move_assign (tree); extern void defaulted_late_check (tree); extern bool defaultable_fn_check (tree); extern void fixup_type_variants (tree); @@ -4626,8 +4715,8 @@ extern tree ocp_convert (tree, tree, int, int); extern tree cp_convert (tree, tree); extern tree cp_convert_and_check (tree, tree); extern tree cp_fold_convert (tree, tree); -extern tree convert_to_void (tree, const char */*implicit context*/, - tsubst_flags_t); +extern tree convert_to_void (tree, impl_conv_void, + tsubst_flags_t); extern tree convert_force (tree, tree, int); extern tree build_expr_type_conversion (int, tree, bool); extern tree type_promotes_to (tree); @@ -4644,6 +4733,7 @@ extern tree pushdecl_top_level_and_finish (tree, tree); extern tree check_for_out_of_scope_variable (tree); extern void print_other_binding_stack (struct cp_binding_level *); extern tree maybe_push_decl (tree); +extern tree current_decl_namespace (void); /* decl.c */ extern tree poplevel (int, int, int); @@ -4690,7 +4780,7 @@ extern tree xref_tag_from_type (tree, tree, tag_scope); extern bool xref_basetypes (tree, tree); extern tree start_enum (tree, tree, bool); extern void finish_enum (tree); -extern void build_enumerator (tree, tree, tree); +extern void build_enumerator (tree, tree, tree, location_t); extern tree lookup_enumerator (tree, tree); extern void start_preparsed_function (tree, tree, int); extern int start_function (cp_decl_specifier_seq *, const cp_declarator *, tree); @@ -4724,7 +4814,7 @@ extern tree check_elaborated_type_specifier (enum tag_types, tree, bool); extern void warn_extern_redeclared_static (tree, tree); extern tree cxx_comdat_group (tree); extern bool cp_missing_noreturn_ok_p (tree); -extern void initialize_artificial_var (tree, tree); +extern void initialize_artificial_var (tree, VEC(constructor_elt,gc) *); extern tree check_var_type (tree, tree); extern tree reshape_init (tree, tree); extern tree next_initializable_field (tree); @@ -4791,7 +4881,7 @@ extern const char *class_key_or_enum_as_string (tree); extern void print_instantiation_context (void); extern void maybe_warn_variadic_templates (void); extern void maybe_warn_cpp0x (cpp0x_warn_str str); -extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_CXXDIAG(3,4); +extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); /* in except.c */ extern void init_exception_processing (void); @@ -4801,14 +4891,25 @@ extern tree build_exc_ptr (void); extern tree build_throw (tree); extern int nothrow_libfn_p (const_tree); extern void check_handlers (tree); +extern tree finish_noexcept_expr (tree, tsubst_flags_t); +extern void perform_deferred_noexcept_checks (void); +extern bool nothrow_spec_p (const_tree); +extern bool type_noexcept_p (const_tree); +extern bool type_throw_all_p (const_tree); +extern tree build_noexcept_spec (tree, int); extern void choose_personality_routine (enum languages); extern tree eh_type_info (tree); extern tree begin_eh_spec_block (void); extern void finish_eh_spec_block (tree, tree); extern tree build_eh_type_type (tree); +extern tree cp_protect_cleanup_actions (void); /* in expr.c */ extern tree cplus_expand_constant (tree); +extern tree mark_rvalue_use (tree); +extern tree mark_lvalue_use (tree); +extern tree mark_type_use (tree); +extern void mark_exp_read (tree); /* friend.c */ extern int is_friend (tree, tree); @@ -4824,8 +4925,8 @@ extern tree build_aggr_init (tree, tree, int, extern int is_class_type (tree, int); extern tree get_type_value (tree); extern tree build_zero_init (tree, tree, bool); -extern tree build_value_init (tree); -extern tree build_value_init_noctor (tree); +extern tree build_value_init (tree, tsubst_flags_t); +extern tree build_value_init_noctor (tree, tsubst_flags_t); extern tree build_offset_ref (tree, tree, bool); extern tree build_new (VEC(tree,gc) **, tree, tree, VEC(tree,gc) **, int, @@ -4842,6 +4943,7 @@ extern tree create_temporary_var (tree); extern void initialize_vtbl_ptrs (tree); extern tree build_java_class_ref (tree); extern tree integral_constant_value (tree); +extern int diagnose_uninitialized_cst_or_ref_member (tree, bool, bool); /* in lex.c */ extern void cxx_dup_lang_specific_decl (tree); @@ -4850,6 +4952,7 @@ extern void yyungetc (int, int); extern tree unqualified_name_lookup_error (tree); extern tree unqualified_fn_lookup_error (tree); extern tree build_lang_decl (enum tree_code, tree, tree); +extern tree build_lang_decl_loc (location_t, enum tree_code, tree, tree); extern void retrofit_lang_decl (tree); extern tree copy_decl (tree); extern tree copy_type (tree); @@ -4864,15 +4967,19 @@ extern void init_method (void); extern tree make_thunk (tree, bool, tree, tree); extern void finish_thunk (tree); extern void use_thunk (tree, bool); +extern bool trivial_fn_p (tree); +extern bool maybe_explain_implicit_delete (tree); extern void synthesize_method (tree); extern tree lazily_declare_fn (special_function_kind, tree); extern tree skip_artificial_parms_for (const_tree, tree); extern int num_artificial_parms_for (const_tree); extern tree make_alias_for (tree, tree); -extern tree locate_copy (tree, void *); -extern tree locate_ctor (tree, void *); -extern tree locate_dtor (tree, void *); +extern tree get_copy_ctor (tree); +extern tree get_copy_assign (tree); +extern tree get_default_ctor (tree); +extern tree get_dtor (tree); +extern tree locate_ctor (tree); /* In optimize.c */ extern bool maybe_clone_body (tree); @@ -4975,6 +5082,7 @@ extern void pop_tinst_level (void); extern struct tinst_level *outermost_tinst_level(void); extern bool parameter_of_template_p (tree, tree); extern void init_template_processing (void); +extern void print_template_statistics (void); bool template_template_parameter_p (const_tree); extern bool primary_template_instantiation_p (const_tree); extern tree get_primary_template_innermost_parameters (const_tree); @@ -5012,6 +5120,7 @@ extern int accessible_p (tree, tree, bool); extern tree lookup_field_1 (tree, tree, bool); extern tree lookup_field (tree, tree, int, bool); extern int lookup_fnfields_1 (tree, tree); +extern tree lookup_fnfields_slot (tree, tree); extern int class_method_index_for_fn (tree, tree); extern tree lookup_fnfields (tree, tree, int); extern tree lookup_member (tree, tree, int, bool); @@ -5090,6 +5199,9 @@ extern void finish_for_init_stmt (tree); extern void finish_for_cond (tree, tree); extern void finish_for_expr (tree, tree); extern void finish_for_stmt (tree); +extern tree begin_range_for_stmt (void); +extern void finish_range_for_decl (tree, tree, tree); +extern void finish_range_for_stmt (tree); extern tree finish_break_stmt (void); extern tree finish_continue_stmt (void); extern tree begin_switch_stmt (void); @@ -5130,7 +5242,7 @@ extern tree finish_stmt_expr_expr (tree, tree); extern tree finish_stmt_expr (tree, bool); extern tree stmt_expr_value_expr (tree); bool empty_expr_stmt_p (tree); -extern tree perform_koenig_lookup (tree, VEC(tree,gc) *); +extern tree perform_koenig_lookup (tree, VEC(tree,gc) *, bool); extern tree finish_call_expr (tree, VEC(tree,gc) **, bool, bool, tsubst_flags_t); extern tree finish_increment_expr (tree, enum tree_code); @@ -5204,6 +5316,7 @@ extern tree add_capture (tree, tree, tree, bool, bool); extern tree add_default_capture (tree, tree, tree); extern void register_capture_members (tree); extern tree lambda_expr_this_capture (tree); +extern tree nonlambda_method_basetype (void); extern void maybe_add_lambda_conv_op (tree); /* in tree.c */ @@ -5222,12 +5335,12 @@ 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 trivially_copyable_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); -extern bool typedef_variant_p (tree); extern void cp_set_underlying_type (tree); extern tree copy_binfo (tree, tree, tree, tree *, int); @@ -5249,6 +5362,7 @@ extern tree hash_tree_cons (tree, tree, tree); extern tree hash_tree_chain (tree, tree); extern tree build_qualified_name (tree, tree, tree, bool); extern int is_overloaded_fn (tree); +extern tree get_fns (tree); extern tree get_first_fn (tree); extern tree ovl_cons (tree, tree); extern tree build_overload (tree, tree); @@ -5319,9 +5433,12 @@ extern tree condition_conversion (tree); extern tree require_complete_type (tree); extern tree complete_type (tree); extern tree complete_type_or_else (tree, tree); +extern tree complete_type_or_maybe_complain (tree, tree, tsubst_flags_t); extern int type_unknown_p (const_tree); -extern bool comp_except_specs (const_tree, const_tree, bool); +enum { ce_derived, ce_normal, ce_exact }; +extern bool comp_except_specs (const_tree, const_tree, int); extern bool comptypes (tree, tree, int); +extern bool same_type_ignoring_top_level_qualifiers_p (tree, tree); extern bool compparms (const_tree, const_tree); extern int comp_cv_qualification (const_tree, const_tree); extern int comp_cv_qual_signature (tree, tree); @@ -5340,8 +5457,12 @@ extern tree build_x_indirect_ref (tree, ref_operator, extern tree cp_build_indirect_ref (tree, ref_operator, tsubst_flags_t); extern tree build_array_ref (location_t, tree, tree); +extern tree cp_build_array_ref (location_t, tree, tree, + tsubst_flags_t); extern tree get_member_function_from_ptrfunc (tree *, tree); extern tree cp_build_function_call (tree, tree, tsubst_flags_t); +extern tree cp_build_function_call_nary (tree, tsubst_flags_t, ...) + ATTRIBUTE_SENTINEL; extern tree cp_build_function_call_vec (tree, VEC(tree,gc) **, tsubst_flags_t); extern tree build_x_binary_op (enum tree_code, tree, @@ -5356,7 +5477,8 @@ extern tree cp_build_unary_op (enum tree_code, tree, int, extern tree unary_complex_lvalue (enum tree_code, tree); extern tree build_x_conditional_expr (tree, tree, tree, tsubst_flags_t); -extern tree build_x_compound_expr_from_list (tree, const char *); +extern tree build_x_compound_expr_from_list (tree, expr_list_kind, + tsubst_flags_t); extern tree build_x_compound_expr_from_vec (VEC(tree,gc) *, const char *); extern tree build_x_compound_expr (tree, tree, tsubst_flags_t); extern tree build_compound_expr (location_t, tree, tree); @@ -5371,15 +5493,17 @@ extern tree build_x_modify_expr (tree, enum tree_code, tree, extern tree cp_build_modify_expr (tree, enum tree_code, tree, tsubst_flags_t); extern tree convert_for_initialization (tree, tree, tree, int, - const char *, tree, int, + impl_conv_rhs, tree, int, tsubst_flags_t); extern int comp_ptr_ttypes (tree, tree); extern bool comp_ptr_ttypes_const (tree, tree); extern bool error_type_p (const_tree); extern int ptr_reasonably_similar (const_tree, const_tree); -extern tree build_ptrmemfunc (tree, tree, int, bool); +extern tree build_ptrmemfunc (tree, tree, int, bool, + tsubst_flags_t); extern int cp_type_quals (const_tree); -extern bool cp_type_readonly (const_tree); +extern int type_memfn_quals (const_tree); +extern tree apply_memfn_quals (tree, cp_cv_quals); extern bool cp_has_mutable_p (const_tree); extern bool at_least_as_qualified_p (const_tree, const_tree); extern void cp_apply_type_quals_to_decl (int, tree); @@ -5391,6 +5515,7 @@ extern tree composite_pointer_type (tree, tree, tree, tree, composite_pointer_operation, tsubst_flags_t); extern tree merge_types (tree, tree); +extern tree strip_array_domain (tree); extern tree check_return_expr (tree, bool *); extern tree cp_build_binary_op (location_t, enum tree_code, tree, tree, @@ -5404,7 +5529,8 @@ extern tree non_reference (tree); extern tree lookup_anon_field (tree, tree); extern bool invalid_nonstatic_memfn_p (const_tree, tsubst_flags_t); extern tree convert_member_func_to_ptr (tree, tree); -extern tree convert_ptrmem (tree, tree, bool, bool); +extern tree convert_ptrmem (tree, tree, bool, bool, + tsubst_flags_t); extern int lvalue_or_else (tree, enum lvalue_use, tsubst_flags_t); extern void check_template_keyword (tree); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 6fcb1f0a19a..ab2b6bf2d70 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1,6 +1,6 @@ /* Language-level data type conversion for GNU C++. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) @@ -176,7 +176,7 @@ cp_convert_to_pointer (tree type, tree expr) else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))) return convert_ptrmem (type, expr, /*allow_inverse_p=*/false, - /*c_cast_p=*/false); + /*c_cast_p=*/false, tf_warning_or_error); else if (TYPE_PTRMEMFUNC_P (intype)) { if (!warn_pmf2ptr) @@ -196,11 +196,11 @@ cp_convert_to_pointer (tree type, tree expr) return error_mark_node; } - if (integer_zerop (expr)) + if (null_ptr_cst_p (expr)) { if (TYPE_PTRMEMFUNC_P (type)) return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0, - /*c_cast_p=*/false); + /*c_cast_p=*/false, tf_warning_or_error); if (TYPE_PTRMEM_P (type)) { @@ -481,7 +481,7 @@ convert_to_reference (tree reftype, tree expr, int convtype, else { rval = convert_for_initialization (NULL_TREE, type, expr, flags, - "converting", 0, 0, + ICR_CONVERTING, 0, 0, tf_warning_or_error); if (rval == NULL_TREE || rval == error_mark_node) return rval; @@ -610,6 +610,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags) } e = integral_constant_value (e); + if (error_operand_p (e)) + return error_mark_node; if (MAYBE_CLASS_TYPE_P (type) && (convtype & CONV_FORCE_TEMP)) /* We need a new temporary; don't take this shortcut. */; @@ -649,7 +651,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags) if (code == VOID_TYPE && (convtype & CONV_STATIC)) { - e = convert_to_void (e, /*implicit=*/NULL, tf_warning_or_error); + e = convert_to_void (e, ICV_CAST, tf_warning_or_error); return e; } @@ -680,7 +682,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags) the original value is within the range of the enumeration values. Otherwise, the resulting enumeration value is unspecified. */ - if (TREE_CODE (expr) == INTEGER_CST && !int_fits_type_p (expr, type)) + if (TREE_CODE (expr) == INTEGER_CST + && !int_fits_type_p (expr, ENUM_UNDERLYING_TYPE (type))) warning (OPT_Wconversion, "the result of the conversion is unspecified because " "%qE is outside the range of type %qT", @@ -701,6 +704,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags) return fold_if_not_in_template (convert_to_integer (type, e)); } + if (NULLPTR_TYPE_P (type) && e && null_ptr_cst_p (e)) + return nullptr_node; if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type)) return fold_if_not_in_template (cp_convert_to_pointer (type, e)); if (code == VECTOR_TYPE) @@ -809,17 +814,36 @@ ocp_convert (tree type, tree expr, int convtype, int flags) make it impossible to ignore the reference return value from functions. We issue warnings in the confusing cases. - IMPLICIT is non-NULL iff an expression is being implicitly converted; it - is NULL when the user is explicitly converting an expression to void via - a cast. When non-NULL, IMPLICIT is a string indicating the context of - the implicit conversion. */ + The IMPLICIT is ICV_CAST when the user is explicitly converting an expression + to void via a cast. If an expression is being implicitly converted, IMPLICIT + indicates the context of the implicit conversion. */ tree -convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) +convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) { if (expr == error_mark_node || TREE_TYPE (expr) == error_mark_node) return error_mark_node; + + if (implicit == ICV_CAST) + mark_exp_read (expr); + else + { + tree exprv = expr; + + while (TREE_CODE (exprv) == COMPOUND_EXPR) + exprv = TREE_OPERAND (exprv, 1); + if (DECL_P (exprv) + || handled_component_p (exprv) + || TREE_CODE (exprv) == INDIRECT_REF) + /* Expr is not being 'used' here, otherwise we whould have + called mark_{rl}value_use use here, which would have in turn + called mark_exp_read. Rather, we call mark_exp_read directly + to avoid some warnings when + -Wunused-but-set-{variable,parameter} is in effect. */ + mark_exp_read (exprv); + } + if (!TREE_TYPE (expr)) return expr; if (invalid_nonstatic_memfn_p (expr, complain)) @@ -840,12 +864,17 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) tree op1 = TREE_OPERAND (expr,1); tree op2 = TREE_OPERAND (expr,2); bool side_effects = TREE_SIDE_EFFECTS (op1) || TREE_SIDE_EFFECTS (op2); - tree new_op1 = convert_to_void - (op1, (implicit && !side_effects - ? "second operand of conditional" : NULL), complain); - tree new_op2 = convert_to_void - (op2, (implicit && !side_effects - ? "third operand of conditional" : NULL), complain); + tree new_op1, new_op2; + if (implicit != ICV_CAST && !side_effects) + { + new_op1 = convert_to_void (op1, ICV_SECOND_OF_COND, complain); + new_op2 = convert_to_void (op2, ICV_THIRD_OF_COND, complain); + } + else + { + new_op1 = convert_to_void (op1, ICV_CAST, complain); + new_op2 = convert_to_void (op2, ICV_CAST, complain); + } expr = build3 (COND_EXPR, TREE_TYPE (new_op1), TREE_OPERAND (expr, 0), new_op1, new_op2); @@ -856,9 +885,11 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) { /* The second part of a compound expr contains the value. */ tree op1 = TREE_OPERAND (expr,1); - tree new_op1 = convert_to_void - (op1, (implicit && !TREE_NO_WARNING (expr) - ? "right-hand operand of comma" : NULL), complain); + tree new_op1; + if (implicit != ICV_CAST && !TREE_NO_WARNING (expr)) + new_op1 = convert_to_void (op1, ICV_RIGHT_OF_COMMA, complain); + else + new_op1 = convert_to_void (op1, ICV_CAST, complain); if (new_op1 != op1) { @@ -890,18 +921,133 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) if (is_volatile && !is_complete) { if (complain & tf_warning) - warning (0, "object of incomplete type %qT will not be accessed in %s", - type, implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object of incomplete type %qT", type); + break; + case ICV_SECOND_OF_COND: + warning (0, "indirection will not access object of " + "incomplete type %qT in second operand " + "of conditional expression", type); + break; + case ICV_THIRD_OF_COND: + warning (0, "indirection will not access object of " + "incomplete type %qT in third operand " + "of conditional expression", type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "indirection will not access object of " + "incomplete type %qT in right operand of " + "comma operator", type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "indirection will not access object of " + "incomplete type %qT in left operand of " + "comma operator", type); + break; + case ICV_STATEMENT: + warning (0, "indirection will not access object of " + "incomplete type %qT in statement", type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "indirection will not access object of " + "incomplete type %qT in for increment " + "expression", type); + break; + default: + gcc_unreachable (); + } } /* Don't load the value if this is an implicit dereference, or if the type needs to be handled by ctors/dtors. */ - else if (is_volatile && (is_reference || TREE_ADDRESSABLE (type))) + else if (is_volatile && is_reference) { if (complain & tf_warning) - warning (0, "object of type %qT will not be accessed in %s", - TREE_TYPE (TREE_OPERAND (expr, 0)), - implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object of type %qT", type); + break; + case ICV_SECOND_OF_COND: + warning (0, "implicit dereference will not access object " + "of type %qT in second operand of " + "conditional expression", type); + break; + case ICV_THIRD_OF_COND: + warning (0, "implicit dereference will not access object " + "of type %qT in third operand of " + "conditional expression", type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "implicit dereference will not access object " + "of type %qT in right operand of " + "comma operator", type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "implicit dereference will not access object " + "of type %qT in left operand of comma operator", + type); + break; + case ICV_STATEMENT: + warning (0, "implicit dereference will not access object " + "of type %qT in statement", type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "implicit dereference will not access object " + "of type %qT in for increment expression", + type); + break; + default: + gcc_unreachable (); + } } + else if (is_volatile && TREE_ADDRESSABLE (type)) + { + if (complain & tf_warning) + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object of non-trivially-copyable type %qT", + type); + break; + case ICV_SECOND_OF_COND: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in second " + "operand of conditional expression", type); + break; + case ICV_THIRD_OF_COND: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in third " + "operand of conditional expression", type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in right " + "operand of comma operator", type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in left " + "operand of comma operator", type); + break; + case ICV_STATEMENT: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in statement", + type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in for " + "increment expression", type); + break; + default: + gcc_unreachable (); + } + } if (is_reference || !is_volatile || !is_complete || TREE_ADDRESSABLE (type)) { /* Emit a warning (if enabled) when the "effect-less" INDIRECT_REF @@ -911,7 +1057,7 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) - automatic dereferencing of references, since the user cannot control it. (See also warn_if_unused_value() in stmt.c.) */ if (warn_unused_value - && implicit + && implicit != ICV_CAST && (complain & tf_warning) && !TREE_NO_WARNING (expr) && !is_reference) @@ -929,8 +1075,45 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) int is_complete = COMPLETE_TYPE_P (complete_type (type)); if (TYPE_VOLATILE (type) && !is_complete && (complain & tf_warning)) - warning (0, "object %qE of incomplete type %qT will not be accessed in %s", - expr, type, implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object %qE of incomplete type %qT", expr, type); + break; + case ICV_SECOND_OF_COND: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in second operand of " + "conditional expression", expr, type); + break; + case ICV_THIRD_OF_COND: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in third operand of " + "conditional expression", expr, type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in right operand of comma operator", + expr, type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in left operand of comma operator", + expr, type); + break; + case ICV_STATEMENT: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in statement", expr, type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in for increment expression", + expr, type); + break; + default: + gcc_unreachable (); + } + break; } @@ -969,18 +1152,81 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) /* [over.over] enumerates the places where we can take the address of an overloaded function, and this is not one of them. */ if (complain & tf_error) - error ("%s cannot resolve address of overloaded function", - implicit ? implicit : "void cast"); + switch (implicit) + { + case ICV_CAST: + error ("conversion to void " + "cannot resolve address of overloaded function"); + break; + case ICV_SECOND_OF_COND: + error ("second operand of conditional expression " + "cannot resolve address of overloaded function"); + break; + case ICV_THIRD_OF_COND: + error ("third operand of conditional expression " + "cannot resolve address of overloaded function"); + break; + case ICV_RIGHT_OF_COMMA: + error ("right operand of comma operator " + "cannot resolve address of overloaded function"); + break; + case ICV_LEFT_OF_COMMA: + error ("left operand of comma operator " + "cannot resolve address of overloaded function"); + break; + case ICV_STATEMENT: + error ("statement " + "cannot resolve address of overloaded function"); + break; + case ICV_THIRD_IN_FOR: + error ("for increment expression " + "cannot resolve address of overloaded function"); + break; + } else return error_mark_node; expr = void_zero_node; } - else if (implicit && probe == expr && is_overloaded_fn (probe)) + else if (implicit != ICV_CAST && probe == expr && is_overloaded_fn (probe)) { /* Only warn when there is no &. */ if (complain & tf_warning) - warning (OPT_Waddress, "%s is a reference, not call, to function %qE", - implicit, expr); + switch (implicit) + { + case ICV_SECOND_OF_COND: + warning (OPT_Waddress, + "second operand of conditional expression " + "is a reference, not call, to function %qE", expr); + break; + case ICV_THIRD_OF_COND: + warning (OPT_Waddress, + "third operand of conditional expression " + "is a reference, not call, to function %qE", expr); + break; + case ICV_RIGHT_OF_COMMA: + warning (OPT_Waddress, + "right operand of comma operator " + "is a reference, not call, to function %qE", expr); + break; + case ICV_LEFT_OF_COMMA: + warning (OPT_Waddress, + "left operand of comma operator " + "is a reference, not call, to function %qE", expr); + break; + case ICV_STATEMENT: + warning (OPT_Waddress, + "statement is a reference, not call, to function %qE", + expr); + break; + case ICV_THIRD_IN_FOR: + warning (OPT_Waddress, + "for increment expression " + "is a reference, not call, to function %qE", expr); + break; + default: + gcc_unreachable (); + } + if (TREE_CODE (expr) == COMPONENT_REF) expr = TREE_OPERAND (expr, 0); } @@ -988,7 +1234,7 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr))) { - if (implicit + if (implicit != ICV_CAST && warn_unused_value && !TREE_NO_WARNING (expr) && !processing_template_decl) @@ -997,7 +1243,35 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) been explicitly cast to void, so we must do so here. */ if (!TREE_SIDE_EFFECTS (expr)) { if (complain & tf_warning) - warning (OPT_Wunused_value, "%s has no effect", implicit); + switch (implicit) + { + case ICV_SECOND_OF_COND: + warning (OPT_Wunused_value, + "second operand of conditional expression has no effect"); + break; + case ICV_THIRD_OF_COND: + warning (OPT_Wunused_value, + "third operand of conditional expression has no effect"); + break; + case ICV_RIGHT_OF_COMMA: + warning (OPT_Wunused_value, + "right operand of comma operator has no effect"); + break; + case ICV_LEFT_OF_COMMA: + warning (OPT_Wunused_value, + "left operand of comma operator has no effect"); + break; + case ICV_STATEMENT: + warning (OPT_Wunused_value, + "statement has no effect"); + break; + case ICV_THIRD_IN_FOR: + warning (OPT_Wunused_value, + "for increment expression has no effect"); + break; + default: + gcc_unreachable (); + } } else { @@ -1102,7 +1376,7 @@ convert_force (tree type, tree expr, int convtype) && TYPE_PTRMEMFUNC_P (type)) /* compatible pointer to member functions. */ return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1, - /*c_cast_p=*/1); + /*c_cast_p=*/1, tf_warning_or_error); return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL); } @@ -1194,7 +1468,7 @@ build_expr_type_conversion (int desires, tree expr, bool complain) /* The code for conversions from class type is currently only used for delete expressions. Other expressions are handled by build_new_op. */ - if (!complete_type_or_else (basetype, expr)) + if (!complete_type_or_maybe_complain (basetype, expr, complain)) return error_mark_node; if (!TYPE_HAS_CONVERSION (basetype)) return NULL_TREE; @@ -1309,6 +1583,8 @@ type_promotes_to (tree type) int precision = MAX (TYPE_PRECISION (type), TYPE_PRECISION (integer_type_node)); tree totype = c_common_type_for_size (precision, 0); + if (TREE_CODE (type) == ENUMERAL_TYPE) + type = ENUM_UNDERLYING_TYPE (type); if (TYPE_UNSIGNED (type) && ! int_fits_type_p (TYPE_MAX_VALUE (type), totype)) type = c_common_type_for_size (precision, 1); diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index 5ef84fe5217..24e282475cb 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -1,6 +1,6 @@ /* Implementation of subroutines for the GNU C++ pretty-printer. Copyright (C) 2003, 2004, 2005, 2007, 2008, - 2009 Free Software Foundation, Inc. + 2009, 2010 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> This file is part of GCC. @@ -23,10 +23,10 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" -#include "real.h" #include "intl.h" -#include "cxx-pretty-print.h" #include "cp-tree.h" +#include "cxx-pretty-print.h" +#include "tree-pretty-print.h" #include "toplev.h" /* Translate if being used for diagnostics, but not for dump files or @@ -339,6 +339,14 @@ pp_cxx_constant (cxx_pretty_printer *pp, tree t) } break; + case INTEGER_CST: + if (NULLPTR_TYPE_P (TREE_TYPE (t))) + { + pp_string (pp, "nullptr"); + break; + } + /* else fall through. */ + default: pp_c_constant (pp_c_base (pp), t); break; @@ -783,6 +791,14 @@ pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t) pp_unary_expression (pp, TREE_OPERAND (t, 0)); break; + case NOEXCEPT_EXPR: + pp_cxx_ws_string (pp, "noexcept"); + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + pp_cxx_expression (pp, TREE_OPERAND (t, 0)); + pp_cxx_right_paren (pp); + break; + case UNARY_PLUS_EXPR: pp_plus (pp); pp_cxx_cast_expression (pp, TREE_OPERAND (t, 0)); @@ -1053,6 +1069,7 @@ pp_cxx_expression (cxx_pretty_printer *pp, tree t) case SIZEOF_EXPR: case ALIGNOF_EXPR: + case NOEXCEPT_EXPR: pp_cxx_unary_expression (pp, t); break; @@ -1170,16 +1187,6 @@ pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t) pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t)); break; - case RECORD_TYPE: - if (TYPE_PTRMEMFUNC_P (t)) - { - tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t); - pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm))); - pp_cxx_whitespace (pp); - pp_cxx_ptr_operator (pp, t); - } - break; - case FUNCTION_DECL: /* Constructors don't have return types. And conversion functions do not have a type-specifier in their return types. */ @@ -1275,6 +1282,17 @@ pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t) pp_cxx_right_paren (pp); break; + case RECORD_TYPE: + if (TYPE_PTRMEMFUNC_P (t)) + { + tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t); + pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm))); + pp_cxx_whitespace (pp); + pp_cxx_ptr_operator (pp, t); + break; + } + /* else fall through */ + default: if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t))) pp_c_specifier_qualifier_list (pp_c_base (pp), t); @@ -1409,8 +1427,17 @@ pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t) tree ex_spec = TYPE_RAISES_EXCEPTIONS (t); bool need_comma = false; - if (!TYPE_NOTHROW_P (t) && ex_spec == NULL) + if (ex_spec == NULL) return; + if (TREE_PURPOSE (ex_spec)) + { + pp_cxx_ws_string (pp, "noexcept"); + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + pp_cxx_expression (pp, TREE_PURPOSE (ex_spec)); + pp_cxx_right_paren (pp); + return; + } pp_cxx_ws_string (pp, "throw"); pp_cxx_left_paren (pp); for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec)) @@ -1894,6 +1921,23 @@ pp_cxx_statement (cxx_pretty_printer *pp, tree t) pp_needs_newline (pp) = true; break; + case RANGE_FOR_STMT: + pp_cxx_ws_string (pp, "for"); + pp_space (pp); + pp_cxx_left_paren (pp); + pp_cxx_statement (pp, RANGE_FOR_DECL (t)); + pp_space (pp); + pp_needs_newline (pp) = false; + pp_colon (pp); + pp_space (pp); + pp_cxx_statement (pp, RANGE_FOR_EXPR (t)); + pp_cxx_right_paren (pp); + pp_newline_and_indent (pp, 3); + pp_cxx_statement (pp, FOR_BODY (t)); + pp_indentation (pp) -= 3; + pp_needs_newline (pp) = true; + break; + /* jump-statement: goto identifier; continue ; diff --git a/gcc/cp/cxx-pretty-print.h b/gcc/cp/cxx-pretty-print.h index a88d4c5ccdb..5a51f44bdb8 100644 --- a/gcc/cp/cxx-pretty-print.h +++ b/gcc/cp/cxx-pretty-print.h @@ -21,7 +21,7 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_CXX_PRETTY_PRINT_H #define GCC_CXX_PRETTY_PRINT_H -#include "c-pretty-print.h" +#include "c-family/c-pretty-print.h" #undef pp_c_base #define pp_c_base(PP) (&(PP)->c_base) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a308d64d9ff..3d1420a23eb 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 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -33,29 +33,35 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "rtl.h" -#include "expr.h" #include "flags.h" #include "cp-tree.h" +#include "tree-iterator.h" #include "tree-inline.h" #include "decl.h" #include "intl.h" #include "output.h" -#include "except.h" #include "toplev.h" #include "hashtab.h" #include "tm_p.h" #include "target.h" -#include "c-common.h" -#include "c-pragma.h" +#include "c-family/c-common.h" +#include "c-family/c-pragma.h" #include "diagnostic.h" #include "intl.h" #include "debug.h" #include "timevar.h" -#include "tree-flow.h" #include "pointer-set.h" +#include "splay-tree.h" #include "plugin.h" +/* Possible cases of bad specifiers type used by bad_specifiers. */ +enum bad_spec_place { + BSP_VAR, /* variable */ + BSP_PARM, /* parameter */ + BSP_TYPE, /* type */ + BSP_FIELD /* field */ +}; + static tree grokparms (tree parmlist, tree *); static const char *redeclaration_error_message (tree, tree); @@ -71,7 +77,7 @@ static void record_unknown_type (tree, const char *); static tree builtin_function_1 (tree, tree, bool); static tree build_library_fn_1 (tree, enum tree_code, tree); static int member_function_or_else (tree, tree, enum overload_flags); -static void bad_specifiers (tree, const char *, int, int, int, int, +static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int, int); static void check_for_uninitialized_const_var (tree); static hashval_t typename_hash (const void *); @@ -90,6 +96,7 @@ static void check_function_type (tree, tree); static void finish_constructor_body (void); static void begin_destructor_body (void); static void finish_destructor_body (void); +static void record_key_method_defined (tree); static tree create_array_type_for_decl (tree, tree, tree); static tree get_atexit_node (void); static tree get_dso_handle_node (void); @@ -162,9 +169,9 @@ tree static_aggregates; /* -- end of C++ */ -/* A node for the integer constants 2, and 3. */ +/* A node for the integer constant 2. */ -tree integer_two_node, integer_three_node; +tree integer_two_node; /* Used only for jumps to as-yet undefined labels, since jumps to defined labels can have their validity checked immediately. */ @@ -203,9 +210,9 @@ struct GTY(()) named_label_entry { defined, or the inner scope popped. These are the decls that will be skipped when jumping to the label. */ tree names_in_scope; - /* A tree list of all decls from all binding levels that would be + /* A vector of all decls from all binding levels that would be crossed by a backward branch to the label. */ - tree bad_decls; + VEC(tree,gc) *bad_decls; /* A list of uses of the label, before the label is defined. */ struct named_label_use_entry *uses; @@ -237,11 +244,18 @@ VEC(tree, gc) *deferred_mark_used_calls; enum deprecated_states deprecated_state = DEPRECATED_NORMAL; -/* A TREE_LIST of VAR_DECLs. The TREE_PURPOSE is a RECORD_TYPE or - UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type. At the - time the VAR_DECL was declared, the type was incomplete. */ +/* A list of VAR_DECLs whose type was incomplete at the time the + variable was declared. */ + +typedef struct GTY(()) incomplete_var_d { + tree decl; + tree incomplete_type; +} incomplete_var; -static GTY(()) tree incomplete_vars; +DEF_VEC_O(incomplete_var); +DEF_VEC_ALLOC_O(incomplete_var,gc); + +static GTY(()) VEC(incomplete_var,gc) *incomplete_vars; /* Returns the kind of template specialization we are currently processing, given that it's declaration contained N_CLASS_SCOPES @@ -379,7 +393,7 @@ pop_labels_1 (void **slot, void *data) /* Put the labels into the "variables" of the top-level block, so debugger can see them. */ - TREE_CHAIN (ent->label_decl) = BLOCK_VARS (block); + DECL_CHAIN (ent->label_decl) = BLOCK_VARS (block); BLOCK_VARS (block) = ent->label_decl; htab_clear_slot (named_labels, slot); @@ -460,9 +474,9 @@ poplevel_named_label_1 (void **slot, void *data) { tree decl; - for (decl = ent->names_in_scope; decl; decl = TREE_CHAIN (decl)) + for (decl = ent->names_in_scope; decl; decl = DECL_CHAIN (decl)) if (decl_jump_unsafe (decl)) - ent->bad_decls = tree_cons (NULL, decl, ent->bad_decls); + VEC_safe_push (tree, gc, ent->bad_decls, decl); ent->binding_level = obl; ent->names_in_scope = obl->names; @@ -498,6 +512,10 @@ poplevel_named_label_1 (void **slot, void *data) return 1; } +/* Saved errorcount to avoid -Wunused-but-set-{parameter,variable} warnings + when errors were reported, except for -Werror-unused-but-set-*. */ +static int unused_but_set_errorcount; + /* Exit a binding level. Pop the level off, and restore the state of the identifier-decl mappings that were in effect when this level was entered. @@ -525,6 +543,8 @@ poplevel (int keep, int reverse, int functionbody) tree decl; int leaving_for_scope; scope_kind kind; + unsigned ix; + cp_label_binding *label_bind; timevar_push (TV_NAME_LOOKUP); restart: @@ -589,14 +609,28 @@ poplevel (int keep, int reverse, int functionbody) = current_binding_level->kind == sk_for && flag_new_for_scope == 1; /* Before we remove the declarations first check for unused variables. */ - if (warn_unused_variable + if ((warn_unused_variable || warn_unused_but_set_variable) && !processing_template_decl) for (decl = getdecls (); decl; decl = TREE_CHAIN (decl)) if (TREE_CODE (decl) == VAR_DECL - && ! TREE_USED (decl) + && (! TREE_USED (decl) || !DECL_READ_P (decl)) && ! DECL_IN_SYSTEM_HEADER (decl) && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)) - warning (OPT_Wunused_variable, "unused variable %q+D", decl); + { + if (! TREE_USED (decl)) + warning (OPT_Wunused_variable, "unused variable %q+D", decl); + else if (DECL_CONTEXT (decl) == current_function_decl + && TREE_TYPE (decl) != error_mark_node + && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE + && errorcount == unused_but_set_errorcount + && (!CLASS_TYPE_P (TREE_TYPE (decl)) + || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))) + { + warning (OPT_Wunused_but_set_variable, + "variable %q+D set but not used", decl); + unused_but_set_errorcount = errorcount; + } + } /* Remove declarations for all the DECLs in this level. */ for (link = decls; link; link = TREE_CHAIN (link)) @@ -655,10 +689,9 @@ poplevel (int keep, int reverse, int functionbody) /* Add it to the list of dead variables in the next outermost binding to that we can remove these when we leave that binding. */ - current_binding_level->level_chain->dead_vars_from_for - = tree_cons (NULL_TREE, link, - current_binding_level->level_chain-> - dead_vars_from_for); + VEC_safe_push (tree, gc, + current_binding_level->level_chain->dead_vars_from_for, + link); /* Although we don't pop the cxx_binding, we do clear its SCOPE since the scope is going away now. */ @@ -687,9 +720,9 @@ poplevel (int keep, int reverse, int functionbody) /* Remove declarations for any `for' variables from inner scopes that we kept around. */ - for (link = current_binding_level->dead_vars_from_for; - link; link = TREE_CHAIN (link)) - pop_binding (DECL_NAME (TREE_VALUE (link)), TREE_VALUE (link)); + FOR_EACH_VEC_ELT_REVERSE (tree, current_binding_level->dead_vars_from_for, + ix, decl) + pop_binding (DECL_NAME (decl), decl); /* Restore the IDENTIFIER_TYPE_VALUEs. */ for (link = current_binding_level->type_shadowed; @@ -697,10 +730,10 @@ poplevel (int keep, int reverse, int functionbody) SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link)); /* Restore the IDENTIFIER_LABEL_VALUEs for local labels. */ - for (link = current_binding_level->shadowed_labels; - link; - link = TREE_CHAIN (link)) - pop_local_label (TREE_VALUE (link), TREE_PURPOSE (link)); + FOR_EACH_VEC_ELT_REVERSE (cp_label_binding, + current_binding_level->shadowed_labels, + ix, label_bind) + pop_local_label (label_bind->label, label_bind->prev_value); /* There may be OVERLOADs (wrapped in TREE_LISTs) on the BLOCK_VARs list if a `using' declaration put them there. The debugging @@ -717,7 +750,7 @@ poplevel (int keep, int reverse, int functionbody) if (TREE_CODE (*d) == TREE_LIST) *d = TREE_CHAIN (*d); else - d = &TREE_CHAIN (*d); + d = &DECL_CHAIN (*d); } } @@ -790,7 +823,7 @@ walk_namespaces_r (tree name_space, walk_namespaces_fn f, void* data) result |= (*f) (name_space, data); - for (; current; current = TREE_CHAIN (current)) + for (; current; current = DECL_CHAIN (current)) result |= walk_namespaces_r (current, f, data); return result; @@ -1086,10 +1119,10 @@ check_redeclaration_exception_specification (tree new_decl, if ((pedantic || ! DECL_IN_SYSTEM_HEADER (old_decl)) && ! DECL_IS_BUILTIN (old_decl) && flag_exceptions - && !comp_except_specs (new_exceptions, old_exceptions, - /*exact=*/true)) + && !comp_except_specs (new_exceptions, old_exceptions, ce_normal)) { - error ("declaration of %qF throws different exceptions", new_decl); + error ("declaration of %qF has a different exception specifier", + new_decl); error ("from previous declaration %q+F", old_decl); } } @@ -1268,7 +1301,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* Even if the types match, prefer the new declarations type for built-ins which have not been explicitly declared, for exception lists, etc... */ - else if (DECL_ANTICIPATED (olddecl)) + else if (DECL_IS_BUILTIN (olddecl)) { tree type = TREE_TYPE (newdecl); tree attribs = (*targetm.merge_type_attributes) @@ -1694,7 +1727,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) DECL_ARGUMENTS (old_result) = DECL_ARGUMENTS (new_result); for (parm = DECL_ARGUMENTS (old_result); parm; - parm = TREE_CHAIN (parm)) + parm = DECL_CHAIN (parm)) DECL_CONTEXT (parm) = old_result; } } @@ -1929,6 +1962,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (DECL_VIRTUAL_P (newdecl)) DECL_THUNKS (newdecl) = DECL_THUNKS (olddecl); } + /* Only variables have this field. */ + else if (TREE_CODE (newdecl) == VAR_DECL + && VAR_HAD_UNKNOWN_BOUND (olddecl)) + SET_VAR_HAD_UNKNOWN_BOUND (newdecl); } if (TREE_CODE (newdecl) == FUNCTION_DECL) @@ -1940,7 +1977,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) for (oldarg = DECL_ARGUMENTS(olddecl), newarg = DECL_ARGUMENTS(newdecl); oldarg && newarg; - oldarg = TREE_CHAIN(oldarg), newarg = TREE_CHAIN(newarg)) { + oldarg = DECL_CHAIN(oldarg), newarg = DECL_CHAIN(newarg)) { DECL_ATTRIBUTES (newarg) = (*targetm.merge_decl_attributes) (oldarg, newarg); DECL_ATTRIBUTES (oldarg) = DECL_ATTRIBUTES (newarg); @@ -2004,7 +2041,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* Update newdecl's parms to point at olddecl. */ for (parm = DECL_ARGUMENTS (newdecl); parm; - parm = TREE_CHAIN (parm)) + parm = DECL_CHAIN (parm)) DECL_CONTEXT (parm) = olddecl; if (! types_match) @@ -2077,6 +2114,10 @@ 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. */ + DECL_USER_ALIGN (olddecl) = DECL_USER_ALIGN (newdecl); + if (TREE_CODE (newdecl) == FIELD_DECL) + DECL_PACKED (olddecl) = DECL_PACKED (newdecl); /* The DECL_LANG_SPECIFIC information in OLDDECL will be replaced with that from NEWDECL below. */ @@ -2092,6 +2133,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) TREE_USED (newdecl) = 1; else if (TREE_USED (newdecl)) TREE_USED (olddecl) = 1; + if (TREE_CODE (newdecl) == VAR_DECL) + { + if (DECL_READ_P (olddecl)) + DECL_READ_P (newdecl) = 1; + else if (DECL_READ_P (newdecl)) + DECL_READ_P (olddecl) = 1; + } if (DECL_PRESERVE_P (olddecl)) DECL_PRESERVE_P (newdecl) = 1; else if (DECL_PRESERVE_P (newdecl)) @@ -2420,7 +2468,7 @@ make_label_decl (tree id, int local_p) /* Record this label on the list of labels used in this function. We do this before calling make_label_decl so that we get the IDENTIFIER_LABEL_VALUE before the new label is declared. */ - ent = GGC_CNEW (struct named_label_entry); + ent = ggc_alloc_cleared_named_label_entry (); ent->label_decl = decl; slot = htab_find_slot (named_labels, ent, INSERT); @@ -2461,16 +2509,17 @@ lookup_label (tree id) tree declare_local_label (tree id) { - tree decl, shadow; + tree decl; + cp_label_binding *bind; /* Add a new entry to the SHADOWED_LABELS list so that when we leave this scope we can restore the old value of IDENTIFIER_TYPE_VALUE. */ - shadow = tree_cons (IDENTIFIER_LABEL_VALUE (id), NULL_TREE, - current_binding_level->shadowed_labels); - current_binding_level->shadowed_labels = shadow; + bind = VEC_safe_push (cp_label_binding, gc, + current_binding_level->shadowed_labels, NULL); + bind->prev_value = IDENTIFIER_LABEL_VALUE (id); decl = make_label_decl (id, /*local_p=*/1); - TREE_VALUE (shadow) = decl; + bind->label = decl; return decl; } @@ -2543,7 +2592,7 @@ check_previous_goto_1 (tree decl, struct cp_binding_level* level, tree names, tree new_decls, old_decls = (b == level ? names : NULL_TREE); for (new_decls = b->names; new_decls != old_decls; - new_decls = TREE_CHAIN (new_decls)) + new_decls = DECL_CHAIN (new_decls)) { int problem = decl_jump_unsafe (new_decls); if (! problem) @@ -2614,6 +2663,7 @@ check_goto (tree decl) struct named_label_entry *ent, dummy; bool saw_catch = false, identified = false; tree bad; + unsigned ix; /* We can't know where a computed goto is jumping. So we assume that it's OK. */ @@ -2640,7 +2690,7 @@ check_goto (tree decl) && ent->uses->names_in_scope == current_binding_level->names) return; - new_use = GGC_NEW (struct named_label_use_entry); + new_use = ggc_alloc_named_label_use_entry (); new_use->binding_level = current_binding_level; new_use->names_in_scope = current_binding_level->names; new_use->o_goto_locus = input_location; @@ -2652,29 +2702,28 @@ check_goto (tree decl) } if (ent->in_try_scope || ent->in_catch_scope - || ent->in_omp_scope || ent->bad_decls) + || ent->in_omp_scope || !VEC_empty (tree, ent->bad_decls)) { permerror (input_location, "jump to label %q+D", decl); permerror (input_location, " from here"); identified = true; } - for (bad = ent->bad_decls; bad; bad = TREE_CHAIN (bad)) + FOR_EACH_VEC_ELT (tree, ent->bad_decls, ix, bad) { - tree b = TREE_VALUE (bad); - int u = decl_jump_unsafe (b); + int u = decl_jump_unsafe (bad); - if (u > 1 && DECL_ARTIFICIAL (b)) + if (u > 1 && DECL_ARTIFICIAL (bad)) { /* Can't skip init of __exception_info. */ - error_at (DECL_SOURCE_LOCATION (b), " enters catch block"); + error_at (DECL_SOURCE_LOCATION (bad), " enters catch block"); saw_catch = true; } else if (u > 1) - error (" skips initialization of %q+#D", b); + error (" skips initialization of %q+#D", bad); else permerror (input_location, " enters scope of %q+#D which has " - "non-trivial destructor", b); + "non-trivial destructor", bad); } if (ent->in_try_scope) @@ -3354,7 +3403,7 @@ cxx_init_decl_processing (void) tree void_ftype; tree void_ftype_ptr; - build_common_tree_nodes (flag_signed_char, false); + build_common_tree_nodes (flag_signed_char); /* Create all the identifiers we need. */ initialize_predefined_identifiers (); @@ -3396,7 +3445,6 @@ cxx_init_decl_processing (void) java_boolean_type_node = record_builtin_java_type ("__java_boolean", -1); integer_two_node = build_int_cst (NULL_TREE, 2); - integer_three_node = build_int_cst (NULL_TREE, 3); record_builtin_type (RID_BOOL, "bool", boolean_type_node); truthvalue_type_node = boolean_type_node; @@ -3404,6 +3452,8 @@ cxx_init_decl_processing (void) truthvalue_true_node = boolean_true_node; empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE); + noexcept_true_spec = build_tree_list (boolean_true_node, NULL_TREE); + noexcept_false_spec = build_tree_list (boolean_false_node, NULL_TREE); #if 0 record_builtin_type (RID_MAX, NULL, string_type_node); @@ -3413,17 +3463,15 @@ cxx_init_decl_processing (void) vtable_index_type = ptrdiff_type_node; vtt_parm_type = build_pointer_type (const_ptr_type_node); - void_ftype = build_function_type (void_type_node, void_list_node); - void_ftype_ptr = build_function_type (void_type_node, - tree_cons (NULL_TREE, - ptr_type_node, - void_list_node)); + void_ftype = build_function_type_list (void_type_node, NULL_TREE); + void_ftype_ptr = build_function_type_list (void_type_node, + ptr_type_node, NULL_TREE); void_ftype_ptr = build_exception_variant (void_ftype_ptr, empty_except_spec); /* C++ extensions */ - unknown_type_node = make_node (UNKNOWN_TYPE); + unknown_type_node = make_node (LANG_TYPE); record_unknown_type (unknown_type_node, "unknown type"); /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node. */ @@ -3434,7 +3482,7 @@ cxx_init_decl_processing (void) TYPE_POINTER_TO (unknown_type_node) = unknown_type_node; TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node; - init_list_type_node = make_node (UNKNOWN_TYPE); + init_list_type_node = make_node (LANG_TYPE); record_unknown_type (init_list_type_node, "init list"); { @@ -3452,7 +3500,7 @@ cxx_init_decl_processing (void) vtbl_type_node = build_cplus_array_type (vtable_entry_type, NULL_TREE); layout_type (vtbl_type_node); - vtbl_type_node = build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST); + vtbl_type_node = cp_build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST); record_builtin_type (RID_MAX, NULL, vtbl_type_node); vtbl_ptr_type_node = build_pointer_type (vtable_entry_type); layout_type (vtbl_ptr_type_node); @@ -3469,34 +3517,49 @@ cxx_init_decl_processing (void) current_lang_name = lang_name_cplusplus; { - tree bad_alloc_id; - tree bad_alloc_type_node; - tree bad_alloc_decl; tree newtype, deltype; tree ptr_ftype_sizetype; - - push_namespace (std_identifier); - bad_alloc_id = get_identifier ("bad_alloc"); - bad_alloc_type_node = make_class_type (RECORD_TYPE); - TYPE_CONTEXT (bad_alloc_type_node) = current_namespace; - bad_alloc_decl - = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node); - DECL_CONTEXT (bad_alloc_decl) = current_namespace; - pop_namespace (); + tree new_eh_spec; ptr_ftype_sizetype - = build_function_type (ptr_type_node, - tree_cons (NULL_TREE, - size_type_node, - void_list_node)); - newtype = build_exception_variant - (ptr_ftype_sizetype, add_exception_specifier - (NULL_TREE, bad_alloc_type_node, -1)); + = build_function_type_list (ptr_type_node, size_type_node, NULL_TREE); + if (cxx_dialect == cxx98) + { + tree bad_alloc_id; + tree bad_alloc_type_node; + tree bad_alloc_decl; + + push_namespace (std_identifier); + bad_alloc_id = get_identifier ("bad_alloc"); + bad_alloc_type_node = make_class_type (RECORD_TYPE); + TYPE_CONTEXT (bad_alloc_type_node) = current_namespace; + bad_alloc_decl + = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node); + DECL_CONTEXT (bad_alloc_decl) = current_namespace; + pop_namespace (); + + new_eh_spec + = add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1); + } + else + new_eh_spec = noexcept_false_spec; + + newtype = build_exception_variant (ptr_ftype_sizetype, new_eh_spec); deltype = build_exception_variant (void_ftype_ptr, empty_except_spec); push_cp_library_fn (NEW_EXPR, newtype); push_cp_library_fn (VEC_NEW_EXPR, newtype); global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype); push_cp_library_fn (VEC_DELETE_EXPR, deltype); + + nullptr_type_node = make_node (LANG_TYPE); + TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode)); + TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode)); + TYPE_UNSIGNED (nullptr_type_node) = 1; + TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode); + SET_TYPE_MODE (nullptr_type_node, Pmode); + record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node); + nullptr_node = make_node (INTEGER_CST); + TREE_TYPE (nullptr_node) = nullptr_type_node; } abort_fndecl @@ -3540,7 +3603,7 @@ cp_fname_init (const char* name, tree *type_p) init = build_string (length + 1, name); } - type = build_qualified_type (char_type_node, TYPE_QUAL_CONST); + type = cp_build_qualified_type (char_type_node, TYPE_QUAL_CONST); type = build_cplus_array_type (type, domain); *type_p = type; @@ -3814,10 +3877,10 @@ fixup_anonymous_aggr (tree t) /* Wipe out memory of synthesized methods. */ TYPE_HAS_USER_CONSTRUCTOR (t) = 0; TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0; - TYPE_HAS_INIT_REF (t) = 0; - TYPE_HAS_CONST_INIT_REF (t) = 0; - TYPE_HAS_ASSIGN_REF (t) = 0; - TYPE_HAS_CONST_ASSIGN_REF (t) = 0; + TYPE_HAS_COPY_CTOR (t) = 0; + TYPE_HAS_CONST_COPY_CTOR (t) = 0; + TYPE_HAS_COPY_ASSIGN (t) = 0; + TYPE_HAS_CONST_COPY_ASSIGN (t) = 0; /* Splice the implicitly generated functions out of the TYPE_METHODS list. */ @@ -3827,7 +3890,7 @@ fixup_anonymous_aggr (tree t) if (DECL_ARTIFICIAL (*q)) *q = TREE_CHAIN (*q); else - q = &TREE_CHAIN (*q); + q = &DECL_CHAIN (*q); } /* ISO C++ 9.5.3. Anonymous unions may not have function members. */ @@ -3851,7 +3914,7 @@ fixup_anonymous_aggr (tree t) { tree field, type; - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL) { type = TREE_TYPE (field); @@ -3863,7 +3926,7 @@ fixup_anonymous_aggr (tree t) if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) error ("member %q+#D with destructor not allowed " "in anonymous aggregate", field); - if (TYPE_HAS_COMPLEX_ASSIGN_REF (type)) + if (TYPE_HAS_COMPLEX_COPY_ASSIGN (type)) error ("member %q+#D with copy assignment operator " "not allowed in anonymous aggregate", field); } @@ -4080,6 +4143,7 @@ start_decl (const cp_declarator *declarator, tree context; bool was_public; int flags; + bool alias; *pushed_scope_p = NULL_TREE; @@ -4141,6 +4205,10 @@ start_decl (const cp_declarator *declarator, if (toplevel_bindings_p ()) TREE_STATIC (decl) = 1; } + alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)) != 0; + + if (alias && TREE_CODE (decl) == FUNCTION_DECL) + record_key_method_defined (decl); /* If this is a typedef that names the class for linkage purposes (7.1.3p8), apply any attributes directly to the type. */ @@ -4243,7 +4311,9 @@ start_decl (const cp_declarator *declarator, DECL_EXTERNAL (decl) = 1; } - if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)) + if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl) + /* Aliases are definitions. */ + && !alias) permerror (input_location, "declaration of %q#D outside of class is not definition", decl); @@ -4280,7 +4350,7 @@ start_decl (const cp_declarator *declarator, /* This is a const variable with implicit 'static'. Set DECL_THIS_STATIC so we can tell it from variables that are !TREE_PUBLIC because of the anonymous namespace. */ - gcc_assert (cp_type_readonly (TREE_TYPE (decl))); + gcc_assert (CP_TYPE_CONST_P (TREE_TYPE (decl))); DECL_THIS_STATIC (decl) = 1; } @@ -4398,7 +4468,8 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup) } if (TREE_CODE (init) == TREE_LIST) - init = build_x_compound_expr_from_list (init, "initializer"); + init = build_x_compound_expr_from_list (init, ELK_INIT, + tf_warning_or_error); if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE) @@ -4524,9 +4595,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init) VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initializer); constructor_elt *ce; HOST_WIDE_INT i; - for (i = 0; - VEC_iterate (constructor_elt, v, i, ce); - ++i) + FOR_EACH_VEC_ELT (constructor_elt, v, i, ce) if (!check_array_designated_initializer (ce)) failure = 1; } @@ -4688,7 +4757,7 @@ maybe_commonize_var (tree decl) static void check_for_uninitialized_const_var (tree decl) { - tree type = TREE_TYPE (decl); + tree type = strip_array_types (TREE_TYPE (decl)); if (TREE_CODE (decl) == VAR_DECL && DECL_DECLARED_CONSTEXPR_P (decl) && DECL_INITIAL (decl) == NULL) @@ -4700,11 +4769,28 @@ check_for_uninitialized_const_var (tree decl) else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (type) != REFERENCE_TYPE && CP_TYPE_CONST_P (type) - && !TYPE_NEEDS_CONSTRUCTING (type) + && (!TYPE_NEEDS_CONSTRUCTING (type) + || !type_has_user_provided_default_constructor (type)) && !DECL_INITIAL (decl)) - error ("uninitialized const %qD", decl); -} + { + permerror (DECL_SOURCE_LOCATION (decl), + "uninitialized const %qD", decl); + if (CLASS_TYPE_P (type) + && !type_has_user_provided_default_constructor (type)) + { + tree defaulted_ctor; + + inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)), + "%q#T has no user-provided default constructor", type); + defaulted_ctor = in_class_defaulted_default_constructor (type); + if (defaulted_ctor) + inform (DECL_SOURCE_LOCATION (defaulted_ctor), + "constructor is not user-provided because it is " + "explicitly defaulted in the class body"); + } + } +} /* Structure holding the current initializer being processed by reshape_init. CUR is a pointer to the current element being processed, END is a pointer @@ -4729,7 +4815,7 @@ next_initializable_field (tree field) && (TREE_CODE (field) != FIELD_DECL || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field)) || DECL_ARTIFICIAL (field))) - field = TREE_CHAIN (field); + field = DECL_CHAIN (field); return field; } @@ -4805,7 +4891,6 @@ static tree reshape_init_vector (tree type, reshape_iter *d) { tree max_index = NULL_TREE; - tree rtype; gcc_assert (TREE_CODE (type) == VECTOR_TYPE); @@ -4822,12 +4907,9 @@ reshape_init_vector (tree type, reshape_iter *d) return value; } - /* For a vector, the representation type is a struct - containing a single member which is an array of the - appropriate size. */ - rtype = TYPE_DEBUG_REPRESENTATION_TYPE (type); - if (rtype && TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (rtype)))) - max_index = array_type_nelts (TREE_TYPE (TYPE_FIELDS (rtype))); + /* For a vector, we initialize it as an array of the appropriate size. */ + if (TREE_CODE (type) == VECTOR_TYPE) + max_index = size_int (TYPE_VECTOR_SUBPARTS (type) - 1); return reshape_init_array_1 (TREE_TYPE (type), max_index, d); } @@ -4899,7 +4981,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p) if (TREE_CODE (type) == UNION_TYPE) break; - field = next_initializable_field (TREE_CHAIN (field)); + field = next_initializable_field (DECL_CHAIN (field)); } return new_init; @@ -5150,6 +5232,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) { tree type = TREE_TYPE (decl); tree init_code = NULL; + tree core_type; /* Things that are going to be initialized need to have complete type. */ @@ -5220,7 +5303,6 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) error ("in C++98 %qD must be initialized by constructor, " "not by %<{...}%>", decl); - init = build_tree_list (NULL_TREE, init); } else if (TREE_CODE (type) == VECTOR_TYPE && TYPE_VECTOR_OPAQUE (type)) { @@ -5257,15 +5339,16 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) else if (DECL_EXTERNAL (decl)) ; else if (TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type)) - return build_aggr_init_full_exprs (decl, init, flags); - else if (MAYBE_CLASS_TYPE_P (type)) { - tree core_type = strip_array_types (type); - - if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)) - error ("structure %qD with uninitialized const members", decl); - if (CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)) - error ("structure %qD with uninitialized reference members", decl); + check_for_uninitialized_const_var (decl); + return build_aggr_init_full_exprs (decl, init, flags); + } + else if (MAYBE_CLASS_TYPE_P (core_type = strip_array_types (type))) + { + if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type) + || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)) + diagnose_uninitialized_cst_or_ref_member (core_type, /*using_new=*/false, + /*complain=*/true); check_for_uninitialized_const_var (decl); } @@ -5441,6 +5524,8 @@ initialize_local_var (tree decl, tree init) /* Compute and store the initial value. */ already_used = TREE_USED (decl) || TREE_USED (type); + if (TREE_USED (type)) + DECL_READ_P (decl) = 1; /* Generate a cleanup, if necessary. */ cleanup = cxx_maybe_build_cleanup (decl); @@ -5485,16 +5570,15 @@ initialize_local_var (tree decl, tree init) /* DECL is a VAR_DECL for a compiler-generated variable with static storage duration (like a virtual table) whose initializer is a - compile-time constant. INIT must be either a TREE_LIST of values, - or a CONSTRUCTOR. Initialize the variable and provide it to the + compile-time constant. Initialize the variable and provide it to the back end. */ void -initialize_artificial_var (tree decl, tree init) +initialize_artificial_var (tree decl, VEC(constructor_elt,gc) *v) { + tree init; gcc_assert (DECL_ARTIFICIAL (decl)); - if (TREE_CODE (init) == TREE_LIST) - init = build_constructor_from_list (TREE_TYPE (decl), init); + init = build_constructor (TREE_TYPE (decl), v); gcc_assert (TREE_CODE (init) == CONSTRUCTOR); DECL_INITIAL (decl) = init; DECL_INITIALIZED_P (decl) = 1; @@ -5593,17 +5677,21 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, auto_node = type_uses_auto (type); if (auto_node) { + tree d_init; if (init == NULL_TREE) { error ("declaration of %q#D has no initializer", decl); TREE_TYPE (decl) = error_mark_node; return; } - if (TREE_CODE (init) == TREE_LIST) - init = build_x_compound_expr_from_list (init, "initializer"); - if (describable_type (init)) + d_init = init; + if (TREE_CODE (d_init) == TREE_LIST) + d_init = build_x_compound_expr_from_list (d_init, ELK_INIT, + tf_warning_or_error); + if (describable_type (d_init)) { - type = TREE_TYPE (decl) = do_auto_deduction (type, init, auto_node); + type = TREE_TYPE (decl) = do_auto_deduction (type, d_init, + auto_node); if (type == error_mark_node) return; } @@ -5754,8 +5842,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, but [cd]tors are never actually compiled directly. We need to put statics on the list so we can deal with the label address extension. */ - cfun->local_decls = tree_cons (NULL_TREE, decl, - cfun->local_decls); + add_local_decl (cfun, decl); } /* Convert the initializer to the type of DECL, if we have not @@ -5964,10 +6051,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (was_readonly) TREE_READONLY (decl) = 1; - - /* If this was marked 'used', be sure it will be output. */ - if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) - mark_decl_referenced (decl); } /* Returns a declaration for a VAR_DECL as if: @@ -6005,20 +6088,21 @@ declare_global_var (tree name, tree type) static tree get_atexit_fn_ptr_type (void) { - tree arg_types; tree fn_type; if (!atexit_fn_ptr_type_node) { + tree arg_type; if (flag_use_cxa_atexit && !targetm.cxx.use_atexit_for_cxa_atexit ()) /* The parameter to "__cxa_atexit" is "void (*)(void *)". */ - arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node); + arg_type = ptr_type_node; else /* The parameter to "atexit" is "void (*)(void)". */ - arg_types = void_list_node; + arg_type = NULL_TREE; - fn_type = build_function_type (void_type_node, arg_types); + fn_type = build_function_type_list (void_type_node, + arg_type, NULL_TREE); atexit_fn_ptr_type_node = build_pointer_type (fn_type); } @@ -6033,7 +6117,6 @@ static tree get_atexit_node (void) { tree atexit_fndecl; - tree arg_types; tree fn_type; tree fn_ptr_type; const char *name; @@ -6050,25 +6133,28 @@ get_atexit_node (void) We build up the argument types and then then function type itself. */ + tree argtype0, argtype1, argtype2; use_aeabi_atexit = targetm.cxx.use_aeabi_atexit (); /* First, build the pointer-to-function type for the first argument. */ fn_ptr_type = get_atexit_fn_ptr_type (); /* Then, build the rest of the argument types. */ - arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node); + argtype2 = ptr_type_node; if (use_aeabi_atexit) { - arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types); - arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types); + argtype1 = fn_ptr_type; + argtype0 = ptr_type_node; } else { - arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types); - arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types); + argtype1 = ptr_type_node; + argtype0 = fn_ptr_type; } /* And the final __cxa_atexit type. */ - fn_type = build_function_type (integer_type_node, arg_types); + fn_type = build_function_type_list (integer_type_node, + argtype0, argtype1, argtype2, + NULL_TREE); fn_ptr_type = build_pointer_type (fn_type); if (use_aeabi_atexit) name = "__aeabi_atexit"; @@ -6084,9 +6170,9 @@ get_atexit_node (void) We build up the argument types and then then function type itself. */ fn_ptr_type = get_atexit_fn_ptr_type (); - arg_types = tree_cons (NULL_TREE, fn_ptr_type, void_list_node); /* Build the final atexit type. */ - fn_type = build_function_type (integer_type_node, arg_types); + fn_type = build_function_type_list (integer_type_node, + fn_ptr_type, NULL_TREE); name = "atexit"; } @@ -6157,6 +6243,7 @@ start_cleanup_fn (void) parmdecl = cp_build_parm_decl (NULL_TREE, ptr_type_node); DECL_CONTEXT (parmdecl) = fndecl; TREE_USED (parmdecl) = 1; + DECL_READ_P (parmdecl) = 1; DECL_ARGUMENTS (fndecl) = parmdecl; } @@ -6186,10 +6273,10 @@ register_dtor_fn (tree decl) { tree cleanup; tree compound_stmt; - tree args; tree fcall; tree type; bool use_dtor; + tree arg0, arg1 = NULL_TREE, arg2 = NULL_TREE; type = TREE_TYPE (decl); if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type)) @@ -6267,25 +6354,23 @@ register_dtor_fn (tree decl) in, and, in general, it's cheaper to pass NULL than any other value. */ addr = null_pointer_node; - args = tree_cons (NULL_TREE, - cp_build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0, - tf_warning_or_error), - NULL_TREE); + arg2 = cp_build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0, + tf_warning_or_error); if (targetm.cxx.use_aeabi_atexit ()) { - args = tree_cons (NULL_TREE, cleanup, args); - args = tree_cons (NULL_TREE, addr, args); + arg1 = cleanup; + arg0 = addr; } else { - args = tree_cons (NULL_TREE, addr, args); - args = tree_cons (NULL_TREE, cleanup, args); + arg1 = addr; + arg0 = cleanup; } } else - args = tree_cons (NULL_TREE, cleanup, NULL_TREE); - return cp_build_function_call (get_atexit_node (), args, - tf_warning_or_error); + arg0 = cleanup; + return cp_build_function_call_nary (get_atexit_node (), tf_warning_or_error, + arg0, arg1, arg2, NULL_TREE); } /* DECL is a VAR_DECL with static storage duration. INIT, if present, @@ -6367,11 +6452,13 @@ expand_static_init (tree decl, tree init) abort_fn = get_identifier ("__cxa_guard_abort"); if (!get_global_value_if_present (acquire_fn, &acquire_fn)) { - tree argtypes = tree_cons (NULL_TREE, TREE_TYPE (guard_addr), - void_list_node); - tree vfntype = build_function_type (void_type_node, argtypes); + tree vfntype = build_function_type_list (void_type_node, + TREE_TYPE (guard_addr), + NULL_TREE); acquire_fn = push_library_fn - (acquire_fn, build_function_type (integer_type_node, argtypes), + (acquire_fn, build_function_type_list (integer_type_node, + TREE_TYPE (guard_addr), + NULL_TREE), NULL_TREE); release_fn = push_library_fn (release_fn, vfntype, NULL_TREE); abort_fn = push_library_fn (abort_fn, vfntype, NULL_TREE); @@ -6521,21 +6608,54 @@ member_function_or_else (tree ctype, tree cur_type, enum overload_flags flags) static void bad_specifiers (tree object, - const char* type, + enum bad_spec_place type, int virtualp, int quals, int inlinep, int friendp, int raises) { - if (virtualp) - error ("%qD declared as a %<virtual%> %s", object, type); - if (inlinep) - error ("%qD declared as an %<inline%> %s", object, type); - if (quals) - error ("%<const%> and %<volatile%> function specifiers on " - "%qD invalid in %s declaration", - object, type); + switch (type) + { + case BSP_VAR: + if (virtualp) + error ("%qD declared as a %<virtual%> variable", object); + if (inlinep) + error ("%qD declared as an %<inline%> variable", object); + if (quals) + error ("%<const%> and %<volatile%> function specifiers on " + "%qD invalid in variable declaration", object); + break; + case BSP_PARM: + if (virtualp) + error ("%qD declared as a %<virtual%> parameter", object); + if (inlinep) + error ("%qD declared as an %<inline%> parameter", object); + if (quals) + error ("%<const%> and %<volatile%> function specifiers on " + "%qD invalid in parameter declaration", object); + break; + case BSP_TYPE: + if (virtualp) + error ("%qD declared as a %<virtual%> type", object); + if (inlinep) + error ("%qD declared as an %<inline%> type", object); + if (quals) + error ("%<const%> and %<volatile%> function specifiers on " + "%qD invalid in type declaration", object); + break; + case BSP_FIELD: + if (virtualp) + error ("%qD declared as a %<virtual%> field", object); + if (inlinep) + error ("%qD declared as an %<inline%> field", object); + if (quals) + error ("%<const%> and %<volatile%> function specifiers on " + "%qD invalid in field declaration", object); + break; + default: + gcc_unreachable(); + } if (friendp) error ("%q+D declared as a friend", object); if (raises @@ -6660,11 +6780,11 @@ grokfndecl (tree ctype, { tree parm; parm = build_this_parm (type, quals); - TREE_CHAIN (parm) = parms; + DECL_CHAIN (parm) = parms; parms = parm; } DECL_ARGUMENTS (decl) = parms; - for (t = parms; t; t = TREE_CHAIN (t)) + for (t = parms; t; t = DECL_CHAIN (t)) DECL_CONTEXT (t) = decl; /* Propagate volatile out from type to decl. */ if (TYPE_VOLATILE (type)) @@ -6758,7 +6878,7 @@ grokfndecl (tree ctype, if (in_namespace) set_decl_namespace (decl, in_namespace, friendp); else if (!ctype) - DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); + DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ()); /* `main' and builtins have implicit 'C' linkage. */ if ((MAIN_NAME_P (declarator) @@ -6821,8 +6941,9 @@ grokfndecl (tree ctype, /* Allow this; it's pretty common in C. */; else { - permerror (input_location, "non-local function %q#D uses anonymous type", - decl); + permerror (input_location, "anonymous type with no linkage " + "used to declare function %q#D with linkage", + decl); if (DECL_ORIGINAL_TYPE (TYPE_NAME (t))) permerror (input_location, "%q+#D does not refer to the unqualified " "type, so it is not used for linkage", @@ -6830,7 +6951,8 @@ grokfndecl (tree ctype, } } else - permerror (input_location, "non-local function %q#D uses local type %qT", decl, t); + permerror (input_location, "type %qT with no linkage used to " + "declare function %q#D with linkage", t, decl); } } @@ -7018,7 +7140,7 @@ grokvardecl (tree type, /* An explicit "extern" specifier indicates a namespace-scope variable. */ if (declspecs->storage_class == sc_extern) - scope = current_namespace; + scope = current_decl_namespace (); else if (!at_function_scope_p ()) scope = current_scope (); } @@ -7104,8 +7226,8 @@ grokvardecl (tree type, no linkage can only be used to declare extern "C" entities. Since it's not always an error in the ISO C++ 90 Standard, we only issue a warning. */ - warning (0, "non-local variable %q#D uses anonymous type", - decl); + warning (0, "anonymous type with no linkage used to declare " + "variable %q#D with linkage", decl); if (DECL_ORIGINAL_TYPE (TYPE_NAME (t))) warning (0, "%q+#D does not refer to the unqualified " "type, so it is not used for linkage", @@ -7113,7 +7235,8 @@ grokvardecl (tree type, } } else - warning (0, "non-local variable %q#D uses local type %qT", decl, t); + warning (0, "type %qT with no linkage used to declare variable " + "%q#D with linkage", t, decl); } } else @@ -7161,7 +7284,7 @@ build_ptrmemfunc_type (tree type) field = build_decl (input_location, FIELD_DECL, delta_identifier, delta_type_node); - TREE_CHAIN (field) = fields; + DECL_CHAIN (field) = fields; fields = field; finish_builtin_struct (t, "__ptrmemfunc_type", fields, ptr_type_node); @@ -7206,8 +7329,7 @@ build_ptrmem_type (tree class_type, tree member_type) { if (TREE_CODE (member_type) == METHOD_TYPE) { - tree arg_types = TYPE_ARG_TYPES (member_type); - cp_cv_quals quals = cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types))); + cp_cv_quals quals = type_memfn_quals (member_type); member_type = build_memfn_type (member_type, class_type, quals); return build_ptrmemfunc_type (build_pointer_type (member_type)); } @@ -7310,8 +7432,12 @@ compute_array_index_type (tree name, tree size) /* The size might be the result of a cast. */ STRIP_TYPE_NOPS (size); + size = mark_rvalue_use (size); + /* It might be a const variable or enumeration constant. */ size = integral_constant_value (size); + if (error_operand_p (size)) + return error_mark_node; /* Normally, the array-bound will be a constant. */ if (TREE_CODE (size) == INTEGER_CST) @@ -7641,6 +7767,7 @@ grokdeclarator (const cp_declarator *declarator, { tree type = NULL_TREE; int longlong = 0; + int explicit_int128 = 0; int virtualp, explicitp, friendp, inlinep, staticp; int explicit_int = 0; int explicit_char = 0; @@ -7704,6 +7831,7 @@ grokdeclarator (const cp_declarator *declarator, short_p = declspecs->specs[(int)ds_short]; long_p = declspecs->specs[(int)ds_long]; longlong = declspecs->specs[(int)ds_long] >= 2; + explicit_int128 = declspecs->explicit_int128_p; thread_p = declspecs->specs[(int)ds_thread]; if (decl_context == FUNCDEF) @@ -7986,7 +8114,8 @@ grokdeclarator (const cp_declarator *declarator, common. With no options, it is allowed. With -Wreturn-type, it is a warning. It is only an error with -pedantic-errors. */ is_main = (funcdef_flag - && dname && MAIN_NAME_P (dname) + && dname && TREE_CODE (dname) == IDENTIFIER_NODE + && MAIN_NAME_P (dname) && ctype == NULL_TREE && in_namespace == NULL_TREE && current_namespace == global_namespace); @@ -8016,8 +8145,8 @@ grokdeclarator (const cp_declarator *declarator, if (long_p && !longlong && TYPE_MAIN_VARIANT (type) == double_type_node) { long_p = false; - type = build_qualified_type (long_double_type_node, - cp_type_quals (type)); + type = cp_build_qualified_type (long_double_type_node, + cp_type_quals (type)); } /* Check all other uses of type modifiers. */ @@ -8032,12 +8161,16 @@ grokdeclarator (const cp_declarator *declarator, error ("%<signed%> and %<unsigned%> specified together for %qs", name); else if (longlong && TREE_CODE (type) != INTEGER_TYPE) error ("%<long long%> invalid for %qs", name); + else if (explicit_int128 && TREE_CODE (type) != INTEGER_TYPE) + error ("%<__int128%> invalid for %qs", name); else if (long_p && TREE_CODE (type) == REAL_TYPE) error ("%<long%> invalid for %qs", name); else if (short_p && TREE_CODE (type) == REAL_TYPE) error ("%<short%> invalid for %qs", name); else if ((long_p || short_p) && TREE_CODE (type) != INTEGER_TYPE) error ("%<long%> or %<short%> invalid for %qs", name); + else if ((long_p || short_p || explicit_char || explicit_int) && explicit_int128) + error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs", name); else if ((long_p || short_p) && explicit_char) error ("%<long%> or %<short%> specified with char for %qs", name); else if (long_p && short_p) @@ -8052,7 +8185,7 @@ grokdeclarator (const cp_declarator *declarator, else { ok = 1; - if (!explicit_int && !defaulted_int && !explicit_char && pedantic) + if (!explicit_int && !defaulted_int && !explicit_char && !explicit_int128 && pedantic) { pedwarn (input_location, OPT_pedantic, "long, short, signed or unsigned used invalidly for %qs", @@ -8060,6 +8193,22 @@ grokdeclarator (const cp_declarator *declarator, if (flag_pedantic_errors) ok = 0; } + if (explicit_int128) + { + if (int128_integer_type_node == NULL_TREE) + { + error ("%<__int128%> is not supported by this target"); + ok = 0; + } + else if (pedantic) + { + pedwarn (input_location, OPT_pedantic, + "ISO C++ does not support %<__int128%> for %qs", + name); + if (flag_pedantic_errors) + ok = 0; + } + } } /* Discard the type modifiers if they are invalid. */ @@ -8070,6 +8219,7 @@ grokdeclarator (const cp_declarator *declarator, long_p = false; short_p = false; longlong = 0; + explicit_int128 = false; } } @@ -8094,7 +8244,9 @@ grokdeclarator (const cp_declarator *declarator, && TREE_CODE (type) == INTEGER_TYPE && !same_type_p (TYPE_MAIN_VARIANT (type), wchar_type_node))) { - if (longlong) + if (explicit_int128) + type = int128_unsigned_type_node; + else if (longlong) type = long_long_unsigned_type_node; else if (long_p) type = long_unsigned_type_node; @@ -8109,6 +8261,8 @@ grokdeclarator (const cp_declarator *declarator, } else if (signed_p && type == char_type_node) type = signed_char_type_node; + else if (explicit_int128) + type = int128_integer_type_node; else if (longlong) type = long_long_integer_type_node; else if (long_p) @@ -8124,8 +8278,7 @@ grokdeclarator (const cp_declarator *declarator, "complex double", but if any modifiers at all are specified it is the complex form of TYPE. E.g, "complex short" is "complex short int". */ - - else if (defaulted_int && ! longlong + else if (defaulted_int && ! longlong && ! explicit_int128 && ! (long_p || short_p || signed_p || unsigned_p)) type = complex_double_type_node; else if (type == integer_type_node) @@ -8162,21 +8315,6 @@ grokdeclarator (const cp_declarator *declarator, error ("qualifiers are not allowed on declaration of %<operator %T%>", ctor_return_type); - if (TREE_CODE (type) == FUNCTION_TYPE - && type_quals != TYPE_UNQUALIFIED) - { - /* This was an error in C++98 (cv-qualifiers cannot be added to - a function type), but DR 295 makes the code well-formed by - dropping the extra qualifiers. */ - if (pedantic && cxx_dialect == cxx98) - { - tree bad_type = build_qualified_type (type, type_quals); - pedwarn (input_location, OPT_pedantic, - "ignoring %qV qualifiers added to function type %qT", - bad_type, type); - } - type_quals = TYPE_UNQUALIFIED; - } type_quals |= cp_type_quals (type); type = cp_build_qualified_type_real (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl) @@ -8620,20 +8758,50 @@ grokdeclarator (const cp_declarator *declarator, && (TREE_CODE (type) == FUNCTION_TYPE || (memfn_quals && TREE_CODE (type) == METHOD_TYPE))) { - memfn_quals |= cp_type_quals (type); + memfn_quals |= type_memfn_quals (type); type = build_memfn_type (type, declarator->u.pointer.class_type, memfn_quals); + if (type == error_mark_node) + return error_mark_node; memfn_quals = TYPE_UNQUALIFIED; } if (TREE_CODE (type) == FUNCTION_TYPE - && cp_type_quals (type) != TYPE_UNQUALIFIED) + && type_memfn_quals (type) != TYPE_UNQUALIFIED) error (declarator->kind == cdk_reference ? G_("cannot declare reference to qualified function type %qT") : G_("cannot declare pointer to qualified function type %qT"), type); + /* When the pointed-to type involves components of variable size, + care must be taken to ensure that the size evaluation code is + emitted early enough to dominate all the possible later uses + and late enough for the variables on which it depends to have + been assigned. + + This is expected to happen automatically when the pointed-to + type has a name/declaration of it's own, but special attention + is required if the type is anonymous. + + We handle the NORMAL and FIELD contexts here by inserting a + dummy statement that just evaluates the size at a safe point + and ensures it is not deferred until e.g. within a deeper + conditional context (c++/43555). + + We expect nothing to be needed here for PARM or TYPENAME. + Evaluating the size at this point for TYPENAME would + actually be incorrect, as we might be in the middle of an + expression with side effects on the pointed-to type size + "arguments" prior to the pointer declaration point and the + size evaluation could end up prior to the side effects. */ + + if (!TYPE_NAME (type) + && (decl_context == NORMAL || decl_context == FIELD) + && at_function_scope_p () + && variably_modified_type_p (type, NULL_TREE)) + finish_expr_stmt (TYPE_SIZE (type)); + if (declarator->kind == cdk_reference) { /* In C++0x, the type we are creating a reference to might be @@ -8931,7 +9099,7 @@ grokdeclarator (const cp_declarator *declarator, function type. */ if (memfn_quals && TREE_CODE (type) == FUNCTION_TYPE) { - type = cp_build_qualified_type (type, memfn_quals); + type = apply_memfn_quals (type, memfn_quals); /* We have now dealt with these qualifiers. */ memfn_quals = TYPE_UNQUALIFIED; @@ -8982,10 +9150,12 @@ grokdeclarator (const cp_declarator *declarator, for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) { if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) - { - debug_hooks->set_name (t, decl); - TYPE_NAME (t) = decl; - } + /* We do not rename the debug info representing the + anonymous tagged type because the standard says in + [dcl.typedef] that the naming applies only for + linkage purposes. */ + /*debug_hooks->set_name (t, decl);*/ + TYPE_NAME (t) = decl; } if (TYPE_LANG_SPECIFIC (type)) @@ -9010,7 +9180,7 @@ grokdeclarator (const cp_declarator *declarator, || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; - bad_specifiers (decl, "type", virtualp, + bad_specifiers (decl, BSP_TYPE, virtualp, memfn_quals != TYPE_UNQUALIFIED, inlinep, friendp, raises != NULL_TREE); @@ -9041,7 +9211,7 @@ grokdeclarator (const cp_declarator *declarator, { tree decl = cp_build_parm_decl (NULL_TREE, TREE_VALUE (args)); - TREE_CHAIN (decl) = decls; + DECL_CHAIN (decl) = decls; decls = decl; } @@ -9051,7 +9221,7 @@ grokdeclarator (const cp_declarator *declarator, { /* A cv-qualifier-seq shall only be part of the function type for a non-static member function. [8.3.5/4 dcl.fct] */ - if (cp_type_quals (type) != TYPE_UNQUALIFIED + if (type_memfn_quals (type) != TYPE_UNQUALIFIED && (current_class_type == NULL_TREE || staticp) ) { error (staticp @@ -9064,7 +9234,7 @@ grokdeclarator (const cp_declarator *declarator, /* The qualifiers on the function type become the qualifiers on the non-static member function. */ - memfn_quals |= cp_type_quals (type); + memfn_quals |= type_memfn_quals (type); type_quals = TYPE_UNQUALIFIED; } } @@ -9132,7 +9302,7 @@ grokdeclarator (const cp_declarator *declarator, type = build_memfn_type (type, ctype, memfn_quals); /* Core issue #547: need to allow this in template type args. */ else if (template_type_arg && TREE_CODE (type) == FUNCTION_TYPE) - type = cp_build_qualified_type (type, memfn_quals); + type = apply_memfn_quals (type, memfn_quals); else error ("invalid qualifiers on non-member function type"); } @@ -9196,7 +9366,7 @@ grokdeclarator (const cp_declarator *declarator, { decl = cp_build_parm_decl (unqualified_id, type); - bad_specifiers (decl, "parameter", virtualp, + bad_specifiers (decl, BSP_PARM, virtualp, memfn_quals != TYPE_UNQUALIFIED, inlinep, friendp, raises != NULL_TREE); } @@ -9474,7 +9644,7 @@ grokdeclarator (const cp_declarator *declarator, } } - bad_specifiers (decl, "field", virtualp, + bad_specifiers (decl, BSP_FIELD, virtualp, memfn_quals != TYPE_UNQUALIFIED, inlinep, friendp, raises != NULL_TREE); } @@ -9597,7 +9767,7 @@ grokdeclarator (const cp_declarator *declarator, initialized, (type_quals & TYPE_QUAL_CONST) != 0, ctype ? ctype : in_namespace); - bad_specifiers (decl, "variable", virtualp, + bad_specifiers (decl, BSP_VAR, virtualp, memfn_quals != TYPE_UNQUALIFIED, inlinep, friendp, raises != NULL_TREE); @@ -9673,7 +9843,7 @@ grokdeclarator (const cp_declarator *declarator, static void require_complete_types_for_parms (tree parms) { - for (; parms; parms = TREE_CHAIN (parms)) + for (; parms; parms = DECL_CHAIN (parms)) { if (dependent_type_p (TREE_TYPE (parms))) continue; @@ -9943,7 +10113,7 @@ grokparms (tree parmlist, tree *parms) && TREE_CHAIN (parm) != void_list_node) error ("parameter packs must be at the end of the parameter list"); - TREE_CHAIN (decl) = decls; + DECL_CHAIN (decl) = decls; decls = decl; result = tree_cons (init, type, result); } @@ -10103,11 +10273,11 @@ grok_special_member_properties (tree decl) X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments. */ - TYPE_HAS_INIT_REF (class_type) = 1; + TYPE_HAS_COPY_CTOR (class_type) = 1; if (user_provided_p (decl)) - TYPE_HAS_COMPLEX_INIT_REF (class_type) = 1; + TYPE_HAS_COMPLEX_COPY_CTOR (class_type) = 1; if (ctor > 1) - TYPE_HAS_CONST_INIT_REF (class_type) = 1; + TYPE_HAS_CONST_COPY_CTOR (class_type) = 1; } else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl))) { @@ -10115,6 +10285,8 @@ grok_special_member_properties (tree decl) if (user_provided_p (decl)) TYPE_HAS_COMPLEX_DFLT (class_type) = 1; } + else if (move_fn_p (decl) && user_provided_p (decl)) + TYPE_HAS_COMPLEX_MOVE_CTOR (class_type) = 1; else if (is_list_ctor (decl)) TYPE_HAS_LIST_CTOR (class_type) = 1; } @@ -10130,13 +10302,16 @@ grok_special_member_properties (tree decl) if (assop) { - TYPE_HAS_ASSIGN_REF (class_type) = 1; + TYPE_HAS_COPY_ASSIGN (class_type) = 1; if (user_provided_p (decl)) - TYPE_HAS_COMPLEX_ASSIGN_REF (class_type) = 1; + TYPE_HAS_COMPLEX_COPY_ASSIGN (class_type) = 1; if (assop != 1) - TYPE_HAS_CONST_ASSIGN_REF (class_type) = 1; + TYPE_HAS_CONST_COPY_ASSIGN (class_type) = 1; } + else if (move_fn_p (decl) && user_provided_p (decl)) + TYPE_HAS_COMPLEX_MOVE_ASSIGN (class_type) = 1; } + /* Destructors are handled in check_methods. */ } /* Check a constructor DECL has the correct form. Complains @@ -10978,7 +11153,12 @@ xref_basetypes (tree ref, tree base_list) /* The binfo slot should be empty, unless this is an (ill-formed) redefinition. */ - gcc_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref)); + if (TYPE_BINFO (ref) && !TYPE_SIZE (ref)) + { + error ("redefinition of %q#T", ref); + return false; + } + gcc_assert (TYPE_MAIN_VARIANT (ref) == ref); binfo = make_tree_binfo (max_bases); @@ -11226,12 +11406,6 @@ finish_enum (tree enumtype) tree maxnode; tree value; tree t; - bool unsignedp; - bool use_short_enum; - int lowprec; - int highprec; - int precision; - unsigned int itk; tree underlying_type = NULL_TREE; bool fixed_underlying_type_p = ENUM_UNDERLYING_TYPE (enumtype) != NULL_TREE; @@ -11294,17 +11468,19 @@ finish_enum (tree enumtype) the enumeration had a single enumerator with value 0. */ minnode = maxnode = integer_zero_node; - /* Compute the number of bits require to represent all values of the - enumeration. We must do this before the type of MINNODE and - MAXNODE are transformed, since tree_int_cst_min_precision relies - on the TREE_TYPE of the value it is passed. */ - unsignedp = tree_int_cst_sgn (minnode) >= 0; - lowprec = tree_int_cst_min_precision (minnode, unsignedp); - highprec = tree_int_cst_min_precision (maxnode, unsignedp); - precision = MAX (lowprec, highprec); - if (!fixed_underlying_type_p) { + /* Compute the number of bits require to represent all values of the + enumeration. We must do this before the type of MINNODE and + MAXNODE are transformed, since tree_int_cst_min_precision relies + on the TREE_TYPE of the value it is passed. */ + bool unsignedp = tree_int_cst_sgn (minnode) >= 0; + int lowprec = tree_int_cst_min_precision (minnode, unsignedp); + int highprec = tree_int_cst_min_precision (maxnode, unsignedp); + int precision = MAX (lowprec, highprec); + unsigned int itk; + bool use_short_enum; + /* Determine the underlying type of the enumeration. [dcl.enum] @@ -11330,7 +11506,8 @@ finish_enum (tree enumtype) itk++) { underlying_type = integer_types[itk]; - if (TYPE_PRECISION (underlying_type) >= precision + if (underlying_type != NULL_TREE + && TYPE_PRECISION (underlying_type) >= precision && TYPE_UNSIGNED (underlying_type) == unsignedp) break; } @@ -11351,43 +11528,51 @@ finish_enum (tree enumtype) The value of sizeof() applied to an enumeration type, an object of an enumeration type, or an enumerator, is the value of sizeof() applied to the underlying type. */ + TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (underlying_type); + TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (underlying_type); TYPE_SIZE (enumtype) = TYPE_SIZE (underlying_type); TYPE_SIZE_UNIT (enumtype) = TYPE_SIZE_UNIT (underlying_type); SET_TYPE_MODE (enumtype, TYPE_MODE (underlying_type)); + TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type); TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type); TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type); TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (underlying_type); - /* Set the underlying type of the enumeration type to the - computed enumeration type, restricted to the enumerator - values. */ + /* Compute the minimum and maximum values for the type. + + [dcl.enum] + + For an enumeration where emin is the smallest enumerator and emax + is the largest, the values of the enumeration are the values of the + underlying type in the range bmin to bmax, where bmin and bmax are, + respectively, the smallest and largest values of the smallest bit- + field that can store emin and emax. */ + + /* The middle-end currently assumes that types with TYPE_PRECISION + narrower than their underlying type are suitably zero or sign + extended to fill their mode. Similarly, it assumes that the front + end assures that a value of a particular type must be within + TYPE_MIN_VALUE and TYPE_MAX_VALUE. + + We used to set these fields based on bmin and bmax, but that led + to invalid assumptions like optimizing away bounds checking. So + now we just set the TYPE_PRECISION, TYPE_MIN_VALUE, and + TYPE_MAX_VALUE to the values for the mode above and only restrict + the ENUM_UNDERLYING_TYPE for the benefit of diagnostics. */ ENUM_UNDERLYING_TYPE (enumtype) = build_distinct_type_copy (underlying_type); - set_min_and_max_values_for_integral_type + TYPE_PRECISION (ENUM_UNDERLYING_TYPE (enumtype)) = precision; + set_min_and_max_values_for_integral_type (ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp); + + /* If -fstrict-enums, still constrain TYPE_MIN/MAX_VALUE. */ + if (flag_strict_enums) + set_min_and_max_values_for_integral_type (enumtype, precision, + unsignedp); } else underlying_type = ENUM_UNDERLYING_TYPE (enumtype); - /* Compute the minimum and maximum values for the type. - - [dcl.enum] - - For an enumeration where emin is the smallest enumerator and emax - is the largest, the values of the enumeration are the values of the - underlying type in the range bmin to bmax, where bmin and bmax are, - respectively, the smallest and largest values of the smallest bit- - field that can store emin and emax. */ - - /* The middle-end currently assumes that types with TYPE_PRECISION - narrower than their underlying type are suitably zero or sign - extended to fill their mode. g++ doesn't make these guarantees. - Until the middle-end can represent such paradoxical types, we - set the TYPE_PRECISION to the width of the underlying type. */ - TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type); - - set_min_and_max_values_for_integral_type (enumtype, precision, unsignedp); - /* Convert each of the enumerators to the type of the underlying type of the enumeration. */ for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values)) @@ -11440,10 +11625,11 @@ finish_enum (tree enumtype) /* Build and install a CONST_DECL for an enumeration constant of the enumeration type ENUMTYPE whose NAME and VALUE (if any) are provided. + LOC is the location of NAME. Assignment of sequential values by default is handled here. */ void -build_enumerator (tree name, tree value, tree enumtype) +build_enumerator (tree name, tree value, tree enumtype, location_t loc) { tree decl; tree context; @@ -11558,12 +11744,12 @@ build_enumerator (tree name, tree value, tree enumtype) if (context && context == current_class_type) /* This enum declaration is local to the class. We need the full lang_decl so that we can record DECL_CLASS_CONTEXT, for example. */ - decl = build_lang_decl (CONST_DECL, name, type); + decl = build_lang_decl_loc (loc, CONST_DECL, name, type); else /* It's a global enum, or it's local to a function. (Note local to - a function could mean local to a class method. */ - decl = build_decl (input_location, CONST_DECL, name, type); - + a function could mean local to a class method. */ + decl = build_decl (loc, CONST_DECL, name, type); + DECL_CONTEXT (decl) = FROB_CONTEXT (context); TREE_CONSTANT (decl) = 1; TREE_READONLY (decl) = 1; @@ -11896,7 +12082,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) /* Initialize the language data structures. Whenever we start a new function, we destroy temporaries in the usual way. */ - cfun->language = GGC_CNEW (struct language_function); + cfun->language = ggc_alloc_cleared_language_function (); current_stmt_tree ()->stmts_are_full_exprs_p = 1; current_binding_level = bl; @@ -11931,11 +12117,11 @@ start_preparsed_function (tree decl1, tree attrs, int flags) /* Constructors and destructors need to know whether they're "in charge" of initializing virtual base classes. */ - t = TREE_CHAIN (t); + t = DECL_CHAIN (t); if (DECL_HAS_IN_CHARGE_PARM_P (decl1)) { current_in_charge_parm = t; - t = TREE_CHAIN (t); + t = DECL_CHAIN (t); } if (DECL_HAS_VTT_PARM_P (decl1)) { @@ -12016,9 +12202,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) if ((DECL_DECLARED_INLINE_P (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1)) - && ! DECL_INTERFACE_KNOWN (decl1) - /* Don't try to defer nested functions for now. */ - && ! decl_function_context (decl1)) + && ! DECL_INTERFACE_KNOWN (decl1)) DECL_DEFER_OUTPUT (decl1) = 1; else DECL_INTERFACE_KNOWN (decl1) = 1; @@ -12094,7 +12278,7 @@ use_eh_spec_block (tree fn) { return (flag_exceptions && flag_enforce_eh_specs && !processing_template_decl - && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)) + && !type_throw_all_p (TREE_TYPE (fn)) /* We insert the EH_SPEC_BLOCK only in the original function; then, it is copied automatically to the clones. */ @@ -12148,7 +12332,7 @@ store_parm_decls (tree current_function_parms) for (parm = specparms; parm; parm = next) { - next = TREE_CHAIN (parm); + next = DECL_CHAIN (parm); if (TREE_CODE (parm) == PARM_DECL) { if (DECL_NAME (parm) == NULL_TREE @@ -12199,7 +12383,7 @@ save_function_data (tree decl) gcc_assert (!DECL_PENDING_INLINE_P (decl)); /* Make a copy. */ - f = GGC_NEW (struct language_function); + f = ggc_alloc_language_function (); memcpy (f, cp_function_chain, sizeof (struct language_function)); DECL_SAVED_FUNCTION_DATA (decl) = f; @@ -12384,6 +12568,22 @@ outer_curly_brace_block (tree fndecl) return block; } +/* If FNDECL is a class's key method, add the class to the list of + keyed classes that should be emitted. */ + +static void +record_key_method_defined (tree fndecl) +{ + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl) + && DECL_VIRTUAL_P (fndecl) + && !processing_template_decl) + { + tree fnclass = DECL_CONTEXT (fndecl); + if (fndecl == CLASSTYPE_KEY_METHOD (fnclass)) + keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes); + } +} + /* Finish up a function declaration and compile that function all the way to assembler language output. The free the storage for the function definition. @@ -12410,14 +12610,7 @@ finish_function (int flags) gcc_assert (!defer_mark_used_calls); defer_mark_used_calls = true; - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl) - && DECL_VIRTUAL_P (fndecl) - && !processing_template_decl) - { - tree fnclass = DECL_CONTEXT (fndecl); - if (fndecl == CLASSTYPE_KEY_METHOD (fnclass)) - keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes); - } + record_key_method_defined (fndecl); nested = function_depth > 1; fntype = TREE_TYPE (fndecl); @@ -12565,6 +12758,33 @@ finish_function (int flags) info for the epilogue. */ cfun->function_end_locus = input_location; + /* Complain about parameters that are only set, but never otherwise used. */ + if (warn_unused_but_set_parameter + && !processing_template_decl + && errorcount == unused_but_set_errorcount + && !DECL_CLONED_FUNCTION_P (fndecl)) + { + tree decl; + + for (decl = DECL_ARGUMENTS (fndecl); + decl; + decl = DECL_CHAIN (decl)) + if (TREE_USED (decl) + && TREE_CODE (decl) == PARM_DECL + && !DECL_READ_P (decl) + && DECL_NAME (decl) + && !DECL_ARTIFICIAL (decl) + && !TREE_NO_WARNING (decl) + && !DECL_IN_SYSTEM_HEADER (decl) + && TREE_TYPE (decl) != error_mark_node + && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE + && (!CLASS_TYPE_P (TREE_TYPE (decl)) + || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))) + warning (OPT_Wunused_but_set_parameter, + "parameter %q+D set but not used", decl); + unused_but_set_errorcount = errorcount; + } + /* Genericize before inlining. */ if (!processing_template_decl) { @@ -12615,7 +12835,7 @@ finish_function (int flags) unsigned int i; tree decl; - for (i = 0; VEC_iterate (tree, deferred_mark_used_calls, i, decl); i++) + FOR_EACH_VEC_ELT (tree, deferred_mark_used_calls, i, decl) mark_used (decl); VEC_free (tree, gc, deferred_mark_used_calls); } @@ -12691,7 +12911,7 @@ grokmethod (cp_decl_specifier_seq *declspecs, if (! DECL_FRIEND_P (fndecl)) { - if (TREE_CHAIN (fndecl)) + if (DECL_CHAIN (fndecl)) { fndecl = copy_node (fndecl); TREE_CHAIN (fndecl) = NULL_TREE; @@ -12727,7 +12947,12 @@ maybe_register_incomplete_var (tree var) /* RTTI TD entries are created while defining the type_info. */ || (TYPE_LANG_SPECIFIC (inner_type) && TYPE_BEING_DEFINED (inner_type))) - incomplete_vars = tree_cons (inner_type, var, incomplete_vars); + { + incomplete_var *iv + = VEC_safe_push (incomplete_var, gc, incomplete_vars, NULL); + iv->decl = var; + iv->incomplete_type = inner_type; + } } } @@ -12738,24 +12963,24 @@ maybe_register_incomplete_var (tree var) void complete_vars (tree type) { - tree *list = &incomplete_vars; + unsigned ix; + incomplete_var *iv; - gcc_assert (CLASS_TYPE_P (type)); - while (*list) + for (ix = 0; VEC_iterate (incomplete_var, incomplete_vars, ix, iv); ) { - if (same_type_p (type, TREE_PURPOSE (*list))) + if (same_type_p (type, iv->incomplete_type)) { - tree var = TREE_VALUE (*list); + tree var = iv->decl; tree type = TREE_TYPE (var); /* Complete the type of the variable. The VAR_DECL itself will be laid out in expand_expr. */ complete_type (type); cp_apply_type_quals_to_decl (cp_type_quals (type), var); /* Remove this entry from the list. */ - *list = TREE_CHAIN (*list); + VEC_unordered_remove (incomplete_var, incomplete_vars, ix); } else - list = &TREE_CHAIN (*list); + ix++; } /* Check for pending declarations which may have abstract type. */ @@ -12802,9 +13027,8 @@ cxx_maybe_build_cleanup (tree decl) fn = lookup_name (id); arg = build_address (decl); mark_used (decl); - cleanup = cp_build_function_call (fn, build_tree_list (NULL_TREE, - arg), - tf_warning_or_error); + cleanup = cp_build_function_call_nary (fn, tf_warning_or_error, + arg, NULL_TREE); } /* Handle ordinary C++ destructors. */ type = TREE_TYPE (decl); @@ -12852,7 +13076,6 @@ static_fn_type (tree memfntype) { tree fntype; tree args; - int quals; if (TYPE_PTRMEMFUNC_P (memfntype)) memfntype = TYPE_PTRMEMFUNC_FN_TYPE (memfntype); @@ -12864,8 +13087,7 @@ static_fn_type (tree memfntype) gcc_assert (TREE_CODE (memfntype) == METHOD_TYPE); args = TYPE_ARG_TYPES (memfntype); fntype = build_function_type (TREE_TYPE (memfntype), TREE_CHAIN (args)); - quals = cp_type_quals (TREE_TYPE (TREE_VALUE (args))); - fntype = build_qualified_type (fntype, quals); + fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype)); fntype = (cp_build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (memfntype))); fntype = (build_exception_variant @@ -12885,7 +13107,7 @@ revert_static_member_fn (tree decl) error ("static member function %q#D declared with type qualifiers", decl); if (DECL_ARGUMENTS (decl)) - DECL_ARGUMENTS (decl) = TREE_CHAIN (DECL_ARGUMENTS (decl)); + DECL_ARGUMENTS (decl) = DECL_CHAIN (DECL_ARGUMENTS (decl)); DECL_STATIC_FUNCTION_P (decl) = 1; } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 90adc68c493..63197705b32 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.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, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) @@ -33,26 +33,26 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "rtl.h" -#include "expr.h" #include "flags.h" #include "cp-tree.h" #include "decl.h" #include "output.h" -#include "except.h" #include "toplev.h" #include "timevar.h" #include "cpplib.h" #include "target.h" -#include "c-common.h" +#include "c-family/c-common.h" #include "tree-mudflap.h" #include "cgraph.h" #include "tree-inline.h" -#include "c-pragma.h" +#include "c-family/c-pragma.h" #include "tree-dump.h" #include "intl.h" #include "gimple.h" #include "pointer-set.h" +#include "splay-tree.h" +#include "langhooks.h" +#include "c-family/c-ada-spec.h" extern cpp_reader *parse_in; @@ -154,7 +154,10 @@ change_return_type (tree new_ret, tree fntype) return fntype; if (TREE_CODE (fntype) == FUNCTION_TYPE) - newtype = build_function_type (new_ret, args); + { + newtype = build_function_type (new_ret, args); + newtype = apply_memfn_quals (newtype, type_memfn_quals (fntype)); + } else newtype = build_method_type_directly (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), @@ -239,7 +242,7 @@ maybe_retrofit_in_chrg (tree fn) basetype = TREE_TYPE (TREE_VALUE (arg_types)); arg_types = TREE_CHAIN (arg_types); - parms = TREE_CHAIN (DECL_ARGUMENTS (fn)); + parms = DECL_CHAIN (DECL_ARGUMENTS (fn)); /* If this is a subobject constructor or destructor, our caller will pass us a pointer to our VTT. */ @@ -248,7 +251,7 @@ maybe_retrofit_in_chrg (tree fn) parm = build_artificial_parm (vtt_parm_identifier, vtt_parm_type); /* First add it to DECL_ARGUMENTS between 'this' and the real args... */ - TREE_CHAIN (parm) = parms; + DECL_CHAIN (parm) = parms; parms = parm; /* ...and then to TYPE_ARG_TYPES. */ @@ -259,12 +262,12 @@ maybe_retrofit_in_chrg (tree fn) /* Then add the in-charge parm (before the VTT parm). */ parm = build_artificial_parm (in_charge_identifier, integer_type_node); - TREE_CHAIN (parm) = parms; + DECL_CHAIN (parm) = parms; parms = parm; arg_types = hash_tree_chain (integer_type_node, arg_types); /* Insert our new parameter(s) into the list. */ - TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms; + DECL_CHAIN (DECL_ARGUMENTS (fn)) = parms; /* And rebuild the function type. */ fntype = build_method_type_directly (basetype, TREE_TYPE (TREE_TYPE (fn)), @@ -785,6 +788,10 @@ finish_static_data_member_decl (tree decl, DECL_INITIAL (decl) = init; DECL_IN_AGGR_P (decl) = 1; + if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE + && TYPE_DOMAIN (TREE_TYPE (decl)) == NULL_TREE) + SET_VAR_HAD_UNKNOWN_BOUND (decl); + cp_finish_decl (decl, init, init_const_expr_p, asmspec_tree, flags); } @@ -1059,6 +1066,10 @@ grokbitfield (const cp_declarator *declarator, if (width != error_mark_node) { + /* The width must be an integer type. */ + if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (width))) + error ("width of bit-field %qD has non-integral type %qT", value, + TREE_TYPE (width)); constant_expression_warning (width); DECL_INITIAL (value) = width; SET_DECL_C_BIT_FIELD (value); @@ -1242,6 +1253,7 @@ cp_reconstruct_complex_type (tree type, tree bottom) { inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); outer = build_function_type (inner, TYPE_ARG_TYPES (type)); + outer = apply_memfn_quals (outer, type_memfn_quals (type)); } else if (TREE_CODE (type) == METHOD_TYPE) { @@ -1264,7 +1276,7 @@ cp_reconstruct_complex_type (tree type, tree bottom) if (TYPE_ATTRIBUTES (type)) outer = cp_build_type_attribute_variant (outer, TYPE_ATTRIBUTES (type)); - return cp_build_qualified_type (outer, TYPE_QUALS (type)); + return cp_build_qualified_type (outer, cp_type_quals (type)); } /* Like decl_attributes, but handle C++ complexity. */ @@ -1313,7 +1325,7 @@ build_anon_union_vars (tree type, tree object) for (field = TYPE_FIELDS (type); field != NULL_TREE; - field = TREE_CHAIN (field)) + field = DECL_CHAIN (field)) { tree decl; tree ref; @@ -1800,6 +1812,7 @@ maybe_emit_vtables (tree ctype) tree vtbl; tree primary_vtbl; int needed = 0; + struct varpool_node *current = NULL, *last = NULL, *first = NULL; /* If the vtables for this class have already been emitted there is nothing more to do. */ @@ -1817,7 +1830,7 @@ maybe_emit_vtables (tree ctype) determine_key_method (ctype); /* See if any of the vtables are needed. */ - for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl)) + for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl)) { import_export_decl (vtbl); if (DECL_NOT_REALLY_EXTERN (vtbl) && decl_needed_p (vtbl)) @@ -1836,7 +1849,7 @@ maybe_emit_vtables (tree ctype) /* The ABI requires that we emit all of the vtables if we emit any of them. */ - for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl)) + for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl)) { /* Mark entities references from the virtual table as used. */ mark_vtable_entries (vtbl); @@ -1857,8 +1870,20 @@ maybe_emit_vtables (tree ctype) actually marking the variable as written. */ if (flag_syntax_only) TREE_ASM_WRITTEN (vtbl) = 1; + else if (DECL_COMDAT (vtbl)) + { + current = varpool_node (vtbl); + if (last) + last->same_comdat_group = current; + last = current; + if (!first) + first = current; + } } + if (first != last) + last->same_comdat_group = first; + /* Since we're writing out the vtable here, also write the debug info. */ note_debug_info_needed (ctype); @@ -2221,7 +2246,7 @@ constrain_class_visibility (tree type) if (CLASSTYPE_VISIBILITY_SPECIFIED (type)) vis = VISIBILITY_INTERNAL; - for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t)) + for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t)) if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node) { tree ftype = strip_pointer_or_array_types (TREE_TYPE (t)); @@ -2703,8 +2728,8 @@ start_objects (int method_type, int initp) fndecl = build_lang_decl (FUNCTION_DECL, get_file_function_name (type), - build_function_type (void_type_node, - void_list_node)); + build_function_type_list (void_type_node, + NULL_TREE)); start_preparsed_function (fndecl, /*attrs=*/NULL_TREE, SF_PRE_PARSED); TREE_PUBLIC (current_function_decl) = 0; @@ -2796,7 +2821,6 @@ static splay_tree priority_info_map; static tree start_static_storage_duration_function (unsigned count) { - tree parm_types; tree type; tree body; char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 32]; @@ -2805,11 +2829,9 @@ start_static_storage_duration_function (unsigned count) SSDF_IDENTIFIER_<number>. */ sprintf (id, "%s_%u", SSDF_IDENTIFIER, count); - /* Create the parameters. */ - parm_types = void_list_node; - parm_types = tree_cons (NULL_TREE, integer_type_node, parm_types); - parm_types = tree_cons (NULL_TREE, integer_type_node, parm_types); - type = build_function_type (void_type_node, parm_types); + type = build_function_type_list (void_type_node, + integer_type_node, integer_type_node, + NULL_TREE); /* Create the FUNCTION_DECL itself. */ ssdf_decl = build_lang_decl (FUNCTION_DECL, @@ -2850,7 +2872,7 @@ start_static_storage_duration_function (unsigned count) DECL_CONTEXT (priority_decl) = ssdf_decl; TREE_USED (priority_decl) = 1; - TREE_CHAIN (initialize_p_decl) = priority_decl; + DECL_CHAIN (initialize_p_decl) = priority_decl; DECL_ARGUMENTS (ssdf_decl) = initialize_p_decl; /* Put the function in the global scope. */ @@ -2948,7 +2970,7 @@ fix_temporary_vars_context_r (tree *node, { tree var; - for (var = BIND_EXPR_VARS (*node); var; var = TREE_CHAIN (var)) + for (var = BIND_EXPR_VARS (*node); var; var = DECL_CHAIN (var)) if (TREE_CODE (var) == VAR_DECL && !DECL_NAME (var) && DECL_ARTIFICIAL (var) @@ -3255,7 +3277,6 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority, location_t *locus) { char function_key; - tree arguments; tree fndecl; tree body; size_t i; @@ -3283,22 +3304,23 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority, /* Call the static storage duration function with appropriate arguments. */ - for (i = 0; VEC_iterate (tree, ssdf_decls, i, fndecl); ++i) + FOR_EACH_VEC_ELT (tree, ssdf_decls, i, fndecl) { /* Calls to pure or const functions will expand to nothing. */ if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE))) { + tree call; + if (! body) body = start_objects (function_key, priority); - arguments = tree_cons (NULL_TREE, - build_int_cst (NULL_TREE, priority), - NULL_TREE); - arguments = tree_cons (NULL_TREE, - build_int_cst (NULL_TREE, constructor_p), - arguments); - finish_expr_stmt (cp_build_function_call (fndecl, arguments, - tf_warning_or_error)); + call = cp_build_function_call_nary (fndecl, tf_warning_or_error, + build_int_cst (NULL_TREE, + constructor_p), + build_int_cst (NULL_TREE, + priority), + NULL_TREE); + finish_expr_stmt (call); } } @@ -3350,19 +3372,9 @@ cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED) cgraph_mark_address_taken_node (cgraph_node (BASELINK_FUNCTIONS (t))); break; case VAR_DECL: - if (DECL_VTABLE_OR_VTT_P (t)) - { - /* The ABI requires that all virtual tables be emitted - whenever one of them is. */ - tree vtbl; - for (vtbl = CLASSTYPE_VTABLES (DECL_CONTEXT (t)); - vtbl; - vtbl = TREE_CHAIN (vtbl)) - mark_decl_referenced (vtbl); - } - else if (DECL_CONTEXT (t) - && flag_use_repository - && TREE_CODE (DECL_CONTEXT (t)) == FUNCTION_DECL) + if (DECL_CONTEXT (t) + && flag_use_repository + && TREE_CODE (DECL_CONTEXT (t)) == FUNCTION_DECL) /* If we need a static variable in a function, then we need the containing function. */ mark_decl_referenced (DECL_CONTEXT (t)); @@ -3451,6 +3463,69 @@ build_java_method_aliases (struct pointer_set_t *candidates) } } +/* Return C++ property of T, based on given operation OP. */ + +static int +cpp_check (tree t, cpp_operation op) +{ + switch (op) + { + case IS_ABSTRACT: + return DECL_PURE_VIRTUAL_P (t); + case IS_CONSTRUCTOR: + return DECL_CONSTRUCTOR_P (t); + case IS_DESTRUCTOR: + return DECL_DESTRUCTOR_P (t); + case IS_COPY_CONSTRUCTOR: + return DECL_COPY_CONSTRUCTOR_P (t); + case IS_TEMPLATE: + return TREE_CODE (t) == TEMPLATE_DECL; + default: + return 0; + } +} + +/* Collect source file references recursively, starting from NAMESPC. */ + +static void +collect_source_refs (tree namespc) +{ + tree t; + + if (!namespc) + return; + + /* Iterate over names in this name space. */ + for (t = NAMESPACE_LEVEL (namespc)->names; t; t = TREE_CHAIN (t)) + if (!DECL_IS_BUILTIN (t) ) + collect_source_ref (DECL_SOURCE_FILE (t)); + + /* Dump siblings, if any */ + collect_source_refs (TREE_CHAIN (namespc)); + + /* Dump children, if any */ + collect_source_refs (NAMESPACE_LEVEL (namespc)->namespaces); +} + +/* Collect decls relevant to SOURCE_FILE from all namespaces recursively, + starting from NAMESPC. */ + +static void +collect_ada_namespace (tree namespc, const char *source_file) +{ + if (!namespc) + return; + + /* Collect decls from this namespace */ + collect_ada_nodes (NAMESPACE_LEVEL (namespc)->names, source_file); + + /* Collect siblings, if any */ + collect_ada_namespace (TREE_CHAIN (namespc), source_file); + + /* Collect children, if any */ + collect_ada_namespace (NAMESPACE_LEVEL (namespc)->namespaces, source_file); +} + /* Returns true iff there is a definition available for variable or function DECL. */ @@ -3485,6 +3560,14 @@ no_linkage_error (tree decl) "is used but never defined", decl, t); } +/* Collect declarations from all namespaces relevant to SOURCE_FILE. */ + +static void +collect_all_refs (const char *source_file) +{ + collect_ada_namespace (global_namespace, source_file); +} + /* This routine is called at the end of compilation. Its job is to create all the code needed to initialize and destroy the global aggregates. We do the destruction @@ -3506,12 +3589,24 @@ cp_write_global_declarations (void) at_eof = 1; /* Bad parse errors. Just forget about it. */ - if (! global_bindings_p () || current_class_type || decl_namespace_list) + if (! global_bindings_p () || current_class_type + || !VEC_empty (tree,decl_namespace_list)) return; if (pch_file) c_common_write_pch (); + /* Handle -fdump-ada-spec[-slim] */ + if (dump_enabled_p (TDI_ada)) + { + if (get_dump_file_info (TDI_ada)->flags & TDF_SLIM) + collect_source_ref (main_input_filename); + else + collect_source_refs (global_namespace); + + dump_ada_specs (collect_all_refs, cpp_check); + } + /* FIXME - huh? was input_line -= 1;*/ /* We now have to write out all the stuff we put off writing out. @@ -3651,7 +3746,7 @@ cp_write_global_declarations (void) /* Go through the set of inline functions whose bodies have not been emitted yet. If out-of-line copies of these functions are required, emit them. */ - for (i = 0; VEC_iterate (tree, deferred_fns, i, decl); ++i) + FOR_EACH_VEC_ELT (tree, deferred_fns, i, decl) { /* Does it need synthesizing? */ if (DECL_DEFAULTED_FN (decl) && ! DECL_INITIAL (decl) @@ -3753,7 +3848,7 @@ cp_write_global_declarations (void) reconsider = true; /* Static data members are just like namespace-scope globals. */ - for (i = 0; VEC_iterate (tree, pending_statics, i, decl); ++i) + FOR_EACH_VEC_ELT (tree, pending_statics, i, decl) { if (var_finalized_p (decl) || DECL_REALLY_EXTERN (decl) /* Don't write it out if we haven't seen a definition. */ @@ -3775,7 +3870,7 @@ cp_write_global_declarations (void) while (reconsider); /* All used inline functions must have a definition at this point. */ - for (i = 0; VEC_iterate (tree, deferred_fns, i, decl); ++i) + FOR_EACH_VEC_ELT (tree, deferred_fns, i, decl) { if (/* Check online inline functions that were actually used. */ DECL_ODR_USED (decl) && DECL_DECLARED_INLINE_P (decl) @@ -3797,7 +3892,7 @@ cp_write_global_declarations (void) } /* So must decls that use a type with no linkage. */ - for (i = 0; VEC_iterate (tree, no_linkage_decls, i, decl); ++i) + FOR_EACH_VEC_ELT (tree, no_linkage_decls, i, decl) if (!decl_defined_p (decl)) no_linkage_error (decl); @@ -3843,6 +3938,8 @@ cp_write_global_declarations (void) VEC_length (tree, pending_statics)); } + perform_deferred_noexcept_checks (); + /* Generate hidden aliases for Java. */ if (candidates) { @@ -4019,8 +4116,9 @@ mark_used (tree decl) return; } } - error ("deleted function %q+D", decl); - error ("used here"); + error ("use of deleted function %qD", decl); + if (!maybe_explain_implicit_delete (decl)) + error_at (DECL_SOURCE_LOCATION (decl), "declared here"); return; } /* If we don't need a value, then we don't need to synthesize DECL. */ diff --git a/gcc/cp/dump.c b/gcc/cp/dump.c index 5ca10fca2a1..1e698bceb97 100644 --- a/gcc/cp/dump.c +++ b/gcc/cp/dump.c @@ -453,6 +453,13 @@ cp_dump_tree (void* dump_info, tree t) dump_child ("body", FOR_BODY (t)); break; + case RANGE_FOR_STMT: + dump_stmt (di, t); + dump_child ("decl", RANGE_FOR_DECL (t)); + dump_child ("expr", RANGE_FOR_EXPR (t)); + dump_child ("body", RANGE_FOR_BODY (t)); + break; + case SWITCH_STMT: dump_stmt (di, t); dump_child ("cond", SWITCH_STMT_COND (t)); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index b03c83ff152..981b71f5452 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1,7 +1,7 @@ /* Call-backs for C++ error reporting. This code is non-reentrant. - Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, + 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify @@ -24,13 +24,14 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tree.h" #include "cp-tree.h" -#include "real.h" #include "toplev.h" #include "flags.h" #include "diagnostic.h" +#include "tree-diagnostic.h" #include "langhooks-def.h" #include "intl.h" #include "cxx-pretty-print.h" +#include "tree-pretty-print.h" #include "pointer-set.h" #define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',') @@ -114,7 +115,7 @@ init_error (void) static void dump_scope (tree scope, int flags) { - int f = ~TFF_RETURN_TYPE & (flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF)); + int f = flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF); if (scope == NULL_TREE) return; @@ -303,7 +304,7 @@ dump_template_bindings (tree parms, tree args, VEC(tree,gc)* typenames) parms = TREE_CHAIN (parms); } - for (i = 0; VEC_iterate (tree, typenames, i, t); ++i) + FOR_EACH_VEC_ELT (tree, typenames, i, t) { if (need_comma) pp_separate_with_comma (cxx_pp); @@ -328,16 +329,40 @@ dump_type (tree t, int flags) if (t == NULL_TREE) return; + /* Don't print e.g. "struct mytypedef". */ + if (TYPE_P (t) && typedef_variant_p (t)) + { + tree decl = TYPE_NAME (t); + if ((flags & TFF_CHASE_TYPEDEF) + || DECL_SELF_REFERENCE_P (decl) + || (!flag_pretty_templates + && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))) + t = strip_typedefs (t); + else if (same_type_p (t, TREE_TYPE (decl))) + t = decl; + else + { + pp_cxx_cv_qualifier_seq (cxx_pp, t); + pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); + return; + } + } + if (TYPE_PTRMEMFUNC_P (t)) goto offset_type; switch (TREE_CODE (t)) { - case UNKNOWN_TYPE: + case LANG_TYPE: if (t == init_list_type_node) pp_string (cxx_pp, M_("<brace-enclosed initializer list>")); - else + else if (t == unknown_type_node) pp_string (cxx_pp, M_("<unresolved overloaded function type>")); + else + { + pp_cxx_cv_qualifier_seq (cxx_pp, t); + pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); + } break; case TREE_LIST: @@ -694,7 +719,7 @@ dump_type_prefix (tree t, int flags) case TYPE_DECL: case TREE_VEC: case UNION_TYPE: - case UNKNOWN_TYPE: + case LANG_TYPE: case VOID_TYPE: case TYPENAME_TYPE: case COMPLEX_TYPE: @@ -796,7 +821,7 @@ dump_type_suffix (tree t, int flags) case TYPE_DECL: case TREE_VEC: case UNION_TYPE: - case UNKNOWN_TYPE: + case LANG_TYPE: case VOID_TYPE: case TYPENAME_TYPE: case COMPLEX_TYPE: @@ -840,6 +865,7 @@ dump_simple_decl (tree t, tree type, int flags) pp_maybe_space (cxx_pp); } if (! (flags & TFF_UNQUALIFIED_NAME) + && TREE_CODE (t) != PARM_DECL && (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)) dump_scope (CP_DECL_CONTEXT (t), flags); @@ -920,7 +946,7 @@ dump_decl (tree t, int flags) dump_scope (CP_DECL_CONTEXT (t), flags); flags &= ~TFF_UNQUALIFIED_NAME; if (DECL_NAME (t) == NULL_TREE) - pp_string (cxx_pp, M_("<unnamed>")); + pp_cxx_ws_string (cxx_pp, M_("{anonymous}")); else pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t)); } @@ -1221,7 +1247,7 @@ dump_function_decl (tree t, int flags) tree exceptions; VEC(tree,gc) *typenames = NULL; - if (LAMBDA_FUNCTION_P (t)) + if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t)) { /* A lambda's signature is essentially its "type", so defer. */ gcc_assert (LAMBDA_TYPE_P (DECL_CONTEXT (t))); @@ -1330,6 +1356,7 @@ static void dump_parameters (tree parmtypes, int flags) { int first = 1; + flags &= ~TFF_SCOPE; pp_cxx_left_paren (cxx_pp); for (first = 1; parmtypes != void_list_node; @@ -1363,7 +1390,15 @@ dump_parameters (tree parmtypes, int flags) static void dump_exception_spec (tree t, int flags) { - if (t) + if (t && TREE_PURPOSE (t)) + { + pp_cxx_ws_string (cxx_pp, "noexcept"); + pp_cxx_whitespace (cxx_pp); + pp_cxx_left_paren (cxx_pp); + dump_expr (TREE_PURPOSE (t), flags); + pp_cxx_right_paren (cxx_pp); + } + else if (t) { pp_cxx_ws_string (cxx_pp, "throw"); pp_cxx_whitespace (cxx_pp); @@ -1724,7 +1759,9 @@ dump_expr (tree t, int flags) if (TREE_CODE (fn) == OBJ_TYPE_REF) fn = resolve_virtual_fun_from_obj_type_ref (fn); - if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE) + if (TREE_TYPE (fn) != NULL_TREE + && NEXT_CODE (fn) == METHOD_TYPE + && call_expr_nargs (t)) { tree ob = CALL_EXPR_ARG (t, 0); if (TREE_CODE (ob) == ADDR_EXPR) @@ -2091,6 +2128,14 @@ dump_expr (tree t, int flags) pp_cxx_right_paren (cxx_pp); break; + case NOEXCEPT_EXPR: + pp_cxx_ws_string (cxx_pp, "noexcept"); + pp_cxx_whitespace (cxx_pp); + pp_cxx_left_paren (cxx_pp); + dump_expr (TREE_OPERAND (t, 0), flags); + pp_cxx_right_paren (cxx_pp); + break; + case REALPART_EXPR: case IMAGPART_EXPR: pp_cxx_ws_string (cxx_pp, operator_name_info[TREE_CODE (t)].name); @@ -2544,7 +2589,8 @@ cp_diagnostic_starter (diagnostic_context *context, diagnostic_report_current_module (context); cp_print_error_function (context, diagnostic); maybe_print_instantiation_context (context); - pp_base_set_prefix (context->printer, diagnostic_build_prefix (diagnostic)); + pp_base_set_prefix (context->printer, diagnostic_build_prefix (context, + diagnostic)); } static void @@ -2564,7 +2610,7 @@ cp_print_error_function (diagnostic_context *context, { const char *old_prefix = context->printer->prefix; const char *file = LOCATION_FILE (diagnostic->location); - tree abstract_origin = diagnostic->abstract_origin; + tree abstract_origin = diagnostic_abstract_origin (diagnostic); char *new_prefix = (file && abstract_origin == NULL) ? file_name_as_prefix (file) : NULL; @@ -2638,7 +2684,7 @@ cp_print_error_function (diagnostic_context *context, pp_base_newline (context->printer); if (s.file != NULL) { - if (flag_show_column && s.column != 0) + if (context->show_column && s.column != 0) pp_printf (context->printer, _(" inlined from %qs at %s:%d:%d"), cxx_printable_name_translate (fndecl, 2), @@ -2733,31 +2779,45 @@ print_instantiation_full_context (diagnostic_context *context) static void print_instantiation_partial_context_line (diagnostic_context *context, - const struct tinst_level *t, location_t loc) + const struct tinst_level *t, + location_t loc, bool recursive_p) { expanded_location xloc; xloc = expand_location (loc); - if (t != NULL) { - const char *str; - str = decl_as_string_translate (t->decl, - TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE); - if (flag_show_column) - pp_verbatim (context->printer, - _("%s:%d:%d: instantiated from %qs\n"), - xloc.file, xloc.line, xloc.column, str); - else - pp_verbatim (context->printer, - _("%s:%d: instantiated from %qs\n"), - xloc.file, xloc.line, str); - } else { - if (flag_show_column) - pp_verbatim (context->printer, _("%s:%d:%d: instantiated from here"), - xloc.file, xloc.line, xloc.column); - else - pp_verbatim (context->printer, _("%s:%d: instantiated from here"), - xloc.file, xloc.line); - } + if (t != NULL) + { + const char *str; + str = decl_as_string_translate (t->decl, + TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE); + if (context->show_column) + pp_verbatim (context->printer, + recursive_p + ? _("%s:%d:%d: recursively instantiated from %qs\n") + : _("%s:%d:%d: instantiated from %qs\n"), + xloc.file, xloc.line, xloc.column, str); + else + pp_verbatim (context->printer, + recursive_p + ? _("%s:%d: recursively instantiated from %qs\n") + : _("%s:%d: recursively instantiated from %qs\n"), + xloc.file, xloc.line, str); + } + else + { + if (context->show_column) + pp_verbatim (context->printer, + recursive_p + ? _("%s:%d:%d: recursively instantiated from here") + : _("%s:%d:%d: instantiated from here"), + xloc.file, xloc.line, xloc.column); + else + pp_verbatim (context->printer, + recursive_p + ? _("%s:%d: recursively instantiated from here") + : _("%s:%d: instantiated from here"), + xloc.file, xloc.line); + } } /* Same as print_instantiation_full_context but less verbose. */ @@ -2769,9 +2829,14 @@ print_instantiation_partial_context (diagnostic_context *context, struct tinst_level *t; int n_total = 0; int n; + location_t prev_loc = loc; for (t = t0; t != NULL; t = t->next) - n_total++; + if (prev_loc != t->locus) + { + prev_loc = t->locus; + n_total++; + } t = t0; @@ -2781,15 +2846,17 @@ print_instantiation_partial_context (diagnostic_context *context, for (n = 0; n < 5; n++) { gcc_assert (t != NULL); - print_instantiation_partial_context_line (context, t, loc); + if (loc != t->locus) + print_instantiation_partial_context_line (context, t, loc, + /*recursive_p=*/false); loc = t->locus; t = t->next; } - if (skip > 1) + if (t != NULL && skip > 1) { expanded_location xloc; xloc = expand_location (loc); - if (flag_show_column) + if (context->show_column) pp_verbatim (context->printer, _("%s:%d:%d: [ skipping %d instantiation contexts ]\n"), xloc.file, xloc.line, xloc.column, skip); @@ -2799,18 +2866,26 @@ print_instantiation_partial_context (diagnostic_context *context, xloc.file, xloc.line, skip); do { - loc = t->locus; - t = t->next; - } while (--skip > 0); + loc = t->locus; + t = t->next; + } while (t != NULL && --skip > 0); } } - for (; t != NULL; t = t->next) + while (t != NULL) { - print_instantiation_partial_context_line (context, t, loc); + while (t->next != NULL && t->locus == t->next->locus) + { + loc = t->locus; + t = t->next; + } + print_instantiation_partial_context_line (context, t, loc, + t->locus == loc); loc = t->locus; + t = t->next; } - print_instantiation_partial_context_line (context, NULL, loc); + print_instantiation_partial_context_line (context, NULL, loc, + /*recursive_p=*/false); pp_base_newline (context->printer); } @@ -2893,6 +2968,10 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec, case 'T': result = type_to_string (next_tree, verbose); break; case 'V': result = cv_to_string (next_tree, verbose); break; + case 'K': + percent_K_format (text); + return true; + default: return false; } @@ -2949,6 +3028,11 @@ maybe_warn_cpp0x (cpp0x_warn_str str) pedwarn (input_location, 0, "defaulted and deleted functions " "only available with -std=c++0x or -std=gnu++0x"); + break; + case CPP0X_INLINE_NAMESPACES: + pedwarn (input_location, OPT_pedantic, + "inline namespaces " + "only available with -std=c++0x or -std=gnu++0x"); break; default: gcc_unreachable(); diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 4f4f85b490d..351e685a687 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -28,13 +28,9 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "rtl.h" -#include "expr.h" -#include "libfuncs.h" #include "cp-tree.h" #include "flags.h" #include "output.h" -#include "except.h" #include "toplev.h" #include "tree-inline.h" #include "tree-iterator.h" @@ -53,7 +49,6 @@ static tree wrap_cleanups_r (tree *, int *, void *); static int complete_ptr_ref_or_void_ptr_p (tree, tree); static bool is_admissible_throw_operand (tree); static int can_convert_eh (tree, tree); -static tree cp_protect_cleanup_actions (void); /* Sets up all the global eh stuff that needs to be initialized at the start of compilation. */ @@ -65,25 +60,22 @@ init_exception_processing (void) /* void std::terminate (); */ push_namespace (std_identifier); - tmp = build_function_type (void_type_node, void_list_node); + tmp = build_function_type_list (void_type_node, NULL_TREE); terminate_node = build_cp_library_fn_ptr ("terminate", tmp); TREE_THIS_VOLATILE (terminate_node) = 1; TREE_NOTHROW (terminate_node) = 1; pop_namespace (); /* void __cxa_call_unexpected(void *); */ - tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node); - tmp = build_function_type (void_type_node, tmp); + tmp = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); call_unexpected_node = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp); - - lang_protect_cleanup_actions = &cp_protect_cleanup_actions; } /* Returns an expression to be executed if an unhandled exception is propagated out of a cleanup region. */ -static tree +tree cp_protect_cleanup_actions (void) { /* [except.terminate] @@ -163,8 +155,9 @@ build_exc_ptr (void) static tree declare_nothrow_library_fn (tree name, tree return_type, tree parm_type) { - tree tmp = tree_cons (NULL_TREE, parm_type, void_list_node); - return push_library_fn (name, build_function_type (return_type, tmp), + return push_library_fn (name, build_function_type_list (return_type, + parm_type, + NULL_TREE), empty_except_spec); } @@ -183,9 +176,8 @@ do_get_exception_ptr (void) fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node); } - return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (), - NULL_TREE), - tf_warning_or_error); + return cp_build_function_call_nary (fn, tf_warning_or_error, + build_exc_ptr (), NULL_TREE); } /* Build up a call to __cxa_begin_catch, to tell the runtime that the @@ -203,9 +195,8 @@ do_begin_catch (void) fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node); } - return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (), - NULL_TREE), - tf_warning_or_error); + return cp_build_function_call_nary (fn, tf_warning_or_error, + build_exc_ptr (), NULL_TREE); } /* Returns nonzero if cleaning up an exception of type TYPE (which can be @@ -214,10 +205,10 @@ do_begin_catch (void) static int dtor_nothrow (tree type) { - if (type == NULL_TREE) + if (type == NULL_TREE || type == error_mark_node) return 0; - if (!CLASS_TYPE_P (type)) + if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type)) return 1; if (CLASSTYPE_LAZY_DESTRUCTOR (type)) @@ -243,7 +234,7 @@ do_end_catch (tree type) TREE_NOTHROW (fn) = 0; } - cleanup = cp_build_function_call (fn, NULL_TREE, tf_warning_or_error); + cleanup = cp_build_function_call_vec (fn, NULL, tf_warning_or_error); TREE_NOTHROW (cleanup) = dtor_nothrow (type); return cleanup; @@ -369,6 +360,7 @@ initialize_handler_parm (tree decl, tree exp) /* Make sure we mark the catch param as used, otherwise we'll get a warning about an unused ((anonymous)). */ TREE_USED (decl) = 1; + DECL_READ_P (decl) = 1; /* Figure out the type that the initializer is. Pointers are returned adjusted by value from __cxa_begin_catch. Others are returned by @@ -411,6 +403,30 @@ initialize_handler_parm (tree decl, tree exp) LOOKUP_ONLYCONVERTING|DIRECT_BIND); } + +/* Routine to see if exception handling is turned on. + DO_WARN is nonzero if we want to inform the user that exception + handling is turned off. + + This is used to ensure that -fexceptions has been specified if the + compiler tries to use any exception-specific functions. */ + +static inline int +doing_eh (void) +{ + if (! flag_exceptions) + { + static int warned = 0; + if (! warned) + { + error ("exception handling disabled, use -fexceptions to enable"); + warned = 1; + } + return 0; + } + return 1; +} + /* Call this to start a catch block. DECL is the catch parameter. */ tree @@ -419,7 +435,7 @@ expand_start_catch_block (tree decl) tree exp; tree type, init; - if (! doing_eh (1)) + if (! doing_eh ()) return NULL_TREE; /* Make sure this declaration is reasonable. */ @@ -498,7 +514,7 @@ expand_start_catch_block (tree decl) void expand_end_catch_block (void) { - if (! doing_eh (1)) + if (! doing_eh ()) return; /* The exception being handled is rethrown if control reaches the end of @@ -512,9 +528,18 @@ expand_end_catch_block (void) tree begin_eh_spec_block (void) { - tree r = build_stmt (input_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE); + tree r; + /* A noexcept specification (or throw() with -fnothrow-opt) is a + MUST_NOT_THROW_EXPR. */ + if (TYPE_NOEXCEPT_P (TREE_TYPE (current_function_decl))) + { + r = build_stmt (input_location, MUST_NOT_THROW_EXPR, NULL_TREE); + TREE_SIDE_EFFECTS (r) = 1; + } + else + r = build_stmt (input_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE); add_stmt (r); - EH_SPEC_STMTS (r) = push_stmt_list (); + TREE_OPERAND (r, 0) = push_stmt_list (); return r; } @@ -523,7 +548,11 @@ finish_eh_spec_block (tree raw_raises, tree eh_spec_block) { tree raises; - EH_SPEC_STMTS (eh_spec_block) = pop_stmt_list (EH_SPEC_STMTS (eh_spec_block)); + TREE_OPERAND (eh_spec_block, 0) + = pop_stmt_list (TREE_OPERAND (eh_spec_block, 0)); + + if (TREE_CODE (eh_spec_block) == MUST_NOT_THROW_EXPR) + return; /* Strip cv quals, etc, from the specification types. */ for (raises = NULL_TREE; @@ -554,10 +583,8 @@ do_allocate_exception (tree type) fn = declare_nothrow_library_fn (fn, ptr_type_node, size_type_node); } - return cp_build_function_call (fn, - tree_cons (NULL_TREE, size_in_bytes (type), - NULL_TREE), - tf_warning_or_error); + return cp_build_function_call_nary (fn, tf_warning_or_error, + size_in_bytes (type), NULL_TREE); } /* Call __cxa_free_exception from a cleanup. This is never invoked @@ -575,8 +602,7 @@ do_free_exception (tree ptr) fn = declare_nothrow_library_fn (fn, void_type_node, ptr_type_node); } - return cp_build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE), - tf_warning_or_error); + return cp_build_function_call_nary (fn, tf_warning_or_error, ptr, NULL_TREE); } /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR. @@ -635,7 +661,7 @@ build_throw (tree exp) return error_mark_node; } - if (! doing_eh (1)) + if (! doing_eh ()) return error_mark_node; if (exp && decl_is_java_type (TREE_TYPE (exp), 1)) @@ -644,8 +670,9 @@ build_throw (tree exp) if (!get_global_value_if_present (fn, &fn)) { /* Declare void _Jv_Throw (void *). */ - tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node); - tmp = build_function_type (ptr_type_node, tmp); + tree tmp; + tmp = build_function_type_list (ptr_type_node, + ptr_type_node, NULL_TREE); fn = push_throw_library_fn (fn, tmp); } else if (really_overloaded_fn (fn)) @@ -654,8 +681,8 @@ build_throw (tree exp) return error_mark_node; } fn = OVL_CURRENT (fn); - exp = cp_build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE), - tf_warning_or_error); + exp = cp_build_function_call_nary (fn, tf_warning_or_error, + exp, NULL_TREE); } else if (exp) { @@ -664,15 +691,13 @@ build_throw (tree exp) tree cleanup; tree object, ptr; tree tmp; - tree temp_expr, allocate_expr; - bool elided; + tree allocate_expr; /* The CLEANUP_TYPE is the internal type of a destructor. */ if (!cleanup_type) { - tmp = void_list_node; - tmp = tree_cons (NULL_TREE, ptr_type_node, tmp); - tmp = build_function_type (void_type_node, tmp); + tmp = build_function_type_list (void_type_node, + ptr_type_node, NULL_TREE); cleanup_type = build_pointer_type (tmp); } @@ -681,11 +706,9 @@ build_throw (tree exp) { /* Declare void __cxa_throw (void*, void*, void (*)(void*)). */ /* ??? Second argument is supposed to be "std::type_info*". */ - tmp = void_list_node; - tmp = tree_cons (NULL_TREE, cleanup_type, tmp); - tmp = tree_cons (NULL_TREE, ptr_type_node, tmp); - tmp = tree_cons (NULL_TREE, ptr_type_node, tmp); - tmp = build_function_type (void_type_node, tmp); + tmp = build_function_type_list (void_type_node, + ptr_type_node, ptr_type_node, + cleanup_type, NULL_TREE); fn = push_throw_library_fn (fn, tmp); } @@ -718,11 +741,12 @@ build_throw (tree exp) allocate_expr = do_allocate_exception (temp_type); allocate_expr = get_target_expr (allocate_expr); ptr = TARGET_EXPR_SLOT (allocate_expr); + TARGET_EXPR_CLEANUP (allocate_expr) = do_free_exception (ptr); + CLEANUP_EH_ONLY (allocate_expr) = 1; + object = build_nop (build_pointer_type (temp_type), ptr); object = cp_build_indirect_ref (object, RO_NULL, tf_warning_or_error); - elided = (TREE_CODE (exp) == TARGET_EXPR); - /* And initialize the exception object. */ if (CLASS_TYPE_P (temp_type)) { @@ -760,54 +784,16 @@ build_throw (tree exp) exp = build2 (INIT_EXPR, temp_type, object, tmp); } - /* Pre-evaluate the thrown expression first, since if we allocated - the space first we would have to deal with cleaning it up if - evaluating this expression throws. - - The case where EXP the initializer is a cast or a function - returning a class is a bit of a grey area in the standard; it's - unclear whether or not it should be allowed to throw. We used to - say no, as that allowed us to optimize this case without worrying - about deallocating the exception object if it does. But that - conflicted with expectations (PR 13944) and the EDG compiler; now - we wrap the initialization in a TRY_CATCH_EXPR to call - do_free_exception rather than in a MUST_NOT_THROW_EXPR, for this - case only. - - BUT: Issue 475 may do away with this inconsistency by removing the - terminate() in this situation. - - Note that we don't check the return value from stabilize_init - because it will only return false in cases where elided is true, - and therefore we don't need to work around the failure to - preevaluate. */ - temp_expr = NULL_TREE; - stabilize_init (exp, &temp_expr); - - /* Wrap the initialization in a CLEANUP_POINT_EXPR so that cleanups - for temporaries within the initialization are run before the one - for the exception object, preserving LIFO order. */ - exp = build1 (CLEANUP_POINT_EXPR, void_type_node, exp); - - if (elided) - exp = build2 (TRY_CATCH_EXPR, void_type_node, exp, - do_free_exception (ptr)); - else - exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp); + /* Mark any cleanups from the initialization as MUST_NOT_THROW, since + they are run after the exception object is initialized. */ + cp_walk_tree_without_duplicates (&exp, wrap_cleanups_r, 0); /* Prepend the allocation. */ exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp); - if (temp_expr) - { - /* Prepend the calculation of the throw expression. Also, force - any cleanups from the expression to be evaluated here so that - we don't have to do them during unwinding. But first wrap - them in MUST_NOT_THROW_EXPR, since they are run after the - exception object is initialized. */ - cp_walk_tree_without_duplicates (&temp_expr, wrap_cleanups_r, 0); - exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), temp_expr, exp); - exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp); - } + + /* Force all the cleanups to be evaluated here so that we don't have + to do them during unwinding. */ + exp = build1 (CLEANUP_POINT_EXPR, void_type_node, exp); throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object))); @@ -824,11 +810,9 @@ build_throw (tree exp) else cleanup = build_int_cst (cleanup_type, 0); - tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE); - tmp = tree_cons (NULL_TREE, throw_type, tmp); - tmp = tree_cons (NULL_TREE, ptr, tmp); /* ??? Indicate that this function call throws throw_type. */ - tmp = cp_build_function_call (fn, tmp, tf_warning_or_error); + tmp = cp_build_function_call_nary (fn, tf_warning_or_error, + ptr, throw_type, cleanup, NULL_TREE); /* Tack on the initialization stuff. */ exp = build2 (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp); @@ -842,12 +826,12 @@ build_throw (tree exp) { /* Declare void __cxa_rethrow (void). */ fn = push_throw_library_fn - (fn, build_function_type (void_type_node, void_list_node)); + (fn, build_function_type_list (void_type_node, NULL_TREE)); } /* ??? Indicate that this function call allows exceptions of the type of the enclosing catch block (if known). */ - exp = cp_build_function_call (fn, NULL_TREE, tf_warning_or_error); + exp = cp_build_function_call_vec (fn, NULL, tf_warning_or_error); } exp = build1 (THROW_EXPR, void_type_node, exp); @@ -1032,3 +1016,193 @@ check_handlers (tree handlers) check_handlers_1 (handler, i); } } + +/* walk_tree helper for finish_noexcept_expr. Returns non-null if the + expression *TP causes the noexcept operator to evaluate to false. + + 5.3.7 [expr.noexcept]: The result of the noexcept operator is false if + in a potentially-evaluated context the expression would contain + * a potentially evaluated call to a function, member function, + function pointer, or member function pointer that does not have a + non-throwing exception-specification (15.4), + * a potentially evaluated throw-expression (15.1), + * a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), + where T is a reference type, that requires a run-time check (5.2.7), or + * a potentially evaluated typeid expression (5.2.8) applied to a glvalue + expression whose type is a polymorphic class type (10.3). */ + +static tree +check_noexcept_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED) +{ + tree t = *tp; + enum tree_code code = TREE_CODE (t); + if (code == CALL_EXPR + || code == AGGR_INIT_EXPR) + { + /* We can only use the exception specification of the called function + for determining the value of a noexcept expression; we can't use + TREE_NOTHROW, as it might have a different value in another + translation unit, creating ODR problems. + + We could use TREE_NOTHROW (t) for !TREE_PUBLIC fns, though... */ + tree fn = (code == AGGR_INIT_EXPR + ? AGGR_INIT_EXPR_FN (t) : CALL_EXPR_FN (t)); + tree type = TREE_TYPE (TREE_TYPE (fn)); + + STRIP_NOPS (fn); + if (TREE_CODE (fn) == ADDR_EXPR) + { + /* We do use TREE_NOTHROW for ABI internals like __dynamic_cast, + and for C library functions known not to throw. */ + fn = TREE_OPERAND (fn, 0); + if (TREE_CODE (fn) == FUNCTION_DECL + && DECL_EXTERN_C_P (fn) + && (DECL_ARTIFICIAL (fn) + || nothrow_libfn_p (fn))) + return TREE_NOTHROW (fn) ? NULL_TREE : fn; + } + if (!TYPE_NOTHROW_P (type)) + return fn; + } + + return NULL_TREE; +} + +/* If a function that causes a noexcept-expression to be false isn't + defined yet, remember it and check it for TREE_NOTHROW again at EOF. */ + +typedef struct GTY(()) pending_noexcept { + tree fn; + location_t loc; +} pending_noexcept; +DEF_VEC_O(pending_noexcept); +DEF_VEC_ALLOC_O(pending_noexcept,gc); +static GTY(()) VEC(pending_noexcept,gc) *pending_noexcept_checks; + +/* FN is a FUNCTION_DECL that caused a noexcept-expr to be false. Warn if + it can't throw. */ + +static void +maybe_noexcept_warning (tree fn) +{ + if (TREE_NOTHROW (fn)) + { + warning (OPT_Wnoexcept, "noexcept-expression evaluates to %<false%> " + "because of a call to %qD", fn); + warning (OPT_Wnoexcept, "but %q+D does not throw; perhaps " + "it should be declared %<noexcept%>", fn); + } +} + +/* Check any functions that weren't defined earlier when they caused a + noexcept expression to evaluate to false. */ + +void +perform_deferred_noexcept_checks (void) +{ + int i; + pending_noexcept *p; + location_t saved_loc = input_location; + FOR_EACH_VEC_ELT (pending_noexcept, pending_noexcept_checks, i, p) + { + input_location = p->loc; + maybe_noexcept_warning (p->fn); + } + input_location = saved_loc; +} + +/* Evaluate noexcept ( EXPR ). */ + +tree +finish_noexcept_expr (tree expr, tsubst_flags_t complain) +{ + tree fn; + + if (processing_template_decl) + return build_min (NOEXCEPT_EXPR, boolean_type_node, expr); + + fn = cp_walk_tree_without_duplicates (&expr, check_noexcept_r, 0); + if (fn) + { + if ((complain & tf_warning) && warn_noexcept + && TREE_CODE (fn) == FUNCTION_DECL) + { + if (!DECL_INITIAL (fn)) + { + /* Not defined yet; check again at EOF. */ + pending_noexcept *p + = VEC_safe_push (pending_noexcept, gc, + pending_noexcept_checks, NULL); + p->fn = fn; + p->loc = input_location; + } + else + maybe_noexcept_warning (fn); + } + return boolean_false_node; + } + else + return boolean_true_node; +} + +/* Return true iff SPEC is throw() or noexcept(true). */ + +bool +nothrow_spec_p (const_tree spec) +{ + if (spec == NULL_TREE + || TREE_VALUE (spec) != NULL_TREE + || spec == noexcept_false_spec) + return false; + if (TREE_PURPOSE (spec) == NULL_TREE + || spec == noexcept_true_spec) + return true; + gcc_assert (processing_template_decl + || TREE_PURPOSE (spec) == error_mark_node); + return false; +} + +/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE is noexcept. This is the + case for things declared noexcept(true) and, with -fnothrow-opt, for + throw() functions. */ + +bool +type_noexcept_p (const_tree type) +{ + tree spec = TYPE_RAISES_EXCEPTIONS (type); + if (flag_nothrow_opt) + return nothrow_spec_p (spec); + else + return spec == noexcept_true_spec; +} + +/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE can throw any type, + i.e. no exception-specification or noexcept(false). */ + +bool +type_throw_all_p (const_tree type) +{ + tree spec = TYPE_RAISES_EXCEPTIONS (type); + return spec == NULL_TREE || spec == noexcept_false_spec; +} + +/* Create a representation of the noexcept-specification with + constant-expression of EXPR. COMPLAIN is as for tsubst. */ + +tree +build_noexcept_spec (tree expr, int complain) +{ + expr = perform_implicit_conversion_flags (boolean_type_node, expr, + complain, + LOOKUP_NORMAL); + if (expr == boolean_true_node) + return noexcept_true_spec; + else if (expr == boolean_false_node) + return noexcept_false_spec; + else + { + gcc_assert (processing_template_decl || expr == error_mark_node); + return build_tree_list (expr, NULL_TREE); + } +} diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index feafd7034c0..681834d9a37 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -1,7 +1,7 @@ /* Convert language-specific tree expression to rtl instructions, for GNU compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 2000, 2001, 2002, 2003, 2004, 2007 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003, 2004, 2007, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -24,13 +24,10 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" -#include "rtl.h" #include "tree.h" #include "flags.h" -#include "expr.h" #include "cp-tree.h" #include "toplev.h" -#include "except.h" #include "tm_p.h" /* Expand C++-specific constants. Currently, this means PTRMEM_CST. */ @@ -82,3 +79,72 @@ cplus_expand_constant (tree cst) return cst; } + +/* Called whenever an expression is used + in a rvalue context. */ + +tree +mark_rvalue_use (tree expr) +{ + mark_exp_read (expr); + return expr; +} + +/* Called whenever an expression is used + in a lvalue context. */ + +tree +mark_lvalue_use (tree expr) +{ + mark_exp_read (expr); + return expr; +} + +/* Called whenever an expression is used in a type use context. */ + +tree +mark_type_use (tree expr) +{ + mark_exp_read (expr); + return expr; +} + +/* Mark EXP as read, not just set, for set but not used -Wunused + warning purposes. */ + +void +mark_exp_read (tree exp) +{ + if (exp == NULL) + return; + + switch (TREE_CODE (exp)) + { + case VAR_DECL: + case PARM_DECL: + DECL_READ_P (exp) = 1; + break; + case ARRAY_REF: + case COMPONENT_REF: + case MODIFY_EXPR: + case REALPART_EXPR: + case IMAGPART_EXPR: + CASE_CONVERT: + case ADDR_EXPR: + case INDIRECT_REF: + mark_exp_read (TREE_OPERAND (exp, 0)); + break; + case COMPOUND_EXPR: + mark_exp_read (TREE_OPERAND (exp, 1)); + break; + case COND_EXPR: + if (TREE_OPERAND (exp, 1)) + mark_exp_read (TREE_OPERAND (exp, 1)); + if (TREE_OPERAND (exp, 2)) + mark_exp_read (TREE_OPERAND (exp, 2)); + break; + default: + break; + } +} + diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index 03748fe64d2..7bc11c760f9 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -23,8 +23,6 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "rtl.h" -#include "expr.h" #include "cp-tree.h" #include "flags.h" #include "output.h" diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c index 28530880eb6..9ebf6bc2eae 100644 --- a/gcc/cp/g++spec.c +++ b/gcc/cp/g++spec.c @@ -1,6 +1,6 @@ /* Specific flags and argument handling of the C++ front end. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2007, 2008, 2009 Free Software Foundation, Inc. + 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "gcc.h" +#include "opts.h" /* This bit is set if we saw a `-xfoo' language specification. */ #define LANGSPEC (1<<1) @@ -34,14 +35,14 @@ along with GCC; see the file COPYING3. If not see #define SKIPOPT (1<<4) #ifndef MATH_LIBRARY -#define MATH_LIBRARY "-lm" +#define MATH_LIBRARY "m" #endif #ifndef MATH_LIBRARY_PROFILE #define MATH_LIBRARY_PROFILE MATH_LIBRARY #endif #ifndef LIBSTDCXX -#define LIBSTDCXX "-lstdc++" +#define LIBSTDCXX "stdc++" #endif #ifndef LIBSTDCXX_PROFILE #define LIBSTDCXX_PROFILE LIBSTDCXX @@ -51,10 +52,11 @@ along with GCC; see the file COPYING3. If not see #endif void -lang_specific_driver (int *in_argc, const char *const **in_argv, +lang_specific_driver (struct cl_decoded_option **in_decoded_options, + unsigned int *in_decoded_options_count, int *in_added_libraries) { - int i, j; + unsigned int i, j; /* If nonzero, the user gave us the `-p' or `-pg' flag. */ int saw_profile_flag = 0; @@ -71,12 +73,8 @@ lang_specific_driver (int *in_argc, const char *const **in_argv, -xc++/-xnone. */ int added = 0; - /* Used to track options that take arguments, so we don't go wrapping - those with -xc++/-xnone. */ - const char *quote = NULL; - /* The new argument list will be contained in this. */ - const char **arglist; + struct cl_decoded_option *new_decoded_options; /* Nonzero if we saw a `-xfoo' language specification on the command line. Used to avoid adding our own -xc++ if the user @@ -84,10 +82,10 @@ lang_specific_driver (int *in_argc, const char *const **in_argv, int saw_speclang = 0; /* "-lm" or "-lmath" if it appears on the command line. */ - const char *saw_math = 0; + const struct cl_decoded_option *saw_math = NULL; /* "-lc" if it appears on the command line. */ - const char *saw_libc = 0; + const struct cl_decoded_option *saw_libc = NULL; /* An array used to flag each argument that needs a bit set for LANGSPEC, MATHLIB, or WITHLIBC. */ @@ -103,220 +101,206 @@ lang_specific_driver (int *in_argc, const char *const **in_argv, int shared_libgcc = 1; /* The total number of arguments with the new stuff. */ - int argc; + unsigned int argc; /* The argument list. */ - const char *const *argv; + struct cl_decoded_option *decoded_options; /* The number of libraries added in. */ int added_libraries; /* The total number of arguments with the new stuff. */ - int num_args = 1; + unsigned int num_args = 1; - argc = *in_argc; - argv = *in_argv; + argc = *in_decoded_options_count; + decoded_options = *in_decoded_options; added_libraries = *in_added_libraries; args = XCNEWVEC (int, argc); for (i = 1; i < argc; i++) { - /* If the previous option took an argument, we swallow it here. */ - if (quote) - { - quote = NULL; - continue; - } + const char *arg = decoded_options[i].arg; + if (decoded_options[i].errors & CL_ERR_MISSING_ARG) + continue; /* Avoid examining arguments of options missing them. */ - /* We don't do this anymore, since we don't get them with minus - signs on them. */ - if (argv[i][0] == '\0' || argv[i][1] == '\0') - continue; - - if (argv[i][0] == '-') + switch (decoded_options[i].opt_index) { - if (strcmp (argv[i], "-nostdlib") == 0 - || strcmp (argv[i], "-nodefaultlibs") == 0) - { - library = -1; - } - else if (strcmp (argv[i], MATH_LIBRARY) == 0) + case OPT_nostdlib: + case OPT_nodefaultlibs: + library = -1; + break; + + case OPT_l: + if (strcmp (arg, MATH_LIBRARY) == 0) { args[i] |= MATHLIB; need_math = 0; } - else if (strcmp (argv[i], "-lc") == 0) + else if (strcmp (arg, "c") == 0) args[i] |= WITHLIBC; - else if (strcmp (argv[i], "-pg") == 0 || strcmp (argv[i], "-p") == 0) - saw_profile_flag++; - else if (strncmp (argv[i], "-x", 2) == 0) - { - const char * arg; - if (argv[i][2] != '\0') - arg = argv[i]+2; - else if ((argv[i+1]) != NULL) - /* We need to swallow arg on next loop. */ - quote = arg = argv[i+1]; - else /* Error condition, message will be printed later. */ - arg = ""; - if (library == 0 - && (strcmp (arg, "c++") == 0 - || strcmp (arg, "c++-cpp-output") == 0 - || strcmp (arg, "objective-c++") == 0 - || strcmp (arg, "objective-c++-cpp-output") == 0)) - library = 1; + else + /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */ + library = (library == 0) ? 1 : library; + break; + + case OPT_pg: + case OPT_p: + saw_profile_flag++; + break; + + case OPT_x: + if (library == 0 + && (strcmp (arg, "c++") == 0 + || strcmp (arg, "c++-cpp-output") == 0 + || strcmp (arg, "objective-c++") == 0 + || strcmp (arg, "objective-c++-cpp-output") == 0)) + library = 1; - saw_speclang = 1; - } - else if (strcmp (argv[i], "-ObjC++") == 0) - { - if (library == 0) - library = 1; - saw_speclang = 1; - } + saw_speclang = 1; + break; + + case OPT_Xlinker: + case OPT_Wl_: /* Arguments that go directly to the linker might be .o files, or something, and so might cause libstdc++ to be needed. */ - else if (strcmp (argv[i], "-Xlinker") == 0) - { - quote = argv[i]; - if (library == 0) - library = 1; - } - else if (strncmp (argv[i], "-Wl,", 4) == 0) - library = (library == 0) ? 1 : library; - /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */ - else if (strncmp (argv[i], "-l", 2) == 0) - library = (library == 0) ? 1 : library; - else if (((argv[i][2] == '\0' - && strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL) - || strcmp (argv[i], "-Tdata") == 0)) - quote = argv[i]; - else if ((argv[i][2] == '\0' - && strchr ("cSEM", argv[i][1]) != NULL) - || strcmp (argv[i], "-MM") == 0 - || strcmp (argv[i], "-fsyntax-only") == 0) - { - /* Don't specify libraries if we won't link, since that would - cause a warning. */ - library = -1; - } - else if (strcmp (argv[i], "-static") == 0) - static_link = 1; - else if (strcmp (argv[i], "-static-libgcc") == 0) - shared_libgcc = 0; - else if (strcmp (argv[i], "-static-libstdc++") == 0) - { - library = library >= 0 ? 2 : library; - args[i] |= SKIPOPT; - } - else if (DEFAULT_WORD_SWITCH_TAKES_ARG (&argv[i][1])) - i++; - else - /* Pass other options through. */ - continue; - } - else - { - int len; - - if (saw_speclang) - { - saw_speclang = 0; + if (library == 0) + library = 1; + break; + + case OPT_c: + case OPT_S: + case OPT_E: + case OPT_M: + case OPT_MM: + case OPT_fsyntax_only: + /* Don't specify libraries if we won't link, since that would + cause a warning. */ + library = -1; + break; + + case OPT_static: + static_link = 1; + break; + + case OPT_static_libgcc: + shared_libgcc = 0; + break; + + case OPT_static_libstdc__: + library = library >= 0 ? 2 : library; + args[i] |= SKIPOPT; + break; + + case OPT_SPECIAL_input_file: + { + int len; + + /* We don't do this anymore, since we don't get them with minus + signs on them. */ + if (arg[0] == '\0' || arg[1] == '\0') continue; - } - /* If the filename ends in .[chi], put options around it. - But not if a specified -x option is currently active. */ - len = strlen (argv[i]); - if (len > 2 - && (argv[i][len - 1] == 'c' - || argv[i][len - 1] == 'i' - || argv[i][len - 1] == 'h') - && argv[i][len - 2] == '.') - { - args[i] |= LANGSPEC; - added += 2; - } - - /* If we don't know that this is a header file, we might - need to be linking in the libraries. */ - if (library == 0) - { - if ((len <= 2 || strcmp (argv[i] + (len - 2), ".H") != 0) - && (len <= 2 || strcmp (argv[i] + (len - 2), ".h") != 0) - && (len <= 4 || strcmp (argv[i] + (len - 4), ".hpp") != 0) - && (len <= 3 || strcmp (argv[i] + (len - 3), ".hp") != 0) - && (len <= 4 || strcmp (argv[i] + (len - 4), ".hxx") != 0) - && (len <= 4 || strcmp (argv[i] + (len - 4), ".h++") != 0) - && (len <= 4 || strcmp (argv[i] + (len - 4), ".HPP") != 0) - && (len <= 4 || strcmp (argv[i] + (len - 4), ".tcc") != 0) - && (len <= 3 || strcmp (argv[i] + (len - 3), ".hh") != 0)) - library = 1; - } + if (saw_speclang) + { + saw_speclang = 0; + continue; + } + + /* If the filename ends in .[chi], put options around it. + But not if a specified -x option is currently active. */ + len = strlen (arg); + if (len > 2 + && (arg[len - 1] == 'c' + || arg[len - 1] == 'i' + || arg[len - 1] == 'h') + && arg[len - 2] == '.') + { + args[i] |= LANGSPEC; + added += 2; + } + + /* If we don't know that this is a header file, we might + need to be linking in the libraries. */ + if (library == 0) + { + if ((len <= 2 || strcmp (arg + (len - 2), ".H") != 0) + && (len <= 2 || strcmp (arg + (len - 2), ".h") != 0) + && (len <= 4 || strcmp (arg + (len - 4), ".hpp") != 0) + && (len <= 3 || strcmp (arg + (len - 3), ".hp") != 0) + && (len <= 4 || strcmp (arg + (len - 4), ".hxx") != 0) + && (len <= 4 || strcmp (arg + (len - 4), ".h++") != 0) + && (len <= 4 || strcmp (arg + (len - 4), ".HPP") != 0) + && (len <= 4 || strcmp (arg + (len - 4), ".tcc") != 0) + && (len <= 3 || strcmp (arg + (len - 3), ".hh") != 0)) + library = 1; + } + } + break; } } - if (quote) - fatal ("argument to '%s' missing\n", quote); - /* There's no point adding -shared-libgcc if we don't have a shared libgcc. */ #ifndef ENABLE_SHARED_LIBGCC shared_libgcc = 0; #endif - /* Make sure to have room for the trailing NULL argument. - Add one for shared_libgcc or extra static library. */ - num_args = argc + added + need_math + (library > 0) * 4 + 2; - arglist = XNEWVEC (const char *, num_args); + /* Add one for shared_libgcc or extra static library. */ + num_args = argc + added + need_math + (library > 0) * 4 + 1; + new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args); i = 0; j = 0; /* Copy the 0th argument, i.e., the name of the program itself. */ - arglist[i++] = argv[j++]; + new_decoded_options[j++] = decoded_options[i++]; /* NOTE: We start at 1 now, not 0. */ while (i < argc) { - arglist[j] = argv[i]; + new_decoded_options[j] = decoded_options[i]; /* Make sure -lstdc++ is before the math library, since libstdc++ itself uses those math routines. */ if (!saw_math && (args[i] & MATHLIB) && library > 0) { --j; - saw_math = argv[i]; + saw_math = &decoded_options[i]; } if (!saw_libc && (args[i] & WITHLIBC) && library > 0) { --j; - saw_libc = argv[i]; + saw_libc = &decoded_options[i]; } /* Wrap foo.[chi] files in a language specification to force the gcc compiler driver to run cc1plus on them. */ if (args[i] & LANGSPEC) { - int len = strlen (argv[i]); - switch (argv[i][len - 1]) + const char *arg = decoded_options[i].arg; + int len = strlen (arg); + switch (arg[len - 1]) { case 'c': - arglist[j++] = "-xc++"; + generate_option (OPT_x, "c++", 1, CL_DRIVER, + &new_decoded_options[j++]); break; case 'i': - arglist[j++] = "-xc++-cpp-output"; + generate_option (OPT_x, "c++-cpp-output", 1, CL_DRIVER, + &new_decoded_options[j++]); break; case 'h': - arglist[j++] = "-xc++-header"; + generate_option (OPT_x, "c++-header", 1, CL_DRIVER, + &new_decoded_options[j++]); break; default: gcc_unreachable (); } - arglist[j++] = argv[i]; - arglist[j] = "-xnone"; + new_decoded_options[j++] = decoded_options[i]; + generate_option (OPT_x, "none", 1, CL_DRIVER, + &new_decoded_options[j]); } if ((args[i] & SKIPOPT) != 0) @@ -332,48 +316,51 @@ lang_specific_driver (int *in_argc, const char *const **in_argv, #ifdef HAVE_LD_STATIC_DYNAMIC if (library > 1 && !static_link) { - arglist[j] = "-Wl,-Bstatic"; + generate_option (OPT_Wl_, "-Bstatic", 1, CL_DRIVER, + &new_decoded_options[j]); j++; } #endif - arglist[j] = saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX; - if (arglist[j][0] != '-' || arglist[j][1] == 'l') - added_libraries++; + generate_option (OPT_l, + saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX, 1, + CL_DRIVER, &new_decoded_options[j]); + added_libraries++; j++; /* Add target-dependent static library, if necessary. */ if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL) { - arglist[j] = LIBSTDCXX_STATIC; - if (arglist[j][0] != '-' || arglist[j][1] == 'l') - added_libraries++; + generate_option (OPT_l, LIBSTDCXX_STATIC, 1, + CL_DRIVER, &new_decoded_options[j]); + added_libraries++; j++; } #ifdef HAVE_LD_STATIC_DYNAMIC if (library > 1 && !static_link) { - arglist[j] = "-Wl,-Bdynamic"; + generate_option (OPT_Wl_, "-Bdynamic", 1, CL_DRIVER, + &new_decoded_options[j]); j++; } #endif } if (saw_math) - arglist[j++] = saw_math; + new_decoded_options[j++] = *saw_math; else if (library > 0 && need_math) { - arglist[j] = saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY; - if (arglist[j][0] != '-' || arglist[j][1] == 'l') - added_libraries++; + generate_option (OPT_l, + saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY, + 1, CL_DRIVER, &new_decoded_options[j]); + added_libraries++; j++; } if (saw_libc) - arglist[j++] = saw_libc; + new_decoded_options[j++] = *saw_libc; if (shared_libgcc && !static_link) - arglist[j++] = "-shared-libgcc"; - - arglist[j] = NULL; + generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER, + &new_decoded_options[j++]); - *in_argc = j; - *in_argv = arglist; + *in_decoded_options_count = j; + *in_decoded_options = new_decoded_options; *in_added_libraries = added_libraries; } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 1bd80ffa0f8..189bcbec9a5 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1,6 +1,6 @@ /* Handle initialization things in C++. Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -27,12 +27,9 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "rtl.h" -#include "expr.h" #include "cp-tree.h" #include "flags.h" #include "output.h" -#include "except.h" #include "toplev.h" #include "target.h" @@ -54,6 +51,7 @@ static tree dfs_initialize_vtbl_ptrs (tree, void *); static tree build_dtor_call (tree, special_function_kind, int); static tree build_field_list (tree, tree, int *); static tree build_vtbl_address (tree); +static int diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool, bool); /* We are about to generate some complex initialization code. Conceptually, it is all a single expression. However, we may want @@ -186,7 +184,7 @@ build_zero_init (tree type, tree nelts, bool static_storage_p) VEC(constructor_elt,gc) *v = NULL; /* Iterate over the fields, building initializations. */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { if (TREE_CODE (field) != FIELD_DECL) continue; @@ -271,7 +269,7 @@ build_zero_init (tree type, tree nelts, bool static_storage_p) TYPE, as described in [dcl.init]. */ tree -build_value_init (tree type) +build_value_init (tree type, tsubst_flags_t complain) { /* [dcl.init] @@ -297,6 +295,9 @@ build_value_init (tree type) zero-initializing the object and then calling the default constructor. */ + /* The AGGR_INIT_EXPR tweaking below breaks in templates. */ + gcc_assert (!processing_template_decl); + if (CLASS_TYPE_P (type)) { if (type_has_user_provided_constructor (type)) @@ -304,7 +305,7 @@ build_value_init (tree type) (type, build_special_member_call (NULL_TREE, complete_ctor_identifier, NULL, type, LOOKUP_NORMAL, - tf_warning_or_error)); + complain)); else if (TREE_CODE (type) != UNION_TYPE && TYPE_NEEDS_CONSTRUCTING (type)) { /* This is a class that needs constructing, but doesn't have @@ -313,21 +314,21 @@ build_value_init (tree type) This will be handled in simplify_aggr_init_expr. */ tree ctor = build_special_member_call (NULL_TREE, complete_ctor_identifier, - NULL, type, LOOKUP_NORMAL, tf_warning_or_error); + NULL, type, LOOKUP_NORMAL, complain); ctor = build_aggr_init_expr (type, ctor); AGGR_INIT_ZERO_FIRST (ctor) = 1; return ctor; } } - return build_value_init_noctor (type); + return build_value_init_noctor (type, complain); } /* Like build_value_init, but don't call the constructor for TYPE. Used for base initializers. */ tree -build_value_init_noctor (tree type) +build_value_init_noctor (tree type, tsubst_flags_t complain) { if (CLASS_TYPE_P (type)) { @@ -339,7 +340,7 @@ build_value_init_noctor (tree type) VEC(constructor_elt,gc) *v = NULL; /* Iterate over the fields, building initializations. */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { tree ftype, value; @@ -349,7 +350,12 @@ build_value_init_noctor (tree type) ftype = TREE_TYPE (field); if (TREE_CODE (ftype) == REFERENCE_TYPE) - error ("value-initialization of reference"); + { + if (complain & tf_error) + error ("value-initialization of reference"); + else + return error_mark_node; + } /* We could skip vfields and fields of types with user-defined constructors, but I think that won't improve @@ -361,7 +367,7 @@ build_value_init_noctor (tree type) corresponding to base classes as well. Thus, iterating over TYPE_FIELDs will result in correct initialization of all of the subobjects. */ - value = build_value_init (ftype); + value = build_value_init (ftype, complain); if (value) CONSTRUCTOR_APPEND_ELT(v, field, value); @@ -381,7 +387,10 @@ build_value_init_noctor (tree type) /* If we have an error_mark here, we should just return error mark as we don't know the size of the array yet. */ if (max_index == error_mark_node) - return error_mark_node; + { + error ("cannot value-initialize array of unknown bound %qT", type); + return error_mark_node; + } gcc_assert (TREE_CODE (max_index) == INTEGER_CST); /* A zero-sized array, which is accepted as an extension, will @@ -400,7 +409,7 @@ build_value_init_noctor (tree type) ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node, max_index); - ce->value = build_value_init (TREE_TYPE (type)); + ce->value = build_value_init (TREE_TYPE (type), complain); /* The gimplifier can't deal with a RANGE_EXPR of TARGET_EXPRs. */ gcc_assert (TREE_CODE (ce->value) != TARGET_EXPR @@ -458,7 +467,8 @@ perform_member_init (tree member, tree init) member); else { - init = build2 (INIT_EXPR, type, decl, build_value_init (type)); + init = build2 (INIT_EXPR, type, decl, + build_value_init (type, tf_warning_or_error)); finish_expr_stmt (init); } } @@ -505,6 +515,7 @@ perform_member_init (tree member, tree init) { if (init == NULL_TREE) { + tree core_type; /* member traversal: note it leaves init NULL */ if (TREE_CODE (type) == REFERENCE_TYPE) permerror (DECL_SOURCE_LOCATION (current_function_decl), @@ -514,11 +525,20 @@ perform_member_init (tree member, tree init) permerror (DECL_SOURCE_LOCATION (current_function_decl), "uninitialized member %qD with %<const%> type %qT", member, type); + + core_type = strip_array_types (type); + if (CLASS_TYPE_P (core_type) + && (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type) + || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type))) + diagnose_uninitialized_cst_or_ref_member (core_type, + /*using_new=*/false, + /*complain=*/true); } else if (TREE_CODE (init) == TREE_LIST) /* There was an explicit member initialization. Do some work in that case. */ - init = build_x_compound_expr_from_list (init, "member initializer"); + init = build_x_compound_expr_from_list (init, ELK_MEM_INIT, + tf_warning_or_error); if (init) finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init, @@ -555,27 +575,29 @@ build_field_list (tree t, tree list, int *uses_unions_p) if (TREE_CODE (t) == UNION_TYPE) *uses_unions_p = 1; - for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields)) + for (fields = TYPE_FIELDS (t); fields; fields = DECL_CHAIN (fields)) { + tree fieldtype; + /* Skip CONST_DECLs for enumeration constants and so forth. */ if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields)) continue; + fieldtype = TREE_TYPE (fields); /* Keep track of whether or not any fields are unions. */ - if (TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE) + if (TREE_CODE (fieldtype) == UNION_TYPE) *uses_unions_p = 1; /* For an anonymous struct or union, we must recursively consider the fields of the anonymous type. They can be directly initialized from the constructor. */ - if (ANON_AGGR_TYPE_P (TREE_TYPE (fields))) + if (ANON_AGGR_TYPE_P (fieldtype)) { /* Add this field itself. Synthesized copy constructors initialize the entire aggregate. */ list = tree_cons (fields, NULL_TREE, list); /* And now add the fields in the anonymous aggregate. */ - list = build_field_list (TREE_TYPE (fields), list, - uses_unions_p); + list = build_field_list (fieldtype, list, uses_unions_p); } /* Add this field. */ else if (DECL_NAME (fields)) @@ -701,38 +723,54 @@ sort_mem_initializers (tree t, tree mem_inits) If a ctor-initializer specifies more than one mem-initializer for multiple members of the same union (including members of - anonymous unions), the ctor-initializer is ill-formed. */ + anonymous unions), the ctor-initializer is ill-formed. + + Here we also splice out uninitialized union members. */ if (uses_unions_p) { tree last_field = NULL_TREE; - for (init = sorted_inits; init; init = TREE_CHAIN (init)) + tree *p; + for (p = &sorted_inits; *p; ) { tree field; - tree field_type; + tree ctx; int done; - /* Skip uninitialized members and base classes. */ - if (!TREE_VALUE (init) - || TREE_CODE (TREE_PURPOSE (init)) != FIELD_DECL) - continue; + init = *p; + + field = TREE_PURPOSE (init); + + /* Skip base classes. */ + if (TREE_CODE (field) != FIELD_DECL) + goto next; + + /* If this is an anonymous union with no explicit initializer, + splice it out. */ + if (!TREE_VALUE (init) && ANON_UNION_TYPE_P (TREE_TYPE (field))) + goto splice; + /* See if this field is a member of a union, or a member of a structure contained in a union, etc. */ - field = TREE_PURPOSE (init); - for (field_type = DECL_CONTEXT (field); - !same_type_p (field_type, t); - field_type = TYPE_CONTEXT (field_type)) - if (TREE_CODE (field_type) == UNION_TYPE) + for (ctx = DECL_CONTEXT (field); + !same_type_p (ctx, t); + ctx = TYPE_CONTEXT (ctx)) + if (TREE_CODE (ctx) == UNION_TYPE) break; /* If this field is not a member of a union, skip it. */ - if (TREE_CODE (field_type) != UNION_TYPE) - continue; + if (TREE_CODE (ctx) != UNION_TYPE) + goto next; + + /* If this union member has no explicit initializer, splice + it out. */ + if (!TREE_VALUE (init)) + goto splice; /* It's only an error if we have two initializers for the same union type. */ if (!last_field) { last_field = field; - continue; + goto next; } /* See if LAST_FIELD and the field initialized by INIT are @@ -743,41 +781,48 @@ sort_mem_initializers (tree t, tree mem_inits) union { struct { int i; int j; }; }; initializing both `i' and `j' makes sense. */ - field_type = DECL_CONTEXT (field); + ctx = DECL_CONTEXT (field); done = 0; do { - tree last_field_type; + tree last_ctx; - last_field_type = DECL_CONTEXT (last_field); + last_ctx = DECL_CONTEXT (last_field); while (1) { - if (same_type_p (last_field_type, field_type)) + if (same_type_p (last_ctx, ctx)) { - if (TREE_CODE (field_type) == UNION_TYPE) + if (TREE_CODE (ctx) == UNION_TYPE) error_at (DECL_SOURCE_LOCATION (current_function_decl), "initializations for multiple members of %qT", - last_field_type); + last_ctx); done = 1; break; } - if (same_type_p (last_field_type, t)) + if (same_type_p (last_ctx, t)) break; - last_field_type = TYPE_CONTEXT (last_field_type); + last_ctx = TYPE_CONTEXT (last_ctx); } /* If we've reached the outermost class, then we're done. */ - if (same_type_p (field_type, t)) + if (same_type_p (ctx, t)) break; - field_type = TYPE_CONTEXT (field_type); + ctx = TYPE_CONTEXT (ctx); } while (!done); last_field = field; + + next: + p = &TREE_CHAIN (*p); + continue; + splice: + *p = TREE_CHAIN (*p); + continue; } } @@ -998,7 +1043,7 @@ construct_virtual_base (tree vbase, tree arguments) in the outer block.) We trust the back end to figure out that the FLAG will not change across initializations, and avoid doing multiple tests. */ - flag = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)); + flag = DECL_CHAIN (DECL_ARGUMENTS (current_function_decl)); inner_if_stmt = begin_if_stmt (); finish_if_stmt_cond (flag, inner_if_stmt); @@ -1230,7 +1275,9 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain) TREE_READONLY (exp) = 0; TREE_THIS_VOLATILE (exp) = 0; - if (init && TREE_CODE (init) != TREE_LIST) + if (init && TREE_CODE (init) != TREE_LIST + && !(BRACE_ENCLOSED_INITIALIZER_P (init) + && CONSTRUCTOR_IS_DIRECT_INIT (init))) flags |= LOOKUP_ONLYCONVERTING; if (TREE_CODE (type) == ARRAY_TYPE) @@ -1298,6 +1345,18 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags, tree rval; VEC(tree,gc) *parms; + if (init && BRACE_ENCLOSED_INITIALIZER_P (init) + && CP_AGGREGATE_TYPE_P (type)) + { + /* A brace-enclosed initializer for an aggregate. In C++0x this can + happen for direct-initialization, too. */ + init = digest_init (type, init); + init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init); + TREE_SIDE_EFFECTS (init) = 1; + finish_expr_stmt (init); + return; + } + if (init && TREE_CODE (init) != TREE_LIST && (flags & LOOKUP_ONLYCONVERTING)) { @@ -1310,12 +1369,6 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags, to run a new constructor; and catching an exception, where we have already built up the constructor call so we could wrap it in an exception region. */; - else if (BRACE_ENCLOSED_INITIALIZER_P (init) - && CP_AGGREGATE_TYPE_P (type)) - { - /* A brace-enclosed initializer for an aggregate. */ - init = digest_init (type, init); - } else init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); @@ -1359,7 +1412,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags, release_tree_vector (parms); if (TREE_SIDE_EFFECTS (rval)) - finish_expr_stmt (convert_to_void (rval, NULL, complain)); + finish_expr_stmt (convert_to_void (rval, ICV_CAST, complain)); } /* This function is responsible for initializing EXP with INIT @@ -1429,7 +1482,8 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags, then just zero out the object and we're done. */ else { - init = build2 (INIT_EXPR, type, exp, build_value_init_noctor (type)); + init = build2 (INIT_EXPR, type, exp, + build_value_init_noctor (type, complain)); finish_expr_stmt (init); return; } @@ -1492,9 +1546,9 @@ build_offset_ref (tree type, tree member, bool address_p) if (TREE_CODE (member) == TEMPLATE_DECL) return member; - if (dependent_type_p (type) || type_dependent_expression_p (member)) + if (dependent_scope_p (type) || type_dependent_expression_p (member)) return build_qualified_name (NULL_TREE, type, member, - /*template_p=*/false); + /*template_p=*/false); gcc_assert (TYPE_P (type)); if (! is_class_type (type, 1)) @@ -1504,8 +1558,8 @@ build_offset_ref (tree type, tree member, bool address_p) /* Callers should call mark_used before this point. */ gcc_assert (!DECL_P (member) || TREE_USED (member)); - if (!COMPLETE_TYPE_P (complete_type (type)) - && !TYPE_BEING_DEFINED (type)) + type = TYPE_MAIN_VARIANT (type); + if (!COMPLETE_OR_OPEN_TYPE_P (complete_type (type))) { error ("incomplete type %qT does not have member %qD", type, member); return error_mark_node; @@ -1657,7 +1711,14 @@ constant_value_1 (tree decl, bool integral_p) init = DECL_INITIAL (decl); } if (init == error_mark_node) - return decl; + { + if (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)) + /* Treat the error as a constant to avoid cascading errors on + excessively recursive template instantiation (c++/9335). */ + return init; + else + return decl; + } /* Initializers in templates are generally expanded during instantiation, so before that for const int i(2) INIT is a TREE_LIST with the actual initializer as @@ -1753,6 +1814,74 @@ build_raw_new_expr (VEC(tree,gc) *placement, tree type, tree nelts, return new_expr; } +/* Diagnose uninitialized const members or reference members of type + TYPE. USING_NEW is used to disambiguate the diagnostic between a + new expression without a new-initializer and a declaration. Returns + the error count. */ + +static int +diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, + bool using_new, bool complain) +{ + tree field; + int error_count = 0; + + if (type_has_user_provided_constructor (type)) + return 0; + + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) + { + tree field_type; + + if (TREE_CODE (field) != FIELD_DECL) + continue; + + field_type = strip_array_types (TREE_TYPE (field)); + + if (TREE_CODE (field_type) == REFERENCE_TYPE) + { + ++ error_count; + if (complain) + { + if (using_new) + error ("uninitialized reference member in %q#T " + "using %<new%> without new-initializer", origin); + else + error ("uninitialized reference member in %q#T", origin); + inform (DECL_SOURCE_LOCATION (field), + "%qD should be initialized", field); + } + } + + if (CP_TYPE_CONST_P (field_type)) + { + ++ error_count; + if (complain) + { + if (using_new) + error ("uninitialized const member in %q#T " + "using %<new%> without new-initializer", origin); + else + error ("uninitialized const member in %q#T", origin); + inform (DECL_SOURCE_LOCATION (field), + "%qD should be initialized", field); + } + } + + if (CLASS_TYPE_P (field_type)) + error_count + += diagnose_uninitialized_cst_or_ref_member_1 (field_type, origin, + using_new, complain); + } + return error_count; +} + +int +diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new, bool complain) +{ + return diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new, complain); +} + /* Generate code for a new-expression, including calling the "operator new" function, initializing the object, and, if an exception occurs during construction, cleaning up. The arguments are as for @@ -1839,6 +1968,36 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || *init != NULL); + if (*init == NULL) + { + bool maybe_uninitialized_error = false; + /* A program that calls for default-initialization [...] of an + entity of reference type is ill-formed. */ + if (CLASSTYPE_REF_FIELDS_NEED_INIT (elt_type)) + maybe_uninitialized_error = true; + + /* A new-expression that creates an object of type T initializes + that object as follows: + - If the new-initializer is omitted: + -- If T is a (possibly cv-qualified) non-POD class type + (or array thereof), the object is default-initialized (8.5). + [...] + -- Otherwise, the object created has indeterminate + value. If T is a const-qualified type, or a (possibly + cv-qualified) POD class type (or array thereof) + containing (directly or indirectly) a member of + const-qualified type, the program is ill-formed; */ + + if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (elt_type)) + maybe_uninitialized_error = true; + + if (maybe_uninitialized_error + && diagnose_uninitialized_cst_or_ref_member (elt_type, + /*using_new=*/true, + complain & tf_error)) + return error_mark_node; + } + if (CP_TYPE_CONST_P (elt_type) && *init == NULL && !type_has_user_provided_default_constructor (elt_type)) { @@ -1888,10 +2047,8 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, } alloc_fn = OVL_CURRENT (alloc_fn); class_addr = build1 (ADDR_EXPR, jclass_node, class_decl); - alloc_call = (cp_build_function_call - (alloc_fn, - build_tree_list (NULL_TREE, class_addr), - complain)); + alloc_call = cp_build_function_call_nary (alloc_fn, complain, + class_addr, NULL_TREE); } else if (TYPE_FOR_JAVA (elt_type) && MAYBE_CLASS_TYPE_P (elt_type)) { @@ -2085,7 +2242,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, /* But we want to operate on a non-const version to start with, since we'll be modifying the elements. */ non_const_pointer_type = build_pointer_type - (cp_build_qualified_type (type, TYPE_QUALS (type) & ~TYPE_QUAL_CONST)); + (cp_build_qualified_type (type, cp_type_quals (type) & ~TYPE_QUAL_CONST)); data_addr = fold_convert (non_const_pointer_type, data_addr); /* Any further uses of alloc_node will want this type, too. */ @@ -2156,7 +2313,8 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, { init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain); - if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p) + if (TYPE_NEEDS_CONSTRUCTING (type) + && (!explicit_value_init_p || processing_template_decl)) { init_expr = build_special_member_call (init_expr, complete_ctor_identifier, @@ -2166,9 +2324,17 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, } else if (explicit_value_init_p) { - /* Something like `new int()'. */ - init_expr = build2 (INIT_EXPR, type, - init_expr, build_value_init (type)); + if (processing_template_decl) + /* Don't worry about it, we'll handle this properly at + instantiation time. */; + else + { + /* Something like `new int()'. */ + tree val = build_value_init (type, complain); + if (val == error_mark_node) + return error_mark_node; + init_expr = build2 (INIT_EXPR, type, init_expr, val); + } } else { @@ -2361,6 +2527,7 @@ build_new (VEC(tree,gc) **placement, tree type, tree nelts, else return error_mark_node; } + nelts = mark_rvalue_use (nelts); nelts = cp_save_expr (cp_convert (sizetype, nelts)); } @@ -2386,7 +2553,7 @@ build_new (VEC(tree,gc) **placement, tree type, tree nelts, /* The type allocated must be complete. If the new-type-id was "T[N]" then we are just checking that "T" is complete here, but that is equivalent, since the value of "N" doesn't matter. */ - if (!complete_type_or_else (type, NULL_TREE)) + if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)) return error_mark_node; rval = build_new_1 (placement, type, nelts, init, use_global_new, complain); @@ -2432,7 +2599,7 @@ build_java_class_ref (tree type) /* Mangle the class$ field. */ { tree field; - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (DECL_NAME (field) == CL_suffix) { mangle_decl (field); @@ -2597,7 +2764,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type, /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR. */ body = build2 (COMPOUND_EXPR, void_type_node, base, body); - return convert_to_void (body, /*implicit=*/NULL, tf_warning_or_error); + return convert_to_void (body, ICV_CAST, tf_warning_or_error); } /* Create an unnamed variable of the indicated TYPE. */ @@ -2705,7 +2872,7 @@ build_vec_init (tree base, tree maxindex, tree init, && TREE_CODE (atype) == ARRAY_TYPE && (from_array == 2 ? (!CLASS_TYPE_P (inner_elt_type) - || !TYPE_HAS_COMPLEX_ASSIGN_REF (inner_elt_type)) + || !TYPE_HAS_COMPLEX_COPY_ASSIGN (inner_elt_type)) : !TYPE_NEEDS_CONSTRUCTING (type)) && ((TREE_CODE (init) == CONSTRUCTOR /* Don't do this if the CONSTRUCTOR might contain something @@ -2893,8 +3060,13 @@ build_vec_init (tree base, tree maxindex, tree init, 0, complain); } else if (explicit_value_init_p) - elt_init = build2 (INIT_EXPR, type, to, - build_value_init (type)); + { + elt_init = build_value_init (type, complain); + if (elt_init == error_mark_node) + return error_mark_node; + else + elt_init = build2 (INIT_EXPR, type, to, elt_init); + } else { gcc_assert (TYPE_NEEDS_CONSTRUCTING (type)); @@ -3016,6 +3188,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, type = TYPE_MAIN_VARIANT (type); + addr = mark_rvalue_use (addr); + if (TREE_CODE (type) == POINTER_TYPE) { bool complete_p = true; @@ -3230,21 +3404,27 @@ push_base_cleanups (void) finish_decl_cleanup (NULL_TREE, expr); } + /* Don't automatically destroy union members. */ + if (TREE_CODE (current_class_type) == UNION_TYPE) + return; + for (member = TYPE_FIELDS (current_class_type); member; - member = TREE_CHAIN (member)) + member = DECL_CHAIN (member)) { - if (TREE_TYPE (member) == error_mark_node + tree this_type = TREE_TYPE (member); + if (this_type == error_mark_node || TREE_CODE (member) != FIELD_DECL || DECL_ARTIFICIAL (member)) continue; - if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (member))) + if (ANON_UNION_TYPE_P (this_type)) + continue; + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (this_type)) { tree this_member = (build_class_member_access_expr (current_class_ref, member, /*access_path=*/NULL_TREE, /*preserve_reference=*/false, tf_warning_or_error)); - tree this_type = TREE_TYPE (member); expr = build_delete (this_type, this_member, sfk_complete_destructor, LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL, diff --git a/gcc/cp/lang-specs.h b/gcc/cp/lang-specs.h index 54d69a115fa..24213587f76 100644 --- a/gcc/cp/lang-specs.h +++ b/gcc/cp/lang-specs.h @@ -1,6 +1,6 @@ /* Definitions for specs for C++. Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2007 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2007, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -47,8 +47,9 @@ along with GCC; see the file COPYING3. If not see %(cpp_options) %2 -o %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\ cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\ %{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options)}}\ - %(cc1_options) %2 %{+e1*}\ - %{!fsyntax-only:-o %g.s %{!o*:--output-pch=%i.gch} %W{o*:--output-pch=%*}%V}}}}", + %(cc1_options) %2\ + %{!fsyntax-only:%{!fdump-ada-spec*:-o %g.s %{!o*:--output-pch=%i.gch}\ + %W{o*:--output-pch=%*}}%V}}}}", CPLUSPLUS_CPP_SPEC, 0, 0}, {"@c++", "%{E|M|MM:cc1plus -E %(cpp_options) %2 %(cpp_debug_options)}\ @@ -57,11 +58,11 @@ along with GCC; see the file COPYING3. If not see %(cpp_options) %2 -o %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\ cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\ %{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options)}}\ - %(cc1_options) %2 %{+e1*}\ + %(cc1_options) %2\ %{!fsyntax-only:%(invoke_as)}}}}", CPLUSPLUS_CPP_SPEC, 0, 0}, {".ii", "@c++-cpp-output", 0, 0, 0}, {"@c++-cpp-output", "%{!M:%{!MM:%{!E:\ - cc1plus -fpreprocessed %i %(cc1_options) %2 %{+e*}\ + cc1plus -fpreprocessed %i %(cc1_options) %2\ %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0}, diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 041e391f543..8a894c743ba 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "cp-tree.h" #include "cpplib.h" #include "flags.h" -#include "c-pragma.h" +#include "c-family/c-pragma.h" #include "toplev.h" #include "output.h" #include "tm_p.h" @@ -184,7 +184,7 @@ init_reswords (void) /* The Objective-C keywords are all context-dependent. */ mask |= D_OBJC; - ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX); + ridpointers = ggc_alloc_cleared_vec_tree ((int) RID_MAX); for (i = 0; i < num_c_common_reswords; i++) { if (c_common_reswords[i].disable & D_CONLY) @@ -226,8 +226,9 @@ cxx_init (void) CTOR_INITIALIZER, TRY_BLOCK, HANDLER, EH_SPEC_BLOCK, USING_STMT, TAG_DEFN, IF_STMT, CLEANUP_STMT, FOR_STMT, - WHILE_STMT, DO_STMT, BREAK_STMT, - CONTINUE_STMT, SWITCH_STMT, EXPR_STMT + RANGE_FOR_STMT, WHILE_STMT, DO_STMT, + BREAK_STMT, CONTINUE_STMT, SWITCH_STMT, + EXPR_STMT }; memset (&statement_code_p, 0, sizeof (statement_code_p)); @@ -507,13 +508,25 @@ unqualified_fn_lookup_error (tree name) return unqualified_name_lookup_error (name); } +/* Wrapper around build_lang_decl_loc(). Should gradually move to + build_lang_decl_loc() and then rename build_lang_decl_loc() back to + build_lang_decl(). */ + tree build_lang_decl (enum tree_code code, tree name, tree type) { + return build_lang_decl_loc (input_location, code, name, type); +} + +/* Build a decl from CODE, NAME, TYPE declared at LOC, and then add + DECL_LANG_SPECIFIC info to the result. */ + +tree +build_lang_decl_loc (location_t loc, enum tree_code code, tree name, tree type) +{ tree t; - t = build_decl (input_location, - code, name, type); + t = build_decl (loc, code, name, type); retrofit_lang_decl (t); return t; @@ -540,7 +553,7 @@ retrofit_lang_decl (tree t) else gcc_unreachable (); - ld = GGC_CNEWVAR (struct lang_decl, size); + ld = ggc_alloc_cleared_lang_decl (size); ld->u.base.selector = sel; @@ -581,7 +594,7 @@ cxx_dup_lang_specific_decl (tree node) else gcc_unreachable (); - ld = GGC_NEWVAR (struct lang_decl, size); + ld = ggc_alloc_lang_decl (size); memcpy (ld, DECL_LANG_SPECIFIC (node), size); DECL_LANG_SPECIFIC (node) = ld; @@ -618,7 +631,7 @@ copy_lang_type (tree node) size = sizeof (struct lang_type); else size = sizeof (struct lang_type_ptrmem); - lt = GGC_NEWVAR (struct lang_type, size); + lt = ggc_alloc_lang_type (size); memcpy (lt, TYPE_LANG_SPECIFIC (node), size); TYPE_LANG_SPECIFIC (node) = lt; @@ -649,7 +662,8 @@ cxx_make_type (enum tree_code code) if (RECORD_OR_UNION_CODE_P (code) || code == BOUND_TEMPLATE_TEMPLATE_PARM) { - struct lang_type *pi = GGC_CNEW (struct lang_type); + struct lang_type *pi + = ggc_alloc_cleared_lang_type (sizeof (struct lang_type)); TYPE_LANG_SPECIFIC (t) = pi; pi->u.c.h.is_lang_type_class = 1; diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 3b81ea94b95..03e28374810 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -52,10 +52,8 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "tm_p.h" #include "cp-tree.h" -#include "real.h" #include "obstack.h" #include "toplev.h" -#include "varray.h" #include "flags.h" #include "target.h" #include "cgraph.h" @@ -150,7 +148,9 @@ integer_type_codes[itk_none] = 'l', /* itk_long */ 'm', /* itk_unsigned_long */ 'x', /* itk_long_long */ - 'y' /* itk_unsigned_long_long */ + 'y', /* itk_unsigned_long_long */ + 'n', /* itk_int128 */ + 'o', /* itk_unsigned_int128 */ }; static int decl_is_template_id (const tree, tree* const); @@ -307,7 +307,7 @@ dump_substitution_candidates (void) tree el; fprintf (stderr, " ++ substitutions "); - for (i = 0; VEC_iterate (tree, G.substitutions, i, el); ++i) + FOR_EACH_VEC_ELT (tree, G.substitutions, i, el) { const char *name = "???"; @@ -346,11 +346,19 @@ canonicalize_for_substitution (tree node) if (TYPE_P (node) && TYPE_CANONICAL (node) != node && TYPE_MAIN_VARIANT (node) != node) + { /* Here we want to strip the topmost typedef only. We need to do that so is_std_substitution can do proper name matching. */ - node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node), - cp_type_quals (node)); + if (TREE_CODE (node) == FUNCTION_TYPE) + /* Use build_qualified_type and TYPE_QUALS here to preserve + the old buggy mangling of attribute noreturn with abi<5. */ + node = build_qualified_type (TYPE_MAIN_VARIANT (node), + TYPE_QUALS (node)); + else + node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node), + cp_type_quals (node)); + } return node; } @@ -379,7 +387,7 @@ add_substitution (tree node) int i; tree candidate; - for (i = 0; VEC_iterate (tree, G.substitutions, i, candidate); i++) + FOR_EACH_VEC_ELT (tree, G.substitutions, i, candidate) { gcc_assert (!(DECL_P (node) && node == candidate)); gcc_assert (!(TYPE_P (node) && TYPE_P (candidate) @@ -1281,7 +1289,7 @@ nested_anon_class_index (tree type) { int index = 0; tree member = TYPE_FIELDS (TYPE_CONTEXT (type)); - for (; member; member = TREE_CHAIN (member)) + for (; member; member = DECL_CHAIN (member)) if (DECL_IMPLICIT_TYPEDEF_P (member)) { tree memtype = TREE_TYPE (member); @@ -1711,7 +1719,7 @@ write_local_name (tree function, const tree local_entity, { tree t; int i = 0; - for (t = DECL_ARGUMENTS (function); t; t = TREE_CHAIN (t)) + for (t = DECL_ARGUMENTS (function); t; t = DECL_CHAIN (t)) { if (t == parm) i = 1; @@ -1760,6 +1768,7 @@ write_local_name (tree function, const tree local_entity, <type> ::= Dt <expression> # decltype of an id-expression or # class member access <type> ::= DT <expression> # decltype of an expression + <type> ::= Dn # decltype of nullptr TYPE is a type node. */ @@ -1775,6 +1784,7 @@ write_type (tree type) if (type == error_mark_node) return; + type = canonicalize_for_substitution (type); if (find_substitution (type)) return; @@ -1937,6 +1947,14 @@ write_type (tree type) sorry ("mangling typeof, use decltype instead"); break; + case LANG_TYPE: + if (NULLPTR_TYPE_P (type)) + { + write_string ("Dn"); + break; + } + /* else fall through. */ + default: gcc_unreachable (); } @@ -1967,18 +1985,25 @@ write_CV_qualifiers_for_type (const tree type) Note that we do not use cp_type_quals below; given "const int[3]", the "const" is emitted with the "int", not with the array. */ + cp_cv_quals quals = TYPE_QUALS (type); + + /* Attribute const/noreturn are not reflected in mangling. */ + if (abi_version_at_least (5) + && (TREE_CODE (type) == FUNCTION_TYPE + || TREE_CODE (type) == METHOD_TYPE)) + return 0; - if (TYPE_QUALS (type) & TYPE_QUAL_RESTRICT) + if (quals & TYPE_QUAL_RESTRICT) { write_char ('r'); ++num_qualifiers; } - if (TYPE_QUALS (type) & TYPE_QUAL_VOLATILE) + if (quals & TYPE_QUAL_VOLATILE) { write_char ('V'); ++num_qualifiers; } - if (TYPE_QUALS (type) & TYPE_QUAL_CONST) + if (quals & TYPE_QUAL_CONST) { write_char ('K'); ++num_qualifiers; @@ -2045,7 +2070,8 @@ write_builtin_type (tree type) it in the array of these nodes. */ iagain: for (itk = 0; itk < itk_none; ++itk) - if (type == integer_types[itk]) + if (integer_types[itk] != NULL_TREE + && type == integer_types[itk]) { /* Print the corresponding single-letter code. */ write_char (integer_type_codes[itk]); @@ -2277,12 +2303,12 @@ write_method_parms (tree parm_types, const int method_p, const tree decl) if (method_p) { parm_types = TREE_CHAIN (parm_types); - parm_decl = parm_decl ? TREE_CHAIN (parm_decl) : NULL_TREE; + parm_decl = parm_decl ? DECL_CHAIN (parm_decl) : NULL_TREE; while (parm_decl && DECL_ARTIFICIAL (parm_decl)) { parm_types = TREE_CHAIN (parm_types); - parm_decl = TREE_CHAIN (parm_decl); + parm_decl = DECL_CHAIN (parm_decl); } } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 5ed98bc93bd..0ec38264062 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -29,8 +29,6 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tree.h" #include "cp-tree.h" -#include "rtl.h" -#include "expr.h" #include "output.h" #include "flags.h" #include "toplev.h" @@ -59,9 +57,8 @@ enum mangling_flags typedef enum mangling_flags mangling_flags; -static void do_build_assign_ref (tree); +static void do_build_copy_assign (tree); static void do_build_copy_constructor (tree); -static tree synthesize_exception_spec (tree, tree (*) (tree, void *), void *); static tree make_alias_for_thunk (tree); /* Called once to initialize method.c. */ @@ -106,7 +103,7 @@ make_thunk (tree function, bool this_adjusting, /* See if we already have the thunk in question. For this_adjusting thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it will be a BINFO. */ - for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk)) + for (thunk = DECL_THUNKS (function); thunk; thunk = DECL_CHAIN (thunk)) if (DECL_THIS_THUNK_P (thunk) == this_adjusting && THUNK_FIXED_OFFSET (thunk) == d && !virtual_offset == !THUNK_VIRTUAL_OFFSET (thunk) @@ -159,7 +156,7 @@ make_thunk (tree function, bool this_adjusting, DECL_TEMPLATE_INFO (thunk) = NULL; /* Add it to the list of thunks associated with FUNCTION. */ - TREE_CHAIN (thunk) = DECL_THUNKS (function); + DECL_CHAIN (thunk) = DECL_THUNKS (function); DECL_THUNKS (function) = thunk; return thunk; @@ -191,7 +188,7 @@ finish_thunk (tree thunk) tree cov_probe; for (cov_probe = DECL_THUNKS (function); - cov_probe; cov_probe = TREE_CHAIN (cov_probe)) + cov_probe; cov_probe = DECL_CHAIN (cov_probe)) if (DECL_NAME (cov_probe) == name) { gcc_assert (!DECL_THUNKS (thunk)); @@ -367,12 +364,12 @@ use_thunk (tree thunk_fndecl, bool emit_p) /* Set up cloned argument trees for the thunk. */ t = NULL_TREE; - for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a)) + for (a = DECL_ARGUMENTS (function); a; a = DECL_CHAIN (a)) { tree x = copy_node (a); - TREE_CHAIN (x) = t; + DECL_CHAIN (x) = t; DECL_CONTEXT (x) = thunk_fndecl; - SET_DECL_RTL (x, NULL_RTX); + SET_DECL_RTL (x, NULL); DECL_HAS_VALUE_EXPR_P (x) = 0; t = x; } @@ -402,6 +399,74 @@ use_thunk (tree thunk_fndecl, bool emit_p) /* Code for synthesizing methods which have default semantics defined. */ +/* True iff CTYPE has a trivial SFK. */ + +static bool +type_has_trivial_fn (tree ctype, special_function_kind sfk) +{ + switch (sfk) + { + case sfk_constructor: + return !TYPE_HAS_COMPLEX_DFLT (ctype); + case sfk_copy_constructor: + return !TYPE_HAS_COMPLEX_COPY_CTOR (ctype); + case sfk_move_constructor: + return !TYPE_HAS_COMPLEX_MOVE_CTOR (ctype); + case sfk_copy_assignment: + return !TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype); + case sfk_move_assignment: + return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype); + case sfk_destructor: + return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype); + default: + gcc_unreachable (); + } +} + +/* Note that CTYPE has a non-trivial SFK even though we previously thought + it was trivial. */ + +static void +type_set_nontrivial_flag (tree ctype, special_function_kind sfk) +{ + switch (sfk) + { + case sfk_constructor: + TYPE_HAS_COMPLEX_DFLT (ctype) = true; + return; + case sfk_copy_constructor: + TYPE_HAS_COMPLEX_COPY_CTOR (ctype) = true; + return; + case sfk_move_constructor: + TYPE_HAS_COMPLEX_MOVE_CTOR (ctype) = true; + return; + case sfk_copy_assignment: + TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype) = true; + return; + case sfk_move_assignment: + TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype) = true; + return; + case sfk_destructor: + TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true; + return; + default: + gcc_unreachable (); + } +} + +/* True iff FN is a trivial defaulted member function ([cd]tor, op=). */ + +bool +trivial_fn_p (tree fn) +{ + if (!DECL_DEFAULTED_FN (fn)) + return false; + + /* If fn is a clone, get the primary variant. */ + fn = DECL_ORIGIN (fn); + return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn)); +} + /* Generate code for default X(X&) or X(X&&) constructor. */ static void @@ -409,14 +474,15 @@ do_build_copy_constructor (tree fndecl) { tree parm = FUNCTION_FIRST_USER_PARM (fndecl); bool move_p = DECL_MOVE_CONSTRUCTOR_P (fndecl); + bool trivial = trivial_fn_p (fndecl); parm = convert_from_reference (parm); - if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type) + if (trivial && is_empty_class (current_class_type)) /* Don't copy the padding byte; it might not have been allocated if *this is a base subobject. */; - else if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)) + else if (trivial) { tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm); finish_expr_stmt (t); @@ -463,7 +529,7 @@ do_build_copy_constructor (tree fndecl) member_init_list); } - for (; fields; fields = TREE_CHAIN (fields)) + for (; fields; fields = DECL_CHAIN (fields)) { tree field = fields; tree expr_type; @@ -479,7 +545,8 @@ do_build_copy_constructor (tree fndecl) } else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type)) /* Just use the field; anonymous types can't have - nontrivial copy ctors or assignment ops. */; + nontrivial copy ctors or assignment ops or this + function would be deleted. */; else continue; @@ -494,7 +561,7 @@ do_build_copy_constructor (tree fndecl) if (DECL_MUTABLE_P (field)) quals &= ~TYPE_QUAL_CONST; - quals |= TYPE_QUALS (expr_type); + quals |= cp_type_quals (expr_type); expr_type = cp_build_qualified_type (expr_type, quals); } @@ -510,19 +577,21 @@ do_build_copy_constructor (tree fndecl) } static void -do_build_assign_ref (tree fndecl) +do_build_copy_assign (tree fndecl) { - tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); + tree parm = DECL_CHAIN (DECL_ARGUMENTS (fndecl)); tree compound_stmt; + bool move_p = move_fn_p (fndecl); + bool trivial = trivial_fn_p (fndecl); compound_stmt = begin_compound_stmt (0); parm = convert_from_reference (parm); - if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type) + if (trivial && is_empty_class (current_class_type)) /* Don't copy the padding byte; it might not have been allocated if *this is a base subobject. */; - else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type)) + else if (trivial) { tree t = build2 (MODIFY_EXPR, void_type_node, current_class_ref, parm); finish_expr_stmt (t); @@ -544,6 +613,8 @@ do_build_assign_ref (tree fndecl) /* We must convert PARM directly to the base class explicitly since the base class may be ambiguous. */ converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1); + if (move_p) + converted_parm = move (converted_parm); /* Call the base class assignment operator. */ parmvec = make_tree_vector_single (converted_parm); finish_expr_stmt @@ -559,7 +630,7 @@ do_build_assign_ref (tree fndecl) /* Assign to each of the non-static data members. */ for (fields = TYPE_FIELDS (current_class_type); fields; - fields = TREE_CHAIN (fields)) + fields = DECL_CHAIN (fields)) { tree comp = current_class_ref; tree init = parm; @@ -593,7 +664,8 @@ do_build_assign_ref (tree fndecl) else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type) != NULL_TREE) /* Just use the field; anonymous types can't have - nontrivial copy ctors or assignment ops. */; + nontrivial copy ctors or assignment ops or this + function would be deleted. */; else continue; @@ -606,6 +678,8 @@ do_build_assign_ref (tree fndecl) expr_type = cp_build_qualified_type (expr_type, quals); init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE); + if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE) + init = move (init); if (DECL_NAME (field)) init = cp_build_modify_expr (comp, NOP_EXPR, init, @@ -659,7 +733,7 @@ synthesize_method (tree fndecl) if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR) { - do_build_assign_ref (fndecl); + do_build_copy_assign (fndecl); need_body = false; } else if (DECL_CONSTRUCTOR_P (fndecl)) @@ -697,163 +771,575 @@ synthesize_method (tree fndecl) fndecl); } -/* Use EXTRACTOR to locate the relevant function called for each base & - class field of TYPE. CLIENT allows additional information to be passed - to EXTRACTOR. Generates the union of all exceptions generated by those - functions. Note that we haven't updated TYPE_FIELDS and such of any - variants yet, so we need to look at the main one. */ +/* Build a reference to type TYPE with cv-quals QUALS, which is an + rvalue if RVALUE is true. */ static tree -synthesize_exception_spec (tree type, tree (*extractor) (tree, void*), - void *client) +build_stub_type (tree type, int quals, bool rvalue) { - tree raises = empty_except_spec; - tree fields = TYPE_FIELDS (type); - tree binfo, base_binfo; - int i; + tree argtype = cp_build_qualified_type (type, quals); + return cp_build_reference_type (argtype, rvalue); +} - for (binfo = TYPE_BINFO (type), i = 0; - BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) - { - tree fn = (*extractor) (BINFO_TYPE (base_binfo), client); - if (fn) - { - tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); +/* Build a dummy glvalue from dereferencing a dummy reference of type + REFTYPE. */ - raises = merge_exception_specifiers (raises, fn_raises); - } - } - for (; fields; fields = TREE_CHAIN (fields)) - { - tree type = TREE_TYPE (fields); - tree fn; +static tree +build_stub_object (tree reftype) +{ + tree stub = build1 (NOP_EXPR, reftype, integer_one_node); + return convert_from_reference (stub); +} - if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields)) - continue; - while (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - if (!CLASS_TYPE_P (type)) - continue; +/* Determine which function will be called when looking up NAME in TYPE, + called with a single ARGTYPE argument, or no argument if ARGTYPE is + null. FLAGS and COMPLAIN are as for build_new_method_call. - fn = (*extractor) (type, client); - if (fn) - { - tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); + Returns a FUNCTION_DECL if all is well. + Returns NULL_TREE if overload resolution failed. + Returns error_mark_node if the chosen function cannot be called. */ - raises = merge_exception_specifiers (raises, fn_raises); - } +static tree +locate_fn_flags (tree type, tree name, tree argtype, int flags, + tsubst_flags_t complain) +{ + tree ob, fn, fns, binfo, rval; + VEC(tree,gc) *args; + + if (TYPE_P (type)) + binfo = TYPE_BINFO (type); + else + { + binfo = type; + type = BINFO_TYPE (binfo); } - return raises; + + ob = build_stub_object (cp_build_reference_type (type, false)); + args = make_tree_vector (); + if (argtype) + { + tree arg = build_stub_object (argtype); + VEC_quick_push (tree, args, arg); + } + + fns = lookup_fnfields (binfo, name, 0); + rval = build_new_method_call (ob, fns, &args, binfo, flags, &fn, complain); + + release_tree_vector (args); + if (fn && rval == error_mark_node) + return rval; + else + return fn; } /* Locate the dtor of TYPE. */ tree -locate_dtor (tree type, void *client ATTRIBUTE_UNUSED) +get_dtor (tree type) { - return CLASSTYPE_DESTRUCTORS (type); + tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE, + LOOKUP_NORMAL, tf_warning_or_error); + if (fn == error_mark_node) + return NULL_TREE; + return fn; } /* Locate the default ctor of TYPE. */ tree -locate_ctor (tree type, void *client ATTRIBUTE_UNUSED) +locate_ctor (tree type) +{ + tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE, + LOOKUP_SPECULATIVE, tf_none); + if (fn == error_mark_node) + return NULL_TREE; + return fn; +} + +/* Likewise, but give any appropriate errors. */ + +tree +get_default_ctor (tree type) +{ + tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE, + LOOKUP_NORMAL, tf_warning_or_error); + if (fn == error_mark_node) + return NULL_TREE; + return fn; +} + +/* Locate the copy ctor of TYPE. */ + +tree +get_copy_ctor (tree type) { - tree fns; + int quals = (TYPE_HAS_CONST_COPY_CTOR (type) + ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED); + tree argtype = build_stub_type (type, quals, false); + tree fn = locate_fn_flags (type, complete_ctor_identifier, argtype, + LOOKUP_NORMAL, tf_warning_or_error); + if (fn == error_mark_node) + return NULL_TREE; + return fn; +} + +/* Locate the copy assignment operator of TYPE. */ - if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) +tree +get_copy_assign (tree type) +{ + int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type) + ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED); + tree argtype = build_stub_type (type, quals, false); + tree fn = locate_fn_flags (type, ansi_assopname (NOP_EXPR), argtype, + LOOKUP_NORMAL, tf_warning_or_error); + if (fn == error_mark_node) return NULL_TREE; + return fn; +} - /* Call lookup_fnfields_1 to create the constructor declarations, if - necessary. */ - if (CLASSTYPE_LAZY_DEFAULT_CTOR (type)) - return lazily_declare_fn (sfk_constructor, type); +/* Subroutine of synthesized_method_walk. Update SPEC_P, TRIVIAL_P and + DELETED_P or give an error message MSG with argument ARG. */ + +static void +process_subob_fn (tree fn, bool move_p, tree *spec_p, bool *trivial_p, + bool *deleted_p, const char *msg, tree arg) +{ + if (!fn || fn == error_mark_node) + goto bad; - for (fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns)) + if (spec_p) { - tree fn = OVL_CURRENT (fns); - tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn)); + tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); + *spec_p = merge_exception_specifiers (*spec_p, raises); + } - parms = skip_artificial_parms_for (fn, parms); + if (!trivial_fn_p (fn)) + { + if (trivial_p) + *trivial_p = false; + if (TREE_CODE (arg) == FIELD_DECL + && TREE_CODE (DECL_CONTEXT (arg)) == UNION_TYPE) + { + if (deleted_p) + *deleted_p = true; + if (msg) + error ("union member %q+D with non-trivial %qD", arg, fn); + } + } - if (sufficient_parms_p (parms)) - return fn; + if (move_p && !move_fn_p (fn) && !trivial_fn_p (fn)) + { + if (msg) + error (msg, arg); + goto bad; } - gcc_unreachable (); + + return; + + bad: + if (deleted_p) + *deleted_p = true; } -struct copy_data +/* Subroutine of synthesized_method_walk to allow recursion into anonymous + aggregates. */ + +static void +walk_field_subobs (tree fields, tree fnname, special_function_kind sfk, + int quals, bool copy_arg_p, bool move_p, + bool assign_p, tree *spec_p, bool *trivial_p, + bool *deleted_p, const char *msg, + int flags, tsubst_flags_t complain) { - tree name; - int quals; -}; + tree field; + for (field = fields; field; field = DECL_CHAIN (field)) + { + tree mem_type, argtype, rval; -/* Locate the copy ctor or copy assignment of TYPE. CLIENT_ - points to a COPY_DATA holding the name (NULL for the ctor) - and desired qualifiers of the source operand. */ + if (TREE_CODE (field) != FIELD_DECL + || DECL_ARTIFICIAL (field)) + continue; -tree -locate_copy (tree type, void *client_) + mem_type = strip_array_types (TREE_TYPE (field)); + if (assign_p) + { + bool bad = true; + if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type)) + { + if (msg) + error ("non-static const member %q#D, can't use default " + "assignment operator", field); + } + else if (TREE_CODE (mem_type) == REFERENCE_TYPE) + { + if (msg) + error ("non-static reference member %q#D, can't use " + "default assignment operator", field); + } + else + bad = false; + + if (bad && deleted_p) + *deleted_p = true; + } + else if (sfk == sfk_constructor) + { + bool bad = true; + if (CP_TYPE_CONST_P (mem_type) + && (!CLASS_TYPE_P (mem_type) + || !type_has_user_provided_default_constructor (mem_type))) + { + if (msg) + error ("uninitialized non-static const member %q#D", + field); + } + else if (TREE_CODE (mem_type) == REFERENCE_TYPE) + { + if (msg) + error ("uninitialized non-static reference member %q#D", + field); + } + else + bad = false; + + if (bad && deleted_p) + *deleted_p = true; + } + + if (!CLASS_TYPE_P (mem_type)) + continue; + + if (ANON_AGGR_TYPE_P (mem_type)) + { + walk_field_subobs (TYPE_FIELDS (mem_type), fnname, sfk, quals, + copy_arg_p, move_p, assign_p, spec_p, trivial_p, + deleted_p, msg, flags, complain); + continue; + } + + if (copy_arg_p) + { + int mem_quals = cp_type_quals (mem_type) | quals; + if (DECL_MUTABLE_P (field)) + mem_quals &= ~TYPE_QUAL_CONST; + argtype = build_stub_type (mem_type, mem_quals, move_p); + } + else + argtype = NULL_TREE; + + rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain); + + process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p, + msg, field); + } +} + +/* The caller wants to generate an implicit declaration of SFK for CTYPE + which is const if relevant and CONST_P is set. If spec_p, trivial_p and + deleted_p are non-null, set their referent appropriately. If diag is + true, we're being called from maybe_explain_implicit_delete to give + errors. */ + +static void +synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, + tree *spec_p, bool *trivial_p, bool *deleted_p, + bool diag) { - struct copy_data *client = (struct copy_data *)client_; - tree fns; - tree best = NULL_TREE; - bool excess_p = false; + tree binfo, base_binfo, scope, fnname, rval, argtype; + bool move_p, copy_arg_p, assign_p, expected_trivial, check_vdtor; + VEC(tree,gc) *vbases; + int i, quals, flags; + tsubst_flags_t complain; + const char *msg; + bool ctor_p; + tree cleanup_spec; + bool cleanup_trivial = true; + bool cleanup_deleted = false; + + cleanup_spec + = (cxx_dialect >= cxx0x ? noexcept_true_spec : empty_except_spec); + if (spec_p) + *spec_p = cleanup_spec; + + if (deleted_p) + { + /* "The closure type associated with a lambda-expression has a deleted + default constructor and a deleted copy assignment operator." + This is diagnosed in maybe_explain_implicit_delete. */ + if (LAMBDA_TYPE_P (ctype) + && (sfk == sfk_constructor + || sfk == sfk_copy_assignment)) + { + *deleted_p = true; + return; + } + + *deleted_p = false; + } - if (client->name) + move_p = false; + switch (sfk) { - int ix; - ix = lookup_fnfields_1 (type, client->name); - if (ix < 0) - return NULL_TREE; - fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix); + case sfk_constructor: + case sfk_destructor: + copy_arg_p = false; + break; + + case sfk_move_constructor: + case sfk_move_assignment: + move_p = true; + case sfk_copy_constructor: + case sfk_copy_assignment: + copy_arg_p = true; + break; + + default: + gcc_unreachable (); } - else if (TYPE_HAS_INIT_REF (type)) + + expected_trivial = type_has_trivial_fn (ctype, sfk); + if (trivial_p) + *trivial_p = expected_trivial; + +#ifndef ENABLE_CHECKING + /* The TYPE_HAS_COMPLEX_* flags tell us about constraints from base + class versions and other properties of the type. But a subobject + class can be trivially copyable and yet have overload resolution + choose a template constructor for initialization, depending on + rvalueness and cv-quals. So we can't exit early for copy/move + methods in C++0x. */ + if (expected_trivial + && (!copy_arg_p || cxx_dialect < cxx0x)) + return; +#endif + + ctor_p = false; + assign_p = false; + check_vdtor = false; + switch (sfk) { - /* If construction of the copy constructor was postponed, create - it now. */ - if (CLASSTYPE_LAZY_COPY_CTOR (type)) - lazily_declare_fn (sfk_copy_constructor, type); - if (CLASSTYPE_LAZY_MOVE_CTOR (type)) - lazily_declare_fn (sfk_move_constructor, type); - fns = CLASSTYPE_CONSTRUCTORS (type); + case sfk_move_assignment: + case sfk_copy_assignment: + assign_p = true; + fnname = ansi_assopname (NOP_EXPR); + break; + + case sfk_destructor: + check_vdtor = true; + /* The synthesized method will call base dtors, but check complete + here to avoid having to deal with VTT. */ + fnname = complete_dtor_identifier; + break; + + case sfk_constructor: + case sfk_move_constructor: + case sfk_copy_constructor: + ctor_p = true; + fnname = complete_ctor_identifier; + break; + + default: + gcc_unreachable (); + } + + ++cp_unevaluated_operand; + ++c_inhibit_evaluation_warnings; + + scope = push_scope (ctype); + + if (diag) + { + flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE; + complain = tf_warning_or_error; } else - return NULL_TREE; - for (; fns; fns = OVL_NEXT (fns)) { - tree fn = OVL_CURRENT (fns); - tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn)); - tree src_type; - int excess; - int quals; - - parms = skip_artificial_parms_for (fn, parms); - if (!parms) - continue; - src_type = non_reference (TREE_VALUE (parms)); + flags = LOOKUP_PROTECT|LOOKUP_SPECULATIVE; + complain = tf_none; + } - if (src_type == error_mark_node) - return NULL_TREE; + if (const_p) + quals = TYPE_QUAL_CONST; + else + quals = TYPE_UNQUALIFIED; + argtype = NULL_TREE; + + if (!diag) + msg = NULL; + else if (assign_p) + msg = ("base %qT does not have a move assignment operator or trivial " + "copy assignment operator"); + else + msg = ("base %qT does not have a move constructor or trivial " + "copy constructor"); - if (!same_type_ignoring_top_level_qualifiers_p (src_type, type)) - continue; - if (!sufficient_parms_p (TREE_CHAIN (parms))) - continue; - quals = cp_type_quals (src_type); - if (client->quals & ~quals) - continue; - excess = quals & ~client->quals; - if (!best || (excess_p && !excess)) + for (binfo = TYPE_BINFO (ctype), i = 0; + BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) + { + tree basetype = BINFO_TYPE (base_binfo); + if (copy_arg_p) + argtype = build_stub_type (basetype, quals, move_p); + rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain); + + process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p, + msg, basetype); + if (ctor_p && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype)) { - best = fn; - excess_p = excess; + /* In a constructor we also need to check the subobject + destructors for cleanup of partially constructed objects. */ + rval = locate_fn_flags (base_binfo, complete_dtor_identifier, + NULL_TREE, flags, complain); + process_subob_fn (rval, false, &cleanup_spec, &cleanup_trivial, + &cleanup_deleted, NULL, basetype); } - else - /* Ambiguous */ - return NULL_TREE; + + if (check_vdtor && type_has_virtual_destructor (basetype)) + { + rval = locate_fn_flags (ctype, ansi_opname (DELETE_EXPR), + ptr_type_node, flags, complain); + /* Unlike for base ctor/op=/dtor, for operator delete it's fine + to have a null rval (no class-specific op delete). */ + if (rval && rval == error_mark_node && deleted_p) + *deleted_p = true; + check_vdtor = false; + } + } + + vbases = CLASSTYPE_VBASECLASSES (ctype); + if (vbases && assign_p && move_p) + { + /* Should the spec be changed to allow vbases that only occur once? */ + if (diag) + error ("%qT has virtual bases, default move assignment operator " + "cannot be generated", ctype); + else if (deleted_p) + *deleted_p = true; + } + else if (!assign_p) + { + if (diag) + msg = ("virtual base %qT does not have a move constructor " + "or trivial copy constructor"); + FOR_EACH_VEC_ELT (tree, vbases, i, base_binfo) + { + tree basetype = BINFO_TYPE (base_binfo); + if (copy_arg_p) + argtype = build_stub_type (basetype, quals, move_p); + rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain); + + process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p, + msg, basetype); + if (ctor_p && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype)) + { + rval = locate_fn_flags (base_binfo, complete_dtor_identifier, + NULL_TREE, flags, complain); + process_subob_fn (rval, false, &cleanup_spec, &cleanup_trivial, + &cleanup_deleted, NULL, basetype); + } + } + } + if (!diag) + /* Leave msg null. */; + else if (assign_p) + msg = ("non-static data member %qD does not have a move " + "assignment operator or trivial copy assignment operator"); + else + msg = ("non-static data member %qD does not have a move " + "constructor or trivial copy constructor"); + walk_field_subobs (TYPE_FIELDS (ctype), fnname, sfk, quals, + copy_arg_p, move_p, assign_p, spec_p, trivial_p, + deleted_p, msg, flags, complain); + if (ctor_p) + walk_field_subobs (TYPE_FIELDS (ctype), complete_dtor_identifier, + sfk_destructor, TYPE_UNQUALIFIED, false, + false, false, &cleanup_spec, &cleanup_trivial, + &cleanup_deleted, NULL, flags, complain); + + pop_scope (scope); + + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; + + /* If the constructor isn't trivial, consider the subobject cleanups. */ + if (ctor_p && trivial_p && !*trivial_p) + { + if (deleted_p && cleanup_deleted) + *deleted_p = true; + if (spec_p) + *spec_p = merge_exception_specifiers (*spec_p, cleanup_spec); + } + +#ifdef ENABLE_CHECKING + /* If we expected this to be trivial but it isn't, then either we're in + C++0x mode and this is a copy/move ctor/op= or there's an error. */ + gcc_assert (!(trivial_p && expected_trivial && !*trivial_p) + || (copy_arg_p && cxx_dialect >= cxx0x) + || errorcount); +#endif +} + +/* DECL is a deleted function. If it's implicitly deleted, explain why and + return true; else return false. */ + +bool +maybe_explain_implicit_delete (tree decl) +{ + /* If decl is a clone, get the primary variant. */ + decl = DECL_ORIGIN (decl); + gcc_assert (DECL_DELETED_FN (decl)); + if (DECL_DEFAULTED_FN (decl) + && DECL_INITIAL (decl) == NULL_TREE) + { + /* Not marked GTY; it doesn't need to be GC'd or written to PCH. */ + static htab_t explained_htab; + void **slot; + + special_function_kind sfk; + location_t loc; + bool informed; + tree ctype; + + if (!explained_htab) + explained_htab = htab_create (37, htab_hash_pointer, + htab_eq_pointer, NULL); + slot = htab_find_slot (explained_htab, decl, INSERT); + if (*slot) + return true; + *slot = decl; + + sfk = special_function_p (decl); + ctype = DECL_CONTEXT (decl); + loc = input_location; + input_location = DECL_SOURCE_LOCATION (decl); + + informed = false; + if (LAMBDA_TYPE_P (ctype)) + { + informed = true; + if (sfk == sfk_constructor) + error ("a lambda closure type has a deleted default constructor"); + else if (sfk == sfk_copy_assignment) + error ("a lambda closure type has a deleted copy assignment operator"); + else + informed = false; + } + if (!informed) + { + tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl)); + bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); + tree scope = push_scope (ctype); + error ("%qD is implicitly deleted because the default " + "definition would be ill-formed:", decl); + pop_scope (scope); + synthesized_method_walk (ctype, sfk, const_p, + NULL, NULL, NULL, true); + } + + input_location = loc; + return true; } - return best; + return false; } /* Implicitly declare the special function indicated by KIND, as a @@ -874,6 +1360,8 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) tree this_parm; tree name; HOST_WIDE_INT saved_processing_template_decl; + bool deleted_p; + bool trivial_p; /* Because we create declarations for implicitly declared functions lazily, we may be creating the declaration for a member of TYPE @@ -905,50 +1393,49 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) case sfk_destructor: /* Destructor. */ name = constructor_name (type); - raises = synthesize_exception_spec (type, &locate_dtor, 0); break; case sfk_constructor: /* Default constructor. */ name = constructor_name (type); - raises = synthesize_exception_spec (type, &locate_ctor, 0); break; case sfk_copy_constructor: - case sfk_assignment_operator: + case sfk_copy_assignment: case sfk_move_constructor: + case sfk_move_assignment: { - struct copy_data data; - - data.name = NULL; - data.quals = 0; - if (kind == sfk_assignment_operator) + bool move_p; + if (kind == sfk_copy_assignment + || kind == sfk_move_assignment) { return_type = build_reference_type (type); name = ansi_assopname (NOP_EXPR); - data.name = name; } else name = constructor_name (type); if (const_p) - { - data.quals = TYPE_QUAL_CONST; - rhs_parm_type = build_qualified_type (type, TYPE_QUAL_CONST); - } + rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST); else rhs_parm_type = type; - rhs_parm_type - = cp_build_reference_type (rhs_parm_type, - kind == sfk_move_constructor); + move_p = (kind == sfk_move_assignment + || kind == sfk_move_constructor); + rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p); + parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types); - raises = synthesize_exception_spec (type, &locate_copy, &data); break; } default: gcc_unreachable (); } + synthesized_method_walk (type, kind, const_p, &raises, &trivial_p, + &deleted_p, false); + + if (!trivial_p && type_has_trivial_fn (type, kind)) + type_set_nontrivial_flag (type, kind); + /* Create the function. */ fn_type = build_method_type_directly (type, return_type, parameter_types); if (raises) @@ -984,7 +1471,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) } /* Add the "this" parameter. */ this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED); - TREE_CHAIN (this_parm) = DECL_ARGUMENTS (fn); + DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn); DECL_ARGUMENTS (fn) = this_parm; grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL); @@ -993,6 +1480,8 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) DECL_IN_AGGR_P (fn) = 1; DECL_ARTIFICIAL (fn) = 1; DECL_DEFAULTED_FN (fn) = 1; + if (cxx_dialect >= cxx0x) + DECL_DELETED_FN (fn) = deleted_p; DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; gcc_assert (!TREE_USED (fn)); @@ -1024,6 +1513,18 @@ defaulted_late_check (tree fn) error_at (DECL_SOURCE_LOCATION (fn), "does not match expected signature %qD", implicit_fn); } + + /* 8.4.2/2: If it is explicitly defaulted on its first declaration, it is + implicitly considered to have the same exception-specification as if + it had been implicitly declared. */ + if (DECL_DEFAULTED_IN_CLASS_P (fn)) + { + tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn)); + TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec); + } + + if (DECL_DELETED_FN (implicit_fn)) + DECL_DELETED_FN (fn) = 1; } /* Returns true iff FN can be explicitly defaulted, and gives any @@ -1048,9 +1549,13 @@ defaultable_fn_check (tree fn) else if (DECL_DESTRUCTOR_P (fn)) kind = sfk_destructor; else if (DECL_ASSIGNMENT_OPERATOR_P (fn) - && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR - && copy_fn_p (fn)) - kind = sfk_assignment_operator; + && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR) + { + if (copy_fn_p (fn)) + kind = sfk_copy_assignment; + else if (move_fn_p (fn)) + kind = sfk_move_assignment; + } if (kind == sfk_none) { @@ -1096,21 +1601,49 @@ tree lazily_declare_fn (special_function_kind sfk, tree type) { tree fn; - bool const_p; - - /* Figure out whether or not the argument has a const reference - type. */ - if (sfk == sfk_copy_constructor) - const_p = TYPE_HAS_CONST_INIT_REF (type); - else if (sfk == sfk_assignment_operator) - const_p = TYPE_HAS_CONST_ASSIGN_REF (type); - else - /* In this case, CONST_P will be ignored. */ - const_p = false; + /* Whether or not the argument has a const reference type. */ + bool const_p = false; + + switch (sfk) + { + case sfk_constructor: + CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0; + break; + case sfk_copy_constructor: + const_p = TYPE_HAS_CONST_COPY_CTOR (type); + CLASSTYPE_LAZY_COPY_CTOR (type) = 0; + break; + case sfk_move_constructor: + CLASSTYPE_LAZY_MOVE_CTOR (type) = 0; + break; + case sfk_copy_assignment: + const_p = TYPE_HAS_CONST_COPY_ASSIGN (type); + CLASSTYPE_LAZY_COPY_ASSIGN (type) = 0; + break; + case sfk_move_assignment: + CLASSTYPE_LAZY_MOVE_ASSIGN (type) = 0; + break; + case sfk_destructor: + CLASSTYPE_LAZY_DESTRUCTOR (type) = 0; + break; + default: + gcc_unreachable (); + } + /* Declare the function. */ fn = implicitly_declare_fn (sfk, type, const_p); + + /* For move variants, rather than declare them as deleted we just + don't declare them at all. */ + if (DECL_DELETED_FN (fn) + && (sfk == sfk_move_constructor + || sfk == sfk_move_assignment)) + return NULL_TREE; + /* A destructor may be virtual. */ - if (sfk == sfk_destructor) + if (sfk == sfk_destructor + || sfk == sfk_move_assignment + || sfk == sfk_copy_assignment) check_for_override (fn, type); /* Add it to CLASSTYPE_METHOD_VEC. */ add_method (type, fn, NULL_TREE); @@ -1131,26 +1664,14 @@ lazily_declare_fn (special_function_kind sfk, tree type) "and may change in a future version of GCC due to " "implicit virtual destructor", type); - TREE_CHAIN (fn) = TYPE_METHODS (type); + DECL_CHAIN (fn) = TYPE_METHODS (type); TYPE_METHODS (type) = fn; } maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0); - if (sfk == sfk_assignment_operator) - CLASSTYPE_LAZY_ASSIGNMENT_OP (type) = 0; - else - { - /* Remember that the function has been created. */ - if (sfk == sfk_constructor) - CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0; - else if (sfk == sfk_copy_constructor) - CLASSTYPE_LAZY_COPY_CTOR (type) = 0; - else if (sfk == sfk_move_constructor) - CLASSTYPE_LAZY_MOVE_CTOR (type) = 0; - else if (sfk == sfk_destructor) - CLASSTYPE_LAZY_DESTRUCTOR (type) = 0; - /* Create appropriate clones. */ - clone_function_decl (fn, /*update_method_vec=*/true); - } + if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn) + || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)) + /* Create appropriate clones. */ + clone_function_decl (fn, /*update_method_vec=*/true); return fn; } diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 7b43d30f47e..41feb57898e 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -29,9 +29,9 @@ along with GCC; see the file COPYING3. If not see #include "name-lookup.h" #include "timevar.h" #include "toplev.h" -#include "diagnostic.h" +#include "diagnostic-core.h" #include "debug.h" -#include "c-pragma.h" +#include "c-family/c-pragma.h" /* The bindings for a particular name in a particular scope. */ @@ -102,7 +102,7 @@ binding_entry_make (tree name, tree type) free_binding_entry = entry->chain; } else - entry = GGC_NEW (struct binding_entry_s); + entry = ggc_alloc_binding_entry_s (); entry->name = name; entry->type = type; @@ -144,7 +144,7 @@ binding_table_construct (binding_table table, size_t chain_count) { table->chain_count = chain_count; table->entry_count = 0; - table->chain = GGC_CNEWVEC (binding_entry, table->chain_count); + table->chain = ggc_alloc_cleared_vec_binding_entry (table->chain_count); } /* Make TABLE's entries ready for reuse. */ @@ -178,7 +178,7 @@ binding_table_free (binding_table table) static inline binding_table binding_table_new (size_t chain_count) { - binding_table table = GGC_NEW (struct binding_table_s); + binding_table table = ggc_alloc_binding_table_s (); table->chain = NULL; binding_table_construct (table, chain_count); return table; @@ -292,7 +292,7 @@ cxx_binding_make (tree value, tree type) free_bindings = binding->previous; } else - binding = GGC_NEW (cxx_binding); + binding = ggc_alloc_cxx_binding (); cxx_binding_init (binding, value, type); @@ -327,9 +327,7 @@ new_class_binding (tree name, tree value, tree type, cxx_scope *scope) /* Fixup the current bindings, as they might have moved. */ size_t i; - for (i = 0; - VEC_iterate (cp_class_binding, scope->class_shadowed, i, cb); - i++) + FOR_EACH_VEC_ELT (cp_class_binding, scope->class_shadowed, i, cb) { cxx_binding **b; b = &IDENTIFIER_BINDING (cb->identifier); @@ -542,7 +540,7 @@ add_decl_to_level (tree decl, cxx_scope *b) if (TREE_CODE (decl) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (decl)) { - TREE_CHAIN (decl) = b->namespaces; + DECL_CHAIN (decl) = b->namespaces; b->namespaces = decl; } else @@ -707,7 +705,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) = htab_create_ggc (20, cxx_int_tree_map_hash, cxx_int_tree_map_eq, NULL); - h = GGC_NEW (struct cxx_int_tree_map); + h = ggc_alloc_cxx_int_tree_map (); h->uid = DECL_UID (x); h->to = t; loc = htab_find_slot_with_hash @@ -805,7 +803,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) TYPE_RAISES_EXCEPTIONS (TREE_TYPE (previous)); if (!comp_except_specs (previous_exception_spec, x_exception_spec, - true)) + ce_normal)) { pedwarn (input_location, 0, "declaration of %q#D with C language linkage", x); @@ -1016,15 +1014,30 @@ pushdecl_maybe_friend (tree x, bool is_friend) else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x) /* Inline decls shadow nothing. */ && !DECL_FROM_INLINE (x) - && TREE_CODE (oldlocal) == PARM_DECL - /* Don't check the `this' parameter. */ - && !DECL_ARTIFICIAL (oldlocal)) + && (TREE_CODE (oldlocal) == PARM_DECL + || TREE_CODE (oldlocal) == VAR_DECL + /* If the old decl is a type decl, only warn if the + old decl is an explicit typedef or if both the old + and new decls are type decls. */ + || (TREE_CODE (oldlocal) == TYPE_DECL + && (!DECL_ARTIFICIAL (oldlocal) + || TREE_CODE (x) == TYPE_DECL))) + /* Don't check the `this' parameter or internally generated + vars unless it's an implicit typedef (see + create_implicit_typedef in decl.c). */ + && (!DECL_ARTIFICIAL (oldlocal) + || DECL_IMPLICIT_TYPEDEF_P (oldlocal)) + /* Don't check for internally generated vars unless + it's an implicit typedef (see create_implicit_typedef + in decl.c). */ + && (!DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x))) { - bool err = false; + bool nowarn = false; /* Don't complain if it's from an enclosing function. */ if (DECL_CONTEXT (oldlocal) == current_function_decl - && TREE_CODE (x) != PARM_DECL) + && TREE_CODE (x) != PARM_DECL + && TREE_CODE (oldlocal) == PARM_DECL) { /* Go to where the parms should be and see if we find them there. */ @@ -1038,25 +1051,52 @@ pushdecl_maybe_friend (tree x, bool is_friend) if (b->kind == sk_function_parms) { error ("declaration of %q#D shadows a parameter", x); - err = true; + nowarn = true; } } - if (warn_shadow && !err) + /* The local structure or class can't use parameters of + the containing function anyway. */ + if (DECL_CONTEXT (oldlocal) != current_function_decl) { - warning_at (input_location, OPT_Wshadow, - "declaration of %q#D shadows a parameter", x); - warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow, - "shadowed declaration is here"); + cxx_scope *scope = current_binding_level; + tree context = DECL_CONTEXT (oldlocal); + for (; scope; scope = scope->level_chain) + { + if (scope->kind == sk_function_parms + && scope->this_entity == context) + break; + if (scope->kind == sk_class + && !LAMBDA_TYPE_P (scope->this_entity)) + { + nowarn = true; + break; + } + } + } + + if (warn_shadow && !nowarn) + { + if (TREE_CODE (oldlocal) == PARM_DECL) + warning_at (input_location, OPT_Wshadow, + "declaration of %q#D shadows a parameter", x); + else + warning_at (input_location, OPT_Wshadow, + "declaration of %qD shadows a previous local", + x); + warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow, + "shadowed declaration is here"); } } /* Maybe warn if shadowing something else. */ else if (warn_shadow && !DECL_EXTERNAL (x) - /* No shadow warnings for internally generated vars. */ - && ! DECL_ARTIFICIAL (x) - /* No shadow warnings for vars made for inlining. */ - && ! DECL_FROM_INLINE (x)) + /* No shadow warnings for internally generated vars unless + it's an implicit typedef (see create_implicit_typedef + in decl.c). */ + && (! DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x)) + /* No shadow warnings for vars made for inlining. */ + && ! DECL_FROM_INLINE (x)) { tree member; @@ -1074,16 +1114,14 @@ pushdecl_maybe_friend (tree x, bool is_friend) warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'", x); } - else if (oldlocal != NULL_TREE - && TREE_CODE (oldlocal) == VAR_DECL) - { - warning_at (input_location, OPT_Wshadow, - "declaration of %qD shadows a previous local", x); - warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow, - "shadowed declaration is here"); - } else if (oldglobal != NULL_TREE - && TREE_CODE (oldglobal) == VAR_DECL) + && (TREE_CODE (oldglobal) == VAR_DECL + /* If the old decl is a type decl, only warn if the + old decl is an explicit typedef or if both the + old and new decls are type decls. */ + || (TREE_CODE (oldglobal) == TYPE_DECL + && (!DECL_ARTIFICIAL (oldglobal) + || TREE_CODE (x) == TYPE_DECL)))) /* XXX shadow warnings in outer-more namespaces */ { warning_at (input_location, OPT_Wshadow, @@ -1133,7 +1171,7 @@ maybe_push_decl (tree decl) possible. */ && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL) || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ()) - || TREE_CODE (type) == UNKNOWN_TYPE + || type == unknown_type_node /* The declaration of a template specialization does not affect the functions available for overload resolution, so we do not call pushdecl. */ @@ -1364,7 +1402,7 @@ begin_scope (scope_kind kind, tree entity) free_binding_level = scope->level_chain; } else - scope = GGC_CNEW (cxx_scope); + scope = ggc_alloc_cleared_cxx_scope (); scope->this_entity = entity; scope->more_cleanups_ok = true; @@ -1647,9 +1685,7 @@ print_binding_level (struct cp_binding_level* lvl) size_t i; cp_class_binding *b; fprintf (stderr, " class-shadowed:"); - for (i = 0; - VEC_iterate(cp_class_binding, lvl->class_shadowed, i, b); - ++i) + FOR_EACH_VEC_ELT (cp_class_binding, lvl->class_shadowed, i, b) fprintf (stderr, " %s ", IDENTIFIER_POINTER (b->identifier)); fprintf (stderr, "\n"); } @@ -1953,7 +1989,7 @@ push_using_decl (tree scope, tree name) timevar_push (TV_NAME_LOOKUP); gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL); gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); - for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl)) + for (decl = current_binding_level->usings; decl; decl = DECL_CHAIN (decl)) if (USING_DECL_SCOPE (decl) == scope && DECL_NAME (decl) == name) break; if (decl) @@ -1961,7 +1997,7 @@ push_using_decl (tree scope, tree name) namespace_bindings_p () ? decl : NULL_TREE); decl = build_lang_decl (USING_DECL, name, NULL_TREE); USING_DECL_SCOPE (decl) = scope; - TREE_CHAIN (decl) = current_binding_level->usings; + DECL_CHAIN (decl) = current_binding_level->usings; current_binding_level->usings = decl; POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); } @@ -2460,6 +2496,8 @@ push_scope (tree t) void pop_scope (tree t) { + if (t == NULL_TREE) + return; if (TREE_CODE (t) == NAMESPACE_DECL) pop_decl_namespace (); else if CLASS_TYPE_P (t) @@ -2602,9 +2640,7 @@ poplevel_class (void) /* Remove the bindings for all of the class-level declarations. */ if (level->class_shadowed) { - for (i = 0; - VEC_iterate (cp_class_binding, level->class_shadowed, i, cb); - ++i) + FOR_EACH_VEC_ELT (cp_class_binding, level->class_shadowed, i, cb) IDENTIFIER_BINDING (cb->identifier) = cb->base.previous; ggc_free (level->class_shadowed); level->class_shadowed = NULL; @@ -2684,7 +2720,7 @@ pushdecl_class_level (tree x) aggregate, for naming purposes. */ tree f; - for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f)) + for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = DECL_CHAIN (f)) { location_t save_location = input_location; input_location = DECL_SOURCE_LOCATION (f); @@ -3170,13 +3206,13 @@ set_decl_namespace (tree decl, tree scope, bool friendp) /* Return the namespace where the current declaration is declared. */ -static tree +tree current_decl_namespace (void) { tree result; /* If we have been pushed into a different namespace, use it. */ - if (decl_namespace_list) - return TREE_PURPOSE (decl_namespace_list); + if (!VEC_empty (tree, decl_namespace_list)) + return VEC_last (tree, decl_namespace_list); if (current_class_type) result = decl_namespace_context (current_class_type); @@ -3342,6 +3378,7 @@ void pop_nested_namespace (tree ns) { timevar_push (TV_NAME_LOOKUP); + gcc_assert (current_namespace == ns); while (ns != global_namespace) { pop_namespace (); @@ -3359,8 +3396,7 @@ push_decl_namespace (tree decl) { if (TREE_CODE (decl) != NAMESPACE_DECL) decl = decl_namespace_context (decl); - decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl), - NULL_TREE, decl_namespace_list); + VEC_safe_push (tree, gc, decl_namespace_list, ORIGINAL_NAMESPACE (decl)); } /* [namespace.memdef]/2 */ @@ -3368,7 +3404,7 @@ push_decl_namespace (tree decl) void pop_decl_namespace (void) { - decl_namespace_list = TREE_CHAIN (decl_namespace_list); + VEC_pop (tree, decl_namespace_list); } /* Return the namespace that is the common ancestor @@ -3677,6 +3713,31 @@ merge_functions (tree s1, tree s2) return s1; } +/* Returns TRUE iff OLD and NEW are the same entity. + + 3 [basic]/3: An entity is a value, object, reference, function, + enumerator, type, class member, template, template specialization, + namespace, parameter pack, or this. + + 7.3.4 [namespace.udir]/4: If name lookup finds a declaration for a name + in two different namespaces, and the declarations do not declare the + same entity and do not declare functions, the use of the name is + ill-formed. */ + +static bool +same_entity_p (tree one, tree two) +{ + if (one == two) + return true; + if (!one || !two) + return false; + if (TREE_CODE (one) == TYPE_DECL + && TREE_CODE (two) == TYPE_DECL + && same_type_p (TREE_TYPE (one), TREE_TYPE (two))) + return true; + return false; +} + /* This should return an error not all definitions define functions. It is not an error if we find two functions with exactly the same signature, only if these are selected in overload resolution. @@ -3742,7 +3803,7 @@ ambiguous_decl (struct scope_binding *old, cxx_binding *new_binding, int flags) if (!old->value) old->value = val; - else if (val && val != old->value) + else if (val && !same_entity_p (val, old->value)) { if (is_overloaded_fn (old->value) && is_overloaded_fn (val)) old->value = merge_functions (old->value, val); @@ -3806,6 +3867,10 @@ qualify_lookup (tree val, int flags) if (cp_unevaluated_operand && TREE_CODE (val) == FIELD_DECL && DECL_NORMAL_CAPTURE_P (val)) return false; + /* None of the lookups that use qualify_lookup want the op() from the + lambda; they want the one from the enclosing class. */ + if (TREE_CODE (val) == FUNCTION_DECL && LAMBDA_FUNCTION_P (val)) + return false; return true; } @@ -3977,7 +4042,7 @@ tree_vec_contains (VEC(tree,gc)* vec, tree target) { unsigned int i; tree elt; - for (i = 0; VEC_iterate(tree,vec,i,elt); ++i) + FOR_EACH_VEC_ELT (tree,vec,i,elt) if (elt == target) return true; return false; @@ -4324,7 +4389,7 @@ lookup_function_nonclass (tree name, VEC(tree,gc) *args, bool block_p) lookup_arg_dependent (name, lookup_name_real (name, 0, 1, block_p, 0, LOOKUP_COMPLAIN), - args); + args, false); } tree @@ -4539,8 +4604,8 @@ struct arg_lookup { tree name; VEC(tree,gc) *args; - tree namespaces; - tree classes; + VEC(tree,gc) *namespaces; + VEC(tree,gc) *classes; tree functions; }; @@ -4588,25 +4653,38 @@ add_function (struct arg_lookup *k, tree fn) bool is_associated_namespace (tree current, tree scope) { - tree seen = NULL_TREE; - tree todo = NULL_TREE; + VEC(tree,gc) *seen = make_tree_vector (); + VEC(tree,gc) *todo = make_tree_vector (); tree t; + bool ret; + while (1) { if (scope == current) - return true; - seen = tree_cons (scope, NULL_TREE, seen); + { + ret = true; + break; + } + VEC_safe_push (tree, gc, seen, scope); for (t = DECL_NAMESPACE_ASSOCIATIONS (scope); t; t = TREE_CHAIN (t)) - if (!purpose_member (TREE_PURPOSE (t), seen)) - todo = tree_cons (TREE_PURPOSE (t), NULL_TREE, todo); - if (todo) + if (!vec_member (TREE_PURPOSE (t), seen)) + VEC_safe_push (tree, gc, todo, TREE_PURPOSE (t)); + if (!VEC_empty (tree, todo)) { - scope = TREE_PURPOSE (todo); - todo = TREE_CHAIN (todo); + scope = VEC_last (tree, todo); + VEC_pop (tree, todo); } else - return false; + { + ret = false; + break; + } } + + release_tree_vector (seen); + release_tree_vector (todo); + + return ret; } /* Add functions of a namespace to the lookup structure. @@ -4617,9 +4695,9 @@ arg_assoc_namespace (struct arg_lookup *k, tree scope) { tree value; - if (purpose_member (scope, k->namespaces)) - return 0; - k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces); + if (vec_member (scope, k->namespaces)) + return false; + VEC_safe_push (tree, gc, k->namespaces, scope); /* Check out our super-users. */ for (value = DECL_NAMESPACE_ASSOCIATIONS (scope); value; @@ -4800,9 +4878,9 @@ arg_assoc_class (struct arg_lookup *k, tree type) if (!CLASS_TYPE_P (type)) return false; - if (purpose_member (type, k->classes)) + if (vec_member (type, k->classes)) return false; - k->classes = tree_cons (type, NULL_TREE, k->classes); + VEC_safe_push (tree, gc, k->classes, type); if (TYPE_CLASS_SCOPE_P (type) && arg_assoc_class_only (k, TYPE_CONTEXT (type))) @@ -4885,6 +4963,7 @@ arg_assoc_type (struct arg_lookup *k, tree type) return false; case LANG_TYPE: gcc_assert (type == unknown_type_node + || NULLPTR_TYPE_P (type) || type == init_list_type_node); return false; case TYPE_PACK_EXPANSION: @@ -4916,7 +4995,7 @@ arg_assoc_args_vec (struct arg_lookup *k, VEC(tree,gc) *args) unsigned int ix; tree arg; - for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix) + FOR_EACH_VEC_ELT (tree, args, ix, arg) if (arg_assoc (k, arg)) return true; return false; @@ -4984,7 +5063,8 @@ arg_assoc (struct arg_lookup *k, tree n) are the functions found in normal lookup. */ tree -lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args) +lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args, + bool include_std) { struct arg_lookup k; @@ -4998,15 +5078,17 @@ lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args) k.name = name; k.args = args; k.functions = fns; - k.classes = NULL_TREE; + k.classes = make_tree_vector (); /* We previously performed an optimization here by setting NAMESPACES to the current namespace when it was safe. However, DR 164 says that namespaces that were already searched in the first stage of template processing are searched again (potentially picking up later definitions) in the second stage. */ - k.namespaces = NULL_TREE; + k.namespaces = make_tree_vector (); + if (include_std) + arg_assoc_namespace (&k, std_node); arg_assoc_args_vec (&k, args); fns = k.functions; @@ -5019,6 +5101,9 @@ lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args) error (" in call to %qD", name); fns = error_mark_node; } + + release_tree_vector (k.classes); + release_tree_vector (k.namespaces); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fns); } @@ -5355,7 +5440,7 @@ push_to_top_level (void) bool need_pop; timevar_push (TV_NAME_LOOKUP); - s = GGC_CNEW (struct saved_scope); + s = ggc_alloc_cleared_saved_scope (); b = scope_chain ? current_binding_level : 0; @@ -5396,7 +5481,7 @@ push_to_top_level (void) SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t)); } - for (i = 0; VEC_iterate (cxx_saved_binding, s->old_bindings, i, sb); ++i) + FOR_EACH_VEC_ELT (cxx_saved_binding, s->old_bindings, i, sb) IDENTIFIER_MARKED (sb->identifier) = 0; s->prev = scope_chain; @@ -5433,7 +5518,7 @@ pop_from_top_level (void) current_lang_base = 0; scope_chain = s->prev; - for (i = 0; VEC_iterate (cxx_saved_binding, s->old_bindings, i, saved); ++i) + FOR_EACH_VEC_ELT (cxx_saved_binding, s->old_bindings, i, saved) { tree id = saved->identifier; @@ -5479,7 +5564,7 @@ void cp_emit_debug_info_for_using (tree t, tree context) { /* Don't try to emit any debug information if we have errors. */ - if (sorrycount || errorcount) + if (seen_error ()) return; /* Ignore this FUNCTION_DECL if it refers to a builtin declaration diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 08514810ab0..7d2f19e19f9 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -22,7 +22,7 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_CP_NAME_LOOKUP_H #define GCC_CP_NAME_LOOKUP_H -#include "c-common.h" +#include "c-family/c-common.h" /* The type of dictionary used to map names to types declared at a given scope. */ @@ -148,6 +148,16 @@ typedef struct GTY(()) cp_class_binding { DEF_VEC_O(cp_class_binding); DEF_VEC_ALLOC_O(cp_class_binding,gc); +typedef struct GTY(()) cp_label_binding { + /* The bound LABEL_DECL. */ + tree label; + /* The previous IDENTIFIER_LABEL_VALUE. */ + tree prev_value; +} cp_label_binding; + +DEF_VEC_O(cp_label_binding); +DEF_VEC_ALLOC_O(cp_label_binding,gc); + /* For each binding contour we allocate a binding_level structure which records the names defined in that contour. Contours include: @@ -206,10 +216,9 @@ struct GTY(()) cp_binding_level { the class. */ tree type_shadowed; - /* A TREE_LIST. Each TREE_VALUE is the LABEL_DECL for a local - label in this scope. The TREE_PURPOSE is the previous value of - the IDENTIFIER_LABEL VALUE. */ - tree shadowed_labels; + /* Similar to class_shadowed, but for IDENTIFIER_LABEL_VALUE, and + used for all binding levels. */ + VEC(cp_label_binding,gc) *shadowed_labels; /* For each level (except not the global one), a chain of BLOCK nodes for all the levels @@ -225,9 +234,8 @@ struct GTY(()) cp_binding_level { /* List of VAR_DECLS saved from a previous for statement. These would be dead in ISO-conforming code, but might - be referenced in ARM-era code. These are stored in a - TREE_LIST; the TREE_VALUE is the actual declaration. */ - tree dead_vars_from_for; + be referenced in ARM-era code. */ + VEC(tree,gc) *dead_vars_from_for; /* STATEMENT_LIST for statements in this binding contour. Only used at present for SK_CLEANUP temporary bindings. */ @@ -334,7 +342,7 @@ extern void do_toplevel_using_decl (tree, tree, tree); extern void do_local_using_decl (tree, tree, tree); extern tree do_class_using_decl (tree, tree); extern void do_using_directive (tree); -extern tree lookup_arg_dependent (tree, tree, VEC(tree,gc) *); +extern tree lookup_arg_dependent (tree, tree, VEC(tree,gc) *, bool); extern bool is_associated_namespace (tree, tree); extern void parse_using_directive (tree, tree); extern tree innermost_non_namespace_value (tree); diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index 5fb769c2c63..302a1332d66 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -1,6 +1,6 @@ /* Perform optimizations on tree structure. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009, + 2010 Free Software Foundation, Inc. Written by Mark Michell (mark@codesourcery.com). This file is part of GCC. @@ -25,12 +25,8 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tree.h" #include "cp-tree.h" -#include "rtl.h" -#include "insn-config.h" #include "input.h" -#include "integrate.h" #include "toplev.h" -#include "varray.h" #include "params.h" #include "hashtab.h" #include "target.h" @@ -38,7 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "flags.h" #include "langhooks.h" -#include "diagnostic.h" +#include "diagnostic-core.h" #include "tree-dump.h" #include "gimple.h" #include "tree-iterator.h" @@ -111,12 +107,11 @@ clone_body (tree clone, tree fn, void *arg_map) if (DECL_NAME (clone) == base_dtor_identifier || DECL_NAME (clone) == base_ctor_identifier) { - tree decls = DECL_STRUCT_FUNCTION (fn)->local_decls; - for (; decls; decls = TREE_CHAIN (decls)) - { - tree decl = TREE_VALUE (decls); - walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL); - } + unsigned ix; + tree decl; + + FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl) + walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL); } append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone)); @@ -287,16 +282,16 @@ maybe_clone_body (tree fn) clone_parm = DECL_ARGUMENTS (clone); /* Update the `this' parameter, which is always first. */ update_cloned_parm (parm, clone_parm, first); - parm = TREE_CHAIN (parm); - clone_parm = TREE_CHAIN (clone_parm); + parm = DECL_CHAIN (parm); + clone_parm = DECL_CHAIN (clone_parm); if (DECL_HAS_IN_CHARGE_PARM_P (fn)) - parm = TREE_CHAIN (parm); + parm = DECL_CHAIN (parm); if (DECL_HAS_VTT_PARM_P (fn)) - parm = TREE_CHAIN (parm); + parm = DECL_CHAIN (parm); if (DECL_HAS_VTT_PARM_P (clone)) - clone_parm = TREE_CHAIN (clone_parm); + clone_parm = DECL_CHAIN (clone_parm); for (; parm; - parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm)) + parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm)) /* Update this parameter. */ update_cloned_parm (parm, clone_parm, first); @@ -353,7 +348,7 @@ maybe_clone_body (tree fn) clone_parm = DECL_ARGUMENTS (clone); parm; ++parmno, - parm = TREE_CHAIN (parm)) + parm = DECL_CHAIN (parm)) { /* Map the in-charge parameter to an appropriate constant. */ if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1) @@ -372,7 +367,7 @@ maybe_clone_body (tree fn) { DECL_ABSTRACT_ORIGIN (clone_parm) = parm; *pointer_map_insert (decl_map, parm) = clone_parm; - clone_parm = TREE_CHAIN (clone_parm); + clone_parm = DECL_CHAIN (clone_parm); } /* Otherwise, map the VTT parameter to `NULL'. */ else @@ -384,7 +379,7 @@ maybe_clone_body (tree fn) else { *pointer_map_insert (decl_map, parm) = clone_parm; - clone_parm = TREE_CHAIN (clone_parm); + clone_parm = DECL_CHAIN (clone_parm); } } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8a1bb9f600e..938534450fe 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1,6 +1,6 @@ /* C++ Parser. Copyright (C) 2000, 2001, 2002, 2003, 2004, - 2005, 2007, 2008, 2009 Free Software Foundation, Inc. + 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Written by Mark Mitchell <mark@codesourcery.com>. This file is part of GCC. @@ -23,21 +23,19 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" -#include "dyn-string.h" -#include "varray.h" #include "cpplib.h" #include "tree.h" #include "cp-tree.h" #include "intl.h" -#include "c-pragma.h" +#include "c-family/c-pragma.h" #include "decl.h" #include "flags.h" -#include "diagnostic.h" +#include "diagnostic-core.h" #include "toplev.h" #include "output.h" #include "target.h" #include "cgraph.h" -#include "c-common.h" +#include "c-family/c-common.h" #include "plugin.h" @@ -150,6 +148,128 @@ typedef struct GTY(()) cp_token_cache { cp_token * GTY ((skip)) last; } cp_token_cache; +/* The various kinds of non integral constant we encounter. */ +typedef enum non_integral_constant { + NIC_NONE, + /* floating-point literal */ + NIC_FLOAT, + /* %<this%> */ + NIC_THIS, + /* %<__FUNCTION__%> */ + NIC_FUNC_NAME, + /* %<__PRETTY_FUNCTION__%> */ + NIC_PRETTY_FUNC, + /* %<__func__%> */ + NIC_C99_FUNC, + /* "%<va_arg%> */ + NIC_VA_ARG, + /* a cast */ + NIC_CAST, + /* %<typeid%> operator */ + NIC_TYPEID, + /* non-constant compound literals */ + NIC_NCC, + /* a function call */ + NIC_FUNC_CALL, + /* an increment */ + NIC_INC, + /* an decrement */ + NIC_DEC, + /* an array reference */ + NIC_ARRAY_REF, + /* %<->%> */ + NIC_ARROW, + /* %<.%> */ + NIC_POINT, + /* the address of a label */ + NIC_ADDR_LABEL, + /* %<*%> */ + NIC_STAR, + /* %<&%> */ + NIC_ADDR, + /* %<++%> */ + NIC_PREINCREMENT, + /* %<--%> */ + NIC_PREDECREMENT, + /* %<new%> */ + NIC_NEW, + /* %<delete%> */ + NIC_DEL, + /* calls to overloaded operators */ + NIC_OVERLOADED, + /* an assignment */ + NIC_ASSIGNMENT, + /* a comma operator */ + NIC_COMMA, + /* a call to a constructor */ + NIC_CONSTRUCTOR +} non_integral_constant; + +/* The various kinds of errors about name-lookup failing. */ +typedef enum name_lookup_error { + /* NULL */ + NLE_NULL, + /* is not a type */ + NLE_TYPE, + /* is not a class or namespace */ + NLE_CXX98, + /* is not a class, namespace, or enumeration */ + NLE_NOT_CXX98 +} name_lookup_error; + +/* The various kinds of required token */ +typedef enum required_token { + RT_NONE, + RT_SEMICOLON, /* ';' */ + RT_OPEN_PAREN, /* '(' */ + RT_CLOSE_BRACE, /* '}' */ + RT_OPEN_BRACE, /* '{' */ + RT_CLOSE_SQUARE, /* ']' */ + RT_OPEN_SQUARE, /* '[' */ + RT_COMMA, /* ',' */ + RT_SCOPE, /* '::' */ + RT_LESS, /* '<' */ + RT_GREATER, /* '>' */ + RT_EQ, /* '=' */ + RT_ELLIPSIS, /* '...' */ + RT_MULT, /* '*' */ + RT_COMPL, /* '~' */ + RT_COLON, /* ':' */ + RT_COLON_SCOPE, /* ':' or '::' */ + RT_CLOSE_PAREN, /* ')' */ + RT_COMMA_CLOSE_PAREN, /* ',' or ')' */ + RT_PRAGMA_EOL, /* end of line */ + RT_NAME, /* identifier */ + + /* The type is CPP_KEYWORD */ + RT_NEW, /* new */ + RT_DELETE, /* delete */ + RT_RETURN, /* return */ + RT_WHILE, /* while */ + RT_EXTERN, /* extern */ + RT_STATIC_ASSERT, /* static_assert */ + RT_DECLTYPE, /* decltype */ + RT_OPERATOR, /* operator */ + RT_CLASS, /* class */ + RT_TEMPLATE, /* template */ + RT_NAMESPACE, /* namespace */ + RT_USING, /* using */ + RT_ASM, /* asm */ + RT_TRY, /* try */ + RT_CATCH, /* catch */ + RT_THROW, /* throw */ + RT_LABEL, /* __label__ */ + RT_AT_TRY, /* @try */ + RT_AT_SYNCHRONIZED, /* @synchronized */ + RT_AT_THROW, /* @throw */ + + RT_SELECT, /* selection-statement */ + RT_INTERATION, /* iteration-statement */ + RT_JUMP, /* jump-statement */ + RT_CLASS_KEY, /* class-key */ + RT_CLASS_TYPENAME_TEMPLATE /* class, typename, or template */ +} required_token; + /* Prototypes. */ static cp_lexer *cp_lexer_new_main @@ -273,7 +393,7 @@ cp_lexer_new_main (void) c_common_no_more_pch (); /* Allocate the memory. */ - lexer = GGC_CNEW (cp_lexer); + lexer = ggc_alloc_cleared_cp_lexer (); #ifdef ENABLE_CHECKING /* Initially we are not debugging. */ @@ -284,7 +404,7 @@ cp_lexer_new_main (void) /* Create the buffer. */ alloc = CP_LEXER_BUFFER_SIZE; - buffer = GGC_NEWVEC (cp_token, alloc); + buffer = ggc_alloc_vec_cp_token (alloc); /* Put the first token in the buffer. */ space = alloc; @@ -325,7 +445,7 @@ cp_lexer_new_from_tokens (cp_token_cache *cache) { cp_token *first = cache->first; cp_token *last = cache->last; - cp_lexer *lexer = GGC_CNEW (cp_lexer); + cp_lexer *lexer = ggc_alloc_cleared_cp_lexer (); /* We do not own the buffer. */ lexer->buffer = NULL; @@ -562,6 +682,7 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer) case RID_SHORT: case RID_INT: case RID_LONG: + case RID_INT128: case RID_SIGNED: case RID_UNSIGNED: case RID_FLOAT: @@ -825,7 +946,7 @@ cp_lexer_stop_debugging (cp_lexer* lexer) static cp_token_cache * cp_token_cache_new (cp_token *first, cp_token *last) { - cp_token_cache *cache = GGC_NEW (cp_token_cache); + cp_token_cache *cache = ggc_alloc_cp_token_cache (); cache->first = first; cache->last = last; return cache; @@ -947,6 +1068,7 @@ make_pointer_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target) declarator->u.pointer.class_type = NULL_TREE; if (target) { + declarator->id_loc = target->id_loc; declarator->parameter_pack_p = target->parameter_pack_p; target->parameter_pack_p = false; } @@ -970,6 +1092,7 @@ make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target, declarator->u.reference.rvalue_ref = rvalue_ref; if (target) { + declarator->id_loc = target->id_loc; declarator->parameter_pack_p = target->parameter_pack_p; target->parameter_pack_p = false; } @@ -1026,6 +1149,7 @@ make_call_declarator (cp_declarator *target, declarator->u.function.late_return_type = late_return_type; if (target) { + declarator->id_loc = target->id_loc; declarator->parameter_pack_p = target->parameter_pack_p; target->parameter_pack_p = false; } @@ -1048,6 +1172,7 @@ make_array_declarator (cp_declarator *element, tree bounds) declarator->u.array.bounds = bounds; if (element) { + declarator->id_loc = element->id_loc; declarator->parameter_pack_p = element->parameter_pack_p; element->parameter_pack_p = false; } @@ -1375,7 +1500,7 @@ cp_parser_context_new (cp_parser_context* next) memset (context, 0, sizeof (*context)); } else - context = GGC_CNEW (cp_parser_context); + context = ggc_alloc_cleared_cp_parser_context (); /* No errors have occurred yet in this context. */ context->status = CP_PARSER_STATUS_KIND_NO_ERROR; @@ -1393,6 +1518,34 @@ cp_parser_context_new (cp_parser_context* next) return context; } +/* An entry in a queue of function arguments that require post-processing. */ + +typedef struct GTY(()) cp_default_arg_entry_d { + /* The current_class_type when we parsed this arg. */ + tree class_type; + + /* The function decl itself. */ + tree decl; +} cp_default_arg_entry; + +DEF_VEC_O(cp_default_arg_entry); +DEF_VEC_ALLOC_O(cp_default_arg_entry,gc); + +/* An entry in a stack for member functions of local classes. */ + +typedef struct GTY(()) cp_unparsed_functions_entry_d { + /* Functions with default arguments that require post-processing. + Functions appear in this list in declaration order. */ + VEC(cp_default_arg_entry,gc) *funs_with_default_args; + + /* Functions with defintions that require post-processing. Functions + appear in this list in declaration order. */ + VEC(tree,gc) *funs_with_definitions; +} cp_unparsed_functions_entry; + +DEF_VEC_O(cp_unparsed_functions_entry); +DEF_VEC_ALLOC_O(cp_unparsed_functions_entry,gc); + /* The cp_parser structure represents the C++ parser. */ typedef struct GTY(()) cp_parser { @@ -1519,21 +1672,10 @@ typedef struct GTY(()) cp_parser { issued as an error message if a type is defined. */ const char *type_definition_forbidden_message; - /* A list of lists. The outer list is a stack, used for member - functions of local classes. At each level there are two sub-list, - one on TREE_VALUE and one on TREE_PURPOSE. Each of those - sub-lists has a FUNCTION_DECL or TEMPLATE_DECL on their - TREE_VALUE's. The functions are chained in reverse declaration - order. - - The TREE_PURPOSE sublist contains those functions with default - arguments that need post processing, and the TREE_VALUE sublist - contains those functions with definitions that need post - processing. - - These lists can only be processed once the outermost class being - defined is complete. */ - tree unparsed_functions_queues; + /* A stack used for member functions of local classes. The lists + contained in an individual entry can only be processed once the + outermost class being defined is complete. */ + VEC(cp_unparsed_functions_entry,gc) *unparsed_queues; /* The number of classes whose definitions are currently in progress. */ @@ -1544,6 +1686,29 @@ typedef struct GTY(()) cp_parser { unsigned num_template_parameter_lists; } cp_parser; +/* Managing the unparsed function queues. */ + +#define unparsed_funs_with_default_args \ + VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->funs_with_default_args +#define unparsed_funs_with_definitions \ + VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->funs_with_definitions + +static void +push_unparsed_function_queues (cp_parser *parser) +{ + VEC_safe_push (cp_unparsed_functions_entry, gc, + parser->unparsed_queues, NULL); + unparsed_funs_with_default_args = NULL; + unparsed_funs_with_definitions = make_tree_vector (); +} + +static void +pop_unparsed_function_queues (cp_parser *parser) +{ + release_tree_vector (unparsed_funs_with_definitions); + VEC_pop (cp_unparsed_functions_entry, parser->unparsed_queues); +} + /* Prototypes. */ /* Constructors and destructors. */ @@ -1596,7 +1761,9 @@ static tree cp_parser_postfix_open_square_expression static tree cp_parser_postfix_dot_deref_expression (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t); static VEC(tree,gc) *cp_parser_parenthesized_expression_list - (cp_parser *, bool, bool, bool, bool *); + (cp_parser *, int, bool, bool, bool *); +/* Values for the second parameter of cp_parser_parenthesized_expression_list. */ +enum { non_attr = 0, normal_attr = 1, id_attr = 2 }; static void cp_parser_pseudo_destructor_name (cp_parser *, tree *, tree *); static tree cp_parser_unary_expression @@ -1662,6 +1829,10 @@ static tree cp_parser_iteration_statement (cp_parser *); static void cp_parser_for_init_statement (cp_parser *); +static tree cp_parser_c_for + (cp_parser *); +static tree cp_parser_range_for + (cp_parser *); static tree cp_parser_jump_statement (cp_parser *); static void cp_parser_declaration_statement @@ -1971,10 +2142,12 @@ static void cp_parser_set_decl_spec_type (cp_decl_specifier_seq *, tree, location_t, bool); static bool cp_parser_friend_p (const cp_decl_specifier_seq *); +static void cp_parser_required_error + (cp_parser *, required_token, bool); static cp_token *cp_parser_require - (cp_parser *, enum cpp_ttype, const char *); + (cp_parser *, enum cpp_ttype, required_token); static cp_token *cp_parser_require_keyword - (cp_parser *, enum rid, const char *); + (cp_parser *, enum rid, required_token); static bool cp_parser_token_starts_function_definition_p (cp_token *); static bool cp_parser_next_token_starts_class_definition_p @@ -2010,7 +2183,7 @@ static bool cp_parser_uncommitted_to_tentative_parse_p static void cp_parser_error (cp_parser *, const char *); static void cp_parser_name_lookup_error - (cp_parser *, tree, tree, const char *, location_t); + (cp_parser *, tree, tree, name_lookup_error, location_t); static bool cp_parser_simulate_error (cp_parser *); static bool cp_parser_check_type_definition @@ -2020,7 +2193,7 @@ static void cp_parser_check_for_definition_in_return_type static void cp_parser_check_for_invalid_template_id (cp_parser *, tree, location_t location); static bool cp_parser_non_integral_constant_expression - (cp_parser *, const char *); + (cp_parser *, non_integral_constant); static void cp_parser_diagnose_invalid_type_name (cp_parser *, tree, tree, location_t); static bool cp_parser_parse_and_diagnose_invalid_type_name @@ -2087,7 +2260,7 @@ cp_parser_is_keyword (cp_token* token, enum rid keyword) OTHER-TOKEN". */ static void -cp_parser_error (cp_parser* parser, const char* message) +cp_parser_error (cp_parser* parser, const char* gmsgid) { if (!cp_parser_simulate_error (parser)) { @@ -2104,7 +2277,7 @@ cp_parser_error (cp_parser* parser, const char* message) return; } - c_parse_error (message, + c_parse_error (gmsgid, /* Because c_parser_error does not understand CPP_KEYWORD, keywords are treated like identifiers. */ @@ -2122,7 +2295,7 @@ static void cp_parser_name_lookup_error (cp_parser* parser, tree name, tree decl, - const char* desired, + name_lookup_error desired, location_t location) { /* If name lookup completely failed, tell the user that NAME was not @@ -2145,11 +2318,64 @@ cp_parser_name_lookup_error (cp_parser* parser, error_at (location, "%qE has not been declared", name); } else if (parser->scope && parser->scope != global_namespace) - error_at (location, "%<%E::%E%> %s", parser->scope, name, desired); + { + switch (desired) + { + case NLE_TYPE: + error_at (location, "%<%E::%E%> is not a type", + parser->scope, name); + break; + case NLE_CXX98: + error_at (location, "%<%E::%E%> is not a class or namespace", + parser->scope, name); + break; + case NLE_NOT_CXX98: + error_at (location, + "%<%E::%E%> is not a class, namespace, or enumeration", + parser->scope, name); + break; + default: + gcc_unreachable (); + + } + } else if (parser->scope == global_namespace) - error_at (location, "%<::%E%> %s", name, desired); + { + switch (desired) + { + case NLE_TYPE: + error_at (location, "%<::%E%> is not a type", name); + break; + case NLE_CXX98: + error_at (location, "%<::%E%> is not a class or namespace", name); + break; + case NLE_NOT_CXX98: + error_at (location, + "%<::%E%> is not a class, namespace, or enumeration", + name); + break; + default: + gcc_unreachable (); + } + } else - error_at (location, "%qE %s", name, desired); + { + switch (desired) + { + case NLE_TYPE: + error_at (location, "%qE is not a type", name); + break; + case NLE_CXX98: + error_at (location, "%qE is not a class or namespace", name); + break; + case NLE_NOT_CXX98: + error_at (location, + "%qE is not a class, namespace, or enumeration", name); + break; + default: + gcc_unreachable (); + } + } } /* If we are parsing tentatively, remember that an error has occurred @@ -2301,20 +2527,112 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser, static bool cp_parser_non_integral_constant_expression (cp_parser *parser, - const char *thing) + non_integral_constant thing) { parser->non_integral_constant_expression_p = true; if (parser->integral_constant_expression_p) { if (!parser->allow_non_integral_constant_expression_p) { - /* Don't use `%s' to print THING, because quotations (`%<', `%>') - in the message need to be interpreted. */ - char *message = concat (thing, - " cannot appear in a constant-expression", - NULL); - error (message); - free (message); + const char *msg = NULL; + switch (thing) + { + case NIC_FLOAT: + error ("floating-point literal " + "cannot appear in a constant-expression"); + return true; + case NIC_CAST: + error ("a cast to a type other than an integral or " + "enumeration type cannot appear in a " + "constant-expression"); + return true; + case NIC_TYPEID: + error ("%<typeid%> operator " + "cannot appear in a constant-expression"); + return true; + case NIC_NCC: + error ("non-constant compound literals " + "cannot appear in a constant-expression"); + return true; + case NIC_FUNC_CALL: + error ("a function call " + "cannot appear in a constant-expression"); + return true; + case NIC_INC: + error ("an increment " + "cannot appear in a constant-expression"); + return true; + case NIC_DEC: + error ("an decrement " + "cannot appear in a constant-expression"); + return true; + case NIC_ARRAY_REF: + error ("an array reference " + "cannot appear in a constant-expression"); + return true; + case NIC_ADDR_LABEL: + error ("the address of a label " + "cannot appear in a constant-expression"); + return true; + case NIC_OVERLOADED: + error ("calls to overloaded operators " + "cannot appear in a constant-expression"); + return true; + case NIC_ASSIGNMENT: + error ("an assignment cannot appear in a constant-expression"); + return true; + case NIC_COMMA: + error ("a comma operator " + "cannot appear in a constant-expression"); + return true; + case NIC_CONSTRUCTOR: + error ("a call to a constructor " + "cannot appear in a constant-expression"); + return true; + case NIC_THIS: + msg = "this"; + break; + case NIC_FUNC_NAME: + msg = "__FUNCTION__"; + break; + case NIC_PRETTY_FUNC: + msg = "__PRETTY_FUNCTION__"; + break; + case NIC_C99_FUNC: + msg = "__func__"; + break; + case NIC_VA_ARG: + msg = "va_arg"; + break; + case NIC_ARROW: + msg = "->"; + break; + case NIC_POINT: + msg = "."; + break; + case NIC_STAR: + msg = "*"; + break; + case NIC_ADDR: + msg = "&"; + break; + case NIC_PREINCREMENT: + msg = "++"; + break; + case NIC_PREDECREMENT: + msg = "--"; + break; + case NIC_NEW: + msg = "new"; + break; + case NIC_DEL: + msg = "delete"; + break; + default: + gcc_unreachable (); + } + if (msg) + error ("%qs cannot appear in a constant-expression", msg); return true; } } @@ -2380,7 +2698,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type); for (field = TYPE_FIELDS (base_type); field; - field = TREE_CHAIN (field)) + field = DECL_CHAIN (field)) if (TREE_CODE (field) == TYPE_DECL && DECL_NAME (field) == id) { @@ -2637,7 +2955,7 @@ static void cp_parser_consume_semicolon_at_end_of_statement (cp_parser *parser) { /* Look for the trailing `;'. */ - if (!cp_parser_require (parser, CPP_SEMICOLON, "%<;%>")) + if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)) { /* If there is additional (erroneous) input, skip to the end of the statement. */ @@ -2765,7 +3083,7 @@ static void cp_parser_require_pragma_eol (cp_parser *parser, cp_token *pragma_tok) { parser->lexer->in_pragma = false; - if (!cp_parser_require (parser, CPP_PRAGMA_EOL, "end of line")) + if (!cp_parser_require (parser, CPP_PRAGMA_EOL, RT_PRAGMA_EOL)) cp_parser_skip_to_pragma_eol (parser, pragma_tok); } @@ -2823,7 +3141,7 @@ cp_parser_new (void) cp_lexer *lexer; unsigned i; - /* cp_lexer_new_main is called before calling ggc_alloc because + /* cp_lexer_new_main is called before doing GC allocation because cp_lexer_new_main might load a PCH file. */ lexer = cp_lexer_new_main (); @@ -2832,7 +3150,7 @@ cp_parser_new (void) for (i = 0; i < sizeof (binops) / sizeof (binops[0]); i++) binops_by_token[binops[i].token_type] = binops[i]; - parser = GGC_CNEW (cp_parser); + parser = ggc_alloc_cleared_cp_parser (); parser->lexer = lexer; parser->context = cp_parser_context_new (NULL); @@ -2881,7 +3199,7 @@ cp_parser_new (void) parser->in_function_body = false; /* The unparsed function queue is empty. */ - parser->unparsed_functions_queues = build_tree_list (NULL_TREE, NULL_TREE); + push_unparsed_function_queues (parser); /* There are no classes being defined. */ parser->num_classes_being_defined = 0; @@ -2933,7 +3251,7 @@ cp_parser_identifier (cp_parser* parser) cp_token *token; /* Look for the identifier. */ - token = cp_parser_require (parser, CPP_NAME, "identifier"); + token = cp_parser_require (parser, CPP_NAME, RT_NAME); /* Return the value. */ return token ? token->u.value : error_mark_node; } @@ -3252,8 +3570,7 @@ cp_parser_primary_expression (cp_parser *parser, checked at that point. If we are not within a cast, then this code is invalid. */ if (!cast_p) - cp_parser_non_integral_constant_expression - (parser, "floating-point literal"); + cp_parser_non_integral_constant_expression (parser, NIC_FLOAT); } return token->u.value; @@ -3331,7 +3648,7 @@ cp_parser_primary_expression (cp_parser *parser, parser->greater_than_is_operator_p = saved_greater_than_is_operator_p; /* Consume the `)'. */ - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) cp_parser_skip_to_end_of_statement (parser); return expr; @@ -3367,6 +3684,11 @@ cp_parser_primary_expression (cp_parser *parser, cp_lexer_consume_token (parser->lexer); return null_node; + /* The `nullptr' literal. */ + case RID_NULLPTR: + cp_lexer_consume_token (parser->lexer); + return nullptr_node; + /* Recognize the `this' keyword. */ case RID_THIS: cp_lexer_consume_token (parser->lexer); @@ -3377,7 +3699,7 @@ cp_parser_primary_expression (cp_parser *parser, return error_mark_node; } /* Pointers cannot appear in constant-expressions. */ - if (cp_parser_non_integral_constant_expression (parser, "%<this%>")) + if (cp_parser_non_integral_constant_expression (parser, NIC_THIS)) return error_mark_node; return finish_this_expr (); @@ -3390,7 +3712,7 @@ cp_parser_primary_expression (cp_parser *parser, case RID_PRETTY_FUNCTION_NAME: case RID_C99_FUNCTION_NAME: { - const char *name; + non_integral_constant name; /* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and __func__ are the names of variables -- but they are @@ -3404,13 +3726,13 @@ cp_parser_primary_expression (cp_parser *parser, switch (token->keyword) { case RID_FUNCTION_NAME: - name = "%<__FUNCTION__%>"; + name = NIC_FUNC_NAME; break; case RID_PRETTY_FUNCTION_NAME: - name = "%<__PRETTY_FUNCTION__%>"; + name = NIC_PRETTY_FUNC; break; case RID_C99_FUNCTION_NAME: - name = "%<__func__%>"; + name = NIC_C99_FUNC; break; default: gcc_unreachable (); @@ -3432,20 +3754,20 @@ cp_parser_primary_expression (cp_parser *parser, `va_arg'. Consume the `__builtin_va_arg' token. */ cp_lexer_consume_token (parser->lexer); /* Look for the opening `('. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Now, parse the assignment-expression. */ expression = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); /* Look for the `,'. */ - cp_parser_require (parser, CPP_COMMA, "%<,%>"); + cp_parser_require (parser, CPP_COMMA, RT_COMMA); /* Parse the type-id. */ type = cp_parser_type_id (parser); /* Look for the closing `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Using `va_arg' in a constant-expression is not allowed. */ if (cp_parser_non_integral_constant_expression (parser, - "%<va_arg%>")) + NIC_VA_ARG)) return error_mark_node; return build_x_va_arg (expression, type); } @@ -3480,6 +3802,16 @@ cp_parser_primary_expression (cp_parser *parser, case RID_AT_SELECTOR: return cp_parser_objc_expression (parser); + case RID_TEMPLATE: + if (parser->in_function_body + && (cp_lexer_peek_nth_token (parser->lexer, 2)->type + == CPP_LESS)) + { + error_at (token->location, + "a template declaration cannot appear at block scope"); + cp_parser_skip_to_end_of_block_or_statement (parser); + return error_mark_node; + } default: cp_parser_error (parser, "expected primary-expression"); return error_mark_node; @@ -4198,7 +4530,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, type_p, is_declaration); /* Look for the `::' token. */ - cp_parser_require (parser, CPP_SCOPE, "%<::%>"); + cp_parser_require (parser, CPP_SCOPE, RT_SCOPE); /* If we found what we wanted, we keep going; otherwise, we're done. */ @@ -4251,12 +4583,14 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, } else { - const char* msg = "is not a class or namespace"; if (cxx_dialect != cxx98) - msg = "is not a class, namespace, or enumeration"; - cp_parser_name_lookup_error - (parser, token->u.value, decl, msg, + cp_parser_name_lookup_error + (parser, token->u.value, decl, NLE_NOT_CXX98, token->location); + else + cp_parser_name_lookup_error + (parser, token->u.value, decl, NLE_CXX98, + token->location); } } parser->scope = error_mark_node; @@ -4329,7 +4663,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, token->type = CPP_NESTED_NAME_SPECIFIER; /* Retrieve any deferred checks. Do not pop this access checks yet so the memory will not be reclaimed during token replacing below. */ - token->u.tree_check_value = GGC_CNEW (struct tree_check); + token->u.tree_check_value = ggc_alloc_cleared_tree_check (); token->u.tree_check_value->value = parser->scope; token->u.tree_check_value->checks = get_deferred_access_checks (); token->u.tree_check_value->qualifying_scope = @@ -4554,26 +4888,23 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, = G_("types may not be defined in casts"); /* Look for the opening `<'. */ - cp_parser_require (parser, CPP_LESS, "%<<%>"); + cp_parser_require (parser, CPP_LESS, RT_LESS); /* Parse the type to which we are casting. */ type = cp_parser_type_id (parser); /* Look for the closing `>'. */ - cp_parser_require (parser, CPP_GREATER, "%<>%>"); + cp_parser_require (parser, CPP_GREATER, RT_GREATER); /* Restore the old message. */ parser->type_definition_forbidden_message = saved_message; /* And the expression which is being cast. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); expression = cp_parser_expression (parser, /*cast_p=*/true, & idk); - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Only type conversions to integral or enumeration types can be used in constant-expressions. */ if (!cast_valid_in_integral_constant_expression_p (type) - && (cp_parser_non_integral_constant_expression - (parser, - "a cast to a type other than an integral or " - "enumeration type"))) + && cp_parser_non_integral_constant_expression (parser, NIC_CAST)) return error_mark_node; switch (keyword) @@ -4610,7 +4941,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* Consume the `typeid' token. */ cp_lexer_consume_token (parser->lexer); /* Look for the `(' token. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Types cannot be defined in a `typeid' expression. */ saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message @@ -4626,7 +4957,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* Look for the `)' token. Otherwise, we can't be sure that we're not looking at an expression: consider `typeid (int (3))', for example. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* If all went well, simply lookup the type-id. */ if (cp_parser_parse_definitely (parser)) postfix_expression = get_typeid (type); @@ -4640,13 +4971,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* Compute its typeid. */ postfix_expression = build_typeid (expression); /* Look for the `)' token. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); } /* Restore the saved message. */ parser->type_definition_forbidden_message = saved_message; /* `typeid' may not appear in an integral constant expression. */ - if (cp_parser_non_integral_constant_expression(parser, - "%<typeid%> operator")) + if (cp_parser_non_integral_constant_expression(parser, NIC_TYPEID)) return error_mark_node; } break; @@ -4701,9 +5031,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, type = cp_parser_type_id (parser); parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p; /* Look for the `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Look for the `{'. */ - cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>"); + cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE); /* If things aren't going well, there's no need to keep going. */ if (!cp_parser_error_occurred (parser)) @@ -4716,7 +5046,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) cp_lexer_consume_token (parser->lexer); /* Look for the final `}'. */ - cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); } /* If that worked, we're definitely looking at a compound-literal expression. */ @@ -4734,8 +5064,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, currently accepted programs. (Of course, as compound literals are not part of ISO C++, the standard has nothing to say.) */ - if (cp_parser_non_integral_constant_expression - (parser, "non-constant compound literals")) + if (cp_parser_non_integral_constant_expression (parser, + NIC_NCC)) { postfix_expression = error_mark_node; break; @@ -4806,7 +5136,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, parser->integral_constant_expression_p = false; } args = (cp_parser_parenthesized_expression_list - (parser, /*is_attribute_list=*/false, + (parser, non_attr, /*cast_p=*/false, /*allow_expansion_p=*/true, /*non_constant_p=*/NULL)); if (is_builtin_constant_p) @@ -4827,7 +5157,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, constant-expressions. */ if (! builtin_valid_in_constant_expr_p (postfix_expression) && cp_parser_non_integral_constant_expression (parser, - "a function call")) + NIC_FUNC_CALL)) { postfix_expression = error_mark_node; release_tree_vector (args); @@ -4845,7 +5175,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, koenig_p = true; if (!any_type_dependent_arguments_p (args)) postfix_expression - = perform_koenig_lookup (postfix_expression, args); + = perform_koenig_lookup (postfix_expression, args, + /*include_std=*/false); } else postfix_expression @@ -4869,7 +5200,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, koenig_p = true; if (!any_type_dependent_arguments_p (args)) postfix_expression - = perform_koenig_lookup (postfix_expression, args); + = perform_koenig_lookup (postfix_expression, args, + /*include_std=*/false); } } } @@ -4965,8 +5297,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, = finish_increment_expr (postfix_expression, POSTINCREMENT_EXPR); /* Increments may not appear in constant-expressions. */ - if (cp_parser_non_integral_constant_expression (parser, - "an increment")) + if (cp_parser_non_integral_constant_expression (parser, NIC_INC)) postfix_expression = error_mark_node; idk = CP_ID_KIND_NONE; is_member_access = false; @@ -4981,8 +5312,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, = finish_increment_expr (postfix_expression, POSTDECREMENT_EXPR); /* Decrements may not appear in constant-expressions. */ - if (cp_parser_non_integral_constant_expression (parser, - "a decrement")) + if (cp_parser_non_integral_constant_expression (parser, NIC_DEC)) postfix_expression = error_mark_node; idk = CP_ID_KIND_NONE; is_member_access = false; @@ -5035,7 +5365,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, index = cp_parser_expression (parser, /*cast_p=*/false, NULL); /* Look for the closing `]'. */ - cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"); + cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); /* Build the ARRAY_REF. */ postfix_expression = grok_array_decl (postfix_expression, index); @@ -5043,8 +5373,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, /* When not doing offsetof, array references are not permitted in constant-expressions. */ if (!for_offsetof - && (cp_parser_non_integral_constant_expression - (parser, "an array reference"))) + && (cp_parser_non_integral_constant_expression (parser, NIC_ARRAY_REF))) postfix_expression = error_mark_node; return postfix_expression; @@ -5219,7 +5548,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, constant-expressions. */ if (!for_offsetof && (cp_parser_non_integral_constant_expression - (parser, token_type == CPP_DEREF ? "%<->%>" : "%<.%>"))) + (parser, token_type == CPP_DEREF ? NIC_ARROW : NIC_POINT))) postfix_expression = error_mark_node; return postfix_expression; @@ -5244,20 +5573,22 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, Returns a vector of trees. Each element is a representation of an assignment-expression. NULL is returned if the ( and or ) are missing. An empty, but allocated, vector is returned on no - expressions. The parentheses are eaten. IS_ATTRIBUTE_LIST is true - if this is really an attribute list being parsed. If + expressions. The parentheses are eaten. IS_ATTRIBUTE_LIST is id_attr + if we are parsing an attribute list for an attribute that wants a + plain identifier argument, normal_attr for an attribute that wants + an expression, or non_attr if we aren't parsing an attribute list. If NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or not all of the expressions in the list were constant. */ static VEC(tree,gc) * cp_parser_parenthesized_expression_list (cp_parser* parser, - bool is_attribute_list, + int is_attribute_list, bool cast_p, bool allow_expansion_p, bool *non_constant_p) { VEC(tree,gc) *expression_list; - bool fold_expr_p = is_attribute_list; + bool fold_expr_p = is_attribute_list != non_attr; tree identifier = NULL_TREE; bool saved_greater_than_is_operator_p; @@ -5265,7 +5596,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, if (non_constant_p) *non_constant_p = false; - if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return NULL; expression_list = make_tree_vector (); @@ -5284,7 +5615,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, /* At the beginning of attribute lists, check to see if the next token is an identifier. */ - if (is_attribute_list + if (is_attribute_list == id_attr && cp_lexer_peek_token (parser->lexer)->type == CPP_NAME) { cp_token *token; @@ -5345,7 +5676,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, /* After the first item, attribute lists look the same as expression lists. */ - is_attribute_list = false; + is_attribute_list = non_attr; get_comma:; /* If the next token isn't a `,', then we are done. */ @@ -5356,7 +5687,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, cp_lexer_consume_token (parser->lexer); } - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) { int ending; @@ -5431,7 +5762,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser, /*check_dependency_p=*/false, /*is_declaration=*/true); /* Look for the `::' token. */ - cp_parser_require (parser, CPP_SCOPE, "%<::%>"); + cp_parser_require (parser, CPP_SCOPE, RT_SCOPE); } /* If the next token is not a `~', then there might be some additional qualification. */ @@ -5457,13 +5788,13 @@ cp_parser_pseudo_destructor_name (cp_parser* parser, return; /* Look for the `::' token. */ - cp_parser_require (parser, CPP_SCOPE, "%<::%>"); + cp_parser_require (parser, CPP_SCOPE, RT_SCOPE); } else *scope = NULL_TREE; /* Look for the `~'. */ - cp_parser_require (parser, CPP_COMPL, "%<~%>"); + cp_parser_require (parser, CPP_COMPL, RT_COMPL); /* Look for the type-name again. We are not responsible for checking that it matches the first type-name. */ *type = cp_parser_nonclass_name (parser); @@ -5570,6 +5901,51 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, } break; + case RID_NOEXCEPT: + { + tree expr; + const char *saved_message; + bool saved_integral_constant_expression_p; + bool saved_non_integral_constant_expression_p; + bool saved_greater_than_is_operator_p; + + cp_lexer_consume_token (parser->lexer); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); + + saved_message = parser->type_definition_forbidden_message; + parser->type_definition_forbidden_message + = G_("types may not be defined in %<noexcept%> expressions"); + + saved_integral_constant_expression_p + = parser->integral_constant_expression_p; + saved_non_integral_constant_expression_p + = parser->non_integral_constant_expression_p; + parser->integral_constant_expression_p = false; + + saved_greater_than_is_operator_p + = parser->greater_than_is_operator_p; + parser->greater_than_is_operator_p = true; + + ++cp_unevaluated_operand; + ++c_inhibit_evaluation_warnings; + expr = cp_parser_expression (parser, false, NULL); + --c_inhibit_evaluation_warnings; + --cp_unevaluated_operand; + + parser->greater_than_is_operator_p + = saved_greater_than_is_operator_p; + + parser->integral_constant_expression_p + = saved_integral_constant_expression_p; + parser->non_integral_constant_expression_p + = saved_non_integral_constant_expression_p; + + parser->type_definition_forbidden_message = saved_message; + + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + return finish_noexcept_expr (expr, tf_warning_or_error); + } + default: break; } @@ -5619,7 +5995,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, /* Create an expression representing the address. */ expression = finish_label_address_expr (identifier, loc); if (cp_parser_non_integral_constant_expression (parser, - "the address of a label")) + NIC_ADDR_LABEL)) expression = error_mark_node; return expression; } @@ -5628,7 +6004,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, { tree cast_expression; tree expression = error_mark_node; - const char *non_constant_p = NULL; + non_integral_constant non_constant_p = NIC_NONE; /* Consume the operator token. */ token = cp_lexer_consume_token (parser->lexer); @@ -5641,13 +6017,13 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, switch (unary_operator) { case INDIRECT_REF: - non_constant_p = "%<*%>"; + non_constant_p = NIC_STAR; expression = build_x_indirect_ref (cast_expression, RO_UNARY_STAR, tf_warning_or_error); break; case ADDR_EXPR: - non_constant_p = "%<&%>"; + non_constant_p = NIC_ADDR; /* Fall through. */ case BIT_NOT_EXPR: expression = build_x_unary_op (unary_operator, cast_expression, @@ -5656,8 +6032,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, case PREINCREMENT_EXPR: case PREDECREMENT_EXPR: - non_constant_p = (unary_operator == PREINCREMENT_EXPR - ? "%<++%>" : "%<--%>"); + non_constant_p = unary_operator == PREINCREMENT_EXPR + ? NIC_PREINCREMENT : NIC_PREDECREMENT; /* Fall through. */ case UNARY_PLUS_EXPR: case NEGATE_EXPR: @@ -5669,7 +6045,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, gcc_unreachable (); } - if (non_constant_p + if (non_constant_p != NIC_NONE && cp_parser_non_integral_constant_expression (parser, non_constant_p)) expression = error_mark_node; @@ -5737,7 +6113,7 @@ cp_parser_new_expression (cp_parser* parser) /*current_scope_valid_p=*/false) != NULL_TREE); /* Look for the `new' operator. */ - cp_parser_require_keyword (parser, RID_NEW, "%<new%>"); + cp_parser_require_keyword (parser, RID_NEW, RT_NEW); /* There's no easy way to tell a new-placement from the `( type-id )' construct. */ cp_parser_parse_tentatively (parser); @@ -5761,7 +6137,7 @@ cp_parser_new_expression (cp_parser* parser) /* Parse the type-id. */ type = cp_parser_type_id (parser); /* Look for the closing `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); token = cp_lexer_peek_token (parser->lexer); /* There should not be a direct-new-declarator in this production, but GCC used to allowed this, so we check and emit a sensible error @@ -5789,7 +6165,7 @@ cp_parser_new_expression (cp_parser* parser) /* A new-expression may not appear in an integral constant expression. */ - if (cp_parser_non_integral_constant_expression (parser, "%<new%>")) + if (cp_parser_non_integral_constant_expression (parser, NIC_NEW)) ret = error_mark_node; else { @@ -5820,7 +6196,8 @@ cp_parser_new_placement (cp_parser* parser) /* Parse the expression-list. */ expression_list = (cp_parser_parenthesized_expression_list - (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true, + (parser, non_attr, /*cast_p=*/false, + /*allow_expansion_p=*/true, /*non_constant_p=*/NULL)); return expression_list; @@ -5954,7 +6331,7 @@ cp_parser_direct_new_declarator (cp_parser* parser) tree expression; /* Look for the opening `['. */ - cp_parser_require (parser, CPP_OPEN_SQUARE, "%<[%>"); + cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE); /* The first expression is not required to be constant. */ if (!declarator) { @@ -5988,7 +6365,7 @@ cp_parser_direct_new_declarator (cp_parser* parser) /*allow_non_constant=*/false, NULL); /* Look for the closing `]'. */ - cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"); + cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); /* Add this bound to the declarator. */ declarator = make_array_declarator (declarator, expression); @@ -6026,7 +6403,8 @@ cp_parser_new_initializer (cp_parser* parser) } else expression_list = (cp_parser_parenthesized_expression_list - (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true, + (parser, non_attr, /*cast_p=*/false, + /*allow_expansion_p=*/true, /*non_constant_p=*/NULL)); return expression_list; @@ -6053,14 +6431,14 @@ cp_parser_delete_expression (cp_parser* parser) /*current_scope_valid_p=*/false) != NULL_TREE); /* Look for the `delete' keyword. */ - cp_parser_require_keyword (parser, RID_DELETE, "%<delete%>"); + cp_parser_require_keyword (parser, RID_DELETE, RT_DELETE); /* See if the array syntax is in use. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)) { /* Consume the `[' token. */ cp_lexer_consume_token (parser->lexer); /* Look for the `]' token. */ - cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"); + cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); /* Remember that this is the `[]' construct. */ array_p = true; } @@ -6072,7 +6450,7 @@ cp_parser_delete_expression (cp_parser* parser) /* A delete-expression may not appear in an integral constant expression. */ - if (cp_parser_non_integral_constant_expression (parser, "%<delete%>")) + if (cp_parser_non_integral_constant_expression (parser, NIC_DEL)) return error_mark_node; return delete_sanity (expression, NULL_TREE, array_p, global_scope_p); @@ -6205,7 +6583,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p, /* Look for the type-id. */ type = cp_parser_type_id (parser); /* Look for the closing `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p; } @@ -6234,10 +6612,8 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p, /* Only type conversions to integral or enumeration types can be used in constant-expressions. */ if (!cast_valid_in_integral_constant_expression_p (type) - && (cp_parser_non_integral_constant_expression - (parser, - "a cast to a type other than an integral or " - "enumeration type"))) + && cp_parser_non_integral_constant_expression (parser, + NIC_CAST)) return error_mark_node; /* Perform the cast. */ @@ -6472,8 +6848,8 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, least one of the operands is of enumeration type. */ if (overloaded_p - && (cp_parser_non_integral_constant_expression - (parser, "calls to overloaded operators"))) + && cp_parser_non_integral_constant_expression (parser, + NIC_OVERLOADED)) return error_mark_node; } @@ -6499,15 +6875,20 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr) { tree expr; tree assignment_expr; + struct cp_token *token; /* Consume the `?' token. */ cp_lexer_consume_token (parser->lexer); + token = cp_lexer_peek_token (parser->lexer); if (cp_parser_allow_gnu_extensions_p (parser) - && cp_lexer_next_token_is (parser->lexer, CPP_COLON)) + && token->type == CPP_COLON) { + pedwarn (token->location, OPT_pedantic, + "ISO C++ does not allow ?: with omitted middle operand"); /* Implicit true clause. */ expr = NULL_TREE; c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_true_node; + warn_for_omitted_condop (token->location, logical_or_expr); } else { @@ -6520,7 +6901,7 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr) } /* The next token should be a `:'. */ - cp_parser_require (parser, CPP_COLON, "%<:%>"); + cp_parser_require (parser, CPP_COLON, RT_COLON); /* Parse the assignment-expression. */ assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); c_inhibit_evaluation_warnings -= logical_or_expr == truthvalue_true_node; @@ -6585,7 +6966,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p, /* An assignment may not appear in a constant-expression. */ if (cp_parser_non_integral_constant_expression (parser, - "an assignment")) + NIC_ASSIGNMENT)) return error_mark_node; /* Build the assignment expression. */ expr = build_x_modify_expr (expr, @@ -6720,8 +7101,7 @@ cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk) /* Consume the `,'. */ cp_lexer_consume_token (parser->lexer); /* A comma operator cannot appear in a constant-expression. */ - if (cp_parser_non_integral_constant_expression (parser, - "a comma operator")) + if (cp_parser_non_integral_constant_expression (parser, NIC_COMMA)) expression = error_mark_node; } @@ -6827,11 +7207,11 @@ cp_parser_builtin_offsetof (cp_parser *parser) /* Consume the "__builtin_offsetof" token. */ cp_lexer_consume_token (parser->lexer); /* Consume the opening `('. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Parse the type-id. */ type = cp_parser_type_id (parser); /* Look for the `,'. */ - cp_parser_require (parser, CPP_COMMA, "%<,%>"); + cp_parser_require (parser, CPP_COMMA, RT_COMMA); token = cp_lexer_peek_token (parser->lexer); /* Build the (type *)null that begins the traditional offsetof macro. */ @@ -6872,7 +7252,7 @@ cp_parser_builtin_offsetof (cp_parser *parser) default: /* Error. We know the following require will fail, but that gives the proper error message. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); cp_parser_skip_to_closing_parenthesis (parser, true, false, true); expr = error_mark_node; goto failure; @@ -6972,7 +7352,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword) /* Consume the token. */ cp_lexer_consume_token (parser->lexer); - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); type1 = cp_parser_type_id (parser); @@ -6989,7 +7369,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword) if (binary) { - cp_parser_require (parser, CPP_COMMA, "%<,%>"); + cp_parser_require (parser, CPP_COMMA, RT_COMMA); type2 = cp_parser_type_id (parser); @@ -7005,7 +7385,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword) /*initialized=*/0, /*attrlist=*/NULL); } - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Complete the trait expression, which may mean either processing the trait expr now or saving it for template instantiation. */ @@ -7081,6 +7461,10 @@ cp_parser_lambda_expression (cp_parser* parser) LAMBDA_EXPR_LOCATION (lambda_expr) = cp_lexer_peek_token (parser->lexer)->location; + if (cp_unevaluated_operand) + error_at (LAMBDA_EXPR_LOCATION (lambda_expr), + "lambda-expression in unevaluated context"); + /* We may be in the middle of deferred access check. Disable it now. */ push_deferring_access_checks (dk_no_deferred); @@ -7170,7 +7554,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) bool first = true; /* Eat the leading `['. */ - cp_parser_require (parser, CPP_OPEN_SQUARE, "%<[%>"); + cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE); /* Record default capture mode. "[&" "[=" "[&," "[=," */ if (cp_lexer_next_token_is (parser->lexer, CPP_AND) @@ -7209,7 +7593,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) if (first) first = false; else - cp_parser_require (parser, CPP_COMMA, "%<,%>"); + cp_parser_require (parser, CPP_COMMA, RT_COMMA); /* Possibly capture `this'. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THIS)) @@ -7304,7 +7688,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) explicit_init_p); } - cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"); + cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); } /* Parse the (optional) middle of a lambda expression. @@ -7349,7 +7733,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)), OPT_pedantic, "default argument specified for lambda parameter"); - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); attributes = cp_parser_attributes_opt (parser); @@ -7372,7 +7756,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) /* The function parameters must be in scope all the way until after the trailing-return-type in case of decltype. */ - for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) + for (t = current_binding_level->names; t; t = DECL_CHAIN (t)) pop_binding (DECL_NAME (t), t); leave_scope (); @@ -7483,13 +7867,13 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) statement. */ cp_parser_parse_tentatively (parser); - cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>"); - cp_parser_require_keyword (parser, RID_RETURN, "%<return%>"); + cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE); + cp_parser_require_keyword (parser, RID_RETURN, RT_RETURN); expr = cp_parser_expression (parser, /*cast_p=*/false, &idk); - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); - cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); if (cp_parser_parse_definitely (parser)) { @@ -7766,7 +8150,7 @@ cp_parser_label_for_labeled_statement (cp_parser* parser) } /* Require the `:' token. */ - cp_parser_require (parser, CPP_COLON, "%<:%>"); + cp_parser_require (parser, CPP_COLON, RT_COLON); /* An ordinary label may optionally be followed by attributes. However, this is only permitted if the attributes are then @@ -7870,7 +8254,7 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr, tree compound_stmt; /* Consume the `{'. */ - if (!cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>")) + if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE)) return error_mark_node; /* Begin the compound-statement. */ compound_stmt = begin_compound_stmt (in_try ? BCS_TRY_BLOCK : 0); @@ -7882,7 +8266,7 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr, /* Finish the compound-statement. */ finish_compound_stmt (compound_stmt); /* Consume the `}'. */ - cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); return compound_stmt; } @@ -7949,7 +8333,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p) *if_p = false; /* Peek at the next token. */ - token = cp_parser_require (parser, CPP_KEYWORD, "selection-statement"); + token = cp_parser_require (parser, CPP_KEYWORD, RT_SELECT); /* See what kind of keyword it is. */ keyword = token->keyword; @@ -7962,7 +8346,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p) tree condition; /* Look for the `('. */ - if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) { cp_parser_skip_to_end_of_statement (parser); return error_mark_node; @@ -7977,7 +8361,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p) /* Parse the condition. */ condition = cp_parser_condition (parser); /* Look for the `)'. */ - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) cp_parser_skip_to_closing_parenthesis (parser, true, false, /*consume_paren=*/true); @@ -8172,7 +8556,7 @@ cp_parser_condition (cp_parser* parser) else { /* Consume the `='. */ - cp_parser_require (parser, CPP_EQ, "%<=%>"); + cp_parser_require (parser, CPP_EQ, RT_EQ); initializer = cp_parser_initializer_clause (parser, &non_constant_p); } if (BRACE_ENCLOSED_INITIALIZER_P (initializer)) @@ -8202,6 +8586,258 @@ cp_parser_condition (cp_parser* parser) return cp_parser_expression (parser, /*cast_p=*/false, NULL); } +/* Parses a traditional for-statement until the closing ')', not included. */ + +static tree +cp_parser_c_for (cp_parser *parser) +{ + /* Normal for loop */ + tree stmt; + tree condition = NULL_TREE; + tree expression = NULL_TREE; + + /* Begin the for-statement. */ + stmt = begin_for_stmt (); + + /* Parse the initialization. */ + cp_parser_for_init_statement (parser); + finish_for_init_stmt (stmt); + + /* If there's a condition, process it. */ + if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) + condition = cp_parser_condition (parser); + finish_for_cond (condition, stmt); + /* Look for the `;'. */ + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); + + /* If there's an expression, process it. */ + if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) + expression = cp_parser_expression (parser, /*cast_p=*/false, NULL); + finish_for_expr (expression, stmt); + + return stmt; +} + +/* Tries to parse a range-based for-statement: + + range-based-for: + type-specifier-seq declarator : expression + + If succesful, assigns to *DECL the DECLARATOR and to *EXPR the + expression. Note that the *DECL is returned unfinished, so + later you should call cp_finish_decl(). + + Returns TRUE iff a range-based for is parsed. */ + +static tree +cp_parser_range_for (cp_parser *parser) +{ + tree stmt, range_decl, range_expr; + cp_decl_specifier_seq type_specifiers; + cp_declarator *declarator; + const char *saved_message; + tree attributes, pushed_scope; + + cp_parser_parse_tentatively (parser); + /* New types are not allowed in the type-specifier-seq for a + range-based for loop. */ + saved_message = parser->type_definition_forbidden_message; + parser->type_definition_forbidden_message + = G_("types may not be defined in range-based for loops"); + /* Parse the type-specifier-seq. */ + cp_parser_type_specifier_seq (parser, /*is_declaration==*/true, + /*is_trailing_return=*/false, + &type_specifiers); + /* Restore the saved message. */ + parser->type_definition_forbidden_message = saved_message; + /* If all is well, we might be looking at a declaration. */ + if (cp_parser_error_occurred (parser)) + { + cp_parser_abort_tentative_parse (parser); + return NULL_TREE; + } + /* Parse the declarator. */ + declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, + /*ctor_dtor_or_conv_p=*/NULL, + /*parenthesized_p=*/NULL, + /*member_p=*/false); + /* Parse the attributes. */ + attributes = cp_parser_attributes_opt (parser); + /* The next token should be `:'. */ + if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)) + cp_parser_simulate_error (parser); + + /* Check if it is a range-based for */ + if (!cp_parser_parse_definitely (parser)) + return NULL_TREE; + + cp_parser_require (parser, CPP_COLON, RT_COLON); + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) + { + bool expr_non_constant_p; + range_expr = cp_parser_braced_list (parser, &expr_non_constant_p); + } + else + range_expr = cp_parser_expression (parser, /*cast_p=*/false, NULL); + + /* If in template, STMT is converted to a normal for-statements + at instantiation. If not, it is done just ahead. */ + if (processing_template_decl) + stmt = begin_range_for_stmt (); + else + stmt = begin_for_stmt (); + + /* Create the declaration. It must be after begin{,_range}_for_stmt(). */ + range_decl = start_decl (declarator, &type_specifiers, + /*initialized_p=*/SD_INITIALIZED, + attributes, /*prefix_attributes=*/NULL_TREE, + &pushed_scope); + /* No scope allowed here */ + pop_scope (pushed_scope); + + if (TREE_CODE (stmt) == RANGE_FOR_STMT) + finish_range_for_decl (stmt, range_decl, range_expr); + else + /* Convert the range-based for loop into a normal for-statement. */ + stmt = cp_convert_range_for (stmt, range_decl, range_expr); + + return stmt; +} + +/* Converts a range-based for-statement into a normal + for-statement, as per the definition. + + for (RANGE_DECL : RANGE_EXPR) + BLOCK + + should be equivalent to: + + { + auto &&__range = RANGE_EXPR; + for (auto __begin = BEGIN_EXPR, end = END_EXPR; + __begin != __end; + ++__begin) + { + RANGE_DECL = *__begin; + BLOCK + } + } + + If RANGE_EXPR is an array: + BEGIN_EXPR = __range + END_EXPR = __range + ARRAY_SIZE(__range) + Else: + BEGIN_EXPR = begin(__range) + END_EXPR = end(__range); + + When calling begin()/end() we must use argument dependent + lookup, but always considering 'std' as an associated namespace. */ + +tree +cp_convert_range_for (tree statement, tree range_decl, tree range_expr) +{ + tree range_type, range_temp; + tree begin, end; + tree iter_type, begin_expr, end_expr; + tree condition, expression; + + /* Find out the type deduced by the declaration + * `auto &&__range = range_expr' */ + range_type = cp_build_reference_type (make_auto (), true); + range_type = do_auto_deduction (range_type, range_expr, + type_uses_auto (range_type)); + + /* Create the __range variable */ + range_temp = build_decl (input_location, VAR_DECL, + get_identifier ("__for_range"), range_type); + TREE_USED (range_temp) = 1; + DECL_ARTIFICIAL (range_temp) = 1; + pushdecl (range_temp); + finish_expr_stmt (cp_build_modify_expr (range_temp, INIT_EXPR, range_expr, + tf_warning_or_error)); + range_temp = convert_from_reference (range_temp); + + if (TREE_CODE (TREE_TYPE (range_temp)) == ARRAY_TYPE) + { + /* If RANGE_TEMP is an array we will use pointer arithmetic */ + iter_type = build_pointer_type (TREE_TYPE (TREE_TYPE (range_temp))); + begin_expr = range_temp; + end_expr + = build_binary_op (input_location, PLUS_EXPR, + range_temp, + array_type_nelts_top (TREE_TYPE (range_temp)), 0); + } + else + { + /* If it is not an array, we must call begin(__range)/end__range() */ + VEC(tree,gc) *vec; + + begin_expr = get_identifier ("begin"); + vec = make_tree_vector (); + VEC_safe_push (tree, gc, vec, range_temp); + begin_expr = perform_koenig_lookup (begin_expr, vec, + /*include_std=*/true); + begin_expr = finish_call_expr (begin_expr, &vec, false, true, + tf_warning_or_error); + release_tree_vector (vec); + + end_expr = get_identifier ("end"); + vec = make_tree_vector (); + VEC_safe_push (tree, gc, vec, range_temp); + end_expr = perform_koenig_lookup (end_expr, vec, + /*include_std=*/true); + end_expr = finish_call_expr (end_expr, &vec, false, true, + tf_warning_or_error); + release_tree_vector (vec); + + /* The unqualified type of the __begin and __end temporaries should + * be the same as required by the multiple auto declaration */ + iter_type = cv_unqualified (TREE_TYPE (begin_expr)); + if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE (end_expr)))) + error ("inconsistent begin/end types in range-based for: %qT and %qT", + TREE_TYPE (begin_expr), TREE_TYPE (end_expr)); + } + + /* The new for initialization statement */ + begin = build_decl (input_location, VAR_DECL, + get_identifier ("__for_begin"), iter_type); + TREE_USED (begin) = 1; + DECL_ARTIFICIAL (begin) = 1; + pushdecl (begin); + finish_expr_stmt (cp_build_modify_expr (begin, INIT_EXPR, begin_expr, + tf_warning_or_error)); + end = build_decl (input_location, VAR_DECL, + get_identifier ("__for_end"), iter_type); + TREE_USED (end) = 1; + DECL_ARTIFICIAL (end) = 1; + pushdecl (end); + + finish_expr_stmt (cp_build_modify_expr (end, INIT_EXPR, end_expr, + tf_warning_or_error)); + + finish_for_init_stmt (statement); + +/* The new for condition */ + condition = build_x_binary_op (NE_EXPR, + begin, ERROR_MARK, + end, ERROR_MARK, + NULL, tf_warning_or_error); + finish_for_cond (condition, statement); + + /* The new increment expression */ + expression = finish_unary_op_expr (PREINCREMENT_EXPR, begin); + finish_for_expr (expression, statement); + + /* The declaration is initialized with *__begin inside the loop body */ + cp_finish_decl (range_decl, + build_x_indirect_ref (begin, RO_NULL, tf_warning_or_error), + /*is_constant_init*/false, NULL_TREE, + LOOKUP_ONLYCONVERTING); + + return statement; +} + + /* Parse an iteration-statement. iteration-statement: @@ -8210,7 +8846,7 @@ cp_parser_condition (cp_parser* parser) for ( for-init-statement condition [opt] ; expression [opt] ) statement - Returns the new WHILE_STMT, DO_STMT, or FOR_STMT. */ + Returns the new WHILE_STMT, DO_STMT, FOR_STMT or RANGE_FOR_STMT. */ static tree cp_parser_iteration_statement (cp_parser* parser) @@ -8221,7 +8857,7 @@ cp_parser_iteration_statement (cp_parser* parser) unsigned char in_statement; /* Peek at the next token. */ - token = cp_parser_require (parser, CPP_KEYWORD, "iteration-statement"); + token = cp_parser_require (parser, CPP_KEYWORD, RT_INTERATION); if (!token) return error_mark_node; @@ -8240,12 +8876,12 @@ cp_parser_iteration_statement (cp_parser* parser) /* Begin the while-statement. */ statement = begin_while_stmt (); /* Look for the `('. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Parse the condition. */ condition = cp_parser_condition (parser); finish_while_stmt_cond (condition, statement); /* Look for the `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Parse the dependent statement. */ parser->in_statement = IN_ITERATION_STMT; cp_parser_already_scoped_statement (parser); @@ -8267,46 +8903,34 @@ cp_parser_iteration_statement (cp_parser* parser) parser->in_statement = in_statement; finish_do_body (statement); /* Look for the `while' keyword. */ - cp_parser_require_keyword (parser, RID_WHILE, "%<while%>"); + cp_parser_require_keyword (parser, RID_WHILE, RT_WHILE); /* Look for the `('. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Parse the expression. */ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL); /* We're done with the do-statement. */ finish_do_stmt (expression, statement); /* Look for the `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Look for the `;'. */ - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); } break; case RID_FOR: { - tree condition = NULL_TREE; - tree expression = NULL_TREE; - - /* Begin the for-statement. */ - statement = begin_for_stmt (); /* Look for the `('. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); - /* Parse the initialization. */ - cp_parser_for_init_statement (parser); - finish_for_init_stmt (statement); - - /* If there's a condition, process it. */ - if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - condition = cp_parser_condition (parser); - finish_for_cond (condition, statement); - /* Look for the `;'. */ - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); + + if (cxx_dialect == cxx0x) + statement = cp_parser_range_for (parser); + else + statement = NULL_TREE; + if (statement == NULL_TREE) + statement = cp_parser_c_for (parser); - /* If there's an expression, process it. */ - if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) - expression = cp_parser_expression (parser, /*cast_p=*/false, NULL); - finish_for_expr (expression, statement); /* Look for the `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Parse the body of the for-statement. */ parser->in_statement = IN_ITERATION_STMT; @@ -8384,7 +9008,7 @@ cp_parser_jump_statement (cp_parser* parser) unsigned char in_statement; /* Peek at the next token. */ - token = cp_parser_require (parser, CPP_KEYWORD, "jump-statement"); + token = cp_parser_require (parser, CPP_KEYWORD, RT_JUMP); if (!token) return error_mark_node; @@ -8411,7 +9035,7 @@ cp_parser_jump_statement (cp_parser* parser) error_at (token->location, "break statement used with OpenMP for loop"); break; } - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); break; case RID_CONTINUE: @@ -8430,7 +9054,7 @@ cp_parser_jump_statement (cp_parser* parser) default: gcc_unreachable (); } - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); break; case RID_RETURN: @@ -8452,7 +9076,7 @@ cp_parser_jump_statement (cp_parser* parser) /* Build the return-statement. */ statement = finish_return_stmt (expr); /* Look for the final `;'. */ - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); } break; @@ -8470,7 +9094,7 @@ cp_parser_jump_statement (cp_parser* parser) else finish_goto_stmt (cp_parser_identifier (parser)); /* Look for the final `;'. */ - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); break; default: @@ -8568,13 +9192,13 @@ cp_parser_already_scoped_statement (cp_parser* parser) { /* Avoid calling cp_parser_compound_statement, so that we don't create a new scope. Do everything else by hand. */ - cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>"); + cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE); /* If the next keyword is `__label__' we have a label declaration. */ while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL)) cp_parser_label_declaration (parser); /* Parse an (optional) statement-seq. */ cp_parser_statement_seq_opt (parser, NULL_TREE); - cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); } } @@ -9019,7 +9643,7 @@ cp_parser_simple_declaration (cp_parser* parser, } /* Consume the `;'. */ - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); done: pop_deferring_access_checks (); @@ -9386,7 +10010,7 @@ cp_parser_linkage_specification (cp_parser* parser) tree linkage; /* Look for the `extern' keyword. */ - cp_parser_require_keyword (parser, RID_EXTERN, "%<extern%>"); + cp_parser_require_keyword (parser, RID_EXTERN, RT_EXTERN); /* Look for the string-literal. */ linkage = cp_parser_string_literal (parser, false, false); @@ -9416,7 +10040,7 @@ cp_parser_linkage_specification (cp_parser* parser) /* Parse the declarations. */ cp_parser_declaration_seq_opt (parser); /* Look for the closing `}'. */ - cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); } /* Otherwise, there's just one declaration. */ else @@ -9457,7 +10081,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p) /* Look for the `static_assert' keyword. */ if (!cp_parser_require_keyword (parser, RID_STATIC_ASSERT, - "%<static_assert%>")) + RT_STATIC_ASSERT)) return; /* We know we are in a static assertion; commit to any tentative @@ -9466,7 +10090,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p) cp_parser_commit_to_tentative_parse (parser); /* Parse the `(' starting the static assertion condition. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Parse the constant-expression. */ condition = @@ -9475,7 +10099,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p) /*non_constant_p=*/NULL); /* Parse the separating `,'. */ - cp_parser_require (parser, CPP_COMMA, "%<,%>"); + cp_parser_require (parser, CPP_COMMA, RT_COMMA); /* Parse the string-literal message. */ message = cp_parser_string_literal (parser, @@ -9483,14 +10107,14 @@ cp_parser_static_assert(cp_parser *parser, bool member_p) /*wide_ok=*/true); /* A `)' completes the static assertion. */ - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, /*or_comma=*/false, /*consume_paren=*/true); /* A semicolon terminates the declaration. */ - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); /* Complete the static assertion, which may mean either processing the static assert now or saving it for template instantiation. */ @@ -9513,7 +10137,7 @@ cp_parser_decltype (cp_parser *parser) cp_token *id_expr_start_token; /* Look for the `decltype' token. */ - if (!cp_parser_require_keyword (parser, RID_DECLTYPE, "%<decltype%>")) + if (!cp_parser_require_keyword (parser, RID_DECLTYPE, RT_DECLTYPE)) return error_mark_node; /* Types cannot be defined in a `decltype' expression. Save away the @@ -9539,7 +10163,7 @@ cp_parser_decltype (cp_parser *parser) ++c_inhibit_evaluation_warnings; /* Parse the opening `('. */ - if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return error_mark_node; /* First, try parsing an id-expression. */ @@ -9673,7 +10297,7 @@ cp_parser_decltype (cp_parser *parser) } /* Parse to the closing `)'. */ - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) { cp_parser_skip_to_closing_parenthesis (parser, true, false, /*consume_paren=*/true); @@ -9702,7 +10326,7 @@ cp_parser_conversion_function_id (cp_parser* parser) tree pushed_scope = NULL_TREE; /* Look for the `operator' token. */ - if (!cp_parser_require_keyword (parser, RID_OPERATOR, "%<operator%>")) + if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR)) return error_mark_node; /* When we parse the conversion-type-id, the current scope will be reset. However, we need that information in able to look up the @@ -9862,7 +10486,7 @@ cp_parser_mem_initializer_list (cp_parser* parser) mem-initializer-list. */ if (!DECL_CONSTRUCTOR_P (current_function_decl)) error_at (token->location, - "only constructors take base initializers"); + "only constructors take member initializers"); /* Loop through the list. */ while (true) @@ -9963,7 +10587,7 @@ cp_parser_mem_initializer (cp_parser* parser) else { VEC(tree,gc)* vec; - vec = cp_parser_parenthesized_expression_list (parser, false, + vec = cp_parser_parenthesized_expression_list (parser, non_attr, /*cast_p=*/false, /*allow_expansion_p=*/true, /*non_constant_p=*/NULL); @@ -10078,7 +10702,7 @@ static tree cp_parser_operator_function_id (cp_parser* parser) { /* Look for the `operator' keyword. */ - if (!cp_parser_require_keyword (parser, RID_OPERATOR, "%<operator%>")) + if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR)) return error_mark_node; /* And then the name of the operator itself. */ return cp_parser_operator (parser); @@ -10134,7 +10758,7 @@ cp_parser_operator (cp_parser* parser) /* Consume the `[' token. */ cp_lexer_consume_token (parser->lexer); /* Look for the `]' token. */ - cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"); + cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); id = ansi_opname (op == NEW_EXPR ? VEC_NEW_EXPR : VEC_DELETE_EXPR); } @@ -10293,14 +10917,14 @@ cp_parser_operator (cp_parser* parser) /* Consume the `('. */ cp_lexer_consume_token (parser->lexer); /* Look for the matching `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); return ansi_opname (CALL_EXPR); case CPP_OPEN_SQUARE: /* Consume the `['. */ cp_lexer_consume_token (parser->lexer); /* Look for the matching `]'. */ - cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"); + cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); return ansi_opname (ARRAY_REF); default: @@ -10588,8 +11212,7 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) tree parameter; /* Look for a keyword to tell us what kind of parameter this is. */ - token = cp_parser_require (parser, CPP_KEYWORD, - "%<class%>, %<typename%>, or %<template%>"); + token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_TYPENAME_TEMPLATE); if (!token) return error_mark_node; @@ -10662,13 +11285,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) tree default_argument; /* Look for the `<'. */ - cp_parser_require (parser, CPP_LESS, "%<<%>"); + cp_parser_require (parser, CPP_LESS, RT_LESS); /* Parse the template-parameter-list. */ cp_parser_template_parameter_list (parser); /* Look for the `>'. */ - cp_parser_require (parser, CPP_GREATER, "%<>%>"); + cp_parser_require (parser, CPP_GREATER, RT_GREATER); /* Look for the `class' keyword. */ - cp_parser_require_keyword (parser, RID_CLASS, "%<class%>"); + cp_parser_require_keyword (parser, RID_CLASS, RT_CLASS); /* If the next token is an ellipsis, we have a template argument pack. */ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) @@ -10814,14 +11437,10 @@ cp_parser_template_id (cp_parser *parser, access_check = check_value->checks; if (access_check) { - for (i = 0 ; - VEC_iterate (deferred_access_check, access_check, i, chk) ; - ++i) - { - perform_or_defer_access_check (chk->binfo, - chk->decl, - chk->diag_decl); - } + FOR_EACH_VEC_ELT (deferred_access_check, access_check, i, chk) + perform_or_defer_access_check (chk->binfo, + chk->decl, + chk->diag_decl); } /* Return the stored value. */ return check_value->value; @@ -10905,7 +11524,7 @@ cp_parser_template_id (cp_parser *parser, else { /* Look for the `<' that starts the template-argument-list. */ - if (!cp_parser_require (parser, CPP_LESS, "%<<%>")) + if (!cp_parser_require (parser, CPP_LESS, RT_LESS)) { pop_deferring_access_checks (); return error_mark_node; @@ -10957,7 +11576,7 @@ cp_parser_template_id (cp_parser *parser, token->type = CPP_TEMPLATE_ID; /* Retrieve any deferred checks. Do not pop this access checks yet so the memory will not be reclaimed during token replacing below. */ - token->u.tree_check_value = GGC_CNEW (struct tree_check); + token->u.tree_check_value = ggc_alloc_cleared_tree_check (); token->u.tree_check_value->value = template_id; token->u.tree_check_value->checks = get_deferred_access_checks (); token->keyword = RID_MAX; @@ -11539,7 +12158,7 @@ cp_parser_explicit_instantiation (cp_parser* parser) } /* Look for the `template' keyword. */ - cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>"); + cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE); /* Let the front end know that we are processing an explicit instantiation. */ begin_explicit_instantiation (); @@ -11624,11 +12243,11 @@ cp_parser_explicit_specialization (cp_parser* parser) cp_token *token = cp_lexer_peek_token (parser->lexer); /* Look for the `template' keyword. */ - cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>"); + cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE); /* Look for the `<'. */ - cp_parser_require (parser, CPP_LESS, "%<<%>"); + cp_parser_require (parser, CPP_LESS, RT_LESS); /* Look for the `>'. */ - cp_parser_require (parser, CPP_GREATER, "%<>%>"); + cp_parser_require (parser, CPP_GREATER, RT_GREATER); /* We have processed another parameter list. */ ++parser->num_template_parameter_lists; /* [temp] @@ -11892,6 +12511,7 @@ cp_parser_type_specifier (cp_parser* parser, GNU Extension: simple-type-specifier: + __int128 __typeof__ unary-expression __typeof__ ( type-id ) @@ -11939,6 +12559,13 @@ cp_parser_simple_type_specifier (cp_parser* parser, decl_specs->explicit_int_p = true; type = integer_type_node; break; + case RID_INT128: + if (!int128_integer_type_node) + break; + if (decl_specs) + decl_specs->explicit_int128_p = true; + type = int128_integer_type_node; + break; case RID_LONG: if (decl_specs) ++decl_specs->specs[(int) ds_long]; @@ -12205,7 +12832,7 @@ cp_parser_nonclass_name (cp_parser* parser) { if (!cp_parser_simulate_error (parser)) cp_parser_name_lookup_error (parser, identifier, type_decl, - "is not a type", token->location); + NLE_TYPE, token->location); return error_mark_node; } /* Remember that the name was used in the definition of the @@ -12689,7 +13316,7 @@ cp_parser_enum_specifier (cp_parser* parser) cp_parser_enumerator_list (parser, type); /* Consume the final '}'. */ - cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); /* Look for trailing attributes to apply to this enumeration, and apply them if appropriate. */ @@ -12754,6 +13381,11 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type) { tree identifier; tree value; + location_t loc; + + /* Save the input location because we are interested in the location + of the identifier and not the location of the explicit value. */ + loc = cp_lexer_peek_token (parser->lexer)->location; /* Look for the identifier. */ identifier = cp_parser_identifier (parser); @@ -12779,7 +13411,7 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type) value = error_mark_node; /* Create the enumerator. */ - build_enumerator (identifier, value, type); + build_enumerator (identifier, value, type, loc); } /* Parse a namespace-name. @@ -12869,6 +13501,7 @@ cp_parser_namespace_definition (cp_parser* parser) if (cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE)) { + maybe_warn_cpp0x (CPP0X_INLINE_NAMESPACES); is_inline = true; cp_lexer_consume_token (parser->lexer); } @@ -12876,7 +13509,7 @@ cp_parser_namespace_definition (cp_parser* parser) is_inline = false; /* Look for the `namespace' keyword. */ - cp_parser_require_keyword (parser, RID_NAMESPACE, "%<namespace%>"); + cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE); /* Get the name of the namespace. We do not attempt to distinguish between an original-namespace-definition and an @@ -12891,7 +13524,7 @@ cp_parser_namespace_definition (cp_parser* parser) attribs = cp_parser_attributes_opt (parser); /* Look for the `{' to start the namespace. */ - cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>"); + cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE); /* Start the namespace. */ push_namespace (identifier); @@ -12923,7 +13556,7 @@ cp_parser_namespace_definition (cp_parser* parser) /* Finish the namespace. */ pop_namespace (); /* Look for the final `}'. */ - cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); } /* Parse a namespace-body. @@ -12951,7 +13584,7 @@ cp_parser_namespace_alias_definition (cp_parser* parser) cp_token *token = cp_lexer_peek_token (parser->lexer); /* Look for the `namespace' keyword. */ - cp_parser_require_keyword (parser, RID_NAMESPACE, "%<namespace%>"); + cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE); /* Look for the identifier. */ identifier = cp_parser_identifier (parser); if (identifier == error_mark_node) @@ -12967,12 +13600,12 @@ cp_parser_namespace_alias_definition (cp_parser* parser) cp_lexer_consume_token (parser->lexer); return; } - cp_parser_require (parser, CPP_EQ, "%<=%>"); + cp_parser_require (parser, CPP_EQ, RT_EQ); /* Look for the qualified-namespace-specifier. */ namespace_specifier = cp_parser_qualified_namespace_specifier (parser); /* Look for the `;' token. */ - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); /* Register the alias in the symbol table. */ do_namespace_alias (identifier, namespace_specifier); @@ -13031,7 +13664,7 @@ cp_parser_using_declaration (cp_parser* parser, else { /* Look for the `using' keyword. */ - cp_parser_require_keyword (parser, RID_USING, "%<using%>"); + cp_parser_require_keyword (parser, RID_USING, RT_USING); /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); @@ -13122,7 +13755,7 @@ cp_parser_using_declaration (cp_parser* parser, token->location); if (decl == error_mark_node) cp_parser_name_lookup_error (parser, identifier, - decl, NULL, + decl, NLE_NULL, token->location); else if (check_for_bare_parameter_packs (decl)) return false; @@ -13134,7 +13767,7 @@ cp_parser_using_declaration (cp_parser* parser, } /* Look for the final `;'. */ - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); return true; } @@ -13152,9 +13785,9 @@ cp_parser_using_directive (cp_parser* parser) tree attribs; /* Look for the `using' keyword. */ - cp_parser_require_keyword (parser, RID_USING, "%<using%>"); + cp_parser_require_keyword (parser, RID_USING, RT_USING); /* And the `namespace' keyword. */ - cp_parser_require_keyword (parser, RID_NAMESPACE, "%<namespace%>"); + cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE); /* Look for the optional `::' operator. */ cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false); /* And the optional nested-name-specifier. */ @@ -13170,7 +13803,7 @@ cp_parser_using_directive (cp_parser* parser) /* Update the symbol table. */ parse_using_directive (namespace_decl, attribs); /* Look for the final `;'. */ - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); } /* Parse an asm-definition. @@ -13206,10 +13839,10 @@ cp_parser_asm_definition (cp_parser* parser) bool invalid_inputs_p = false; bool invalid_outputs_p = false; bool goto_p = false; - const char *missing = NULL; + required_token missing = RT_NONE; /* Look for the `asm' keyword. */ - cp_parser_require_keyword (parser, RID_ASM, "%<asm%>"); + cp_parser_require_keyword (parser, RID_ASM, RT_ASM); /* See if the next token is `volatile'. */ if (cp_parser_allow_gnu_extensions_p (parser) && cp_lexer_next_token_is_keyword (parser->lexer, RID_VOLATILE)) @@ -13229,7 +13862,7 @@ cp_parser_asm_definition (cp_parser* parser) cp_lexer_consume_token (parser->lexer); } /* Look for the opening `('. */ - if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return; /* Look for the string. */ string = cp_parser_string_literal (parser, false, false); @@ -13334,17 +13967,17 @@ cp_parser_asm_definition (cp_parser* parser) } if (goto_p && !labels_p) - missing = clobbers_p ? "%<:%>" : "%<:%> or %<::%>"; + missing = clobbers_p ? RT_COLON : RT_COLON_SCOPE; } else if (goto_p) - missing = "%<:%> or %<::%>"; + missing = RT_COLON_SCOPE; /* Look for the closing `)'. */ if (!cp_parser_require (parser, missing ? CPP_COLON : CPP_CLOSE_PAREN, - missing ? missing : "%<)%>")) + missing ? missing : RT_CLOSE_PAREN)) cp_parser_skip_to_closing_parenthesis (parser, true, false, /*consume_paren=*/true); - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); if (!invalid_inputs_p && !invalid_outputs_p) { @@ -13633,6 +14266,13 @@ cp_parser_init_declarator (cp_parser* parser, decl = start_decl (declarator, decl_specifiers, is_initialized, attributes, prefix_attributes, &pushed_scope); + /* Adjust location of decl if declarator->id_loc is more appropriate: + set, and decl wasn't merged with another decl, in which case its + location would be different from input_location, and more accurate. */ + if (DECL_P (decl) + && declarator->id_loc != UNKNOWN_LOCATION + && DECL_SOURCE_LOCATION (decl) == input_location) + DECL_SOURCE_LOCATION (decl) = declarator->id_loc; } else if (scope) /* Enter the SCOPE. That way unqualified names appearing in the @@ -13748,7 +14388,7 @@ cp_parser_init_declarator (cp_parser* parser, `explicit' constructor is OK. Otherwise, an `explicit' constructor cannot be used. */ ((is_direct_init || !is_initialized) - ? 0 : LOOKUP_ONLYCONVERTING)); + ? LOOKUP_NORMAL : LOOKUP_IMPLICIT)); } else if ((cxx_dialect != cxx98) && friend_p && decl && TREE_CODE (decl) == FUNCTION_DECL) @@ -14013,7 +14653,7 @@ cp_parser_direct_declarator (cp_parser* parser, *ctor_dtor_or_conv_p = *ctor_dtor_or_conv_p < 0; first = false; /* Consume the `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Parse the cv-qualifier-seq. */ cv_quals = cp_parser_cv_qualifier_seq_opt (parser); @@ -14037,7 +14677,7 @@ cp_parser_direct_declarator (cp_parser* parser, } /* Remove the function parms from scope. */ - for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) + for (t = current_binding_level->names; t; t = DECL_CHAIN (t)) pop_binding (DECL_NAME (t), t); leave_scope(); @@ -14067,7 +14707,7 @@ cp_parser_direct_declarator (cp_parser* parser, parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p; first = false; /* Expect a `)'. */ - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) declarator = cp_error_declarator; if (declarator == cp_error_declarator) break; @@ -14127,7 +14767,7 @@ cp_parser_direct_declarator (cp_parser* parser, else bounds = NULL_TREE; /* Look for the closing `]'. */ - if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>")) + if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE)) { declarator = cp_error_declarator; break; @@ -14441,7 +15081,7 @@ cp_parser_ptr_operator (cp_parser* parser, /* If we found it, and the next token is a `*', then we are indeed looking at a pointer-to-member operator. */ if (!cp_parser_error_occurred (parser) - && cp_parser_require (parser, CPP_MULT, "%<*%>")) + && cp_parser_require (parser, CPP_MULT, RT_MULT)) { /* Indicate that the `*' operator was used. */ code = INDIRECT_REF; @@ -14837,7 +15477,7 @@ cp_parser_parameter_declaration_clause (cp_parser* parser) cp_lexer_consume_token (parser->lexer); /* Expect an ellipsis. */ ellipsis_p - = (cp_parser_require (parser, CPP_ELLIPSIS, "%<...%>") != NULL); + = (cp_parser_require (parser, CPP_ELLIPSIS, RT_ELLIPSIS) != NULL); } /* It might also be `...' if the optional trailing `,' was omitted. */ @@ -15187,6 +15827,7 @@ cp_parser_parameter_declaration (cp_parser *parser, the default argument; otherwise the default argument continues. */ bool error = false; + tree t; /* Set ITALP so cp_parser_parameter_declaration_list doesn't decide to commit to this parse. */ @@ -15195,7 +15836,11 @@ cp_parser_parameter_declaration (cp_parser *parser, cp_parser_parse_tentatively (parser); cp_lexer_consume_token (parser->lexer); + begin_scope (sk_function_parms, NULL_TREE); cp_parser_parameter_declaration_list (parser, &error); + for (t = current_binding_level->names; t; t = DECL_CHAIN (t)) + pop_binding (DECL_NAME (t), t); + leave_scope (); if (!cp_parser_error_occurred (parser) && !error) done = true; cp_parser_abort_tentative_parse (parser); @@ -15449,7 +16094,7 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init, else if (token->type == CPP_OPEN_PAREN) { VEC(tree,gc) *vec; - vec = cp_parser_parenthesized_expression_list (parser, false, + vec = cp_parser_parenthesized_expression_list (parser, non_attr, /*cast_p=*/false, /*allow_expansion_p=*/true, non_constant_p); @@ -15545,7 +16190,7 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p) cp_lexer_consume_token (parser->lexer); } /* Now, there should be a trailing `}'. */ - cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); TREE_TYPE (initializer) = init_list_type_node; return initializer; } @@ -15841,7 +16486,7 @@ cp_parser_class_specifier (cp_parser* parser) } /* Look for the `{'. */ - if (!cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>")) + if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE)) { pop_deferring_access_checks (); return error_mark_node; @@ -15892,7 +16537,7 @@ cp_parser_class_specifier (cp_parser* parser) cp_parser_member_specification_opt (parser); /* Look for the trailing `}'. */ - cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); /* Look for trailing attributes to apply to this class. */ if (cp_parser_allow_gnu_extensions_p (parser)) attributes = cp_parser_attributes_opt (parser); @@ -15922,10 +16567,11 @@ cp_parser_class_specifier (cp_parser* parser) there is no need to delay the parsing of `A::B::f'. */ if (--parser->num_classes_being_defined == 0) { - tree queue_entry; tree fn; tree class_type = NULL_TREE; tree pushed_scope = NULL_TREE; + unsigned ix; + cp_default_arg_entry *e; /* In a first pass, parse default arguments to the functions. Then, in a second pass, parse the bodies of the functions. @@ -15937,20 +16583,17 @@ cp_parser_class_specifier (cp_parser* parser) }; */ - for (TREE_PURPOSE (parser->unparsed_functions_queues) - = nreverse (TREE_PURPOSE (parser->unparsed_functions_queues)); - (queue_entry = TREE_PURPOSE (parser->unparsed_functions_queues)); - TREE_PURPOSE (parser->unparsed_functions_queues) - = TREE_CHAIN (TREE_PURPOSE (parser->unparsed_functions_queues))) + FOR_EACH_VEC_ELT (cp_default_arg_entry, unparsed_funs_with_default_args, + ix, e) { - fn = TREE_VALUE (queue_entry); + fn = e->decl; /* If there are default arguments that have not yet been processed, take care of them now. */ - if (class_type != TREE_PURPOSE (queue_entry)) + if (class_type != e->class_type) { if (pushed_scope) pop_scope (pushed_scope); - class_type = TREE_PURPOSE (queue_entry); + class_type = e->class_type; pushed_scope = push_scope (class_type); } /* Make sure that any template parameters are in scope. */ @@ -15962,18 +16605,11 @@ cp_parser_class_specifier (cp_parser* parser) } if (pushed_scope) pop_scope (pushed_scope); + VEC_truncate (cp_default_arg_entry, unparsed_funs_with_default_args, 0); /* Now parse the body of the functions. */ - for (TREE_VALUE (parser->unparsed_functions_queues) - = nreverse (TREE_VALUE (parser->unparsed_functions_queues)); - (queue_entry = TREE_VALUE (parser->unparsed_functions_queues)); - TREE_VALUE (parser->unparsed_functions_queues) - = TREE_CHAIN (TREE_VALUE (parser->unparsed_functions_queues))) - { - /* Figure out which function we need to process. */ - fn = TREE_VALUE (queue_entry); - /* Parse the function. */ - cp_parser_late_parsing_for_member (parser, fn); - } + FOR_EACH_VEC_ELT (tree, unparsed_funs_with_definitions, ix, fn) + cp_parser_late_parsing_for_member (parser, fn); + VEC_truncate (tree, unparsed_funs_with_definitions, 0); } /* Put back any saved access checks. */ @@ -16395,6 +17031,9 @@ cp_parser_class_head (cp_parser* parser, end_specialization (); --parser->num_template_parameter_lists; } + + if (type) + DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location; *attributes_p = attributes; return type; } @@ -16416,7 +17055,7 @@ cp_parser_class_key (cp_parser* parser) enum tag_types tag_type; /* Look for the class-key. */ - token = cp_parser_require (parser, CPP_KEYWORD, "class-key"); + token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_KEY); if (!token) return none_type; @@ -16461,7 +17100,7 @@ cp_parser_member_specification_opt (cp_parser* parser) /* Remember which access-specifier is active. */ current_access_specifier = token->u.value; /* Look for the `:'. */ - cp_parser_require (parser, CPP_COLON, "%<:%>"); + cp_parser_require (parser, CPP_COLON, RT_COLON); break; default: @@ -16892,7 +17531,7 @@ cp_parser_member_declaration (cp_parser* parser) } } - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); } /* Parse a pure-specifier. @@ -16909,7 +17548,7 @@ cp_parser_pure_specifier (cp_parser* parser) cp_token *token; /* Look for the `=' token. */ - if (!cp_parser_require (parser, CPP_EQ, "%<=%>")) + if (!cp_parser_require (parser, CPP_EQ, RT_EQ)) return error_mark_node; /* Look for the `0' token. */ token = cp_lexer_peek_token (parser->lexer); @@ -16956,7 +17595,7 @@ static tree cp_parser_constant_initializer (cp_parser* parser) { /* Look for the `=' token. */ - if (!cp_parser_require (parser, CPP_EQ, "%<=%>")) + if (!cp_parser_require (parser, CPP_EQ, RT_EQ)) return error_mark_node; /* It is invalid to write: @@ -16973,7 +17612,7 @@ cp_parser_constant_initializer (cp_parser* parser) /* Skip the initializer. */ cp_parser_skip_to_closing_brace (parser); /* Look for the trailing `}'. */ - cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); return error_mark_node; } @@ -17007,7 +17646,7 @@ cp_parser_base_clause (cp_parser* parser) tree bases = NULL_TREE; /* Look for the `:' that begins the list. */ - cp_parser_require (parser, CPP_COLON, "%<:%>"); + cp_parser_require (parser, CPP_COLON, RT_COLON); /* Scan the base-specifier-list. */ while (true) @@ -17205,26 +17844,61 @@ cp_parser_exception_specification_opt (cp_parser* parser) { cp_token *token; tree type_id_list; + const char *saved_message; /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); + + /* Is it a noexcept-specification? */ + if (cp_parser_is_keyword (token, RID_NOEXCEPT)) + { + tree expr; + cp_lexer_consume_token (parser->lexer); + + if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN) + { + cp_lexer_consume_token (parser->lexer); + + /* Types may not be defined in an exception-specification. */ + saved_message = parser->type_definition_forbidden_message; + parser->type_definition_forbidden_message + = G_("types may not be defined in an exception-specification"); + + expr = cp_parser_constant_expression (parser, false, NULL); + + /* Restore the saved message. */ + parser->type_definition_forbidden_message = saved_message; + + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + } + else + expr = boolean_true_node; + + return build_noexcept_spec (expr, tf_warning_or_error); + } + /* If it's not `throw', then there's no exception-specification. */ if (!cp_parser_is_keyword (token, RID_THROW)) return NULL_TREE; +#if 0 + /* Enable this once a lot of code has transitioned to noexcept? */ + if (cxx_dialect == cxx0x && !in_system_header) + warning (OPT_Wdeprecated, "dynamic exception specifications are " + "deprecated in C++0x; use %<noexcept%> instead."); +#endif + /* Consume the `throw'. */ cp_lexer_consume_token (parser->lexer); /* Look for the `('. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); /* If it's not a `)', then there is a type-id-list. */ if (token->type != CPP_CLOSE_PAREN) { - const char *saved_message; - /* Types may not be defined in an exception-specification. */ saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message @@ -17238,7 +17912,7 @@ cp_parser_exception_specification_opt (cp_parser* parser) type_id_list = empty_except_spec; /* Look for the `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); return type_id_list; } @@ -17297,7 +17971,7 @@ cp_parser_try_block (cp_parser* parser) { tree try_block; - cp_parser_require_keyword (parser, RID_TRY, "%<try%>"); + cp_parser_require_keyword (parser, RID_TRY, RT_TRY); try_block = begin_try_block (); cp_parser_compound_statement (parser, NULL, true); finish_try_block (try_block); @@ -17320,7 +17994,7 @@ cp_parser_function_try_block (cp_parser* parser) bool ctor_initializer_p; /* Look for the `try' keyword. */ - if (!cp_parser_require_keyword (parser, RID_TRY, "%<try%>")) + if (!cp_parser_require_keyword (parser, RID_TRY, RT_TRY)) return false; /* Let the rest of the front end know where we are. */ try_block = begin_function_try_block (&compound_stmt); @@ -17370,12 +18044,12 @@ cp_parser_handler (cp_parser* parser) tree handler; tree declaration; - cp_parser_require_keyword (parser, RID_CATCH, "%<catch%>"); + cp_parser_require_keyword (parser, RID_CATCH, RT_CATCH); handler = begin_handler (); - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); declaration = cp_parser_exception_declaration (parser); finish_handler_parms (declaration, handler); - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); cp_parser_compound_statement (parser, NULL, false); finish_handler (handler); } @@ -17446,7 +18120,7 @@ cp_parser_throw_expression (cp_parser* parser) tree expression; cp_token* token; - cp_parser_require_keyword (parser, RID_THROW, "%<throw%>"); + cp_parser_require_keyword (parser, RID_THROW, RT_THROW); token = cp_lexer_peek_token (parser->lexer); /* Figure out whether or not there is an assignment-expression following the "throw" keyword. */ @@ -17491,13 +18165,13 @@ cp_parser_asm_specification_opt (cp_parser* parser) /* Consume the `asm' token. */ cp_lexer_consume_token (parser->lexer); /* Look for the `('. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Look for the string-literal. */ asm_specification = cp_parser_string_literal (parser, false, false); /* Look for the `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); return asm_specification; } @@ -17541,7 +18215,7 @@ cp_parser_asm_operand_list (cp_parser* parser) name = build_string (IDENTIFIER_LENGTH (name), IDENTIFIER_POINTER (name)); /* Look for the closing `]'. */ - cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"); + cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); } else name = NULL_TREE; @@ -17549,11 +18223,11 @@ cp_parser_asm_operand_list (cp_parser* parser) string_literal = cp_parser_string_literal (parser, false, false); /* Look for the `('. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Parse the expression. */ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL); /* Look for the `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); if (name == error_mark_node || string_literal == error_mark_node @@ -17680,8 +18354,8 @@ cp_parser_attributes_opt (cp_parser* parser) /* Consume the `__attribute__' keyword. */ cp_lexer_consume_token (parser->lexer); /* Look for the two `(' tokens. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); @@ -17694,8 +18368,8 @@ cp_parser_attributes_opt (cp_parser* parser) attribute_list = NULL; /* Look for the two `)' tokens. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Add these new attributes to the list. */ attributes = chainon (attributes, attribute_list); @@ -17761,8 +18435,10 @@ cp_parser_attribute_list (cp_parser* parser) if (token->type == CPP_OPEN_PAREN) { VEC(tree,gc) *vec; + int attr_flag = (attribute_takes_identifier_p (identifier) + ? id_attr : normal_attr); vec = cp_parser_parenthesized_expression_list - (parser, true, /*cast_p=*/false, + (parser, attr_flag, /*cast_p=*/false, /*allow_expansion_p=*/false, /*non_constant_p=*/NULL); if (vec == NULL) @@ -17838,7 +18514,7 @@ static void cp_parser_label_declaration (cp_parser* parser) { /* Look for the `__label__' keyword. */ - cp_parser_require_keyword (parser, RID_LABEL, "%<__label__%>"); + cp_parser_require_keyword (parser, RID_LABEL, RT_LABEL); while (true) { @@ -17855,11 +18531,11 @@ cp_parser_label_declaration (cp_parser* parser) if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) break; /* Look for the `,' separating the label declarations. */ - cp_parser_require (parser, CPP_COMMA, "%<,%>"); + cp_parser_require (parser, CPP_COMMA, RT_COMMA); } /* Look for the final `;'. */ - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); } /* Support Functions */ @@ -17999,6 +18675,14 @@ cp_parser_lookup_name (cp_parser *parser, tree name, if (dependent_p) pushed_scope = push_scope (parser->scope); + /* If the PARSER->SCOPE is a template specialization, it + may be instantiated during name lookup. In that case, + errors may be issued. Even if we rollback the current + tentative parse, those errors are valid. */ + decl = lookup_qualified_name (parser->scope, name, + tag_type != none_type, + /*complain=*/true); + /* 3.4.3.1: In a lookup in which the constructor is an acceptable lookup result and the nested-name-specifier nominates a class C: * if the name specified after the nested-name-specifier, when @@ -18014,17 +18698,11 @@ cp_parser_lookup_name (cp_parser *parser, tree name, shall be used only in the declarator-id of a declaration that names a constructor or in a using-declaration. */ if (tag_type == none_type - && CLASS_TYPE_P (parser->scope) - && constructor_name_p (name, parser->scope)) - name = ctor_identifier; - - /* If the PARSER->SCOPE is a template specialization, it - may be instantiated during name lookup. In that case, - errors may be issued. Even if we rollback the current - tentative parse, those errors are valid. */ - decl = lookup_qualified_name (parser->scope, name, - tag_type != none_type, - /*complain=*/true); + && DECL_SELF_REFERENCE_P (decl) + && same_type_p (DECL_CONTEXT (decl), parser->scope)) + decl = lookup_qualified_name (parser->scope, ctor_identifier, + tag_type != none_type, + /*complain=*/true); /* If we have a single function from a using decl, pull it out. */ if (TREE_CODE (decl) == OVERLOAD @@ -18456,7 +19134,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p) takes one parameter (of type `int') and returns a value of type `S'. */ if (constructor_p - && !cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + && !cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) constructor_p = false; if (constructor_p @@ -18674,11 +19352,11 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) /* Look for the `template' keyword. */ token = cp_lexer_peek_token (parser->lexer); - if (!cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>")) + if (!cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE)) return; /* And the `<'. */ - if (!cp_parser_require (parser, CPP_LESS, "%<<%>")) + if (!cp_parser_require (parser, CPP_LESS, RT_LESS)) return; if (at_class_scope_p () && current_function_decl) { @@ -18784,9 +19462,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) if (member_p && decl && (TREE_CODE (decl) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (decl))) - TREE_VALUE (parser->unparsed_functions_queues) - = tree_cons (NULL_TREE, decl, - TREE_VALUE (parser->unparsed_functions_queues)); + VEC_safe_push (tree, gc, unparsed_funs_with_definitions, decl); } /* Perform the deferred access checks from a template-parameter-list. @@ -18927,7 +19603,7 @@ cp_parser_single_declaration (cp_parser* parser, /* Look for a trailing `;' after the declaration. */ if (!function_definition_p && (decl == error_mark_node - || !cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"))) + || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))) cp_parser_skip_to_end_of_block_or_statement (parser); return decl; @@ -18964,7 +19640,7 @@ cp_parser_functional_cast (cp_parser* parser, tree type) } - vec = cp_parser_parenthesized_expression_list (parser, false, + vec = cp_parser_parenthesized_expression_list (parser, non_attr, /*cast_p=*/true, /*allow_expansion_p=*/true, /*non_constant_p=*/NULL); @@ -18984,8 +19660,8 @@ cp_parser_functional_cast (cp_parser* parser, tree type) type = TREE_TYPE (type); if (cast != error_mark_node && !cast_valid_in_integral_constant_expression_p (type) - && (cp_parser_non_integral_constant_expression - (parser, "a call to a constructor"))) + && cp_parser_non_integral_constant_expression (parser, + NIC_CONSTRUCTOR)) return error_mark_node; return cast; } @@ -19056,9 +19732,7 @@ cp_parser_save_member_function_body (cp_parser* parser, DECL_INITIALIZED_IN_CLASS_P (fn) = 1; /* Add FN to the queue of functions to be parsed later. */ - TREE_VALUE (parser->unparsed_functions_queues) - = tree_cons (NULL_TREE, fn, - TREE_VALUE (parser->unparsed_functions_queues)); + VEC_safe_push (tree, gc, unparsed_funs_with_definitions, fn); return fn; } @@ -19189,8 +19863,7 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function) classes. We want to handle them right away, but we don't want them getting mixed up with functions that are currently in the queue. */ - parser->unparsed_functions_queues - = tree_cons (NULL_TREE, NULL_TREE, parser->unparsed_functions_queues); + push_unparsed_function_queues (parser); /* Make sure that any template parameters are in scope. */ maybe_begin_member_template_processing (member_function); @@ -19242,8 +19915,7 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function) maybe_end_member_template_processing (); /* Restore the queue. */ - parser->unparsed_functions_queues - = TREE_CHAIN (parser->unparsed_functions_queues); + pop_unparsed_function_queues (parser); } /* If DECL contains any default args, remember it on the unparsed @@ -19259,9 +19931,11 @@ cp_parser_save_default_args (cp_parser* parser, tree decl) probe = TREE_CHAIN (probe)) if (TREE_PURPOSE (probe)) { - TREE_PURPOSE (parser->unparsed_functions_queues) - = tree_cons (current_class_type, decl, - TREE_PURPOSE (parser->unparsed_functions_queues)); + cp_default_arg_entry *entry + = VEC_safe_push (cp_default_arg_entry, gc, + unparsed_funs_with_default_args, NULL); + entry->class_type = current_class_type; + entry->decl = decl; break; } } @@ -19281,8 +19955,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) statement expression extension) encounter more classes. We want to handle them right away, but we don't want them getting mixed up with default args that are currently in the queue. */ - parser->unparsed_functions_queues - = tree_cons (NULL_TREE, NULL_TREE, parser->unparsed_functions_queues); + push_unparsed_function_queues (parser); /* Local variable names (and the `this' keyword) may not appear in a default argument. */ @@ -19293,7 +19966,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) parmdecl = DECL_ARGUMENTS (fn); parm && parm != void_list_node; parm = TREE_CHAIN (parm), - parmdecl = TREE_CHAIN (parmdecl)) + parmdecl = DECL_CHAIN (parmdecl)) { cp_token_cache *tokens; tree default_arg = TREE_PURPOSE (parm); @@ -19354,8 +20027,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) parser->local_variables_forbidden_p = saved_local_variables_forbidden_p; /* Restore the queue. */ - parser->unparsed_functions_queues - = TREE_CHAIN (parser->unparsed_functions_queues); + pop_unparsed_function_queues (parser); } /* Parse the operand of `sizeof' (or a similar operator). Returns @@ -19424,7 +20096,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword) type = cp_parser_type_id (parser); parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p; /* Now, look for the trailing `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* If all went well, then we're done. */ if (cp_parser_parse_definitely (parser)) { @@ -19597,6 +20269,171 @@ cp_parser_friend_p (const cp_decl_specifier_seq *decl_specifiers) return decl_specifiers->specs[(int) ds_friend] != 0; } +/* Issue an error message indicating that TOKEN_DESC was expected. + If KEYWORD is true, it indicated this function is called by + cp_parser_require_keword and the required token can only be + a indicated keyword. */ + +static void +cp_parser_required_error (cp_parser *parser, + required_token token_desc, + bool keyword) +{ + switch (token_desc) + { + case RT_NEW: + cp_parser_error (parser, "expected %<new%>"); + return; + case RT_DELETE: + cp_parser_error (parser, "expected %<delete%>"); + return; + case RT_RETURN: + cp_parser_error (parser, "expected %<return%>"); + return; + case RT_WHILE: + cp_parser_error (parser, "expected %<while%>"); + return; + case RT_EXTERN: + cp_parser_error (parser, "expected %<extern%>"); + return; + case RT_STATIC_ASSERT: + cp_parser_error (parser, "expected %<static_assert%>"); + return; + case RT_DECLTYPE: + cp_parser_error (parser, "expected %<decltype%>"); + return; + case RT_OPERATOR: + cp_parser_error (parser, "expected %<operator%>"); + return; + case RT_CLASS: + cp_parser_error (parser, "expected %<class%>"); + return; + case RT_TEMPLATE: + cp_parser_error (parser, "expected %<template%>"); + return; + case RT_NAMESPACE: + cp_parser_error (parser, "expected %<namespace%>"); + return; + case RT_USING: + cp_parser_error (parser, "expected %<using%>"); + return; + case RT_ASM: + cp_parser_error (parser, "expected %<asm%>"); + return; + case RT_TRY: + cp_parser_error (parser, "expected %<try%>"); + return; + case RT_CATCH: + cp_parser_error (parser, "expected %<catch%>"); + return; + case RT_THROW: + cp_parser_error (parser, "expected %<throw%>"); + return; + case RT_LABEL: + cp_parser_error (parser, "expected %<__label__%>"); + return; + case RT_AT_TRY: + cp_parser_error (parser, "expected %<@try%>"); + return; + case RT_AT_SYNCHRONIZED: + cp_parser_error (parser, "expected %<@synchronized%>"); + return; + case RT_AT_THROW: + cp_parser_error (parser, "expected %<@throw%>"); + return; + default: + break; + } + if (!keyword) + { + switch (token_desc) + { + case RT_SEMICOLON: + cp_parser_error (parser, "expected %<;%>"); + return; + case RT_OPEN_PAREN: + cp_parser_error (parser, "expected %<(%>"); + return; + case RT_CLOSE_BRACE: + cp_parser_error (parser, "expected %<}%>"); + return; + case RT_OPEN_BRACE: + cp_parser_error (parser, "expected %<{%>"); + return; + case RT_CLOSE_SQUARE: + cp_parser_error (parser, "expected %<]%>"); + return; + case RT_OPEN_SQUARE: + cp_parser_error (parser, "expected %<[%>"); + return; + case RT_COMMA: + cp_parser_error (parser, "expected %<,%>"); + return; + case RT_SCOPE: + cp_parser_error (parser, "expected %<::%>"); + return; + case RT_LESS: + cp_parser_error (parser, "expected %<<%>"); + return; + case RT_GREATER: + cp_parser_error (parser, "expected %<>%>"); + return; + case RT_EQ: + cp_parser_error (parser, "expected %<=%>"); + return; + case RT_ELLIPSIS: + cp_parser_error (parser, "expected %<...%>"); + return; + case RT_MULT: + cp_parser_error (parser, "expected %<*%>"); + return; + case RT_COMPL: + cp_parser_error (parser, "expected %<~%>"); + return; + case RT_COLON: + cp_parser_error (parser, "expected %<:%>"); + return; + case RT_COLON_SCOPE: + cp_parser_error (parser, "expected %<:%> or %<::%>"); + return; + case RT_CLOSE_PAREN: + cp_parser_error (parser, "expected %<)%>"); + return; + case RT_COMMA_CLOSE_PAREN: + cp_parser_error (parser, "expected %<,%> or %<)%>"); + return; + case RT_PRAGMA_EOL: + cp_parser_error (parser, "expected end of line"); + return; + case RT_NAME: + cp_parser_error (parser, "expected identifier"); + return; + case RT_SELECT: + cp_parser_error (parser, "expected selection-statement"); + return; + case RT_INTERATION: + cp_parser_error (parser, "expected iteration-statement"); + return; + case RT_JUMP: + cp_parser_error (parser, "expected jump-statement"); + return; + case RT_CLASS_KEY: + cp_parser_error (parser, "expected class-key"); + return; + case RT_CLASS_TYPENAME_TEMPLATE: + cp_parser_error (parser, + "expected %<class%>, %<typename%>, or %<template%>"); + return; + default: + gcc_unreachable (); + } + } + else + gcc_unreachable (); +} + + + /* If the next token is of the indicated TYPE, consume it. Otherwise, issue an error message indicating that TOKEN_DESC was expected. @@ -19606,7 +20443,7 @@ cp_parser_friend_p (const cp_decl_specifier_seq *decl_specifiers) static cp_token * cp_parser_require (cp_parser* parser, enum cpp_ttype type, - const char* token_desc) + required_token token_desc) { if (cp_lexer_next_token_is (parser->lexer, type)) return cp_lexer_consume_token (parser->lexer); @@ -19614,11 +20451,7 @@ cp_parser_require (cp_parser* parser, { /* Output the MESSAGE -- unless we're parsing tentatively. */ if (!cp_parser_simulate_error (parser)) - { - char *message = concat ("expected ", token_desc, NULL); - cp_parser_error (parser, message); - free (message); - } + cp_parser_required_error (parser, token_desc, /*keyword=*/false); return NULL; } } @@ -19636,7 +20469,7 @@ cp_parser_skip_to_end_of_template_parameter_list (cp_parser* parser) unsigned nesting_depth = 0; /* Are we ready, yet? If not, issue error message. */ - if (cp_parser_require (parser, CPP_GREATER, "%<>%>")) + if (cp_parser_require (parser, CPP_GREATER, RT_GREATER)) return; /* Skip tokens until the desired token is found. */ @@ -19713,20 +20546,13 @@ cp_parser_skip_to_end_of_template_parameter_list (cp_parser* parser) static cp_token * cp_parser_require_keyword (cp_parser* parser, enum rid keyword, - const char* token_desc) + required_token token_desc) { cp_token *token = cp_parser_require (parser, CPP_KEYWORD, token_desc); if (token && token->keyword != keyword) { - dyn_string_t error_msg; - - /* Format the error message. */ - error_msg = dyn_string_new (0); - dyn_string_append_cstr (error_msg, "expected "); - dyn_string_append_cstr (error_msg, token_desc); - cp_parser_error (parser, error_msg->s); - dyn_string_delete (error_msg); + cp_parser_required_error (parser, token_desc, /*keyword=*/true); return NULL; } @@ -19903,14 +20729,10 @@ cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser) checks = check_value->checks; if (checks) { - for (i = 0 ; - VEC_iterate (deferred_access_check, checks, i, chk) ; - ++i) - { - perform_or_defer_access_check (chk->binfo, - chk->decl, - chk->diag_decl); - } + FOR_EACH_VEC_ELT (deferred_access_check, checks, i, chk) + perform_or_defer_access_check (chk->binfo, + chk->decl, + chk->diag_decl); } /* Set the scope from the stored value. */ parser->scope = check_value->value; @@ -20157,7 +20979,7 @@ cp_parser_objc_message_expression (cp_parser* parser) cp_lexer_consume_token (parser->lexer); /* Eat '['. */ receiver = cp_parser_objc_message_receiver (parser); messageargs = cp_parser_objc_message_args (parser); - cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"); + cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); return objc_build_message_expr (build_tree_list (receiver, messageargs)); } @@ -20229,7 +21051,7 @@ cp_parser_objc_message_args (cp_parser* parser) return build_tree_list (selector, NULL_TREE); maybe_unary_selector_p = false; - cp_parser_require (parser, CPP_COLON, "%<:%>"); + cp_parser_require (parser, CPP_COLON, RT_COLON); arg = cp_parser_assignment_expression (parser, false, NULL); sel_args @@ -20271,10 +21093,10 @@ cp_parser_objc_encode_expression (cp_parser* parser) cp_token *token; cp_lexer_consume_token (parser->lexer); /* Eat '@encode'. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); token = cp_lexer_peek_token (parser->lexer); type = complete_type (cp_parser_type_id (parser)); - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); if (!type) { @@ -20294,9 +21116,9 @@ cp_parser_objc_defs_expression (cp_parser *parser) tree name; cp_lexer_consume_token (parser->lexer); /* Eat '@defs'. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); name = cp_parser_identifier (parser); - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); return objc_get_class_ivars (name); } @@ -20314,9 +21136,9 @@ cp_parser_objc_protocol_expression (cp_parser* parser) tree proto; cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); proto = cp_parser_identifier (parser); - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); return objc_build_protocol_expr (proto); } @@ -20345,7 +21167,7 @@ cp_parser_objc_selector_expression (cp_parser* parser) location_t loc = cp_lexer_peek_token (parser->lexer)->location; cp_lexer_consume_token (parser->lexer); /* Eat '@selector'. */ - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); token = cp_lexer_peek_token (parser->lexer); while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON @@ -20392,7 +21214,7 @@ cp_parser_objc_selector_expression (cp_parser* parser) } finish_selector: - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); return objc_build_selector_expr (loc, sel_seq); } @@ -20478,7 +21300,7 @@ cp_parser_objc_protocol_refs_opt (cp_parser* parser) { cp_lexer_consume_token (parser->lexer); /* Eat '<'. */ protorefs = cp_parser_objc_identifier_list (parser); - cp_parser_require (parser, CPP_GREATER, "%<>%>"); + cp_parser_require (parser, CPP_GREATER, RT_GREATER); } return protorefs; @@ -20567,7 +21389,7 @@ cp_parser_objc_typename (cp_parser* parser) if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) cp_type = cp_parser_type_id (parser); - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); type_name = build_tree_list (proto_quals, cp_type); } @@ -20639,7 +21461,7 @@ cp_parser_objc_method_keyword_params (cp_parser* parser) return selector; maybe_unary_selector_p = false; - cp_parser_require (parser, CPP_COLON, "%<:%>"); + cp_parser_require (parser, CPP_COLON, RT_COLON); type_name = cp_parser_objc_typename (parser); identifier = cp_parser_identifier (parser); @@ -20969,7 +21791,7 @@ cp_parser_objc_superclass_or_category (cp_parser *parser, tree *super, { cp_lexer_consume_token (parser->lexer); /* Eat '('. */ *categ = cp_parser_identifier (parser); - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); } } @@ -21090,7 +21912,7 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser) { location_t location; tree stmt; - cp_parser_require_keyword (parser, RID_AT_TRY, "%<@try%>"); + cp_parser_require_keyword (parser, RID_AT_TRY, RT_AT_TRY); location = cp_lexer_peek_token (parser->lexer)->location; /* NB: The @try block needs to be wrapped in its own STATEMENT_LIST node, lest it get absorbed into the surrounding block. */ @@ -21104,13 +21926,13 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser) { tree parm; cp_lexer_consume_token (parser->lexer); - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); parmdecl = cp_parser_parameter_declaration (parser, false, NULL); parm = grokdeclarator (parmdecl->declarator, &parmdecl->decl_specifiers, PARM, /*initialized=*/0, /*attrlist=*/NULL); - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); objc_begin_catch_clause (parm); cp_parser_compound_statement (parser, NULL, false); objc_finish_catch_clause (); @@ -21142,12 +21964,12 @@ cp_parser_objc_synchronized_statement (cp_parser *parser) { location_t location; tree lock, stmt; - cp_parser_require_keyword (parser, RID_AT_SYNCHRONIZED, "%<@synchronized%>"); + cp_parser_require_keyword (parser, RID_AT_SYNCHRONIZED, RT_AT_SYNCHRONIZED); location = cp_lexer_peek_token (parser->lexer)->location; - cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); lock = cp_parser_expression (parser, false, NULL); - cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST node, lest it get absorbed into the surrounding block. */ @@ -21169,7 +21991,7 @@ cp_parser_objc_throw_statement (cp_parser *parser) { tree expr = NULL_TREE; location_t loc = cp_lexer_peek_token (parser->lexer)->location; - cp_parser_require_keyword (parser, RID_AT_THROW, "%<@throw%>"); + cp_parser_require_keyword (parser, RID_AT_THROW, RT_AT_THROW); if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) expr = cp_parser_assignment_expression (parser, false, NULL); @@ -21327,7 +22149,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, decl = cp_parser_lookup_name_simple (parser, name, token->location); if (decl == error_mark_node) - cp_parser_name_lookup_error (parser, name, decl, NULL, token->location); + cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, + token->location); else if (kind != 0) { tree u = build_omp_clause (token->location, kind); @@ -21344,7 +22167,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, cp_lexer_consume_token (parser->lexer); } - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) { int ending; @@ -21368,7 +22191,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, static tree cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list) { - if (cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return cp_parser_omp_var_list_no_open (parser, kind, list); return list; } @@ -21384,12 +22207,12 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list, location_t location HOST_WIDE_INT n; loc = cp_lexer_peek_token (parser->lexer)->location; - if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return list; num = cp_parser_constant_expression (parser, false, NULL); - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, /*or_comma=*/false, /*consume_paren=*/true); @@ -21423,7 +22246,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list, location_t location) enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED; tree c; - if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return list; if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { @@ -21456,7 +22279,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list, location_t location) cp_parser_error (parser, "expected %<none%> or %<shared%>"); } - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, /*or_comma=*/false, /*consume_paren=*/true); @@ -21480,13 +22303,13 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location) { tree t, c; - if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return list; t = cp_parser_condition (parser); if (t == error_mark_node - || !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, /*or_comma=*/false, /*consume_paren=*/true); @@ -21525,13 +22348,13 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list, { tree t, c; - if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return list; t = cp_parser_expression (parser, false, NULL); if (t == error_mark_node - || !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, /*or_comma=*/false, /*consume_paren=*/true); @@ -21575,7 +22398,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list) enum tree_code code; tree nlist, c; - if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return list; switch (cp_lexer_peek_token (parser->lexer)->type) @@ -21615,7 +22438,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list) } cp_lexer_consume_token (parser->lexer); - if (!cp_parser_require (parser, CPP_COLON, "%<:%>")) + if (!cp_parser_require (parser, CPP_COLON, RT_COLON)) goto resync_fail; nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_REDUCTION, list); @@ -21637,7 +22460,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location { tree c, t; - if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return list; c = build_omp_clause (location, OMP_CLAUSE_SCHEDULE); @@ -21698,10 +22521,10 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location else OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t; - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) goto resync_fail; } - else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<,%> or %<)%>")) + else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN)) goto resync_fail; check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule", location); @@ -21934,6 +22757,32 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok) rhs = integer_one_node; break; + case COMPOUND_EXPR: + if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR + && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR + && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR + && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0) + && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND + (TREE_OPERAND (lhs, 1), 0), 0))) + == BOOLEAN_TYPE) + /* Undo effects of boolean_increment for post {in,de}crement. */ + lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0); + /* FALLTHRU */ + case MODIFY_EXPR: + if (TREE_CODE (lhs) == MODIFY_EXPR + && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE) + { + /* Undo effects of boolean_increment. */ + if (integer_onep (TREE_OPERAND (lhs, 1))) + { + /* This is pre or post increment. */ + rhs = TREE_OPERAND (lhs, 1); + lhs = TREE_OPERAND (lhs, 0); + code = NOP_EXPR; + break; + } + } + /* FALLTHRU */ default: switch (cp_lexer_peek_token (parser->lexer)->type) { @@ -22011,7 +22860,7 @@ cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok) name = cp_parser_identifier (parser); if (name == error_mark_node - || !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, /*or_comma=*/false, /*consume_paren=*/true); @@ -22177,11 +23026,12 @@ static tree cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) { tree init, cond, incr, body, decl, pre_body = NULL_TREE, ret; - tree for_block = NULL_TREE, real_decl, initv, condv, incrv, declv; + tree real_decl, initv, condv, incrv, declv; tree this_pre_body, cl; location_t loc_first; bool collapse_err = false; int i, collapse = 1, nbraces = 0; + VEC(tree,gc) *for_block = make_tree_vector (); for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl)) if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE) @@ -22209,7 +23059,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) } loc = cp_lexer_consume_token (parser->lexer)->location; - if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return NULL; init = decl = real_decl = NULL; @@ -22269,7 +23119,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) "OpenMP %<for%> loop"); else /* Trigger an error. */ - cp_parser_require (parser, CPP_EQ, "%<=%>"); + cp_parser_require (parser, CPP_EQ, RT_EQ); init = error_mark_node; cp_parser_skip_to_end_of_statement (parser); @@ -22300,8 +23150,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) LOOKUP_ONLYCONVERTING); if (CLASS_TYPE_P (TREE_TYPE (decl))) { - for_block - = tree_cons (NULL, this_pre_body, for_block); + VEC_safe_push (tree, gc, for_block, this_pre_body); init = NULL_TREE; } else @@ -22344,7 +23193,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) tree rhs; cp_parser_parse_definitely (parser); - cp_parser_require (parser, CPP_EQ, "%<=%>"); + cp_parser_require (parser, CPP_EQ, RT_EQ); rhs = cp_parser_assignment_expression (parser, false, NULL); finish_expr_stmt (build_x_modify_expr (decl, NOP_EXPR, rhs, @@ -22365,7 +23214,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) } } } - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); if (this_pre_body) { this_pre_body = pop_stmt_list (this_pre_body); @@ -22452,7 +23301,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) cond = NULL; if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) cond = cp_parser_omp_for_cond (parser, decl); - cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); incr = NULL; if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) @@ -22467,7 +23316,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) incr = cp_parser_expression (parser, false, NULL); } - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, /*or_comma=*/false, /*consume_paren=*/true); @@ -22555,11 +23404,9 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) } } - while (for_block) - { - add_stmt (pop_stmt_list (TREE_VALUE (for_block))); - for_block = TREE_CHAIN (for_block); - } + while (!VEC_empty (tree, for_block)) + add_stmt (pop_stmt_list (VEC_pop (tree, for_block))); + release_tree_vector (for_block); return ret; } @@ -22638,7 +23485,7 @@ cp_parser_omp_sections_scope (cp_parser *parser) bool error_suppress = false; cp_token *tok; - if (!cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>")) + if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE)) return NULL_TREE; stmt = push_stmt_list (); @@ -22693,7 +23540,7 @@ cp_parser_omp_sections_scope (cp_parser *parser) substmt = build1 (OMP_SECTION, void_type_node, substmt); add_stmt (substmt); } - cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); substmt = pop_stmt_list (stmt); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0bd55e1190c..5a90bdc6ead 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1,6 +1,6 @@ /* Handle parameterized types (templates) for GNU C++. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 + 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. Rewritten by Jason Merrill (jason@cygnus.com). @@ -30,20 +30,17 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" -#include "obstack.h" #include "tree.h" #include "intl.h" #include "pointer-set.h" #include "flags.h" -#include "c-common.h" #include "cp-tree.h" +#include "c-family/c-common.h" #include "cp-objcp-common.h" #include "tree-inline.h" #include "decl.h" #include "output.h" -#include "except.h" #include "toplev.h" -#include "rtl.h" #include "timevar.h" #include "tree-iterator.h" #include "vecprim.h" @@ -134,7 +131,7 @@ static int type_unification_real (tree, tree, tree, const tree *, unsigned int, int, unification_kind_t, int); static void note_template_header (int); static tree convert_nontype_argument_function (tree, tree); -static tree convert_nontype_argument (tree, tree); +static tree convert_nontype_argument (tree, tree, tsubst_flags_t); static tree convert_template_argument (tree, tree, tree, tsubst_flags_t, int, tree); static int for_each_template_parm (tree, tree_fn_t, void*, @@ -161,7 +158,7 @@ static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_parms (tree, tree, tsubst_flags_t); static void regenerate_decl_from_template (tree, tree); -static tree most_specialized_class (tree, tree); +static tree most_specialized_class (tree, tree, tsubst_flags_t); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); @@ -890,10 +887,10 @@ maybe_process_partial_specialization (tree type) slot = (spec_entry **) htab_find_slot (type_specializations, &elt, INSERT); - *slot = GGC_NEW (spec_entry); + *slot = ggc_alloc_spec_entry (); **slot = elt; } - else if (COMPLETE_TYPE_P (inst) || TYPE_BEING_DEFINED (inst)) + else if (COMPLETE_OR_OPEN_TYPE_P (inst)) /* But if we've had an implicit instantiation, that's a problem ([temp.expl.spec]/6). */ error ("specialization %qT after instantiation %qT", @@ -1403,7 +1400,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, if (!optimize_specialization_lookup_p (tmpl)) { gcc_assert (tmpl && args && spec); - *slot = GGC_NEW (spec_entry); + *slot = ggc_alloc_spec_entry (); **slot = elt; if (TREE_CODE (spec) == FUNCTION_DECL && DECL_NAMESPACE_SCOPE_P (spec) && PRIMARY_TEMPLATE_P (tmpl) @@ -1563,31 +1560,49 @@ iterative_hash_template_arg (tree arg, hashval_t val) val = iterative_hash_template_arg (TREE_TYPE (arg), val); return iterative_hash_template_arg (TYPE_DOMAIN (arg), val); + case LAMBDA_EXPR: + /* A lambda can't appear in a template arg, but don't crash on + erroneous input. */ + gcc_assert (seen_error ()); + return val; + + case CAST_EXPR: + case STATIC_CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case CONST_CAST_EXPR: + case DYNAMIC_CAST_EXPR: + case NEW_EXPR: + val = iterative_hash_template_arg (TREE_TYPE (arg), val); + /* Now hash operands as usual. */ + break; + default: - switch (tclass) - { - case tcc_type: - if (TYPE_CANONICAL (arg)) - return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)), - val); - else if (TREE_CODE (arg) == DECLTYPE_TYPE) - return iterative_hash_template_arg (DECLTYPE_TYPE_EXPR (arg), val); - /* Otherwise just compare the types during lookup. */ - return val; + break; + } - case tcc_declaration: - case tcc_constant: - return iterative_hash_expr (arg, val); + switch (tclass) + { + case tcc_type: + if (TYPE_CANONICAL (arg)) + return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)), + val); + else if (TREE_CODE (arg) == DECLTYPE_TYPE) + return iterative_hash_template_arg (DECLTYPE_TYPE_EXPR (arg), val); + /* Otherwise just compare the types during lookup. */ + return val; - default: - gcc_assert (IS_EXPR_CODE_CLASS (tclass)); - { - unsigned n = TREE_OPERAND_LENGTH (arg); - for (i = 0; i < n; ++i) - val = iterative_hash_template_arg (TREE_OPERAND (arg, i), val); - return val; - } - } + case tcc_declaration: + case tcc_constant: + return iterative_hash_expr (arg, val); + + default: + gcc_assert (IS_EXPR_CODE_CLASS (tclass)); + { + unsigned n = TREE_OPERAND_LENGTH (arg); + for (i = 0; i < n; ++i) + val = iterative_hash_template_arg (TREE_OPERAND (arg, i), val); + return val; + } } gcc_unreachable (); return 0; @@ -2550,7 +2565,7 @@ check_explicit_specialization (tree declarator, definition, not in the original declaration. */ DECL_ARGUMENTS (result) = DECL_ARGUMENTS (decl); for (parm = DECL_ARGUMENTS (result); parm; - parm = TREE_CHAIN (parm)) + parm = DECL_CHAIN (parm)) DECL_CONTEXT (parm) = result; } return register_specialization (tmpl, gen_tmpl, targs, @@ -3828,10 +3843,11 @@ process_partial_specialization (tree decl) tree inner_args = INNERMOST_TEMPLATE_ARGS (specargs); tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl); tree inner_parms; + tree inst; int nargs = TREE_VEC_LENGTH (inner_args); int ntparms; int i; - int did_error_intro = 0; + bool did_error_intro = false; struct template_parm_data tpd; struct template_parm_data tpd2; @@ -3871,10 +3887,10 @@ process_partial_specialization (tree decl) or some such would have been OK. */ tpd.level = TMPL_PARMS_DEPTH (current_template_parms); - tpd.parms = (int *) alloca (sizeof (int) * ntparms); + tpd.parms = XALLOCAVEC (int, ntparms); memset (tpd.parms, 0, sizeof (int) * ntparms); - tpd.arg_uses_template_parms = (int *) alloca (sizeof (int) * nargs); + tpd.arg_uses_template_parms = XALLOCAVEC (int, nargs); memset (tpd.arg_uses_template_parms, 0, sizeof (int) * nargs); for (i = 0; i < nargs; ++i) { @@ -3893,12 +3909,15 @@ process_partial_specialization (tree decl) if (!did_error_intro) { error ("template parameters not used in partial specialization:"); - did_error_intro = 1; + did_error_intro = true; } error (" %qD", TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); } + if (did_error_intro) + return error_mark_node; + /* [temp.class.spec] The argument list of the specialization shall not be identical to @@ -3986,12 +4005,11 @@ process_partial_specialization (tree decl) if (!tpd2.parms) { /* We haven't yet initialized TPD2. Do so now. */ - tpd2.arg_uses_template_parms - = (int *) alloca (sizeof (int) * nargs); + tpd2.arg_uses_template_parms = XALLOCAVEC (int, nargs); /* The number of parameters here is the number in the main template, which, as checked in the assertion above, is NARGS. */ - tpd2.parms = (int *) alloca (sizeof (int) * nargs); + tpd2.parms = XALLOCAVEC (int, nargs); tpd2.level = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl)); } @@ -4040,6 +4058,22 @@ process_partial_specialization (tree decl) = tree_cons (specargs, inner_parms, DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; + + for (inst = DECL_TEMPLATE_INSTANTIATIONS (maintmpl); inst; + inst = TREE_CHAIN (inst)) + { + tree inst_type = TREE_VALUE (inst); + if (COMPLETE_TYPE_P (inst_type) + && CLASSTYPE_IMPLICIT_INSTANTIATION (inst_type)) + { + tree spec = most_specialized_class (inst_type, maintmpl, tf_none); + if (spec && TREE_TYPE (spec) == type) + permerror (input_location, + "partial specialization of %qT after instantiation " + "of %qT", type, inst_type); + } + } + return decl; } @@ -4412,7 +4446,7 @@ push_template_decl_real (tree decl, bool is_friend) TREE_VALUE (argtype) = error_mark_node; } - arg = TREE_CHAIN (arg); + arg = DECL_CHAIN (arg); argtype = TREE_CHAIN (argtype); } @@ -4766,8 +4800,8 @@ redeclare_class_template (tree type, tree parms) /* Simplify EXPR if it is a non-dependent expression. Returns the (possibly simplified) expression. */ -tree -fold_non_dependent_expr (tree expr) +static tree +fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain) { if (expr == NULL_TREE) return NULL_TREE; @@ -4789,7 +4823,7 @@ fold_non_dependent_expr (tree expr) processing_template_decl = 0; expr = tsubst_copy_and_build (expr, /*args=*/NULL_TREE, - tf_error, + complain, /*in_decl=*/NULL_TREE, /*function_p=*/false, /*integral_constant_expression_p=*/true); @@ -4798,6 +4832,12 @@ fold_non_dependent_expr (tree expr) return expr; } +tree +fold_non_dependent_expr (tree expr) +{ + return fold_non_dependent_expr_sfinae (expr, tf_error); +} + /* EXPR is an expression which is used in a constant-expression context. For instance, it could be a VAR_DECL with a constant initializer. Extract the innermost constant expression. @@ -4875,6 +4915,36 @@ check_valid_ptrmem_cst_expr (tree type, tree expr) return false; } +/* Returns TRUE iff the address of OP is value-dependent. + + 14.6.2.4 [temp.dep.temp]: + A non-integral non-type template-argument is dependent if its type is + dependent or it has either of the following forms + qualified-id + & qualified-id + and contains a nested-name-specifier which specifies a class-name that + names a dependent type. + + We generalize this to just say that the address of a member of a + dependent class is value-dependent; the above doesn't cover the + address of a static data member named with an unqualified-id. */ + +static bool +has_value_dependent_address (tree op) +{ + /* We could use get_inner_reference here, but there's no need; + this is only relevant for template non-type arguments, which + can only be expressed as &id-expression. */ + if (DECL_P (op)) + { + tree ctx = CP_DECL_CONTEXT (op); + if (TYPE_P (ctx) && dependent_type_p (ctx)) + return true; + } + + return false; +} + /* Attempt to convert the non-type template parameter EXPR to the indicated TYPE. If the conversion is successful, return the converted value. If the conversion is unsuccessful, return @@ -4896,7 +4966,7 @@ check_valid_ptrmem_cst_expr (tree type, tree expr) hacks can go away after we fix the double coercion problem. */ static tree -convert_nontype_argument (tree type, tree expr) +convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { tree expr_type; @@ -4905,14 +4975,21 @@ convert_nontype_argument (tree type, tree expr) catch this later), but only to provide better diagnostic for this common user mistake. As suggested by DR 100, we do not mention linkage issues in the diagnostic as this is not the point. */ + /* FIXME we're making this OK. */ if (TREE_CODE (expr) == STRING_CST) { - error ("%qE is not a valid template argument for type %qT " - "because string literals can never be used in this context", - expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because string literals can never be used in this context", + expr, type); return NULL_TREE; } + /* Add the ADDR_EXPR now for the benefit of + value_dependent_expression_p. */ + if (TYPE_PTROBV_P (type)) + expr = decay_conversion (expr); + /* If we are in a template, EXPR may be non-dependent, but still have a syntactic, rather than semantic, form. For example, EXPR might be a SCOPE_REF, rather than the VAR_DECL to which the @@ -4920,10 +4997,18 @@ convert_nontype_argument (tree type, tree expr) so that access checking can be performed when the template is instantiated -- but here we need the resolved form so that we can convert the argument. */ - expr = fold_non_dependent_expr (expr); + if (TYPE_REF_OBJ_P (type) + && has_value_dependent_address (expr)) + /* If we want the address and it's value-dependent, don't fold. */; + else if (!type_unknown_p (expr)) + expr = fold_non_dependent_expr_sfinae (expr, complain); if (error_operand_p (expr)) return error_mark_node; expr_type = TREE_TYPE (expr); + if (TREE_CODE (type) == REFERENCE_TYPE) + expr = mark_lvalue_use (expr); + else + expr = mark_rvalue_use (expr); /* HACK: Due to double coercion, we can get a NOP_EXPR<REFERENCE_TYPE>(ADDR_EXPR<POINTER_TYPE> (arg)) here, @@ -4984,15 +5069,16 @@ convert_nontype_argument (tree type, tree expr) do not fold into integer constants. */ if (TREE_CODE (expr) != INTEGER_CST) { - error ("%qE is not a valid template argument for type %qT " - "because it is a non-constant expression", expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because it is a non-constant expression", expr, type); return NULL_TREE; } /* At this point, an implicit conversion does what we want, because we already know that the expression is of integral type. */ - expr = ocp_convert (type, expr, CONV_IMPLICIT, LOOKUP_PROTECT); + expr = perform_implicit_conversion (type, expr, complain); if (expr == error_mark_node) return error_mark_node; @@ -5242,7 +5328,8 @@ convert_nontype_argument (tree type, tree expr) /* Sanity check: did we actually convert the argument to the right type? */ - gcc_assert (same_type_p (type, TREE_TYPE (expr))); + gcc_assert (same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (expr))); return expr; } @@ -5707,7 +5794,7 @@ convert_template_argument (tree parm, conversions can occur is part of determining which function template to call, or whether a given explicit argument specification is valid. */ - val = convert_nontype_argument (t, orig_arg); + val = convert_nontype_argument (t, orig_arg, complain); else val = orig_arg; @@ -5914,15 +6001,15 @@ coerce_template_parms (tree parms, { if (complain & tf_error) { - const char *or_more = ""; if (variadic_p) { - or_more = " or more"; --nparms; + error ("wrong number of template arguments " + "(%d, should be %d or more)", nargs, nparms); } - - error ("wrong number of template arguments (%d, should be %d%s)", - nargs, nparms, or_more); + else + error ("wrong number of template arguments " + "(%d, should be %d)", nargs, nparms); if (in_decl) error ("provided for %q+D", in_decl); @@ -6147,7 +6234,7 @@ add_pending_template (tree d) if (level) push_tinst_level (d); - pt = GGC_NEW (struct pending_template); + pt = ggc_alloc_pending_template (); pt->next = NULL; pt->tinst = current_tinst_level; if (last_pending_template) @@ -6463,11 +6550,16 @@ lookup_template_class (tree d1, i > 0 && t != NULL_TREE; --i, t = TREE_CHAIN (t)) { - tree a = coerce_template_parms (TREE_VALUE (t), - arglist, gen_tmpl, - complain, - /*require_all_args=*/true, - /*use_default_args=*/true); + tree a; + if (i == saved_depth) + a = coerce_template_parms (TREE_VALUE (t), + arglist, gen_tmpl, + complain, + /*require_all_args=*/true, + /*use_default_args=*/true); + else + /* Outer levels should have already been coerced. */ + a = TMPL_ARGS_LEVEL (arglist, i); /* Don't process further if one of the levels fails. */ if (a == error_mark_node) @@ -6710,7 +6802,7 @@ lookup_template_class (tree d1, elt.spec = t; slot = (spec_entry **) htab_find_slot_with_hash (type_specializations, &elt, hash, INSERT); - *slot = GGC_NEW (spec_entry); + *slot = ggc_alloc_spec_entry (); **slot = elt; /* Note this use of the partial instantiation so we can check it @@ -7068,7 +7160,7 @@ push_tinst_level (tree d) return 0; } - new_level = GGC_NEW (struct tinst_level); + new_level = ggc_alloc_tinst_level (); new_level->decl = d; new_level->locus = input_location; new_level->in_system_header_p = in_system_header; @@ -7231,7 +7323,7 @@ tsubst_friend_function (tree decl, tree args) later if we need it. */ if (TREE_CODE (new_friend) != TEMPLATE_DECL) { - SET_DECL_RTL (new_friend, NULL_RTX); + SET_DECL_RTL (new_friend, NULL); SET_DECL_ASSEMBLER_NAME (new_friend, NULL_TREE); } @@ -7330,11 +7422,18 @@ tsubst_friend_function (tree decl, tree args) DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info; if (TREE_CODE (old_decl) != TEMPLATE_DECL) - /* We should have called reregister_specialization in - duplicate_decls. */ - gcc_assert (retrieve_specialization (new_template, - new_args, 0) - == old_decl); + { + /* We should have called reregister_specialization in + duplicate_decls. */ + gcc_assert (retrieve_specialization (new_template, + new_args, 0) + == old_decl); + + /* Instantiate it if the global has already been used. */ + if (DECL_ODR_USED (old_decl)) + instantiate_decl (old_decl, /*defer_ok=*/true, + /*expl_inst_class_mem_p=*/false); + } else { tree t; @@ -7646,11 +7745,9 @@ perform_typedefs_access_check (tree tmpl, tree targs) return; saved_location = input_location; - for (i = 0; - VEC_iterate (qualified_typedef_usage_t, + FOR_EACH_VEC_ELT (qualified_typedef_usage_t, get_types_needing_access_check (tmpl), - i, iter); - ++i) + i, iter) { tree type_decl = iter->typedef_decl; tree type_scope = iter->context; @@ -7684,8 +7781,7 @@ instantiate_class_template (tree type) if (type == error_mark_node) return error_mark_node; - if (TYPE_BEING_DEFINED (type) - || COMPLETE_TYPE_P (type) + if (COMPLETE_OR_OPEN_TYPE_P (type) || uses_template_parms (type)) return type; @@ -7695,7 +7791,7 @@ instantiate_class_template (tree type) /* Determine what specialization of the original template to instantiate. */ - t = most_specialized_class (type, templ); + t = most_specialized_class (type, templ, tf_warning_or_error); if (t == error_mark_node) { TYPE_BEING_DEFINED (type) = 1; @@ -7749,16 +7845,17 @@ instantiate_class_template (tree type) /* Set the input location to the most specialized template definition. This is needed if tsubsting causes an error. */ typedecl = TYPE_MAIN_DECL (pattern); - input_location = DECL_SOURCE_LOCATION (typedecl); + input_location = DECL_SOURCE_LOCATION (TYPE_NAME (type)) = + DECL_SOURCE_LOCATION (typedecl); TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern); TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern); TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern); TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern); - TYPE_HAS_ASSIGN_REF (type) = TYPE_HAS_ASSIGN_REF (pattern); - TYPE_HAS_CONST_ASSIGN_REF (type) = TYPE_HAS_CONST_ASSIGN_REF (pattern); - TYPE_HAS_INIT_REF (type) = TYPE_HAS_INIT_REF (pattern); - TYPE_HAS_CONST_INIT_REF (type) = TYPE_HAS_CONST_INIT_REF (pattern); + TYPE_HAS_COPY_ASSIGN (type) = TYPE_HAS_COPY_ASSIGN (pattern); + TYPE_HAS_CONST_COPY_ASSIGN (type) = TYPE_HAS_CONST_COPY_ASSIGN (pattern); + TYPE_HAS_COPY_CTOR (type) = TYPE_HAS_COPY_CTOR (pattern); + TYPE_HAS_CONST_COPY_CTOR (type) = TYPE_HAS_CONST_COPY_CTOR (pattern); TYPE_HAS_DEFAULT_CONSTRUCTOR (type) = TYPE_HAS_DEFAULT_CONSTRUCTOR (pattern); TYPE_HAS_CONVERSION (type) = TYPE_HAS_CONVERSION (pattern); TYPE_PACKED (type) = TYPE_PACKED (pattern); @@ -7780,8 +7877,7 @@ instantiate_class_template (tree type) instantiate it, and that lookup should instantiate the enclosing class. */ gcc_assert (!DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (pattern)) - || COMPLETE_TYPE_P (TYPE_CONTEXT (type)) - || TYPE_BEING_DEFINED (TYPE_CONTEXT (type))); + || COMPLETE_OR_OPEN_TYPE_P (TYPE_CONTEXT (type))); base_list = NULL_TREE; if (BINFO_N_BASE_BINFOS (pbinfo)) @@ -8143,7 +8239,7 @@ instantiate_class_template (tree type) any member functions. We don't do this earlier because the default arguments may reference members of the class. */ if (!PRIMARY_TEMPLATE_P (templ)) - for (t = TYPE_METHODS (type); t; t = TREE_CHAIN (t)) + for (t = TYPE_METHODS (type); t; t = DECL_CHAIN (t)) if (TREE_CODE (t) == FUNCTION_DECL /* Implicitly generated member functions will not have template information; they are not instantiations, but instead are @@ -8184,9 +8280,12 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl) r = tsubst (t, args, complain, in_decl); else { + if (!(complain & tf_warning)) + ++c_inhibit_evaluation_warnings; r = tsubst_expr (t, args, complain, in_decl, /*integral_constant_expression_p=*/true); - r = fold_non_dependent_expr (r); + if (!(complain & tf_warning)) + --c_inhibit_evaluation_warnings; } return r; } @@ -8208,7 +8307,7 @@ make_fnparm_pack (tree spec_parm) /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ parmvec = make_tree_vec (len); parmtypevec = make_tree_vec (len); - for (i = 0; i < len; i++, spec_parm = TREE_CHAIN (spec_parm)) + for (i = 0; i < len; i++, spec_parm = DECL_CHAIN (spec_parm)) { TREE_VEC_ELT (parmvec, i) = spec_parm; TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm); @@ -8236,7 +8335,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, int i, len = -1; tree result; int incomplete = 0; - bool very_local_specializations = false; + htab_t saved_local_specializations = NULL; gcc_assert (PACK_EXPANSION_P (t)); pattern = PACK_EXPANSION_PATTERN (t); @@ -8254,13 +8353,15 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (TREE_CODE (parm_pack) == PARM_DECL) { - arg_pack = retrieve_local_specialization (parm_pack); - if (arg_pack == NULL_TREE) + if (!cp_unevaluated_operand) + arg_pack = retrieve_local_specialization (parm_pack); + else { - /* This can happen for a parameter name used later in a function - declaration (such as in a late-specified return type). Just - make a dummy decl, since it's only used for its type. */ - gcc_assert (cp_unevaluated_operand != 0); + /* We can't rely on local_specializations for a parameter + name used later in a function declaration (such as in a + late-specified return type). Even if it exists, it might + have the wrong value for a recursive call. Just make a + dummy decl, since it's only used for its type. */ arg_pack = tsubst_decl (parm_pack, args, complain); arg_pack = make_fnparm_pack (arg_pack); } @@ -8366,11 +8467,13 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (len < 0) return error_mark_node; - if (!local_specializations) + if (cp_unevaluated_operand) { - /* We're in a late-specified return type, so we don't have a local - specializations table. Create one for doing this expansion. */ - very_local_specializations = true; + /* We're in a late-specified return type, so create our own local + specializations table; the current table is either NULL or (in the + case of recursive unification) might have bindings that we don't + want to use or alter. */ + saved_local_specializations = local_specializations; local_specializations = htab_create (37, hash_local_specialization, eq_local_specializations, @@ -8461,10 +8564,10 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, } } - if (very_local_specializations) + if (saved_local_specializations) { htab_delete (local_specializations); - local_specializations = NULL; + local_specializations = saved_local_specializations; } return result; @@ -8484,7 +8587,7 @@ get_pattern_parm (tree parm, tree tmpl) if (DECL_ARTIFICIAL (parm)) { for (patparm = DECL_ARGUMENTS (pattern); - patparm; patparm = TREE_CHAIN (patparm)) + patparm; patparm = DECL_CHAIN (patparm)) if (DECL_ARTIFICIAL (patparm) && DECL_NAME (parm) == DECL_NAME (patparm)) break; @@ -8508,7 +8611,7 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) tree orig_t = t; int len = TREE_VEC_LENGTH (t); int need_new = 0, i, expanded_len_adjust = 0, out; - tree *elts = (tree *) alloca (len * sizeof (tree)); + tree *elts = XALLOCAVEC (tree, len); for (i = 0; i < len; i++) { @@ -8743,7 +8846,7 @@ tsubst_aggr_type (tree t, { r = lookup_template_class (t, argvec, in_decl, context, entering_scope, complain); - r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain); + r = cp_build_qualified_type_real (r, cp_type_quals (t), complain); } cp_unevaluated_operand = saved_unevaluated_operand; @@ -8879,7 +8982,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) RETURN (error_mark_node); r = copy_decl (t); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; TREE_TYPE (r) = new_type; DECL_TEMPLATE_RESULT (r) = build_decl (DECL_SOURCE_LOCATION (decl), @@ -8929,7 +9032,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) than the old one. */ r = copy_decl (t); gcc_assert (DECL_LANG_SPECIFIC (r) != 0); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; DECL_TEMPLATE_INFO (r) = build_template_info (t, args); @@ -9020,7 +9123,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) specialize R. */ gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t)); argvec = tsubst_template_args (DECL_TI_ARGS - (DECL_TEMPLATE_RESULT (gen_tmpl)), + (DECL_TEMPLATE_RESULT + (DECL_TI_TEMPLATE (t))), args, complain, in_decl); /* Check to see if we already have this specialization. */ @@ -9115,7 +9219,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) TREE_TYPE (r) = type; /* Clear out the mangled name and RTL for the instantiation. */ SET_DECL_ASSEMBLER_NAME (r, NULL_TREE); - SET_DECL_RTL (r, NULL_RTX); + SET_DECL_RTL (r, NULL); /* Leave DECL_INITIAL set on deleted instantiations. */ if (!DECL_DELETED_FN (r)) DECL_INITIAL (r) = NULL_TREE; @@ -9138,7 +9242,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) assigned to the instantiation. */ DECL_INTERFACE_KNOWN (r) = !TREE_PUBLIC (r); DECL_DEFER_OUTPUT (r) = 0; - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; DECL_PENDING_INLINE_INFO (r) = 0; DECL_PENDING_INLINE_P (r) = 0; DECL_SAVED_TREE (r) = NULL_TREE; @@ -9337,12 +9441,12 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /* Build a proper chain of parameters when substituting into a function parameter pack. */ if (prev_r) - TREE_CHAIN (prev_r) = r; + DECL_CHAIN (prev_r) = r; } - if (TREE_CHAIN (t)) - TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args, - complain, TREE_CHAIN (t)); + if (DECL_CHAIN (t)) + DECL_CHAIN (r) = tsubst (DECL_CHAIN (t), args, + complain, DECL_CHAIN (t)); /* FIRST_R contains the start of the chain we've built. */ r = first_r; @@ -9367,7 +9471,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /*integral_constant_expression_p=*/true); /* We don't have to set DECL_CONTEXT here; it is set by finish_member_declaration. */ - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; if (VOID_TYPE_P (type)) error ("instantiation of %q+D as type %qT", r, type); @@ -9394,7 +9498,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) else { r = copy_node (t); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; } break; @@ -9488,6 +9592,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) type = DECL_ORIGINAL_TYPE (t); else type = TREE_TYPE (t); + if (TREE_CODE (t) == VAR_DECL && VAR_HAD_UNKNOWN_BOUND (t)) + type = strip_array_domain (type); type = tsubst (type, args, complain, in_decl); } if (TREE_CODE (r) == VAR_DECL) @@ -9541,12 +9647,12 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /* Clear out the mangled name and RTL for the instantiation. */ SET_DECL_ASSEMBLER_NAME (r, NULL_TREE); if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL)) - SET_DECL_RTL (r, NULL_RTX); + SET_DECL_RTL (r, NULL); /* The initializer must not be expanded until it is required; see [temp.inst]. */ DECL_INITIAL (r) = NULL_TREE; if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL)) - SET_DECL_RTL (r, NULL_RTX); + SET_DECL_RTL (r, NULL); DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0; if (TREE_CODE (r) == VAR_DECL) { @@ -9592,7 +9698,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) else register_local_specialization (r, t); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), /*flags=*/0, @@ -9771,7 +9877,10 @@ tsubst_function_type (tree t, /* Construct a new type node and return it. */ if (TREE_CODE (t) == FUNCTION_TYPE) - fntype = build_function_type (return_type, arg_types); + { + fntype = build_function_type (return_type, arg_types); + fntype = apply_memfn_quals (fntype, type_memfn_quals (t)); + } else { tree r = TREE_TYPE (TREE_VALUE (arg_types)); @@ -9793,7 +9902,6 @@ tsubst_function_type (tree t, fntype = build_method_type_directly (r, return_type, TREE_CHAIN (arg_types)); } - fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain); fntype = cp_build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t)); return fntype; @@ -9814,7 +9922,15 @@ tsubst_exception_specification (tree fntype, specs = TYPE_RAISES_EXCEPTIONS (fntype); new_specs = NULL_TREE; - if (specs) + if (specs && TREE_PURPOSE (specs)) + { + /* A noexcept-specifier. */ + new_specs = tsubst_copy_and_build + (TREE_PURPOSE (specs), args, complain, in_decl, /*function_p=*/false, + /*integral_constant_expression_p=*/true); + new_specs = build_noexcept_spec (new_specs, complain); + } + else if (specs) { if (! TREE_VALUE (specs)) new_specs = specs; @@ -9888,6 +10004,7 @@ tsubst_exception_specification (tree fntype, tree tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { + enum tree_code code; tree type, r; if (t == NULL_TREE || t == error_mark_node @@ -9904,7 +10021,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (args == NULL_TREE) return t; - if (TREE_CODE (t) == IDENTIFIER_NODE) + code = TREE_CODE (t); + + if (code == IDENTIFIER_NODE) type = IDENTIFIER_TYPE_VALUE (t); else type = TREE_TYPE (t); @@ -9947,16 +10066,16 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } if (type - && TREE_CODE (t) != TYPENAME_TYPE - && TREE_CODE (t) != TEMPLATE_TYPE_PARM - && TREE_CODE (t) != IDENTIFIER_NODE - && TREE_CODE (t) != FUNCTION_TYPE - && TREE_CODE (t) != METHOD_TYPE) + && code != TYPENAME_TYPE + && code != TEMPLATE_TYPE_PARM + && code != IDENTIFIER_NODE + && code != FUNCTION_TYPE + && code != METHOD_TYPE) type = tsubst (type, args, complain, in_decl); if (type == error_mark_node) return error_mark_node; - switch (TREE_CODE (t)) + switch (code) { case RECORD_TYPE: case UNION_TYPE: @@ -9997,6 +10116,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) && !TREE_TYPE (max)) TREE_TYPE (max) = TREE_TYPE (TREE_OPERAND (max, 0)); + max = mark_rvalue_use (max); max = fold_decl_constant_value (max); /* If we're in a partial instantiation, preserve the magic NOP_EXPR @@ -10086,24 +10206,17 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) }; */ return t; - if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) + if (code == TEMPLATE_TYPE_PARM) { int quals; gcc_assert (TYPE_P (arg)); - /* cv-quals from the template are discarded when - substituting in a function or reference type. */ - if (TREE_CODE (arg) == FUNCTION_TYPE - || TREE_CODE (arg) == METHOD_TYPE - || TREE_CODE (arg) == REFERENCE_TYPE) - quals = cp_type_quals (arg); - else - quals = cp_type_quals (arg) | cp_type_quals (t); + quals = cp_type_quals (arg) | cp_type_quals (t); return cp_build_qualified_type_real (arg, quals, complain | tf_ignore_bad_quals); } - else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) + else if (code == BOUND_TEMPLATE_TEMPLATE_PARM) { /* We are processing a type constructed from a template template parameter. */ @@ -10126,11 +10239,11 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /*entering_scope=*/0, complain); return cp_build_qualified_type_real - (r, TYPE_QUALS (t), complain); + (r, cp_type_quals (t), complain); } else /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX. */ - return arg; + return unshare_expr (arg); } if (level == 1) @@ -10142,7 +10255,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* If we get here, we must have been looking at a parm for a more deeply nested template. Make a new version of this template parameter, but with a lower level. */ - switch (TREE_CODE (t)) + switch (code) { case TEMPLATE_TYPE_PARM: case TEMPLATE_TEMPLATE_PARM: @@ -10152,7 +10265,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl); r = cp_build_qualified_type_real (r, cp_type_quals (t), - complain | (TREE_CODE (t) == TEMPLATE_TYPE_PARM + complain | (code == TEMPLATE_TYPE_PARM ? tf_ignore_bad_quals : 0)); } else @@ -10180,7 +10293,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) else TYPE_CANONICAL (r) = canonical_type_parameter (r); - if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) + if (code == BOUND_TEMPLATE_TEMPLATE_PARM) { tree argvec = tsubst (TYPE_TI_ARGS (t), args, complain, in_decl); @@ -10251,14 +10364,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case POINTER_TYPE: case REFERENCE_TYPE: { - enum tree_code code; - if (type == TREE_TYPE (t) && TREE_CODE (type) != METHOD_TYPE) return t; - code = TREE_CODE (t); - - /* [temp.deduct] Type deduction may fail for any of the following @@ -10316,7 +10424,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) TYPE_REF_IS_RVALUE (t) && TYPE_REF_IS_RVALUE (type)); else r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t)); - r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain); + r = cp_build_qualified_type_real (r, cp_type_quals (t), complain); if (r != error_mark_node) /* Will this ever be needed for TYPE_..._TO values? */ @@ -10358,14 +10466,14 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* The type of the implicit object parameter gets its cv-qualifiers from the FUNCTION_TYPE. */ tree memptr; - tree method_type = build_memfn_type (type, r, cp_type_quals (type)); + tree method_type = build_memfn_type (type, r, type_memfn_quals (type)); memptr = build_ptrmemfunc_type (build_pointer_type (method_type)); return cp_build_qualified_type_real (memptr, cp_type_quals (t), complain); } else return cp_build_qualified_type_real (build_ptrmem_type (r, type), - TYPE_QUALS (t), + cp_type_quals (t), complain); } case FUNCTION_TYPE: @@ -10443,7 +10551,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) return error_mark_node; return fold_build2_loc (input_location, - TREE_CODE (t), TREE_TYPE (t), e1, e2); + code, TREE_TYPE (t), e1, e2); } case NEGATE_EXPR: @@ -10453,7 +10561,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (e == error_mark_node) return error_mark_node; - return fold_build1_loc (input_location, TREE_CODE (t), TREE_TYPE (t), e); + return fold_build1_loc (input_location, code, TREE_TYPE (t), e); } case TYPENAME_TYPE: @@ -10609,9 +10717,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TYPE_ARGUMENT_PACK: case NONTYPE_ARGUMENT_PACK: { - tree r = TYPE_P (t) - ? cxx_make_type (TREE_CODE (t)) - : make_node (TREE_CODE (t)); + tree r = TYPE_P (t) ? cxx_make_type (code) : make_node (code); tree packed_out = tsubst_template_args (ARGUMENT_PACK_ARGS (t), args, @@ -10621,7 +10727,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* For template nontype argument packs, also substitute into the type. */ - if (TREE_CODE (t) == NONTYPE_ARGUMENT_PACK) + if (code == NONTYPE_ARGUMENT_PACK) TREE_TYPE (r) = tsubst (TREE_TYPE (t), args, complain, in_decl); return r; @@ -10629,8 +10735,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) break; default: - sorry ("use of %qs in template", - tree_code_name [(int) TREE_CODE (t)]); + sorry ("use of %qs in template", tree_code_name [(int) code]); return error_mark_node; } } @@ -10674,6 +10779,8 @@ tsubst_baselink (tree baselink, tree object_type, if (IDENTIFIER_TYPENAME_P (name)) name = mangle_conv_op_name_for_type (optype); baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); + if (!baselink) + return error_mark_node; /* If lookup found a single function, mark it as used at this point. (If it lookup found multiple functions the one selected @@ -11249,8 +11356,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) gcc_unreachable (); case OFFSET_REF: - mark_used (TREE_OPERAND (t, 1)); - return t; + r = build2 + (code, tsubst (TREE_TYPE (t), args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl)); + PTRMEM_OK_P (r) = PTRMEM_OK_P (t); + mark_used (TREE_OPERAND (r, 1)); + return r; case EXPR_PACK_EXPANSION: error ("invalid use of pack expansion expression"); @@ -11602,14 +11714,19 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, tree t = RECUR (init); if (init && !t) - /* If we had an initializer but it - instantiated to nothing, - value-initialize the object. This will - only occur when the initializer was a - pack expansion where the parameter packs - used in that expansion were of length - zero. */ - init = build_value_init (TREE_TYPE (decl)); + { + /* If we had an initializer but it + instantiated to nothing, + value-initialize the object. This will + only occur when the initializer was a + pack expansion where the parameter packs + used in that expansion were of length + zero. */ + init = build_value_init (TREE_TYPE (decl), + complain); + if (TREE_CODE (init) == AGGR_INIT_EXPR) + init = get_target_expr (init); + } else init = t; } @@ -11626,7 +11743,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, case FOR_STMT: stmt = begin_for_stmt (); - RECUR (FOR_INIT_STMT (t)); + RECUR (FOR_INIT_STMT (t)); finish_for_init_stmt (stmt); tmp = RECUR (FOR_COND (t)); finish_for_cond (tmp, stmt); @@ -11636,6 +11753,20 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, finish_for_stmt (stmt); break; + case RANGE_FOR_STMT: + { + tree decl, expr; + stmt = begin_for_stmt (); + decl = RANGE_FOR_DECL (t); + decl = tsubst (decl, args, complain, in_decl); + maybe_push_decl (decl); + expr = RECUR (RANGE_FOR_EXPR (t)); + stmt = cp_convert_range_for (stmt, decl, expr); + RECUR (RANGE_FOR_BODY (t)); + finish_for_stmt (stmt); + } + break; + case WHILE_STMT: stmt = begin_while_stmt (); tmp = RECUR (WHILE_COND (t)); @@ -12228,6 +12359,17 @@ tsubst_copy_and_build (tree t, return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t), complain & tf_error); + case NOEXCEPT_EXPR: + op1 = TREE_OPERAND (t, 0); + ++cp_unevaluated_operand; + ++c_inhibit_evaluation_warnings; + op1 = tsubst_copy_and_build (op1, args, complain, in_decl, + /*function_p=*/false, + /*integral_constant_expression_p=*/false); + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; + return finish_noexcept_expr (op1, complain); + case MODOP_EXPR: { tree r = build_x_modify_expr @@ -12409,7 +12551,7 @@ tsubst_copy_and_build (tree t, into a non-dependent call. */ && type_dependent_expression_p_push (t) && !any_type_dependent_arguments_p (call_args)) - function = perform_koenig_lookup (function, call_args); + function = perform_koenig_lookup (function, call_args, false); if (TREE_CODE (function) == IDENTIFIER_NODE) { @@ -12426,15 +12568,24 @@ tsubst_copy_and_build (tree t, ret = build_offset_ref_call_from_tree (function, &call_args); else if (TREE_CODE (function) == COMPONENT_REF) { - if (!BASELINK_P (TREE_OPERAND (function, 1))) + tree instance = TREE_OPERAND (function, 0); + tree fn = TREE_OPERAND (function, 1); + + if (processing_template_decl + && (type_dependent_expression_p (instance) + || (!BASELINK_P (fn) + && TREE_CODE (fn) != FIELD_DECL) + || type_dependent_expression_p (fn) + || any_type_dependent_arguments_p (call_args))) + ret = build_nt_call_vec (function, call_args); + else if (!BASELINK_P (fn)) ret = finish_call_expr (function, &call_args, /*disallow_virtual=*/false, /*koenig_p=*/false, complain); else ret = (build_new_method_call - (TREE_OPERAND (function, 0), - TREE_OPERAND (function, 1), + (instance, fn, &call_args, NULL_TREE, qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL, /*fn_p=*/NULL, @@ -12674,7 +12825,7 @@ tsubst_copy_and_build (tree t, n = VEC_copy (constructor_elt, gc, CONSTRUCTOR_ELTS (t)); newlen = VEC_length (constructor_elt, n); - for (idx = 0; VEC_iterate (constructor_elt, n, idx, ce); idx++) + FOR_EACH_VEC_ELT (constructor_elt, n, idx, ce) { if (ce->index && process_index_p) ce->index = RECUR (ce->index); @@ -12708,8 +12859,7 @@ tsubst_copy_and_build (tree t, VEC(constructor_elt,gc) *old_n = n; n = VEC_alloc (constructor_elt, gc, newlen); - for (idx = 0; VEC_iterate (constructor_elt, old_n, idx, ce); - idx++) + FOR_EACH_VEC_ELT (constructor_elt, old_n, idx, ce) { if (TREE_CODE (ce->value) == TREE_VEC) { @@ -13047,7 +13197,7 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) instantiate all the alternate entry points as well. We do this by cloning the instantiation of the main entry point, not by instantiating the template clones. */ - if (TREE_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (TREE_CHAIN (gen_tmpl))) + if (DECL_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (DECL_CHAIN (gen_tmpl))) clone_function_decl (fndecl, /*update_method_vec_p=*/0); return fndecl; @@ -14084,9 +14234,9 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm) { /* Although a CVR qualifier is ignored when being applied to a substituted template parameter ([8.3.2]/1 for example), that - does not apply during deduction [14.8.2.4]/1, (even though - that is not explicitly mentioned, [14.8.2.4]/9 indicates - this). Except when we're allowing additional CV qualifiers + does not allow us to unify "const T" with "int&" because both + types are not of the form "cv-list T" [14.8.2.5 temp.deduct.type]. + It is ok when we're allowing additional CV qualifiers at the outer level [14.8.2.1]/3,1st bullet. */ if ((TREE_CODE (arg) == REFERENCE_TYPE || TREE_CODE (arg) == FUNCTION_TYPE @@ -14452,6 +14602,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt) { int elt_strict = strict; + + if (elt == error_mark_node) + return 1; + if (!BRACE_ENCLOSED_INITIALIZER_P (elt)) { tree type = TREE_TYPE (elt); @@ -15018,7 +15172,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) { tree method_type; tree fntype; - cp_cv_quals cv_quals; /* Check top-level cv qualifiers */ if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm)) @@ -15037,9 +15190,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) /* Extract the cv-qualifiers of the member function from the implicit object parameter and place them on the function type to be restored later. */ - cv_quals = - cp_type_quals(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (method_type)))); - fntype = build_qualified_type (fntype, cv_quals); + fntype = apply_memfn_quals (fntype, type_memfn_quals (method_type)); return unify (tparms, targs, TREE_TYPE (parm), fntype, strict); } @@ -15897,7 +16048,7 @@ most_general_template (tree decl) returned. */ static tree -most_specialized_class (tree type, tree tmpl) +most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain) { tree list = NULL_TREE; tree t; @@ -15925,12 +16076,13 @@ most_specialized_class (tree type, tree tmpl) tree parms = TREE_VALUE (t); partial_spec_args = CLASSTYPE_TI_ARGS (TREE_TYPE (t)); + + ++processing_template_decl; + if (outer_args) { int i; - ++processing_template_decl; - /* Discard the outer levels of args, and then substitute in the template args from the enclosing class. */ partial_spec_args = INNERMOST_TEMPLATE_ARGS (partial_spec_args); @@ -15947,7 +16099,6 @@ most_specialized_class (tree type, tree tmpl) TREE_VEC_ELT (parms, i) = tsubst (TREE_VEC_ELT (parms, i), outer_args, tf_none, NULL_TREE); - --processing_template_decl; } partial_spec_args = @@ -15958,6 +16109,8 @@ most_specialized_class (tree type, tree tmpl) /*require_all_args=*/true, /*use_default_args=*/true); + --processing_template_decl; + if (partial_spec_args == error_mark_node) return error_mark_node; @@ -16015,6 +16168,8 @@ most_specialized_class (tree type, tree tmpl) { const char *str; char *spaces = NULL; + if (!(complain & tf_error)) + return error_mark_node; error ("ambiguous class template instantiation for %q#T", type); str = TREE_CHAIN (list) ? _("candidates are:") : _("candidate is:"); for (t = list; t; t = TREE_CHAIN (t)) @@ -16313,12 +16468,12 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) interpretation is that it should be an explicit instantiation. */ if (! static_p) - for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp)) + for (tmp = TYPE_METHODS (t); tmp; tmp = DECL_CHAIN (tmp)) if (TREE_CODE (tmp) == FUNCTION_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) instantiate_class_member (tmp, extern_p); - for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp)) + for (tmp = TYPE_FIELDS (t); tmp; tmp = DECL_CHAIN (tmp)) if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) instantiate_class_member (tmp, extern_p); @@ -16406,8 +16561,8 @@ regenerate_decl_from_template (tree decl, tree tmpl) DECL_ATTRIBUTES (decl_parm) = attributes; cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0); } - decl_parm = TREE_CHAIN (decl_parm); - pattern_parm = TREE_CHAIN (pattern_parm); + decl_parm = DECL_CHAIN (decl_parm); + pattern_parm = DECL_CHAIN (pattern_parm); } /* Merge any parameters that match with the function parameter pack. */ @@ -16439,7 +16594,7 @@ regenerate_decl_from_template (tree decl, tree tmpl) DECL_ATTRIBUTES (decl_parm) = attributes; cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0); } - decl_parm = TREE_CHAIN (decl_parm); + decl_parm = DECL_CHAIN (decl_parm); } } /* Merge additional specifiers from the CODE_PATTERN. */ @@ -16448,10 +16603,15 @@ regenerate_decl_from_template (tree decl, tree tmpl) DECL_DECLARED_INLINE_P (decl) = 1; } else if (TREE_CODE (decl) == VAR_DECL) - DECL_INITIAL (decl) = - tsubst_expr (DECL_INITIAL (code_pattern), args, - tf_error, DECL_TI_TEMPLATE (decl), - /*integral_constant_expression_p=*/false); + { + DECL_INITIAL (decl) = + tsubst_expr (DECL_INITIAL (code_pattern), args, + tf_error, DECL_TI_TEMPLATE (decl), + /*integral_constant_expression_p=*/false); + if (VAR_HAD_UNKNOWN_BOUND (decl)) + TREE_TYPE (decl) = tsubst (TREE_TYPE (code_pattern), args, + tf_error, DECL_TI_TEMPLATE (decl)); + } else gcc_unreachable (); @@ -16791,7 +16951,7 @@ instantiate_decl (tree d, int defer_ok, /* Clear out DECL_RTL; whatever was there before may not be right since we've reset the type of the declaration. */ - SET_DECL_RTL (d, NULL_RTX); + SET_DECL_RTL (d, NULL); DECL_IN_AGGR_P (d) = 0; /* The initializer is placed in DECL_INITIAL by @@ -16844,8 +17004,8 @@ instantiate_decl (tree d, int defer_ok, while (tmpl_parm && !FUNCTION_PARAMETER_PACK_P (tmpl_parm)) { register_local_specialization (spec_parm, tmpl_parm); - tmpl_parm = TREE_CHAIN (tmpl_parm); - spec_parm = TREE_CHAIN (spec_parm); + tmpl_parm = DECL_CHAIN (tmpl_parm); + spec_parm = DECL_CHAIN (spec_parm); } if (tmpl_parm && FUNCTION_PARAMETER_PACK_P (tmpl_parm)) { @@ -16853,7 +17013,7 @@ instantiate_decl (tree d, int defer_ok, TMPL_PARM, then move on. */ tree argpack = make_fnparm_pack (spec_parm); register_local_specialization (argpack, tmpl_parm); - tmpl_parm = TREE_CHAIN (tmpl_parm); + tmpl_parm = DECL_CHAIN (tmpl_parm); spec_parm = NULL_TREE; } gcc_assert (!spec_parm); @@ -17149,7 +17309,8 @@ tsubst_enum (tree tag, tree newtag, tree args) set_current_access_from_decl (decl); /* Actually build the enumerator itself. */ - build_enumerator (DECL_NAME (decl), value, newtag); + build_enumerator + (DECL_NAME (decl), value, newtag, DECL_SOURCE_LOCATION (decl)); } finish_enum (newtag); @@ -17438,40 +17599,6 @@ dependent_scope_p (tree scope) && !currently_open_class (scope)); } -/* Returns TRUE if EXPRESSION is dependent, according to CRITERION. */ - -static bool -dependent_scope_ref_p (tree expression, bool criterion (tree)) -{ - tree scope; - tree name; - - gcc_assert (TREE_CODE (expression) == SCOPE_REF); - - if (!TYPE_P (TREE_OPERAND (expression, 0))) - return true; - - scope = TREE_OPERAND (expression, 0); - name = TREE_OPERAND (expression, 1); - - /* [temp.dep.expr] - - An id-expression is type-dependent if it contains a - nested-name-specifier that contains a class-name that names a - dependent type. */ - /* The suggested resolution to Core Issue 224 implies that if the - qualifying type is the current class, then we must peek - inside it. */ - if (DECL_P (name) - && currently_open_class (scope) - && !criterion (name)) - return false; - if (dependent_type_p (scope)) - return true; - - return false; -} - /* Returns TRUE if the EXPRESSION is value-dependent, in the sense of [temp.dep.constexpr]. EXPRESSION is already known to be a constant expression. */ @@ -17554,8 +17681,17 @@ value_dependent_expression_p (tree expression) return dependent_type_p (expression); return type_dependent_expression_p (expression); + case NOEXCEPT_EXPR: + expression = TREE_OPERAND (expression, 0); + /* FIXME why check value-dependency? */ + return (type_dependent_expression_p (expression) + || value_dependent_expression_p (expression)); + case SCOPE_REF: - return dependent_scope_ref_p (expression, value_dependent_expression_p); + { + tree name = TREE_OPERAND (expression, 1); + return value_dependent_expression_p (name); + } case COMPONENT_REF: return (value_dependent_expression_p (TREE_OPERAND (expression, 0)) @@ -17592,6 +17728,13 @@ value_dependent_expression_p (tree expression) return ((value_dependent_expression_p (TREE_OPERAND (expression, 0))) || (value_dependent_expression_p (TREE_OPERAND (expression, 2)))); + case ADDR_EXPR: + { + tree op = TREE_OPERAND (expression, 0); + return (value_dependent_expression_p (op) + || has_value_dependent_address (op)); + } + default: /* A constant expression is value-dependent if any subexpression is value-dependent. */ @@ -17655,6 +17798,7 @@ type_dependent_expression_p (tree expression) if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR || TREE_CODE (expression) == SIZEOF_EXPR || TREE_CODE (expression) == ALIGNOF_EXPR + || TREE_CODE (expression) == NOEXCEPT_EXPR || TREE_CODE (expression) == TRAIT_EXPR || TREE_CODE (expression) == TYPEID_EXPR || TREE_CODE (expression) == DELETE_EXPR @@ -17690,10 +17834,19 @@ type_dependent_expression_p (tree expression) return dependent_type_p (type); } - if (TREE_CODE (expression) == SCOPE_REF - && dependent_scope_ref_p (expression, - type_dependent_expression_p)) - return true; + if (TREE_CODE (expression) == SCOPE_REF) + { + tree scope = TREE_OPERAND (expression, 0); + tree name = TREE_OPERAND (expression, 1); + + /* 14.6.2.2 [temp.dep.expr]: An id-expression is type-dependent if it + contains an identifier associated by name lookup with one or more + declarations declared with a dependent type, or...a + nested-name-specifier or qualified-id that names a member of an + unknown specialization. */ + return (type_dependent_expression_p (name) + || dependent_scope_p (scope)); + } if (TREE_CODE (expression) == FUNCTION_DECL && DECL_LANG_SPECIFIC (expression) @@ -17722,6 +17875,15 @@ type_dependent_expression_p (tree expression) return false; } + /* A static data member of the current instantiation with incomplete + array type is type-dependent, as the definition and specializations + can have different bounds. */ + if (TREE_CODE (expression) == VAR_DECL + && DECL_CLASS_SCOPE_P (expression) + && dependent_type_p (DECL_CONTEXT (expression)) + && VAR_HAD_UNKNOWN_BOUND (expression)) + return true; + if (TREE_TYPE (expression) == unknown_type_node) { if (TREE_CODE (expression) == ADDR_EXPR) @@ -17787,7 +17949,7 @@ any_type_dependent_arguments_p (const VEC(tree,gc) *args) unsigned int i; tree arg; - for (i = 0; VEC_iterate (tree, args, i, arg); ++i) + FOR_EACH_VEC_ELT (tree, args, i, arg) { if (type_dependent_expression_p (arg)) return true; @@ -18223,7 +18385,7 @@ make_args_non_dependent (VEC(tree,gc) *args) unsigned int ix; tree arg; - for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix) + FOR_EACH_VEC_ELT (tree, args, ix, arg) { tree newarg = build_non_dependent_expr (arg); if (newarg != arg) @@ -18526,11 +18688,9 @@ append_type_to_template_for_access_check (tree templ, gcc_assert (type_decl && (TREE_CODE (type_decl) == TYPE_DECL)); /* Make sure we don't append the type to the template twice. */ - for (i = 0; - VEC_iterate (qualified_typedef_usage_t, + FOR_EACH_VEC_ELT (qualified_typedef_usage_t, get_types_needing_access_check (templ), - i, iter); - ++i) + i, iter) if (iter->typedef_decl == type_decl && scope == iter->context) return; @@ -18553,4 +18713,19 @@ init_template_processing (void) ggc_free); } +/* Print stats about the template hash tables for -fstats. */ + +void +print_template_statistics (void) +{ + fprintf (stderr, "decl_specializations: size %ld, %ld elements, " + "%f collisions\n", (long) htab_size (decl_specializations), + (long) htab_elements (decl_specializations), + htab_collisions (decl_specializations)); + fprintf (stderr, "type_specializations: size %ld, %ld elements, " + "%f collisions\n", (long) htab_size (type_specializations), + (long) htab_elements (type_specializations), + htab_collisions (type_specializations)); +} + #include "gt-cp-pt.h" diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c index a1fa71ffe22..ee3f52faf23 100644 --- a/gcc/cp/ptree.c +++ b/gcc/cp/ptree.c @@ -124,9 +124,9 @@ cxx_print_type (FILE *file, tree node, int indent) fputs (" X()", file); if (TYPE_HAS_CONVERSION (node)) fputs (" has-type-conversion", file); - if (TYPE_HAS_INIT_REF (node)) + if (TYPE_HAS_COPY_CTOR (node)) { - if (TYPE_HAS_CONST_INIT_REF (node)) + if (TYPE_HAS_CONST_COPY_CTOR (node)) fputs (" X(constX&)", file); else fputs (" X(X&)", file); @@ -139,7 +139,7 @@ cxx_print_type (FILE *file, tree node, int indent) fputs (" delete", file); if (TYPE_GETS_DELETE (node) & 2) fputs (" delete[]", file); - if (TYPE_HAS_ASSIGN_REF (node)) + if (TYPE_HAS_COPY_ASSIGN (node)) fputs (" this=(X&)", file); if (CLASSTYPE_SORTED_FIELDS (node)) fprintf (file, " sorted-fields %p", @@ -207,6 +207,15 @@ cxx_print_xnode (FILE *file, tree node, int indent) TEMPLATE_PARM_IDX (node), TEMPLATE_PARM_LEVEL (node), TEMPLATE_PARM_ORIG_LEVEL (node)); break; + case TEMPLATE_INFO: + print_node (file, "template", TI_TEMPLATE (node), indent+4); + print_node (file, "args", TI_ARGS (node), indent+4); + if (TI_PENDING_TEMPLATE_FLAG (node)) + { + indent_to (file, indent + 3); + fprintf (file, "pending_template"); + } + break; default: break; } diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c index aa970785ca3..22d58af0f84 100644 --- a/gcc/cp/repo.c +++ b/gcc/cp/repo.c @@ -1,6 +1,6 @@ /* Code to maintain a C++ template repository. Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008 Free Software Foundation, Inc. + 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Jason Merrill (jason@cygnus.com) This file is part of GCC. @@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "input.h" #include "obstack.h" #include "toplev.h" -#include "diagnostic.h" +#include "diagnostic-core.h" #include "flags.h" static const char *extract_string (const char **); @@ -43,7 +43,7 @@ static FILE *open_repo_file (const char *); static char *afgets (FILE *); static FILE *reopen_repo_file_for_write (void); -static GTY(()) tree pending_repo; +static GTY(()) VEC(tree,gc) *pending_repo; static char *repo_name; static const char *old_args, *old_dir, *old_main; @@ -236,14 +236,15 @@ reopen_repo_file_for_write (void) void finish_repo (void) { - tree t; + tree val; char *dir, *args; FILE *repo_file; + unsigned ix; if (!flag_use_repository || flag_compare_debug) return; - if (errorcount || sorrycount) + if (seen_error ()) return; repo_file = reopen_repo_file_for_write (); @@ -266,9 +267,8 @@ finish_repo (void) fprintf (repo_file, "\n"); } - for (t = pending_repo; t; t = TREE_CHAIN (t)) + FOR_EACH_VEC_ELT_REVERSE (tree, pending_repo, ix, val) { - tree val = TREE_VALUE (t); tree name = DECL_ASSEMBLER_NAME (val); char type = IDENTIFIER_REPO_CHOSEN (name) ? 'C' : 'O'; fprintf (repo_file, "%c %s\n", type, IDENTIFIER_POINTER (name)); @@ -352,7 +352,7 @@ repo_emit_p (tree decl) if (!DECL_REPO_AVAILABLE_P (decl)) { DECL_REPO_AVAILABLE_P (decl) = 1; - pending_repo = tree_cons (NULL_TREE, decl, pending_repo); + VEC_safe_push (tree, gc, pending_repo, decl); } return IDENTIFIER_REPO_CHOSEN (DECL_ASSEMBLER_NAME (decl)) ? 1 : ret; diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 0f7225fc542..c994683aae8 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -33,7 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "toplev.h" #include "convert.h" #include "target.h" -#include "c-pragma.h" +#include "c-family/c-pragma.h" /* C++ returns type information to the user in struct type_info objects. We also use type information to implement dynamic_cast and @@ -116,7 +116,7 @@ static tree tinfo_base_init (tinfo_s *, tree); static tree generic_initializer (tinfo_s *, tree); static tree ptr_initializer (tinfo_s *, tree); static tree ptm_initializer (tinfo_s *, tree); -static tree class_initializer (tinfo_s *, tree, tree); +static tree class_initializer (tinfo_s *, tree, unsigned, ...); static void create_pseudo_type_info (int, const char *, ...); static tree get_pseudo_ti_init (tree, unsigned); static unsigned get_pseudo_ti_index (tree); @@ -155,7 +155,7 @@ init_rtti_processing (void) /*tag_scope=*/ts_current, false); pop_namespace (); const_type_info_type_node - = build_qualified_type (type_info_type, TYPE_QUAL_CONST); + = cp_build_qualified_type (type_info_type, TYPE_QUAL_CONST); type_info_ptr_type = build_pointer_type (const_type_info_type_node); unemitted_tinfo_decls = VEC_alloc (tree, gc, 124); @@ -192,8 +192,8 @@ build_headof (tree exp) tf_warning_or_error), index); - type = build_qualified_type (ptr_type_node, - cp_type_quals (TREE_TYPE (exp))); + type = cp_build_qualified_type (ptr_type_node, + cp_type_quals (TREE_TYPE (exp))); return build2 (POINTER_PLUS_EXPR, type, exp, convert_to_integer (sizetype, offset)); } @@ -207,8 +207,8 @@ throw_bad_cast (void) { tree fn = get_identifier ("__cxa_bad_cast"); if (!get_global_value_if_present (fn, &fn)) - fn = push_throw_library_fn (fn, build_function_type (ptr_type_node, - void_list_node)); + fn = push_throw_library_fn (fn, build_function_type_list (ptr_type_node, + NULL_TREE)); return build_cxx_call (fn, 0, NULL); } @@ -225,7 +225,7 @@ throw_bad_typeid (void) tree t; t = build_reference_type (const_type_info_type_node); - t = build_function_type (t, void_list_node); + t = build_function_type_list (t, NULL_TREE); fn = push_throw_library_fn (fn, t); } @@ -255,7 +255,8 @@ get_tinfo_decl_dynamic (tree exp) type = TYPE_MAIN_VARIANT (type); /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */ - if (CLASS_TYPE_P (type) || TREE_CODE (type) == UNKNOWN_TYPE) + if (CLASS_TYPE_P (type) || type == unknown_type_node + || type == init_list_type_node) type = complete_type_or_else (type, exp); if (!type) @@ -318,7 +319,7 @@ typeid_ok_p (void) tree build_typeid (tree exp) { - tree cond = NULL_TREE; + tree cond = NULL_TREE, initial_expr = exp; int nonnull = 0; if (exp == error_mark_node || !typeid_ok_p ()) @@ -333,6 +334,9 @@ build_typeid (tree exp) && ! resolves_to_fixed_type_p (exp, &nonnull) && ! nonnull) { + /* So we need to look into the vtable of the type of exp. + This is an lvalue use of expr then. */ + exp = mark_lvalue_use (exp); exp = stabilize_reference (exp); cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0)); } @@ -348,6 +352,8 @@ build_typeid (tree exp) exp = build3 (COND_EXPR, TREE_TYPE (exp), cond, exp, bad); } + else + mark_type_use (initial_expr); return exp; } @@ -477,7 +483,8 @@ get_typeid (tree type) type = TYPE_MAIN_VARIANT (type); /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */ - if (CLASS_TYPE_P (type) || TREE_CODE (type) == UNKNOWN_TYPE) + if (CLASS_TYPE_P (type) || type == unknown_type_node + || type == init_list_type_node) type = complete_type_or_else (type, NULL_TREE); if (!type) @@ -546,6 +553,8 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) /* If T is a pointer type, v shall be an rvalue of a pointer to complete class type, and the result is an rvalue of type T. */ + expr = mark_rvalue_use (expr); + if (TREE_CODE (exprtype) != POINTER_TYPE) { errstr = _("source is not a pointer"); @@ -564,6 +573,8 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) } else { + expr = mark_lvalue_use (expr); + exprtype = build_reference_type (exprtype); /* T is a reference type, v shall be an lvalue of a complete class @@ -715,15 +726,13 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) /*tag_scope=*/ts_current, false); tinfo_ptr = build_pointer_type - (build_qualified_type + (cp_build_qualified_type (tinfo_ptr, TYPE_QUAL_CONST)); name = "__dynamic_cast"; - tmp = tree_cons - (NULL_TREE, const_ptr_type_node, tree_cons - (NULL_TREE, tinfo_ptr, tree_cons - (NULL_TREE, tinfo_ptr, tree_cons - (NULL_TREE, ptrdiff_type_node, void_list_node)))); - tmp = build_function_type (ptr_type_node, tmp); + tmp = build_function_type_list (ptr_type_node, + const_ptr_type_node, + tinfo_ptr, tinfo_ptr, + ptrdiff_type_node, NULL_TREE); dcast_fn = build_library_fn_ptr (name, tmp); DECL_PURE_P (dcast_fn) = 1; pop_abi_namespace (); @@ -851,16 +860,17 @@ involves_incomplete_p (tree type) static tree tinfo_base_init (tinfo_s *ti, tree target) { - tree init = NULL_TREE; + tree init; tree name_decl; tree vtable_ptr; + VEC(constructor_elt,gc) *v; { tree name_name, name_string; /* Generate the NTBS array variable. */ tree name_type = build_cplus_array_type - (build_qualified_type (char_type_node, TYPE_QUAL_CONST), + (cp_build_qualified_type (char_type_node, TYPE_QUAL_CONST), NULL_TREE); /* Determine the name of the variable -- and remember with which @@ -916,14 +926,13 @@ tinfo_base_init (tinfo_s *ti, tree target) ti->vtable = vtable_ptr; } - init = tree_cons (NULL_TREE, vtable_ptr, init); - - init = tree_cons (NULL_TREE, decay_conversion (name_decl), init); + v = VEC_alloc (constructor_elt, gc, 2); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, vtable_ptr); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, decay_conversion (name_decl)); - init = build_constructor_from_list (init_list_type_node, nreverse (init)); + init = build_constructor (init_list_type_node, v); TREE_CONSTANT (init) = 1; TREE_STATIC (init) = 1; - init = tree_cons (NULL_TREE, init, NULL_TREE); return init; } @@ -937,7 +946,7 @@ generic_initializer (tinfo_s *ti, tree target) { tree init = tinfo_base_init (ti, target); - init = build_constructor_from_list (init_list_type_node, init); + init = build_constructor_single (init_list_type_node, NULL_TREE, init); TREE_CONSTANT (init) = 1; TREE_STATIC (init) = 1; return init; @@ -954,15 +963,16 @@ ptr_initializer (tinfo_s *ti, tree target) tree to = TREE_TYPE (target); int flags = qualifier_flags (to); bool incomplete = target_incomplete_p (to); + VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, 3); if (incomplete) flags |= 8; - init = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), init); - init = tree_cons (NULL_TREE, - get_tinfo_ptr (TYPE_MAIN_VARIANT (to)), - init); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, flags)); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + get_tinfo_ptr (TYPE_MAIN_VARIANT (to))); - init = build_constructor_from_list (init_list_type_node, nreverse (init)); + init = build_constructor (init_list_type_node, v); TREE_CONSTANT (init) = 1; TREE_STATIC (init) = 1; return init; @@ -981,20 +991,19 @@ ptm_initializer (tinfo_s *ti, tree target) tree klass = TYPE_PTRMEM_CLASS_TYPE (target); int flags = qualifier_flags (to); bool incomplete = target_incomplete_p (to); + VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, 4); if (incomplete) flags |= 0x8; if (!COMPLETE_TYPE_P (klass)) flags |= 0x10; - init = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), init); - init = tree_cons (NULL_TREE, - get_tinfo_ptr (TYPE_MAIN_VARIANT (to)), - init); - init = tree_cons (NULL_TREE, - get_tinfo_ptr (klass), - init); - - init = build_constructor_from_list (init_list_type_node, nreverse (init)); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, flags)); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + get_tinfo_ptr (TYPE_MAIN_VARIANT (to))); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, get_tinfo_ptr (klass)); + + init = build_constructor (init_list_type_node, v); TREE_CONSTANT (init) = 1; TREE_STATIC (init) = 1; return init; @@ -1002,15 +1011,23 @@ ptm_initializer (tinfo_s *ti, tree target) /* Return the CONSTRUCTOR expr for a type_info of class TYPE. TI provides information about the particular __class_type_info derivation, - which adds hint flags and TRAIL initializers to the type_info base. */ + which adds hint flags and N extra initializers to the type_info base. */ static tree -class_initializer (tinfo_s *ti, tree target, tree trail) +class_initializer (tinfo_s *ti, tree target, unsigned n, ...) { tree init = tinfo_base_init (ti, target); + va_list extra_inits; + unsigned i; + VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, n+1); + + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init); + va_start (extra_inits, n); + for (i = 0; i < n; i++) + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, va_arg (extra_inits, tree)); + va_end (extra_inits); - TREE_CHAIN (init) = trail; - init = build_constructor_from_list (init_list_type_node, init); + init = build_constructor (init_list_type_node, v); TREE_CONSTANT (init) = 1; TREE_STATIC (init) = 1; return init; @@ -1037,6 +1054,11 @@ typeinfo_in_lib_p (tree type) case VOID_TYPE: return true; + case LANG_TYPE: + if (NULLPTR_TYPE_P (type)) + return true; + /* else fall through. */ + default: return false; } @@ -1066,17 +1088,16 @@ get_pseudo_ti_init (tree type, unsigned tk_index) return generic_initializer (ti, type); case TK_CLASS_TYPE: - return class_initializer (ti, type, NULL_TREE); + return class_initializer (ti, type, 0); case TK_SI_CLASS_TYPE: { tree base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), 0); tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo)); - tree base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE); /* get_tinfo_ptr might have reallocated the tinfo_descs vector. */ ti = VEC_index (tinfo_s, tinfo_descs, tk_index); - return class_initializer (ti, type, base_inits); + return class_initializer (ti, type, 1, tinfo); } default: @@ -1089,17 +1110,21 @@ get_pseudo_ti_init (tree type, unsigned tk_index) tree offset_type = integer_types[itk_long]; tree base_inits = NULL_TREE; int ix; + VEC(constructor_elt,gc) *init_vec = NULL; + constructor_elt *e; gcc_assert (tk_index >= TK_FIXED); + VEC_safe_grow (constructor_elt, gc, init_vec, nbases); /* Generate the base information initializer. */ for (ix = nbases; ix--;) { tree base_binfo = BINFO_BASE_BINFO (binfo, ix); - tree base_init = NULL_TREE; + tree base_init; int flags = 0; tree tinfo; tree offset; + VEC(constructor_elt,gc) *v; if (VEC_index (tree, base_accesses, ix) == access_public_node) flags |= 2; @@ -1122,25 +1147,22 @@ get_pseudo_ti_init (tree type, unsigned tk_index) offset = fold_build2_loc (input_location, BIT_IOR_EXPR, offset_type, offset, build_int_cst (offset_type, flags)); - base_init = tree_cons (NULL_TREE, offset, base_init); - base_init = tree_cons (NULL_TREE, tinfo, base_init); - base_init = build_constructor_from_list (init_list_type_node, base_init); - base_inits = tree_cons (NULL_TREE, base_init, base_inits); + v = VEC_alloc (constructor_elt, gc, 2); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tinfo); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, offset); + base_init = build_constructor (init_list_type_node, v); + e = VEC_index (constructor_elt, init_vec, ix); + e->index = NULL_TREE; + e->value = base_init; } - base_inits = build_constructor_from_list (init_list_type_node, base_inits); - base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE); - /* Prepend the number of bases. */ - base_inits = tree_cons (NULL_TREE, - build_int_cst (NULL_TREE, nbases), - base_inits); - /* Prepend the hint flags. */ - base_inits = tree_cons (NULL_TREE, - build_int_cst (NULL_TREE, hint), - base_inits); + base_inits = build_constructor (init_list_type_node, init_vec); /* get_tinfo_ptr might have reallocated the tinfo_descs vector. */ ti = VEC_index (tinfo_s, tinfo_descs, tk_index); - return class_initializer (ti, type, base_inits); + return class_initializer (ti, type, 3, + build_int_cst (NULL_TREE, hint), + build_int_cst (NULL_TREE, nbases), + base_inits); } } } @@ -1188,7 +1210,7 @@ create_pseudo_type_info (int tk, const char *real_name, ...) /* Now add the derived fields. */ while ((field_decl = va_arg (ap, tree))) { - TREE_CHAIN (field_decl) = fields; + DECL_CHAIN (field_decl) = fields; fields = field_decl; } @@ -1353,7 +1375,7 @@ create_tinfo_types (void) field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, const_string_type_node); - TREE_CHAIN (field) = fields; + DECL_CHAIN (field) = fields; fields = field; ti = VEC_index (tinfo_s, tinfo_descs, TK_TYPE_INFO_TYPE); @@ -1393,7 +1415,7 @@ create_tinfo_types (void) field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, integer_types[itk_long]); - TREE_CHAIN (field) = fields; + DECL_CHAIN (field) = fields; fields = field; ti = VEC_index (tinfo_s, tinfo_descs, TK_BASE_TYPE); @@ -1440,6 +1462,8 @@ create_tinfo_types (void) void emit_support_tinfos (void) { + /* Dummy static variable so we can put nullptr in the array; it will be + set before we actually start to walk the array. */ static tree *const fundamentals[] = { &void_type_node, @@ -1450,8 +1474,10 @@ emit_support_tinfos (void) &integer_type_node, &unsigned_type_node, &long_integer_type_node, &long_unsigned_type_node, &long_long_integer_type_node, &long_long_unsigned_type_node, + &int128_integer_type_node, &int128_unsigned_type_node, &float_type_node, &double_type_node, &long_double_type_node, &dfloat32_type_node, &dfloat64_type_node, &dfloat128_type_node, + &nullptr_type_node, 0 }; int ix; @@ -1474,10 +1500,12 @@ emit_support_tinfos (void) tree types[3]; int i; + if (bltn == NULL_TREE) + continue; types[0] = bltn; types[1] = build_pointer_type (bltn); - types[2] = build_pointer_type (build_qualified_type (bltn, - TYPE_QUAL_CONST)); + types[2] = build_pointer_type (cp_build_qualified_type (bltn, + TYPE_QUAL_CONST)); for (i = 0; i < 3; ++i) { diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 772ae3b1fbe..0249fb06d48 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -30,9 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "cp-tree.h" #include "intl.h" -#include "obstack.h" #include "flags.h" -#include "rtl.h" #include "output.h" #include "toplev.h" #include "target.h" @@ -172,7 +170,7 @@ accessible_base_p (tree t, tree base, bool consider_local_p) public typedef created in the scope of every class. */ decl = TYPE_FIELDS (base); while (!DECL_SELF_REFERENCE_P (decl)) - decl = TREE_CHAIN (decl); + decl = DECL_CHAIN (decl); while (ANON_AGGR_TYPE_P (t)) t = TYPE_CONTEXT (t); return accessible_p (t, decl, consider_local_p); @@ -218,8 +216,7 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr) /* If BASE is incomplete, it can't be a base of T--and instantiating it might cause an error. */ - if (t_binfo && CLASS_TYPE_P (base) - && (COMPLETE_TYPE_P (base) || TYPE_BEING_DEFINED (base))) + if (t_binfo && CLASS_TYPE_P (base) && COMPLETE_OR_OPEN_TYPE_P (base)) { struct lookup_base_data_s data; @@ -450,7 +447,7 @@ lookup_field_1 (tree type, tree name, bool want_type) #ifdef GATHER_STATISTICS n_calls_lookup_field_1++; #endif /* GATHER_STATISTICS */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { #ifdef GATHER_STATISTICS n_fields_searched++; @@ -973,6 +970,7 @@ shared_member_p (tree t) return 1; if (is_overloaded_fn (t)) { + t = get_fns (t); for (; t; t = OVL_NEXT (t)) { tree fn = OVL_CURRENT (t); @@ -1337,7 +1335,7 @@ lookup_conversion_operator (tree class_type, tree type) } /* TYPE is a class type. Return the index of the fields within - the method vector with name NAME, or -1 is no such field exists. */ + the method vector with name NAME, or -1 if no such field exists. */ int lookup_fnfields_1 (tree type, tree name) @@ -1363,9 +1361,13 @@ lookup_fnfields_1 (tree type, tree name) if (CLASSTYPE_LAZY_MOVE_CTOR (type)) lazily_declare_fn (sfk_move_constructor, type); } - else if (name == ansi_assopname(NOP_EXPR) - && CLASSTYPE_LAZY_ASSIGNMENT_OP (type)) - lazily_declare_fn (sfk_assignment_operator, type); + else if (name == ansi_assopname (NOP_EXPR)) + { + if (CLASSTYPE_LAZY_COPY_ASSIGN (type)) + lazily_declare_fn (sfk_copy_assignment, type); + if (CLASSTYPE_LAZY_MOVE_ASSIGN (type)) + lazily_declare_fn (sfk_move_assignment, type); + } else if ((name == dtor_identifier || name == base_dtor_identifier || name == complete_dtor_identifier @@ -1443,6 +1445,18 @@ lookup_fnfields_1 (tree type, tree name) return -1; } +/* TYPE is a class type. Return the field within the method vector with + name NAME, or NULL_TREE if no such field exists. */ + +tree +lookup_fnfields_slot (tree type, tree name) +{ + int ix = lookup_fnfields_1 (type, name); + if (ix < 0) + return NULL_TREE; + return VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix); +} + /* Like lookup_fnfields_1, except that the name is extracted from FUNCTION, which is a FUNCTION_DECL or a TEMPLATE_DECL. */ @@ -1868,7 +1882,7 @@ check_final_overrider (tree overrider, tree basefn) } /* Check throw specifier is at least as strict. */ - if (!comp_except_specs (base_throw, over_throw, 0)) + if (!comp_except_specs (base_throw, over_throw, ce_derived)) { error ("looser throw specifier for %q+#F", overrider); error (" overriding %q+#F", basefn); @@ -1891,6 +1905,7 @@ check_final_overrider (tree overrider, tree basefn) { error ("deleted function %q+D", overrider); error ("overriding non-deleted function %q+D", basefn); + maybe_explain_implicit_delete (overrider); } else { diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 1c47ded84d0..b73dffb0560 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4,7 +4,7 @@ and during the instantiation of template functions. Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009 Free Software Foundation, Inc. + 2008, 2009, 2010 Free Software Foundation, Inc. Written by Mark Mitchell (mmitchell@usa.net) based on code found formerly in parse.y and pt.c. @@ -30,23 +30,20 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tree.h" #include "cp-tree.h" -#include "c-common.h" +#include "c-family/c-common.h" #include "tree-inline.h" #include "tree-mudflap.h" -#include "except.h" #include "toplev.h" #include "flags.h" -#include "rtl.h" -#include "expr.h" #include "output.h" #include "timevar.h" -#include "debug.h" #include "diagnostic.h" #include "cgraph.h" #include "tree-iterator.h" #include "vec.h" #include "target.h" #include "gimple.h" +#include "bitmap.h" /* There routines provide a modular interface to perform many parsing operations. They may therefore be used during actual parsing, or @@ -235,14 +232,10 @@ pop_to_parent_deferring_access_checks (void) int i, j; deferred_access_check *chk, *probe; - for (i = 0 ; - VEC_iterate (deferred_access_check, checks, i, chk) ; - ++i) + FOR_EACH_VEC_ELT (deferred_access_check, checks, i, chk) { - for (j = 0 ; - VEC_iterate (deferred_access_check, - ptr->deferred_access_checks, j, probe) ; - ++j) + FOR_EACH_VEC_ELT (deferred_access_check, + ptr->deferred_access_checks, j, probe) { if (probe->binfo == chk->binfo && probe->decl == chk->decl && @@ -271,7 +264,7 @@ perform_access_checks (VEC (deferred_access_check,gc)* checks) if (!checks) return; - for (i = 0 ; VEC_iterate (deferred_access_check, checks, i, chk) ; ++i) + FOR_EACH_VEC_ELT (deferred_access_check, checks, i, chk) enforce_access (chk->binfo, chk->decl, chk->diag_decl); } @@ -326,10 +319,8 @@ perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl) } /* See if we are already going to perform this check. */ - for (i = 0 ; - VEC_iterate (deferred_access_check, - ptr->deferred_access_checks, i, chk) ; - ++i) + FOR_EACH_VEC_ELT (deferred_access_check, + ptr->deferred_access_checks, i, chk) { if (chk->decl == decl && chk->binfo == binfo && chk->diag_decl == diag_decl) @@ -610,10 +601,10 @@ finish_expr_stmt (tree expr) { if (warn_sequence_point) verify_sequence_points (expr); - expr = convert_to_void (expr, "statement", tf_warning_or_error); + expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error); } else if (!type_dependent_expression_p (expr)) - convert_to_void (build_non_dependent_expr (expr), "statement", + convert_to_void (build_non_dependent_expr (expr), ICV_STATEMENT, tf_warning_or_error); if (check_for_bare_parameter_packs (expr)) @@ -871,11 +862,11 @@ finish_for_expr (tree expr, tree for_stmt) { if (warn_sequence_point) verify_sequence_points (expr); - expr = convert_to_void (expr, "3rd expression in for", + expr = convert_to_void (expr, ICV_THIRD_IN_FOR, tf_warning_or_error); } else if (!type_dependent_expression_p (expr)) - convert_to_void (build_non_dependent_expr (expr), "3rd expression in for", + convert_to_void (build_non_dependent_expr (expr), ICV_THIRD_IN_FOR, tf_warning_or_error); expr = maybe_cleanup_point_expr_void (expr); if (check_for_bare_parameter_packs (expr)) @@ -885,12 +876,16 @@ finish_for_expr (tree expr, tree for_stmt) /* Finish the body of a for-statement, which may be given by FOR_STMT. The increment-EXPR for the loop must be - provided. */ + provided. + It can also finish RANGE_FOR_STMT. */ void finish_for_stmt (tree for_stmt) { - FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt)); + if (TREE_CODE (for_stmt) == RANGE_FOR_STMT) + RANGE_FOR_BODY (for_stmt) = do_poplevel (RANGE_FOR_BODY (for_stmt)); + else + FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt)); /* Pop the scope for the body of the loop. */ if (flag_new_for_scope > 0) @@ -903,6 +898,36 @@ finish_for_stmt (tree for_stmt) finish_stmt (); } +/* Begin a range-for-statement. Returns a new RANGE_FOR_STMT. + To finish it call finish_for_stmt(). */ + +tree +begin_range_for_stmt (void) +{ + tree r; + + r = build_stmt (input_location, RANGE_FOR_STMT, + NULL_TREE, NULL_TREE, NULL_TREE); + + if (flag_new_for_scope > 0) + TREE_CHAIN (r) = do_pushlevel (sk_for); + + return r; +} + +/* Finish the head of a range-based for statement, which may + be given by RANGE_FOR_STMT. DECL must be the declaration + and EXPR must be the loop expression. */ + +void +finish_range_for_decl (tree range_for_stmt, tree decl, tree expr) +{ + RANGE_FOR_DECL (range_for_stmt) = decl; + RANGE_FOR_EXPR (range_for_stmt) = expr; + add_stmt (range_for_stmt); + RANGE_FOR_BODY (range_for_stmt) = do_pushlevel (sk_block); +} + /* Finish a break-statement. */ tree @@ -1221,7 +1246,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands, tree operand; int i; - oconstraints = (const char **) alloca (noutputs * sizeof (char *)); + oconstraints = XALLOCAVEC (const char *, noutputs); string = resolve_asm_operand_names (string, output_operands, input_operands, labels); @@ -1238,6 +1263,8 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands, otherwise we'll get an error. Gross, but ... */ STRIP_NOPS (operand); + operand = mark_lvalue_use (operand); + if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error)) operand = error_mark_node; @@ -1424,17 +1451,18 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) { gcc_assert (TREE_CODE (decl) == FIELD_DECL); - if (!object && cp_unevaluated_operand != 0) + if (!object) { - /* DR 613: Can use non-static data members without an associated - object in sizeof/decltype/alignof. */ tree scope = qualifying_scope; if (scope == NULL_TREE) scope = context_for_name_lookup (decl); object = maybe_dummy_object (scope, NULL); } - if (!object) + /* DR 613: Can use non-static data members without an associated + object in sizeof/decltype/alignof. */ + if (is_dummy_object (object) && cp_unevaluated_operand == 0 + && (!processing_template_decl || !current_class_ref)) { if (current_function_decl && DECL_STATIC_FUNCTION_P (current_function_decl)) @@ -1446,19 +1474,6 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) return error_mark_node; } - /* If decl is a non-capture field and object has a lambda type, - then we have a reference to a member of 'this' from a - lambda inside a non-static member function, and we must get to decl - through the 'this' capture. If decl is not a member of that object, - either, then its access will still fail later. */ - if (LAMBDA_TYPE_P (TREE_TYPE (object)) - && !LAMBDA_TYPE_P (DECL_CONTEXT (decl))) - object = cp_build_indirect_ref (lambda_expr_this_capture - (CLASSTYPE_LAMBDA_EXPR - (TREE_TYPE (object))), - RO_NULL, - /*complain=*/tf_warning_or_error); - if (current_class_ptr) TREE_USED (current_class_ptr) = 1; if (processing_template_decl && !qualifying_scope) @@ -1494,21 +1509,6 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) else { tree access_type = TREE_TYPE (object); - tree lookup_context = context_for_name_lookup (decl); - - while (!DERIVED_FROM_P (lookup_context, access_type)) - { - access_type = TYPE_CONTEXT (access_type); - while (access_type && DECL_P (access_type)) - access_type = DECL_CONTEXT (access_type); - - if (!access_type) - { - error ("object missing in reference to %q+D", decl); - error ("from this location"); - return error_mark_node; - } - } perform_or_defer_access_check (TYPE_BINFO (access_type), decl, decl); @@ -1683,24 +1683,21 @@ finish_qualified_id_expr (tree qualifying_class, else if (TREE_CODE (expr) == FIELD_DECL) { push_deferring_access_checks (dk_no_check); - expr = finish_non_static_data_member (expr, current_class_ref, + expr = finish_non_static_data_member (expr, NULL_TREE, qualifying_class); pop_deferring_access_checks (); } else if (BASELINK_P (expr) && !processing_template_decl) { - tree fns; + tree ob; /* See if any of the functions are non-static members. */ - fns = BASELINK_FUNCTIONS (expr); - if (TREE_CODE (fns) == TEMPLATE_ID_EXPR) - fns = TREE_OPERAND (fns, 0); /* If so, the expression may be relative to 'this'. */ - if (!shared_member_p (fns) - && current_class_ref - && DERIVED_FROM_P (qualifying_class, TREE_TYPE (current_class_ref))) + if (!shared_member_p (expr) + && (ob = maybe_dummy_object (qualifying_class, NULL), + !is_dummy_object (ob))) expr = (build_class_member_access_expr - (maybe_dummy_object (qualifying_class, NULL), + (ob, expr, BASELINK_ACCESS_BINFO (expr), /*preserve_reference=*/false, @@ -1876,11 +1873,12 @@ empty_expr_stmt_p (tree expr_stmt) /* Perform Koenig lookup. FN is the postfix-expression representing the function (or functions) to call; ARGS are the arguments to the - call. Returns the functions to be considered by overload - resolution. */ + call; if INCLUDE_STD then the `std' namespace is automatically + considered an associated namespace (used in range-based for loops). + Returns the functions to be considered by overload resolution. */ tree -perform_koenig_lookup (tree fn, VEC(tree,gc) *args) +perform_koenig_lookup (tree fn, VEC(tree,gc) *args, bool include_std) { tree identifier = NULL_TREE; tree functions = NULL_TREE; @@ -1916,7 +1914,7 @@ perform_koenig_lookup (tree fn, VEC(tree,gc) *args) if (!any_type_dependent_arguments_p (args) && !any_dependent_template_arguments_p (tmpl_args)) { - fn = lookup_arg_dependent (identifier, functions, args); + fn = lookup_arg_dependent (identifier, functions, args, include_std); if (!fn) /* The unqualified name could not be resolved. */ fn = unqualified_fn_lookup_error (identifier); @@ -2002,31 +2000,18 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual, . operator.... [Otherwise] a contrived object of type T becomes the implied object argument. - This paragraph is unclear about this situation: + In this situation: struct A { void f(); }; struct B : public A {}; struct C : public A { void g() { B::f(); }}; - In particular, for `B::f', this paragraph does not make clear - whether "the class of that member function" refers to `A' or - to `B'. We believe it refers to `B'. */ - if (current_class_type - && DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), - current_class_type) - && current_class_ref) - object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), - NULL); - else - { - tree representative_fn; + "the class of that member function" refers to `A'. But 11.2 + [class.access.base] says that we need to convert 'this' to B* as + part of the access, so we pass 'B' to maybe_dummy_object. */ - representative_fn = BASELINK_FUNCTIONS (fn); - if (TREE_CODE (representative_fn) == TEMPLATE_ID_EXPR) - representative_fn = TREE_OPERAND (representative_fn, 0); - representative_fn = get_first_fn (representative_fn); - object = build_dummy_object (DECL_CONTEXT (representative_fn)); - } + object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), + NULL); if (processing_template_decl) { @@ -2253,20 +2238,7 @@ finish_compound_literal (tree type, tree compound_literal) if (TREE_CODE (type) == ARRAY_TYPE) cp_complete_array_type (&type, compound_literal, false); compound_literal = digest_init (type, compound_literal); - if ((!at_function_scope_p () || cp_type_readonly (type)) - && initializer_constant_valid_p (compound_literal, type)) - { - tree decl = create_temporary_var (type); - DECL_INITIAL (decl) = compound_literal; - TREE_STATIC (decl) = 1; - cp_apply_type_quals_to_decl (cp_type_quals (type), decl); - decl = pushdecl_top_level (decl); - DECL_NAME (decl) = make_anon_name (); - SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl)); - return decl; - } - else - return get_target_expr (compound_literal); + return get_target_expr (compound_literal); } /* Return the declaration for the function-name variable indicated by @@ -2409,9 +2381,6 @@ begin_class_definition (tree t, tree attributes) pushtag (make_anon_name (), t, /*tag_scope=*/ts_current); } - /* Update the location of the decl. */ - DECL_SOURCE_LOCATION (TYPE_NAME (t)) = input_location; - if (TYPE_BEING_DEFINED (t)) { t = make_class_type (TREE_CODE (t)); @@ -2465,7 +2434,7 @@ finish_member_declaration (tree decl) return; /* We should see only one DECL at a time. */ - gcc_assert (TREE_CHAIN (decl) == NULL_TREE); + gcc_assert (DECL_CHAIN (decl) == NULL_TREE); /* Set up access control for DECL. */ TREE_PRIVATE (decl) @@ -2507,7 +2476,7 @@ finish_member_declaration (tree decl) CLASSTYPE_METHOD_VEC. */ if (add_method (current_class_type, decl, NULL_TREE)) { - TREE_CHAIN (decl) = TYPE_METHODS (current_class_type); + DECL_CHAIN (decl) = TYPE_METHODS (current_class_type); TYPE_METHODS (current_class_type) = decl; maybe_add_class_template_decl_list (current_class_type, decl, @@ -2540,7 +2509,7 @@ finish_member_declaration (tree decl) = chainon (TYPE_FIELDS (current_class_type), decl); else { - TREE_CHAIN (decl) = TYPE_FIELDS (current_class_type); + DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type); TYPE_FIELDS (current_class_type) = decl; } @@ -2895,6 +2864,16 @@ finish_id_expression (tree id_expression, return error_mark_node; } } + + /* Also disallow uses of function parameters outside the function + body, except inside an unevaluated context (i.e. decltype). */ + if (TREE_CODE (decl) == PARM_DECL + && DECL_CONTEXT (decl) == NULL_TREE + && !cp_unevaluated_operand) + { + error ("use of parameter %qD outside function body", decl); + return error_mark_node; + } } /* If we didn't find anything, or what we found was a type, @@ -3076,7 +3055,7 @@ finish_id_expression (tree id_expression, already. Turn off checking to avoid duplicate errors. */ push_deferring_access_checks (dk_no_check); decl = finish_non_static_data_member - (decl, current_class_ref, + (decl, NULL_TREE, /*qualifying_scope=*/NULL_TREE); pop_deferring_access_checks (); return decl; @@ -3144,7 +3123,13 @@ finish_id_expression (tree id_expression, { tree r = convert_from_reference (decl); - if (processing_template_decl && TYPE_P (scope)) + /* In a template, return a SCOPE_REF for most qualified-ids + so that we can check access at instantiation time. But if + we're looking at a member of the current instantiation, we + know we have access and building up the SCOPE_REF confuses + non-type template argument handling. */ + if (processing_template_decl && TYPE_P (scope) + && !currently_open_class (scope)) r = build_qualified_name (TREE_TYPE (r), scope, decl, template_p); @@ -3157,7 +3142,7 @@ finish_id_expression (tree id_expression, Access checking has been performed during name lookup already. Turn off checking to avoid duplicate errors. */ push_deferring_access_checks (dk_no_check); - decl = finish_non_static_data_member (decl, current_class_ref, + decl = finish_non_static_data_member (decl, NULL_TREE, /*qualifying_scope=*/NULL_TREE); pop_deferring_access_checks (); } @@ -3165,10 +3150,7 @@ finish_id_expression (tree id_expression, { tree first_fn; - first_fn = decl; - if (TREE_CODE (first_fn) == TEMPLATE_ID_EXPR) - first_fn = TREE_OPERAND (first_fn, 0); - first_fn = get_first_fn (first_fn); + first_fn = get_first_fn (decl); if (TREE_CODE (first_fn) == TEMPLATE_DECL) first_fn = DECL_TEMPLATE_RESULT (first_fn); @@ -3230,6 +3212,8 @@ finish_typeof (tree expr) return type; } + expr = mark_type_use (expr); + type = unlowered_expr_type (expr); if (!type || type == unknown_type_node) @@ -3255,7 +3239,7 @@ finish_offsetof (tree expr) } if (TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE - || TREE_CODE (TREE_TYPE (expr)) == UNKNOWN_TYPE) + || TREE_TYPE (expr) == unknown_type_node) { if (TREE_CODE (expr) == COMPONENT_REF || TREE_CODE (expr) == COMPOUND_EXPR) @@ -3302,6 +3286,7 @@ simplify_aggr_init_expr (tree *tp) fn, aggr_init_expr_nargs (aggr_init_expr), AGGR_INIT_EXPR_ARGP (aggr_init_expr)); + TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr); if (style == ctor) { @@ -3317,7 +3302,7 @@ simplify_aggr_init_expr (tree *tp) expand_call{,_inline}. */ cxx_mark_addressable (slot); CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true; - call_expr = build2 (MODIFY_EXPR, TREE_TYPE (call_expr), slot, call_expr); + call_expr = build2 (INIT_EXPR, TREE_TYPE (call_expr), slot, call_expr); } else if (style == pcc) { @@ -3360,7 +3345,7 @@ emit_associated_thunks (tree fn) { tree thunk; - for (thunk = DECL_THUNKS (fn); thunk; thunk = TREE_CHAIN (thunk)) + for (thunk = DECL_THUNKS (fn); thunk; thunk = DECL_CHAIN (thunk)) { if (!THUNK_ALIAS (thunk)) { @@ -3370,7 +3355,7 @@ emit_associated_thunks (tree fn) tree probe; for (probe = DECL_THUNKS (thunk); - probe; probe = TREE_CHAIN (probe)) + probe; probe = DECL_CHAIN (probe)) use_thunk (probe, /*emit_p=*/1); } } @@ -3449,7 +3434,9 @@ expand_or_defer_fn_1 (tree fn) this function as needed so that finish_file will make sure to output it later. Similarly, all dllexport'd functions must be emitted; there may be callers in other DLLs. */ - if ((flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn)) + if ((flag_keep_inline_functions + && DECL_DECLARED_INLINE_P (fn) + && !DECL_REALLY_EXTERN (fn)) || lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn))) mark_needed (fn); } @@ -3549,14 +3536,15 @@ finalize_nrv (tree *tp, tree var, tree result) { struct nrv_data data; - /* Copy debugging information from VAR to RESULT. */ + /* Copy name from VAR to RESULT. */ DECL_NAME (result) = DECL_NAME (var); - DECL_ARTIFICIAL (result) = DECL_ARTIFICIAL (var); - DECL_IGNORED_P (result) = DECL_IGNORED_P (var); - DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (var); - DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (var); /* Don't forget that we take its address. */ TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (var); + /* Finally set DECL_VALUE_EXPR to avoid assigning + a stack slot at -O0 for the original var and debug info + uses RESULT location for VAR. */ + SET_DECL_VALUE_EXPR (var, result); + DECL_HAS_VALUE_EXPR_P (var) = 1; data.var = var; data.result = result; @@ -3565,31 +3553,6 @@ finalize_nrv (tree *tp, tree var, tree result) htab_delete (data.visited); } -/* Return the declaration for the function called by CALL_EXPR T, - TYPE is the class type of the clause decl. */ - -static tree -omp_clause_info_fndecl (tree t, tree type) -{ - tree ret = get_callee_fndecl (t); - - if (ret) - return ret; - - gcc_assert (TREE_CODE (t) == CALL_EXPR); - t = CALL_EXPR_FN (t); - STRIP_NOPS (t); - if (TREE_CODE (t) == OBJ_TYPE_REF) - { - t = cp_fold_obj_type_ref (t, type); - if (TREE_CODE (t) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL) - return TREE_OPERAND (t, 0); - } - - return NULL_TREE; -} - /* Create CP_OMP_CLAUSE_INFO for clause C. Returns true if it is invalid. */ bool @@ -3607,80 +3570,27 @@ cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor, info = make_tree_vec (3); CP_OMP_CLAUSE_INFO (c) = info; - if (need_default_ctor - || (need_copy_ctor && !TYPE_HAS_TRIVIAL_INIT_REF (type))) + if (need_default_ctor || need_copy_ctor) { - VEC(tree,gc) *vec; - if (need_default_ctor) - vec = NULL; + t = get_default_ctor (type); else - { - t = build_int_cst (build_pointer_type (type), 0); - t = build1 (INDIRECT_REF, type, t); - vec = make_tree_vector_single (t); - } - t = build_special_member_call (NULL_TREE, complete_ctor_identifier, - &vec, type, LOOKUP_NORMAL, - tf_warning_or_error); - - if (vec != NULL) - release_tree_vector (vec); - - if (targetm.cxx.cdtor_returns_this () || errorcount) - /* Because constructors and destructors return this, - the call will have been cast to "void". Remove the - cast here. We would like to use STRIP_NOPS, but it - wouldn't work here because TYPE_MODE (t) and - TYPE_MODE (TREE_OPERAND (t, 0)) are different. - They are VOIDmode and Pmode, respectively. */ - if (TREE_CODE (t) == NOP_EXPR) - t = TREE_OPERAND (t, 0); + t = get_copy_ctor (type); - TREE_VEC_ELT (info, 0) = get_callee_fndecl (t); + if (t && !trivial_fn_p (t)) + TREE_VEC_ELT (info, 0) = t; } if ((need_default_ctor || need_copy_ctor) && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) - { - t = build_int_cst (build_pointer_type (type), 0); - t = build1 (INDIRECT_REF, type, t); - t = build_special_member_call (t, complete_dtor_identifier, - NULL, type, LOOKUP_NORMAL, - tf_warning_or_error); - - if (targetm.cxx.cdtor_returns_this () || errorcount) - /* Because constructors and destructors return this, - the call will have been cast to "void". Remove the - cast here. We would like to use STRIP_NOPS, but it - wouldn't work here because TYPE_MODE (t) and - TYPE_MODE (TREE_OPERAND (t, 0)) are different. - They are VOIDmode and Pmode, respectively. */ - if (TREE_CODE (t) == NOP_EXPR) - t = TREE_OPERAND (t, 0); + TREE_VEC_ELT (info, 1) = get_dtor (type); - TREE_VEC_ELT (info, 1) = omp_clause_info_fndecl (t, type); - } - - if (need_copy_assignment && !TYPE_HAS_TRIVIAL_ASSIGN_REF (type)) + if (need_copy_assignment) { - VEC(tree,gc) *vec; - - t = build_int_cst (build_pointer_type (type), 0); - t = build1 (INDIRECT_REF, type, t); - vec = make_tree_vector_single (t); - t = build_special_member_call (t, ansi_assopname (NOP_EXPR), - &vec, type, LOOKUP_NORMAL, - tf_warning_or_error); - release_tree_vector (vec); + t = get_copy_assign (type); - /* We'll have called convert_from_reference on the call, which - may well have added an indirect_ref. It's unneeded here, - and in the way, so kill it. */ - if (TREE_CODE (t) == INDIRECT_REF) - t = TREE_OPERAND (t, 0); - - TREE_VEC_ELT (info, 2) = omp_clause_info_fndecl (t, type); + if (t && !trivial_fn_p (t)) + TREE_VEC_ELT (info, 2) = t; } return errorcount != save_errorcount; @@ -4839,6 +4749,14 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) /* The type denoted by decltype(e) is defined as follows: */ expr = resolve_nondeduced_context (expr); + + /* To get the size of a static data member declared as an array of + unknown bound, we need to instantiate it. */ + if (TREE_CODE (expr) == VAR_DECL + && VAR_HAD_UNKNOWN_BOUND (expr) + && DECL_TEMPLATE_INSTANTIATION (expr)) + instantiate_decl (expr, /*defer_ok*/true, /*expl_inst_mem*/false); + if (id_expression_or_member_access_p) { /* If e is an id-expression or a class member access (5.2.5 @@ -4897,6 +4815,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) case PARM_DECL: case RESULT_DECL: case TEMPLATE_PARM_INDEX: + expr = mark_type_use (expr); type = TREE_TYPE (expr); break; @@ -4905,6 +4824,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) break; case COMPONENT_REF: + mark_type_use (expr); type = is_bitfield_expr_with_lowered_type (expr); if (!type) type = TREE_TYPE (TREE_OPERAND (expr, 1)); @@ -5005,8 +4925,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) type = TYPE_MAIN_VARIANT (type); else if (real_lvalue_p (expr)) { - if (TREE_CODE (type) != REFERENCE_TYPE) - type = build_reference_type (type); + if (TREE_CODE (type) != REFERENCE_TYPE + || TYPE_REF_IS_RVALUE (type)) + type = build_reference_type (non_reference (type)); } else type = non_reference (type); @@ -5039,7 +4960,7 @@ classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p) return false; fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix); } - else if (TYPE_HAS_INIT_REF (type)) + else if (TYPE_HAS_COPY_CTOR (type)) { /* If construction of the copy constructor was postponed, create it now. */ @@ -5098,13 +5019,13 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE && (trivial_type_p (type1) || (CLASS_TYPE_P (type1) - && TYPE_HAS_TRIVIAL_ASSIGN_REF (type1)))); + && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1)))); case CPTK_HAS_NOTHROW_CONSTRUCTOR: type1 = strip_array_types (type1); return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2) || (CLASS_TYPE_P (type1) - && (t = locate_ctor (type1, NULL)) + && (t = locate_ctor (type1)) && TYPE_NOTHROW_P (TREE_TYPE (t)))); case CPTK_HAS_TRIVIAL_CONSTRUCTOR: @@ -5123,7 +5044,7 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) 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))); + || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_COPY_CTOR (type1))); case CPTK_HAS_TRIVIAL_DESTRUCTOR: type1 = strip_array_types (type1); @@ -5132,8 +5053,7 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1))); case CPTK_HAS_VIRTUAL_DESTRUCTOR: - return (CLASS_TYPE_P (type1) - && (t = locate_dtor (type1, NULL)) && DECL_VIRTUAL_P (t)); + return type_has_virtual_destructor (type1); case CPTK_IS_ABSTRACT: return (CLASS_TYPE_P (type1) && CLASSTYPE_PURE_VIRTUALS (type1)); @@ -5185,7 +5105,8 @@ check_trait_type (tree type) if (COMPLETE_TYPE_P (type)) return true; - if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) + if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type) + && COMPLETE_TYPE_P (TREE_TYPE (type))) return true; if (VOID_TYPE_P (type)) @@ -5514,6 +5435,11 @@ tree lambda_return_type (tree expr) { tree type; + if (BRACE_ENCLOSED_INITIALIZER_P (expr)) + { + warning (0, "cannot deduce lambda return type from a braced-init-list"); + return void_type_node; + } if (type_dependent_expression_p (expr)) { type = cxx_make_type (DECLTYPE_TYPE); @@ -5657,7 +5583,7 @@ capture_decltype (tree decl) if (TREE_CODE (type) != REFERENCE_TYPE) { if (!LAMBDA_EXPR_MUTABLE_P (lam)) - type = cp_build_qualified_type (type, (TYPE_QUALS (type) + type = cp_build_qualified_type (type, (cp_type_quals (type) |TYPE_QUAL_CONST)); type = build_reference_type (type); } @@ -5843,7 +5769,7 @@ lambda_expr_this_capture (tree lambda) gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda)); result = finish_non_static_data_member (this_capture, - current_class_ref, + NULL_TREE, /*qualifying_scope=*/NULL_TREE); /* If 'this' is captured, each use of 'this' is transformed into an @@ -5856,6 +5782,32 @@ lambda_expr_this_capture (tree lambda) return result; } +/* Returns the method basetype of the innermost non-lambda function, or + NULL_TREE if none. */ + +tree +nonlambda_method_basetype (void) +{ + tree fn, type; + if (!current_class_ref) + return NULL_TREE; + + type = current_class_type; + if (!LAMBDA_TYPE_P (type)) + return type; + + /* Find the nearest enclosing non-lambda function. */ + fn = TYPE_NAME (type); + do + fn = decl_function_context (fn); + while (fn && LAMBDA_FUNCTION_P (fn)); + + if (!fn || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) + return NULL_TREE; + + return TYPE_METHOD_BASETYPE (TREE_TYPE (fn)); +} + /* If the closure TYPE has a static op(), also add a conversion to function pointer. */ @@ -5925,8 +5877,8 @@ maybe_add_lambda_conv_op (tree type) DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; DECL_STATIC_FUNCTION_P (fn) = 1; - DECL_ARGUMENTS (fn) = copy_list (TREE_CHAIN (DECL_ARGUMENTS (callop))); - for (arg = DECL_ARGUMENTS (fn); arg; arg = TREE_CHAIN (arg)) + DECL_ARGUMENTS (fn) = copy_list (DECL_CHAIN (DECL_ARGUMENTS (callop))); + for (arg = DECL_ARGUMENTS (fn); arg; arg = DECL_CHAIN (arg)) DECL_CONTEXT (arg) = fn; if (nested) DECL_INTERFACE_KNOWN (fn) = 1; @@ -5959,11 +5911,14 @@ maybe_add_lambda_conv_op (tree type) null_pointer_node); argvec = make_tree_vector (); VEC_quick_push (tree, argvec, arg); - for (arg = DECL_ARGUMENTS (statfn); arg; arg = TREE_CHAIN (arg)) + for (arg = DECL_ARGUMENTS (statfn); arg; arg = DECL_CHAIN (arg)) VEC_safe_push (tree, gc, argvec, arg); - call = build_cxx_call (callop, VEC_length (tree, argvec), - VEC_address (tree, argvec)); + call = build_call_a (callop, VEC_length (tree, argvec), + VEC_address (tree, argvec)); CALL_FROM_THUNK_P (call) = 1; + if (MAYBE_CLASS_TYPE_P (TREE_TYPE (call))) + call = build_cplus_new (TREE_TYPE (call), call); + call = convert_from_reference (call); finish_return_stmt (call); finish_compound_stmt (compound_stmt); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 35b0da62ea5..ea01d1f4677 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -27,17 +27,13 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "cp-tree.h" #include "flags.h" -#include "real.h" -#include "rtl.h" #include "toplev.h" -#include "insn-config.h" -#include "integrate.h" #include "tree-inline.h" #include "debug.h" -#include "target.h" #include "convert.h" -#include "tree-flow.h" #include "cgraph.h" +#include "splay-tree.h" +#include "gimple.h" /* gimple_has_body_p */ static tree bot_manip (tree *, int *, void *); static tree bot_replace (tree *, int *, void *); @@ -422,6 +418,7 @@ build_aggr_init_expr (tree type, tree init) AGGR_INIT_EXPR_ARGP (init)); TREE_SIDE_EFFECTS (rval) = 1; AGGR_INIT_VIA_CTOR_P (rval) = is_ctor; + TREE_NOTHROW (rval) = TREE_NOTHROW (init); } else rval = init; @@ -480,9 +477,10 @@ build_target_expr_with_type (tree init, tree type) { gcc_assert (!VOID_TYPE_P (type)); - if (TREE_CODE (init) == TARGET_EXPR) + if (TREE_CODE (init) == TARGET_EXPR + || init == error_mark_node) return init; - else if (CLASS_TYPE_P (type) && !TYPE_HAS_TRIVIAL_INIT_REF (type) + else if (CLASS_TYPE_P (type) && type_has_nontrivial_copy_init (type) && !VOID_TYPE_P (TREE_TYPE (init)) && TREE_CODE (init) != COND_EXPR && TREE_CODE (init) != CONSTRUCTOR @@ -500,7 +498,8 @@ build_target_expr_with_type (tree init, tree type) /* Like the above function, but without the checking. This function should only be used by code which is deliberately trying to subvert the type - system, such as call_builtin_trap. */ + system, such as call_builtin_trap. Or build_over_call, to avoid + infinite recursion. */ tree force_target_expr (tree type, tree init) @@ -551,6 +550,8 @@ rvalue (tree expr) if (error_operand_p (expr)) return expr; + expr = mark_rvalue_use (expr); + /* [basic.lval] Non-class rvalues always have cv-unqualified types. */ @@ -863,15 +864,22 @@ cp_build_qualified_type_real (tree type, } /* A reference or method type shall not be cv-qualified. - [dcl.ref], [dcl.fct] */ + [dcl.ref], [dcl.fct]. This used to be an error, but as of DR 295 + (in CD1) we always ignore extra cv-quals on functions. */ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE) && (TREE_CODE (type) == REFERENCE_TYPE + || TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)) { - bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); + if (TREE_CODE (type) == REFERENCE_TYPE) + bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); } + /* But preserve any function-cv-quals on a FUNCTION_TYPE. */ + if (TREE_CODE (type) == FUNCTION_TYPE) + type_quals |= type_memfn_quals (type); + /* A restrict-qualified type must be a pointer (or reference) to object or incomplete type. */ if ((type_quals & TYPE_QUAL_RESTRICT) @@ -883,24 +891,16 @@ cp_build_qualified_type_real (tree type, type_quals &= ~TYPE_QUAL_RESTRICT; } - if (bad_quals == TYPE_UNQUALIFIED) + if (bad_quals == TYPE_UNQUALIFIED + || (complain & tf_ignore_bad_quals)) /*OK*/; - else if (!(complain & (tf_error | tf_ignore_bad_quals))) + else if (!(complain & tf_error)) return error_mark_node; else { - if (complain & tf_ignore_bad_quals) - /* We're not going to warn about constifying things that can't - be constified. */ - bad_quals &= ~TYPE_QUAL_CONST; - if (bad_quals) - { - tree bad_type = build_qualified_type (ptr_type_node, bad_quals); - - if (!(complain & tf_ignore_bad_quals)) - error ("%qV qualifiers cannot be applied to %qT", - bad_type, type); - } + tree bad_type = build_qualified_type (ptr_type_node, bad_quals); + error ("%qV qualifiers cannot be applied to %qT", + bad_type, type); } /* Retrieve (or create) the appropriately qualified variant. */ @@ -934,7 +934,12 @@ cp_build_qualified_type_real (tree type, tree cv_unqualified (tree type) { - int quals = TYPE_QUALS (type); + int quals; + + if (type == error_mark_node) + return type; + + quals = cp_type_quals (type); quals &= ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE); return cp_build_qualified_type (type, quals); } @@ -1031,14 +1036,22 @@ strip_typedefs (tree t) TREE_CHAIN (arg_types)); } else + { result = build_function_type (type, arg_types); + result = apply_memfn_quals (result, type_memfn_quals (t)); + } if (TYPE_RAISES_EXCEPTIONS (t)) result = build_exception_variant (result, TYPE_RAISES_EXCEPTIONS (t)); } break; + case TYPENAME_TYPE: + result = make_typename_type (strip_typedefs (TYPE_CONTEXT (t)), + TYPENAME_TYPE_FULLNAME (t), + typename_type, tf_none); + break; default: break; } @@ -1050,14 +1063,6 @@ strip_typedefs (tree t) return cp_build_qualified_type (result, cp_type_quals (t)); } -/* Returns true iff TYPE is a type variant created for a typedef. */ - -bool -typedef_variant_p (tree type) -{ - return is_typedef_decl (TYPE_NAME (type)); -} - /* Setup a TYPE_DECL node as a typedef representation. See comments of set_underlying_type in c-common.c. */ @@ -1347,7 +1352,7 @@ really_overloaded_fn (tree x) } tree -get_first_fn (tree from) +get_fns (tree from) { gcc_assert (is_overloaded_fn (from)); /* A baselink is also considered an overloaded function. */ @@ -1358,7 +1363,13 @@ get_first_fn (tree from) from = BASELINK_FUNCTIONS (from); if (TREE_CODE (from) == TEMPLATE_ID_EXPR) from = TREE_OPERAND (from, 0); - return OVL_CURRENT (from); + return from; +} + +tree +get_first_fn (tree from) +{ + return OVL_CURRENT (get_fns (from)); } /* Return a new OVL node, concatenating it with the old one. */ @@ -1455,12 +1466,16 @@ cxx_printable_name_translate (tree decl, int v) tree build_exception_variant (tree type, tree raises) { - tree v = TYPE_MAIN_VARIANT (type); - int type_quals = TYPE_QUALS (type); + tree v; + int type_quals; - for (; v; v = TYPE_NEXT_VARIANT (v)) + if (comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (type), ce_exact)) + return type; + + type_quals = TYPE_QUALS (type); + for (v = TYPE_MAIN_VARIANT (type); v; v = TYPE_NEXT_VARIANT (v)) if (check_qualified_type (v, type, type_quals) - && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), 1)) + && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), ce_exact)) return v; /* Need to build a new variant. */ @@ -1664,6 +1679,7 @@ cxx_print_statistics (void) { print_search_statistics (); print_class_statistics (); + print_template_statistics (); #ifdef GATHER_STATISTICS fprintf (stderr, "maximum template instantiation depth reached: %d\n", depth_reached); @@ -1891,9 +1907,9 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...) return t; } -/* Similar to `build_call_list', but for template definitions of non-dependent - expressions. NON_DEP is the non-dependent expression that has been - built. */ +/* Similar to `build_nt_call_vec', but for template definitions of + non-dependent expressions. NON_DEP is the non-dependent expression + that has been built. */ tree build_min_non_dep_call_vec (tree non_dep, tree fn, VEC(tree,gc) *argvec) @@ -2013,11 +2029,21 @@ cp_tree_equal (tree t1, tree t2) /* We need to do this when determining whether or not two non-type pointer to member function template arguments are the same. */ - if (!(same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) - /* The first operand is RTL. */ - && TREE_OPERAND (t1, 0) == TREE_OPERAND (t2, 0))) + if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) + || CONSTRUCTOR_NELTS (t1) != CONSTRUCTOR_NELTS (t2)) return false; - return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)); + { + tree field, value; + unsigned int i; + FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t1), i, field, value) + { + constructor_elt *elt2 = CONSTRUCTOR_ELT (t2, i); + if (!cp_tree_equal (field, elt2->index) + || !cp_tree_equal (value, elt2->value)) + return false; + } + } + return true; case TREE_LIST: if (!cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))) @@ -2181,6 +2207,17 @@ cp_tree_equal (tree t1, tree t2) return same_type_p (TRAIT_EXPR_TYPE1 (t1), TRAIT_EXPR_TYPE1 (t2)) && same_type_p (TRAIT_EXPR_TYPE2 (t1), TRAIT_EXPR_TYPE2 (t2)); + case CAST_EXPR: + case STATIC_CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case CONST_CAST_EXPR: + case DYNAMIC_CAST_EXPR: + case NEW_EXPR: + if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))) + return false; + /* Now compare operands as usual. */ + break; + default: break; } @@ -2252,11 +2289,7 @@ error_type (tree arg) int varargs_function_p (const_tree function) { - const_tree parm = TYPE_ARG_TYPES (TREE_TYPE (function)); - for (; parm; parm = TREE_CHAIN (parm)) - if (TREE_VALUE (parm) == void_type_node) - return 0; - return 1; + return stdarg_p (TREE_TYPE (function)); } /* Returns 1 if decl is a member of a class. */ @@ -2287,11 +2320,11 @@ maybe_dummy_object (tree type, tree* binfop) { tree decl, context; tree binfo; + tree current = current_nonlambda_class_type (); - if (current_class_type - && (binfo = lookup_base (current_class_type, type, - ba_unique | ba_quiet, NULL))) - context = current_class_type; + if (current + && (binfo = lookup_base (current, type, ba_any, NULL))) + context = current; else { /* Reference from a nested class member function. */ @@ -2309,6 +2342,13 @@ maybe_dummy_object (tree type, tree* binfop) && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)), current_class_type)) decl = current_class_ref; + else if (current != current_class_type + && context == nonlambda_method_basetype ()) + /* In a lambda, need to go through 'this' capture. */ + decl = (cp_build_indirect_ref + ((lambda_expr_this_capture + (CLASSTYPE_LAMBDA_EXPR (current_class_type))), + RO_NULL, tf_warning_or_error)); else decl = build_dummy_object (context); @@ -2352,7 +2392,9 @@ type_has_nontrivial_default_init (const_tree t) return 0; } -/* Returns true iff copying an object of type T is non-trivial. */ +/* Returns true iff copying an object of type T (including via move + constructor) is non-trivial. That is, T has no non-trivial copy + constructors and no non-trivial move constructors. */ bool type_has_nontrivial_copy_init (const_tree t) @@ -2360,12 +2402,38 @@ 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); + { + gcc_assert (COMPLETE_TYPE_P (t)); + return ((TYPE_HAS_COPY_CTOR (t) + && TYPE_HAS_COMPLEX_COPY_CTOR (t)) + || TYPE_HAS_COMPLEX_MOVE_CTOR (t)); + } else return 0; } -/* Returns 1 iff type T is a trivial type, as defined in [basic.types]. */ +/* Returns 1 iff type T is a trivially copyable type, as defined in + [basic.types] and [class]. */ + +bool +trivially_copyable_p (const_tree t) +{ + t = strip_array_types (CONST_CAST_TREE (t)); + + if (CLASS_TYPE_P (t)) + return ((!TYPE_HAS_COPY_CTOR (t) + || !TYPE_HAS_COMPLEX_COPY_CTOR (t)) + && !TYPE_HAS_COMPLEX_MOVE_CTOR (t) + && (!TYPE_HAS_COPY_ASSIGN (t) + || !TYPE_HAS_COMPLEX_COPY_ASSIGN (t)) + && !TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) + && TYPE_HAS_TRIVIAL_DESTRUCTOR (t)); + else + return scalarish_type_p (t); +} + +/* Returns 1 iff type T is a trivial type, as defined in [basic.types] and + [class]. */ bool trivial_type_p (const_tree t) @@ -2374,9 +2442,7 @@ trivial_type_p (const_tree t) if (CLASS_TYPE_P (t)) return (TYPE_HAS_TRIVIAL_DFLT (t) - && TYPE_HAS_TRIVIAL_INIT_REF (t) - && TYPE_HAS_TRIVIAL_ASSIGN_REF (t) - && TYPE_HAS_TRIVIAL_DESTRUCTOR (t)); + && trivially_copyable_p (t)); else return scalarish_type_p (t); } @@ -2625,10 +2691,8 @@ cp_build_type_attribute_variant (tree type, tree attributes) tree new_type; new_type = build_type_attribute_variant (type, attributes); - if ((TREE_CODE (new_type) == FUNCTION_TYPE - || TREE_CODE (new_type) == METHOD_TYPE) - && (TYPE_RAISES_EXCEPTIONS (new_type) - != TYPE_RAISES_EXCEPTIONS (type))) + if (TREE_CODE (new_type) == FUNCTION_TYPE + || TREE_CODE (new_type) == METHOD_TYPE) new_type = build_exception_variant (new_type, TYPE_RAISES_EXCEPTIONS (type)); @@ -2649,7 +2713,7 @@ cxx_type_hash_eq (const_tree typea, const_tree typeb) gcc_assert (TREE_CODE (typea) == FUNCTION_TYPE); return comp_except_specs (TYPE_RAISES_EXCEPTIONS (typea), - TYPE_RAISES_EXCEPTIONS (typeb), 1); + TYPE_RAISES_EXCEPTIONS (typeb), ce_exact); } /* Apply FUNC to all language-specific sub-trees of TP in a pre-order @@ -2818,7 +2882,12 @@ special_function_p (const_tree decl) if (DECL_CONSTRUCTOR_P (decl)) return sfk_constructor; if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR) - return sfk_assignment_operator; + { + if (copy_fn_p (decl)) + return sfk_copy_assignment; + if (move_fn_p (decl)) + return sfk_move_assignment; + } if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)) return sfk_destructor; if (DECL_COMPLETE_DESTRUCTOR_P (decl)) @@ -3180,6 +3249,16 @@ cp_free_lang_data (tree t) } } +/* Stub for c-common. Please keep in sync with c-decl.c. + FIXME: If address space support is target specific, then this + should be a C target hook. But currently this is not possible, + because this function is called via REGISTER_TARGET_PRAGMAS. */ +void +c_register_addr_space (const char *word ATTRIBUTE_UNUSED, + addr_space_t as ATTRIBUTE_UNUSED) +{ +} + #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) /* Complain that some language-specific thing hanging off a tree diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 4b91912b9e6..0ac95d05b69 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1,6 +1,6 @@ /* Build expressions with type checking for C++ compiler. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) @@ -31,10 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "rtl.h" -#include "expr.h" #include "cp-tree.h" -#include "tm_p.h" #include "flags.h" #include "output.h" #include "toplev.h" @@ -42,12 +39,12 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "target.h" #include "convert.h" -#include "c-common.h" +#include "c-family/c-common.h" #include "params.h" static tree pfn_from_ptrmemfunc (tree); static tree delta_from_ptrmemfunc (tree); -static tree convert_for_assignment (tree, tree, const char *, tree, int, +static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int, tsubst_flags_t, int); static tree cp_pointer_int_sum (enum tree_code, tree, tree); static tree rationalize_conditional_expr (enum tree_code, tree, @@ -56,11 +53,12 @@ static int comp_ptr_ttypes_real (tree, tree, int); static bool comp_except_types (tree, tree, bool); static bool comp_array_types (const_tree, const_tree, bool); static tree pointer_diff (tree, tree, tree); -static tree get_delta_difference (tree, tree, bool, bool); +static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t); static void casts_away_constness_r (tree *, tree *); static bool casts_away_constness (tree, tree); static void maybe_warn_about_returning_address_of_local (tree); static tree lookup_destructor (tree, tree, tree); +static void warn_args_num (location_t, tree, bool); static int convert_arguments (tree, VEC(tree,gc) **, tree, int, tsubst_flags_t); @@ -137,7 +135,7 @@ complete_type (tree type) Returns NULL_TREE if the type cannot be made complete. */ tree -complete_type_or_else (tree type, tree value) +complete_type_or_maybe_complain (tree type, tree value, tsubst_flags_t complain) { type = complete_type (type); if (type == error_mark_node) @@ -145,13 +143,20 @@ complete_type_or_else (tree type, tree value) return NULL_TREE; else if (!COMPLETE_TYPE_P (type)) { - cxx_incomplete_type_diagnostic (value, type, DK_ERROR); + if (complain & tf_error) + cxx_incomplete_type_diagnostic (value, type, DK_ERROR); return NULL_TREE; } else return type; } +tree +complete_type_or_else (tree type, tree value) +{ + return complete_type_or_maybe_complain (type, value, tf_warning_or_error); +} + /* Return truthvalue of whether type of EXP is instantiated. */ int @@ -260,6 +265,7 @@ cp_common_type (tree t1, tree t2) enum tree_code code2 = TREE_CODE (t2); tree attributes; + /* In what follows, we slightly generalize the rules given in [expr] so as to deal with `long long' and `complex'. First, merge the attributes. */ @@ -352,6 +358,17 @@ cp_common_type (tree t1, tree t2) : long_long_integer_type_node); return build_type_attribute_variant (t, attributes); } + if (int128_integer_type_node != NULL_TREE + && (same_type_p (TYPE_MAIN_VARIANT (t1), + int128_integer_type_node) + || same_type_p (TYPE_MAIN_VARIANT (t2), + int128_integer_type_node))) + { + tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2)) + ? int128_unsigned_type_node + : int128_integer_type_node); + return build_type_attribute_variant (t, attributes); + } /* Go through the same procedure, but for longs. */ if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node) @@ -632,10 +649,10 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2, if (DERIVED_FROM_P (class1, class2)) t2 = (build_pointer_type - (cp_build_qualified_type (class1, TYPE_QUALS (class2)))); + (cp_build_qualified_type (class1, cp_type_quals (class2)))); else if (DERIVED_FROM_P (class2, class1)) t1 = (build_pointer_type - (cp_build_qualified_type (class2, TYPE_QUALS (class1)))); + (cp_build_qualified_type (class2, cp_type_quals (class1)))); else { if (complain & tf_error) @@ -809,6 +826,7 @@ merge_types (tree t1, tree t2) tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2)); tree p1 = TYPE_ARG_TYPES (t1); tree p2 = TYPE_ARG_TYPES (t2); + tree parms; tree rval, raises; /* Save space: see if the result is identical to one of the args. */ @@ -819,22 +837,17 @@ merge_types (tree t1, tree t2) /* Simple way if one arg fails to specify argument types. */ if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node) - { - rval = build_function_type (valtype, p2); - if ((raises = TYPE_RAISES_EXCEPTIONS (t2))) - rval = build_exception_variant (rval, raises); - return cp_build_type_attribute_variant (rval, attributes); - } - raises = TYPE_RAISES_EXCEPTIONS (t1); - if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node) - { - rval = build_function_type (valtype, p1); - if (raises) - rval = build_exception_variant (rval, raises); - return cp_build_type_attribute_variant (rval, attributes); - } + parms = p2; + else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node) + parms = p1; + else + parms = commonparms (p1, p2); - rval = build_function_type (valtype, commonparms (p1, p2)); + rval = build_function_type (valtype, parms); + gcc_assert (type_memfn_quals (t1) == type_memfn_quals (t2)); + rval = apply_memfn_quals (rval, type_memfn_quals (t1)); + raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1), + TYPE_RAISES_EXCEPTIONS (t2)); t1 = build_exception_variant (rval, raises); break; } @@ -844,7 +857,8 @@ merge_types (tree t1, tree t2) /* Get this value the long way, since TYPE_METHOD_BASETYPE is just the main variant of this. */ tree basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2))); - tree raises = TYPE_RAISES_EXCEPTIONS (t1); + tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1), + TYPE_RAISES_EXCEPTIONS (t2)); tree t3; /* If this was a member function type, get back to the @@ -878,6 +892,19 @@ merge_types (tree t1, tree t2) return cp_build_type_attribute_variant (t1, attributes); } +/* Return the ARRAY_TYPE type without its domain. */ + +tree +strip_array_domain (tree type) +{ + tree t2; + gcc_assert (TREE_CODE (type) == ARRAY_TYPE); + if (TYPE_DOMAIN (type) == NULL_TREE) + return type; + t2 = build_cplus_array_type (TREE_TYPE (type), NULL_TREE); + return cp_build_type_attribute_variant (t2, TYPE_ATTRIBUTES (type)); +} + /* Wrapper around cp_common_type that is used by c-common.c and other front end optimizations that remove promotions. @@ -962,13 +989,14 @@ comp_except_types (tree a, tree b, bool exact) } /* Return true if TYPE1 and TYPE2 are equivalent exception specifiers. - If EXACT is false, T2 can be stricter than T1 (according to 15.4/7), - otherwise it must be exact. Exception lists are unordered, but - we've already filtered out duplicates. Most lists will be in order, - we should try to make use of that. */ + If EXACT is ce_derived, T2 can be stricter than T1 (according to 15.4/5). + If EXACT is ce_normal, the compatibility rules in 15.4/3 apply. + If EXACT is ce_exact, the specs must be exactly the same. Exception lists + are unordered, but we've already filtered out duplicates. Most lists will + be in order, we should try to make use of that. */ bool -comp_except_specs (const_tree t1, const_tree t2, bool exact) +comp_except_specs (const_tree t1, const_tree t2, int exact) { const_tree probe; const_tree base; @@ -977,14 +1005,42 @@ comp_except_specs (const_tree t1, const_tree t2, bool exact) if (t1 == t2) return true; + /* First handle noexcept. */ + if (exact < ce_exact) + { + /* noexcept(false) is compatible with any throwing dynamic-exc-spec + and stricter than any spec. */ + if (t1 == noexcept_false_spec) + return !nothrow_spec_p (t2) || exact == ce_derived; + /* Even a derived noexcept(false) is compatible with a throwing + dynamic spec. */ + if (t2 == noexcept_false_spec) + return !nothrow_spec_p (t1); + + /* Otherwise, if we aren't looking for an exact match, noexcept is + equivalent to throw(). */ + if (t1 == noexcept_true_spec) + t1 = empty_except_spec; + if (t2 == noexcept_true_spec) + t2 = empty_except_spec; + } + + /* If any noexcept is left, it is only comparable to itself; + either we're looking for an exact match or we're redeclaring a + template with dependent noexcept. */ + if ((t1 && TREE_PURPOSE (t1)) + || (t2 && TREE_PURPOSE (t2))) + return (t1 && t2 + && cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))); + if (t1 == NULL_TREE) /* T1 is ... */ - return t2 == NULL_TREE || !exact; + return t2 == NULL_TREE || exact == ce_derived; if (!TREE_VALUE (t1)) /* t1 is EMPTY */ return t2 != NULL_TREE && !TREE_VALUE (t2); if (t2 == NULL_TREE) /* T2 is ... */ return false; if (TREE_VALUE (t1) && !TREE_VALUE (t2)) /* T2 is EMPTY, T1 is not */ - return !exact; + return exact == ce_derived; /* Neither set is ... or EMPTY, make sure each part of T2 is in T1. Count how many we find, to determine exactness. For exact matching and @@ -999,7 +1055,7 @@ comp_except_specs (const_tree t1, const_tree t2, bool exact) if (comp_except_types (a, b, exact)) { - if (probe == base && exact) + if (probe == base && exact > ce_derived) base = TREE_CHAIN (probe); length++; break; @@ -1008,7 +1064,7 @@ comp_except_specs (const_tree t1, const_tree t2, bool exact) if (probe == NULL_TREE) return false; } - return !exact || base == NULL_TREE || length == list_length (t1); + return exact == ce_derived || base == NULL_TREE || length == list_length (t1); } /* Compare the array types T1 and T2. ALLOW_REDECLARATION is true if @@ -1142,6 +1198,7 @@ static bool incompatible_dependent_types_p (tree t1, tree t2) { tree tparms1 = NULL_TREE, tparms2 = NULL_TREE; + bool t1_typedef_variant_p, t2_typedef_variant_p; if (!uses_template_parms (t1) || !uses_template_parms (t2)) return false; @@ -1154,10 +1211,22 @@ incompatible_dependent_types_p (tree t1, tree t2) return true; } + t1_typedef_variant_p = typedef_variant_p (t1); + t2_typedef_variant_p = typedef_variant_p (t2); + /* Either T1 or T2 must be a typedef. */ - if (!typedef_variant_p (t1) && !typedef_variant_p (t2)) + if (!t1_typedef_variant_p && !t2_typedef_variant_p) return false; + if (!t1_typedef_variant_p || !t2_typedef_variant_p) + /* Either T1 or T2 is not a typedef so we cannot compare the + template parms of the typedefs of T1 and T2. + At this point, if the main variant type of T1 and T2 are equal + it means the two types can't be incompatible, from the perspective + of this function. */ + if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) + return false; + /* So if we reach this point, it means either T1 or T2 is a typedef variant. Let's compare their template parameters. */ @@ -1218,11 +1287,20 @@ structural_comptypes (tree t1, tree t2, int strict) /* Qualifiers must match. For array types, we will check when we recur on the array element types. */ if (TREE_CODE (t1) != ARRAY_TYPE - && TYPE_QUALS (t1) != TYPE_QUALS (t2)) + && cp_type_quals (t1) != cp_type_quals (t2)) + return false; + if (TREE_CODE (t1) == FUNCTION_TYPE + && type_memfn_quals (t1) != type_memfn_quals (t2)) return false; if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2)) return false; + /* If T1 and T2 are dependent typedefs then check upfront that + the template parameters of their typedef DECLs match before + going down checking their subtypes. */ + if (incompatible_dependent_types_p (t1, t2)) + return false; + /* Allow for two different type nodes which have essentially the same definition. Note that we already checked for equality of the type qualifiers (just above). */ @@ -1231,11 +1309,6 @@ structural_comptypes (tree t1, tree t2, int strict) && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) return true; - /* If T1 and T2 are dependent typedefs then check upfront that - the template parameters of their typedef DECLs match before - going down checking their subtypes. */ - if (incompatible_dependent_types_p (t1, t2)) - return false; /* Compare the types. Break out if they could be the same. */ switch (TREE_CODE (t1)) @@ -1438,6 +1511,18 @@ comptypes (tree t1, tree t2, int strict) return structural_comptypes (t1, t2, strict); } +/* Returns nonzero iff TYPE1 and TYPE2 are the same type, ignoring + top-level qualifiers. */ + +bool +same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2) +{ + if (type1 == error_mark_node || type2 == error_mark_node) + return false; + + return same_type_p (TYPE_MAIN_VARIANT (type1), TYPE_MAIN_VARIANT (type2)); +} + /* Returns 1 if TYPE1 is at least as qualified as TYPE2. */ bool @@ -1596,6 +1681,15 @@ cxx_sizeof_expr (tree e, tsubst_flags_t complain) return e; } + /* To get the size of a static data member declared as an array of + unknown bound, we need to instantiate it. */ + if (TREE_CODE (e) == VAR_DECL + && VAR_HAD_UNKNOWN_BOUND (e) + && DECL_TEMPLATE_INSTANTIATION (e)) + instantiate_decl (e, /*defer_ok*/true, /*expl_inst_mem*/false); + + e = mark_type_use (e); + if (TREE_CODE (e) == COMPONENT_REF && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1))) @@ -1651,6 +1745,8 @@ cxx_alignof_expr (tree e, tsubst_flags_t complain) return e; } + e = mark_type_use (e); + if (TREE_CODE (e) == VAR_DECL) t = size_int (DECL_ALIGN_UNIT (e)); else if (TREE_CODE (e) == COMPONENT_REF @@ -1800,7 +1896,9 @@ unlowered_expr_type (const_tree exp) in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and function-to-pointer conversions. In addition, manifest constants are replaced by their values, and bitfield references are converted - to their declared types. + to their declared types. Note that this function does not perform the + lvalue-to-rvalue conversion for class types. If you need that conversion + to for class types, then you probably need to use force_rvalue. Although the returned value is being used as an rvalue, this function does not wrap the returned expression in a @@ -1817,6 +1915,8 @@ decay_conversion (tree exp) if (type == error_mark_node) return error_mark_node; + exp = mark_rvalue_use (exp); + exp = resolve_nondeduced_context (exp); if (type_unknown_p (exp)) { @@ -1828,6 +1928,9 @@ decay_conversion (tree exp) if (error_operand_p (exp)) return error_mark_node; + if (NULLPTR_TYPE_P (type)) + return nullptr_node; + /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. Leave such NOP_EXPRs, since RHS is being used in non-lvalue context. */ code = TREE_CODE (type); @@ -1941,6 +2044,8 @@ perform_integral_promotions (tree expr) tree type; tree promoted_type; + expr = mark_rvalue_use (expr); + /* [conv.prom] If the bitfield has an enumerated type, it is treated as any @@ -1982,7 +2087,7 @@ string_conv_p (const_tree totype, const_tree exp, int warn) else { /* Is this a string constant which has decayed to 'const char *'? */ - t = build_pointer_type (build_qualified_type (t, TYPE_QUAL_CONST)); + t = build_pointer_type (cp_build_qualified_type (t, TYPE_QUAL_CONST)); if (!same_type_p (TREE_TYPE (exp), t)) return 0; STRIP_NOPS (exp); @@ -2054,7 +2159,7 @@ lookup_anon_field (tree t, tree type) { tree field; - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) { if (TREE_STATIC (field)) continue; @@ -2112,7 +2217,7 @@ build_class_member_access_expr (tree object, tree member, complete type). */ object_type = TREE_TYPE (object); if (!currently_open_class (object_type) - && !complete_type_or_else (object_type, object)) + && !complete_type_or_maybe_complain (object_type, object, complain)) return error_mark_node; if (!CLASS_TYPE_P (object_type)) { @@ -2168,6 +2273,7 @@ build_class_member_access_expr (tree object, tree member, { /* A static data member. */ result = member; + mark_exp_read (object); /* If OBJECT has side-effects, they are supposed to occur. */ if (TREE_SIDE_EFFECTS (object)) result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result); @@ -2487,7 +2593,7 @@ finish_class_member_access_expr (tree object, tree name, bool template_p, The type of the first expression shall be "class object" (of a complete type). */ if (!currently_open_class (object_type) - && !complete_type_or_else (object_type, object)) + && !complete_type_or_maybe_complain (object_type, object, complain)) return error_mark_node; if (!CLASS_TYPE_P (object_type)) { @@ -2815,13 +2921,15 @@ cp_build_indirect_ref (tree ptr, ref_operator errorstring, LOC is the location to use in building the array reference. */ tree -build_array_ref (location_t loc, tree array, tree idx) +cp_build_array_ref (location_t loc, tree array, tree idx, + tsubst_flags_t complain) { tree ret; if (idx == 0) { - error_at (loc, "subscript missing in array reference"); + if (complain & tf_error) + error_at (loc, "subscript missing in array reference"); return error_mark_node; } @@ -2835,7 +2943,8 @@ build_array_ref (location_t loc, tree array, tree idx) { case COMPOUND_EXPR: { - tree value = build_array_ref (loc, TREE_OPERAND (array, 1), idx); + tree value = cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx, + complain); ret = build2 (COMPOUND_EXPR, TREE_TYPE (value), TREE_OPERAND (array, 0), value); SET_EXPR_LOCATION (ret, loc); @@ -2845,8 +2954,10 @@ build_array_ref (location_t loc, tree array, tree idx) case COND_EXPR: ret = build_conditional_expr (TREE_OPERAND (array, 0), - build_array_ref (loc, TREE_OPERAND (array, 1), idx), - build_array_ref (loc, TREE_OPERAND (array, 2), idx), + cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx, + complain), + cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx, + complain), tf_warning_or_error); protected_set_expr_location (ret, loc); return ret; @@ -2863,7 +2974,8 @@ build_array_ref (location_t loc, tree array, tree idx) if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (idx))) { - error_at (loc, "array subscript is not an integer"); + if (complain & tf_error) + error_at (loc, "array subscript is not an integer"); return error_mark_node; } @@ -2899,7 +3011,7 @@ build_array_ref (location_t loc, tree array, tree idx) return error_mark_node; } - if (!lvalue_p (array)) + if (!lvalue_p (array) && (complain & tf_error)) pedwarn (loc, OPT_pedantic, "ISO C++ forbids subscripting non-lvalue array"); @@ -2911,7 +3023,8 @@ build_array_ref (location_t loc, tree array, tree idx) tree foo = array; while (TREE_CODE (foo) == COMPONENT_REF) foo = TREE_OPERAND (foo, 0); - if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo)) + if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo) + && (complain & tf_warning)) warning_at (loc, OPT_Wextra, "subscripting array declared %<register%>"); } @@ -2948,12 +3061,14 @@ build_array_ref (location_t loc, tree array, tree idx) if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE) { - error_at (loc, "subscripted value is neither array nor pointer"); + if (complain & tf_error) + error_at (loc, "subscripted value is neither array nor pointer"); return error_mark_node; } if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE) { - error_at (loc, "array subscript is not an integer"); + if (complain & tf_error) + error_at (loc, "array subscript is not an integer"); return error_mark_node; } @@ -2961,13 +3076,21 @@ build_array_ref (location_t loc, tree array, tree idx) ret = cp_build_indirect_ref (cp_build_binary_op (input_location, PLUS_EXPR, ar, ind, - tf_warning_or_error), + complain), RO_ARRAY_INDEXING, - tf_warning_or_error); + complain); protected_set_expr_location (ret, loc); return ret; } } + +/* Entry point for Obj-C++. */ + +tree +build_array_ref (location_t loc, tree array, tree idx) +{ + return cp_build_array_ref (loc, array, idx, tf_warning_or_error); +} /* Resolve a pointer to member function. INSTANCE is the object instance to use, if the member points to a virtual member. @@ -3147,6 +3270,25 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain) return ret; } +/* Build a function call using varargs. */ + +tree +cp_build_function_call_nary (tree function, tsubst_flags_t complain, ...) +{ + VEC(tree,gc) *vec; + va_list args; + tree ret, t; + + vec = make_tree_vector (); + va_start (args, complain); + for (t = va_arg (args, tree); t != NULL_TREE; t = va_arg (args, tree)) + VEC_safe_push (tree, gc, vec, t); + va_end (args); + ret = cp_build_function_call_vec (function, &vec, complain); + release_tree_vector (vec); + return ret; +} + /* Build a function call using a vector of arguments. PARAMS may be NULL if there are no parameters. This changes the contents of PARAMS. */ @@ -3252,6 +3394,44 @@ cp_build_function_call_vec (tree function, VEC(tree,gc) **params, return ret; } +/* Subroutine of convert_arguments. + Warn about wrong number of args are genereted. */ + +static void +warn_args_num (location_t loc, tree fndecl, bool too_many_p) +{ + if (fndecl) + { + if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE) + { + if (DECL_NAME (fndecl) == NULL_TREE + || IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (fndecl))) + error_at (loc, + too_many_p + ? G_("too many arguments to constructor %q#D") + : G_("too few arguments to constructor %q#D"), + fndecl); + else + error_at (loc, + too_many_p + ? G_("too many arguments to member function %q#D") + : G_("too few arguments to member function %q#D"), + fndecl); + } + else + error_at (loc, + too_many_p + ? G_("too many arguments to function %q#D") + : G_("too few arguments to function %q#D"), + fndecl); + inform (DECL_SOURCE_LOCATION (fndecl), + "declared here"); + } + else + error_at (loc, too_many_p ? G_("too many arguments to function") + : G_("too few arguments to function")); +} + /* Convert the actual parameter expressions in the list VALUES to the types in the list TYPELIST. The converted expressions are stored back in the VALUES vector. @@ -3273,26 +3453,11 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl, int flags, tsubst_flags_t complain) { tree typetail; - const char *called_thing = 0; unsigned int i; /* Argument passing is always copy-initialization. */ flags |= LOOKUP_ONLYCONVERTING; - if (fndecl) - { - if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE) - { - if (DECL_NAME (fndecl) == NULL_TREE - || IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (fndecl))) - called_thing = "constructor"; - else - called_thing = "member function"; - } - else - called_thing = "function"; - } - for (i = 0, typetail = typelist; i < VEC_length (tree, *values); i++) @@ -3307,15 +3472,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl, { if (complain & tf_error) { - if (fndecl) - { - error_at (input_location, "too many arguments to %s %q#D", - called_thing, fndecl); - inform (DECL_SOURCE_LOCATION (fndecl), - "declared here"); - } - else - error ("too many arguments to function"); + warn_args_num (input_location, fndecl, /*too_many_p=*/true); return i; } else @@ -3361,7 +3518,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl, { parmval = convert_for_initialization (NULL_TREE, type, val, flags, - "argument passing", fndecl, i, complain); + ICR_ARGPASS, fndecl, i, complain); parmval = convert_for_arg_passing (type, parmval); } @@ -3420,17 +3577,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl, else { if (complain & tf_error) - { - if (fndecl) - { - error_at (input_location, "too few arguments to %s %q#D", - called_thing, fndecl); - inform (DECL_SOURCE_LOCATION (fndecl), - "declared here"); - } - else - error ("too few arguments to function"); - } + warn_args_num (input_location, fndecl, /*too_many_p=*/false); return -1; } } @@ -3943,6 +4090,9 @@ cp_build_binary_op (location_t location, } result_type = type1; } + else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1)) + /* One of the operands must be of nullptr_t type. */ + result_type = TREE_TYPE (nullptr_node); else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; @@ -4134,18 +4284,21 @@ cp_build_binary_op (location_t location, } build_type = boolean_type_node; - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) + if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE + || code0 == ENUMERAL_TYPE) + && (code1 == INTEGER_TYPE || code1 == REAL_TYPE + || code1 == ENUMERAL_TYPE)) short_compare = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) result_type = composite_pointer_type (type0, type1, op0, op1, CPO_COMPARISON, complain); - else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST - && integer_zerop (op1)) + else if (code0 == POINTER_TYPE && null_ptr_cst_p (op1)) result_type = type0; - else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST - && integer_zerop (op0)) + else if (code1 == POINTER_TYPE && null_ptr_cst_p (op0)) result_type = type1; + else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1)) + /* One of the operands must be of nullptr_t type. */ + result_type = TREE_TYPE (nullptr_node); else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; @@ -4210,7 +4363,14 @@ cp_build_binary_op (location_t location, if (!result_type && arithmetic_types_p && (shorten || common || short_compare)) - result_type = cp_common_type (type0, type1); + { + result_type = cp_common_type (type0, type1); + do_warn_double_promotion (result_type, type0, type1, + "implicit conversion from %qT to %qT " + "to match other operand of binary " + "expression", + location); + } if (!result_type) { @@ -4651,7 +4811,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, tree val; const char *invalid_op_diag; - if (error_operand_p (arg)) + if (!arg || error_operand_p (arg)) return error_mark_node; if ((invalid_op_diag @@ -4765,6 +4925,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, if (val != 0) return val; + arg = mark_lvalue_use (arg); + /* Increment or decrement the real part of the value, and don't change the imaginary part. */ if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) @@ -4898,6 +5060,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, argtype = lvalue_type (arg); + arg = mark_lvalue_use (arg); + if (TREE_CODE (arg) == OFFSET_REF) goto offset_ref; @@ -4939,6 +5103,20 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, return arg; } + /* ??? Cope with user tricks that amount to offsetof. */ + if (TREE_CODE (argtype) != FUNCTION_TYPE + && TREE_CODE (argtype) != METHOD_TYPE + && argtype != unknown_type_node + && (val = get_base_address (arg)) + && TREE_CODE (val) == INDIRECT_REF + && TREE_CONSTANT (TREE_OPERAND (val, 0))) + { + tree type = build_pointer_type (argtype); + tree op0 = fold_convert (type, TREE_OPERAND (val, 0)); + tree op1 = fold_convert (sizetype, fold_offsetof (arg, val)); + return fold_build2 (POINTER_PLUS_EXPR, type, op0, op1); + } + /* Uninstantiated types are all functions. Taking the address of a function is a no-op, so just return the argument. */ @@ -5106,7 +5284,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, { build_ptrmemfunc_type (argtype); val = build_ptrmemfunc (argtype, val, 0, - /*c_cast_p=*/false); + /*c_cast_p=*/false, + tf_warning_or_error); } return val; @@ -5340,18 +5519,36 @@ build_x_conditional_expr (tree ifexp, tree op1, tree op2, /* Given a list of expressions, return a compound expression that performs them all and returns the value of the last of them. */ -tree build_x_compound_expr_from_list (tree list, const char *msg) +tree +build_x_compound_expr_from_list (tree list, expr_list_kind exp, + tsubst_flags_t complain) { tree expr = TREE_VALUE (list); if (TREE_CHAIN (list)) { - if (msg) - permerror (input_location, "%s expression list treated as compound expression", msg); + if (complain & tf_error) + switch (exp) + { + case ELK_INIT: + permerror (input_location, "expression list treated as compound " + "expression in initializer"); + break; + case ELK_MEM_INIT: + permerror (input_location, "expression list treated as compound " + "expression in mem-initializer"); + break; + case ELK_FUNC_CAST: + permerror (input_location, "expression list treated as compound " + "expression in functional cast"); + break; + default: + gcc_unreachable (); + } for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list)) expr = build_x_compound_expr (expr, TREE_VALUE (list), - tf_warning_or_error); + complain); } return expr; @@ -5427,7 +5624,7 @@ build_compound_expr (location_t loc ATTRIBUTE_UNUSED, tree lhs, tree rhs) tree cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain) { - lhs = convert_to_void (lhs, "left-hand operand of comma", complain); + lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain); if (lhs == error_mark_node || rhs == error_mark_node) return error_mark_node; @@ -5505,7 +5702,7 @@ check_for_casting_away_constness (tree src_type, tree dest_type, tree convert_ptrmem (tree type, tree expr, bool allow_inverse_p, - bool c_cast_p) + bool c_cast_p, tsubst_flags_t complain) { if (TYPE_PTRMEM_P (type)) { @@ -5516,7 +5713,10 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p, delta = get_delta_difference (TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (expr)), TYPE_PTRMEM_CLASS_TYPE (type), allow_inverse_p, - c_cast_p); + c_cast_p, complain); + if (delta == error_mark_node) + return error_mark_node; + if (!integer_zerop (delta)) { tree cond, op1, op2; @@ -5540,7 +5740,7 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p, } else return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, - allow_inverse_p, c_cast_p); + allow_inverse_p, c_cast_p, complain); } /* If EXPR is an INTEGER_CST and ORIG is an arithmetic constant, return @@ -5694,7 +5894,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, Any expression can be explicitly converted to type cv void. */ if (TREE_CODE (type) == VOID_TYPE) - return convert_to_void (expr, /*implicit=*/NULL, complain); + return convert_to_void (expr, ICV_CAST, complain); /* [expr.static.cast] @@ -5776,7 +5976,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, if (!c_cast_p) check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR); return convert_ptrmem (type, expr, /*allow_inverse_p=*/1, - c_cast_p); + c_cast_p, tf_warning_or_error); } } @@ -5964,8 +6164,11 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, /* [expr.reinterpret.cast] A pointer can be converted to any integral type large enough to - hold it. */ - if (CP_INTEGRAL_TYPE_P (type) && TYPE_PTR_P (intype)) + hold it. ... A value of type std::nullptr_t can be converted to + an integral type; the conversion has the same meaning and + validity as a conversion of (void*)0 to the integral type. */ + if (CP_INTEGRAL_TYPE_P (type) + && (TYPE_PTR_P (intype) || NULLPTR_TYPE_P (intype))) { if (TYPE_PRECISION (type) < TYPE_PRECISION (intype)) { @@ -5975,6 +6178,8 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, else return error_mark_node; } + if (NULLPTR_TYPE_P (intype)) + return build_int_cst (type, 0); } /* [expr.reinterpret.cast] A value of integral or enumeration type can be explicitly @@ -6269,6 +6474,15 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain) return error_mark_node; } + if (TREE_CODE (type) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE + /* Casting to an integer of smaller size is an error detected elsewhere. */ + && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value)) + /* Don't warn about converting any constant. */ + && !TREE_CONSTANT (value)) + warning_at (input_location, OPT_Wint_to_pointer_cast, + "cast to pointer from integer of different size"); + /* A C-style cast can be a const_cast. */ result = build_const_cast_1 (type, value, /*complain=*/false, &valid_p); @@ -6560,6 +6774,12 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, if (BRACE_ENCLOSED_INITIALIZER_P (newrhs)) { + if (modifycode != INIT_EXPR) + { + if (complain & tf_error) + error ("assigning to an array from an initializer list"); + return error_mark_node; + } if (check_array_initializer (lhs, lhstype, newrhs)) return error_mark_node; newrhs = digest_init (lhstype, newrhs); @@ -6601,10 +6821,10 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, /* Calls with INIT_EXPR are all direct-initialization, so don't set LOOKUP_ONLYCONVERTING. */ newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL, - "initialization", NULL_TREE, 0, + ICR_INIT, NULL_TREE, 0, complain); else - newrhs = convert_for_assignment (olhstype, newrhs, "assignment", + newrhs = convert_for_assignment (olhstype, newrhs, ICR_ASSIGN, NULL_TREE, 0, complain, LOOKUP_IMPLICIT); if (!same_type_p (lhstype, olhstype)) @@ -6671,20 +6891,32 @@ build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, /* Helper function for get_delta_difference which assumes FROM is a base class of TO. Returns a delta for the conversion of pointer-to-member - of FROM to pointer-to-member of TO. If the conversion is invalid, + of FROM to pointer-to-member of TO. If the conversion is invalid and + tf_error is not set in COMPLAIN returns error_mark_node, otherwise returns zero. If FROM is not a base class of TO, returns NULL_TREE. - If C_CAST_P is true, this conversion is taking place as part of a C-style - cast. */ + If C_CAST_P is true, this conversion is taking place as part of a + C-style cast. */ static tree -get_delta_difference_1 (tree from, tree to, bool c_cast_p) +get_delta_difference_1 (tree from, tree to, bool c_cast_p, + tsubst_flags_t complain) { tree binfo; base_kind kind; + base_access access = c_cast_p ? ba_unique : ba_check; + + /* Note: ba_quiet does not distinguish between access control and + ambiguity. */ + if (!(complain & tf_error)) + access |= ba_quiet; + + binfo = lookup_base (to, from, access, &kind); - binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check, &kind); if (kind == bk_inaccessible || kind == bk_ambig) { + if (!(complain & tf_error)) + return error_mark_node; + error (" in pointer to member function conversion"); return size_zero_node; } @@ -6696,22 +6928,26 @@ get_delta_difference_1 (tree from, tree to, bool c_cast_p) /* FROM is a virtual base class of TO. Issue an error or warning depending on whether or not this is a reinterpret cast. */ { + if (!(complain & tf_error)) + return error_mark_node; + error ("pointer to member conversion via virtual base %qT", BINFO_TYPE (binfo_from_vbase (binfo))); return size_zero_node; } } - else - return NULL_TREE; + else + return NULL_TREE; } /* Get difference in deltas for different pointer to member function - types. Returns an integer constant of type PTRDIFF_TYPE_NODE. If - the conversion is invalid, the constant is zero. If - ALLOW_INVERSE_P is true, then allow reverse conversions as well. - If C_CAST_P is true this conversion is taking place as part of a - C-style cast. + types. If the conversion is invalid and tf_error is not set in + COMPLAIN, returns error_mark_node, otherwise returns an integer + constant of type PTRDIFF_TYPE_NODE and its value is zero if the + conversion is invalid. If ALLOW_INVERSE_P is true, then allow reverse + conversions as well. If C_CAST_P is true this conversion is taking + place as part of a C-style cast. Note that the naming of FROM and TO is kind of backwards; the return value is what we add to a TO in order to get a FROM. They are named @@ -6721,7 +6957,7 @@ get_delta_difference_1 (tree from, tree to, bool c_cast_p) static tree get_delta_difference (tree from, tree to, bool allow_inverse_p, - bool c_cast_p) + bool c_cast_p, tsubst_flags_t complain) { tree result; @@ -6729,25 +6965,37 @@ get_delta_difference (tree from, tree to, /* Pointer to member of incomplete class is permitted*/ result = size_zero_node; else - result = get_delta_difference_1 (from, to, c_cast_p); + result = get_delta_difference_1 (from, to, c_cast_p, complain); + + if (result == error_mark_node) + return error_mark_node; if (!result) { if (!allow_inverse_p) { + if (!(complain & tf_error)) + return error_mark_node; + error_not_base_type (from, to); error (" in pointer to member conversion"); - result = size_zero_node; + result = size_zero_node; } else { - result = get_delta_difference_1 (to, from, c_cast_p); + result = get_delta_difference_1 (to, from, c_cast_p, complain); + + if (result == error_mark_node) + return error_mark_node; if (result) result = size_diffop_loc (input_location, - size_zero_node, result); + size_zero_node, result); else { + if (!(complain & tf_error)) + return error_mark_node; + error_not_base_type (from, to); error (" in pointer to member conversion"); result = size_zero_node; @@ -6772,7 +7020,7 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn) /* Pull the FIELD_DECLs out of the type. */ pfn_field = TYPE_FIELDS (type); - delta_field = TREE_CHAIN (pfn_field); + delta_field = DECL_CHAIN (pfn_field); /* Make sure DELTA has the type we want. */ delta = convert_and_check (delta_type_node, delta); @@ -6806,7 +7054,8 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn) Return error_mark_node, if something goes wrong. */ tree -build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p) +build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p, + tsubst_flags_t complain) { tree fn; tree pfn_type; @@ -6833,7 +7082,9 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p) n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type), TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type), force, - c_cast_p); + c_cast_p, complain); + if (n == error_mark_node) + return error_mark_node; /* We don't have to do any conversion to convert a pointer-to-member to its own type. But, we don't want to @@ -6873,7 +7124,7 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p) } /* Handle null pointer to member function conversions. */ - if (integer_zerop (pfn)) + if (null_ptr_cst_p (pfn)) { pfn = build_c_cast (input_location, type, integer_zero_node); return build_ptrmemfunc1 (to_type, @@ -6916,7 +7167,7 @@ expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn) /* First, calculate the adjustment to the function's class. */ *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0, - /*c_cast_p=*/0); + /*c_cast_p=*/0, tf_warning_or_error); if (!DECL_VIRTUAL_P (fn)) *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn)); @@ -7004,14 +7255,15 @@ delta_from_ptrmemfunc (tree t) } /* Convert value RHS to type TYPE as preparation for an assignment to - an lvalue of type TYPE. ERRTYPE is a string to use in error - messages: "assignment", "return", etc. If FNDECL is non-NULL, we - are doing the conversion in order to pass the PARMNUMth argument of - FNDECL. */ + an lvalue of type TYPE. ERRTYPE indicates what kind of error the + implicit conversion is. If FNDECL is non-NULL, we are doing the + conversion in order to pass the PARMNUMth argument of FNDECL. + If FNDECL is NULL, we are doing the conversion in function pointer + argument passing, conversion in initialization, etc. */ static tree convert_for_assignment (tree type, tree rhs, - const char *errtype, tree fndecl, int parmnum, + impl_conv_rhs errtype, tree fndecl, int parmnum, tsubst_flags_t complain, int flags) { tree rhstype; @@ -7026,7 +7278,10 @@ convert_for_assignment (tree type, tree rhs, if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE && vector_types_convertible_p (type, rhstype, true)) - return convert (type, rhs); + { + rhs = mark_rvalue_use (rhs); + return convert (type, rhs); + } if (rhs == error_mark_node || rhstype == error_mark_node) return error_mark_node; @@ -7048,27 +7303,32 @@ convert_for_assignment (tree type, tree rhs, if (c_dialect_objc ()) { int parmno; + tree selector; tree rname = fndecl; - if (!strcmp (errtype, "assignment")) - parmno = -1; - else if (!strcmp (errtype, "initialization")) - parmno = -2; - else - { - tree selector = objc_message_selector (); - - parmno = parmnum; - - if (selector && parmno > 1) - { - rname = selector; - parmno -= 1; - } + switch (errtype) + { + case ICR_ASSIGN: + parmno = -1; + break; + case ICR_INIT: + parmno = -2; + break; + default: + selector = objc_message_selector (); + parmno = parmnum; + if (selector && parmno > 1) + { + rname = selector; + parmno -= 1; + } } if (objc_compare_types (type, rhstype, parmno, rname)) - return convert (type, rhs); + { + rhs = mark_rvalue_use (rhs); + return convert (type, rhs); + } } /* [expr.ass] @@ -7101,8 +7361,35 @@ convert_for_assignment (tree type, tree rhs, error ("cannot convert %qT to %qT for argument %qP to %qD", rhstype, type, parmnum, fndecl); else - error ("cannot convert %qT to %qT in %s", rhstype, type, - errtype); + switch (errtype) + { + case ICR_DEFAULT_ARGUMENT: + error ("cannot convert %qT to %qT in default argument", + rhstype, type); + break; + case ICR_ARGPASS: + error ("cannot convert %qT to %qT in argument passing", + rhstype, type); + break; + case ICR_CONVERTING: + error ("cannot convert %qT to %qT", + rhstype, type); + break; + case ICR_INIT: + error ("cannot convert %qT to %qT in initialization", + rhstype, type); + break; + case ICR_RETURN: + error ("cannot convert %qT to %qT in return", + rhstype, type); + break; + case ICR_ASSIGN: + error ("cannot convert %qT to %qT in assignment", + rhstype, type); + break; + default: + gcc_unreachable(); + } } return error_mark_node; } @@ -7114,9 +7401,42 @@ convert_for_assignment (tree type, tree rhs, && coder == codel && check_missing_format_attribute (type, rhstype) && (complain & tf_warning)) - warning (OPT_Wmissing_format_attribute, - "%s might be a candidate for a format attribute", - errtype); + switch (errtype) + { + case ICR_ARGPASS: + case ICR_DEFAULT_ARGUMENT: + if (fndecl) + warning (OPT_Wmissing_format_attribute, + "parameter %qP of %qD might be a candidate " + "for a format attribute", parmnum, fndecl); + else + warning (OPT_Wmissing_format_attribute, + "parameter might be a candidate " + "for a format attribute"); + break; + case ICR_CONVERTING: + warning (OPT_Wmissing_format_attribute, + "target of conversion might be might be a candidate " + "for a format attribute"); + break; + case ICR_INIT: + warning (OPT_Wmissing_format_attribute, + "target of initialization might be a candidate " + "for a format attribute"); + break; + case ICR_RETURN: + warning (OPT_Wmissing_format_attribute, + "return type might be a candidate " + "for a format attribute"); + break; + case ICR_ASSIGN: + warning (OPT_Wmissing_format_attribute, + "left-hand side of assignment might be a candidate " + "for a format attribute"); + break; + default: + gcc_unreachable(); + } } /* If -Wparentheses, warn about a = b = c when a has type bool and b @@ -7142,7 +7462,7 @@ convert_for_assignment (tree type, tree rhs, /* Convert RHS to be of type TYPE. If EXP is nonzero, it is the target of the initialization. - ERRTYPE is a string to use in error messages. + ERRTYPE indicates what kind of error the implicit conversion is. Two major differences between the behavior of `convert_for_assignment' and `convert_for_initialization' @@ -7158,7 +7478,7 @@ convert_for_assignment (tree type, tree rhs, tree convert_for_initialization (tree exp, tree type, tree rhs, int flags, - const char *errtype, tree fndecl, int parmnum, + impl_conv_rhs errtype, tree fndecl, int parmnum, tsubst_flags_t complain) { enum tree_code codel = TREE_CODE (type); @@ -7540,7 +7860,7 @@ check_return_expr (tree retval, bool *no_warning) if ((cxx_dialect != cxx98) && named_return_value_okay_p /* The variable must not have the `volatile' qualifier. */ - && !(cp_type_quals (TREE_TYPE (retval)) & TYPE_QUAL_VOLATILE) + && !CP_TYPE_VOLATILE_P (TREE_TYPE (retval)) /* The return type must be a class type. */ && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) flags = flags | LOOKUP_PREFER_RVALUE; @@ -7549,7 +7869,7 @@ check_return_expr (tree retval, bool *no_warning) to the type of return value's location to handle the case that functype is smaller than the valtype. */ retval = convert_for_initialization - (NULL_TREE, functype, retval, flags, "return", NULL_TREE, 0, + (NULL_TREE, functype, retval, flags, ICR_RETURN, NULL_TREE, 0, tf_warning_or_error); retval = convert (valtype, retval); @@ -7754,24 +8074,50 @@ comp_ptr_ttypes_const (tree to, tree from) int cp_type_quals (const_tree type) { + int quals; /* This CONST_CAST is okay because strip_array_types returns its argument unmodified and we assign it to a const_tree. */ - type = strip_array_types (CONST_CAST_TREE(type)); - if (type == error_mark_node) + type = strip_array_types (CONST_CAST_TREE (type)); + if (type == error_mark_node + /* Quals on a FUNCTION_TYPE are memfn quals. */ + || TREE_CODE (type) == FUNCTION_TYPE) return TYPE_UNQUALIFIED; - return TYPE_QUALS (type); + quals = TYPE_QUALS (type); + /* METHOD and REFERENCE_TYPEs should never have quals. */ + gcc_assert ((TREE_CODE (type) != METHOD_TYPE + && TREE_CODE (type) != REFERENCE_TYPE) + || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)) + == TYPE_UNQUALIFIED)); + return quals; } -/* Returns nonzero if the TYPE is const from a C++ perspective: look inside - arrays. */ +/* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or + METHOD_TYPE. */ -bool -cp_type_readonly (const_tree type) +int +type_memfn_quals (const_tree type) { - /* This CONST_CAST is okay because strip_array_types returns its - argument unmodified and we assign it to a const_tree. */ - type = strip_array_types (CONST_CAST_TREE(type)); - return TYPE_READONLY (type); + if (TREE_CODE (type) == FUNCTION_TYPE) + return TYPE_QUALS (type); + else if (TREE_CODE (type) == METHOD_TYPE) + return cp_type_quals (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type)))); + else + gcc_unreachable (); +} + +/* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to + MEMFN_QUALS. */ + +tree +apply_memfn_quals (tree type, cp_cv_quals memfn_quals) +{ + /* Could handle METHOD_TYPE here if necessary. */ + gcc_assert (TREE_CODE (type) == FUNCTION_TYPE); + if (TYPE_QUALS (type) == memfn_quals) + return type; + /* This should really have a different TYPE_MAIN_VARIANT, but that gets + complex. */ + return build_qualified_type (type, memfn_quals); } /* Returns nonzero if TYPE is const or volatile. */ @@ -7818,23 +8164,8 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl) if (TREE_CODE (decl) == TYPE_DECL) return; - if (TREE_CODE (type) == FUNCTION_TYPE - && type_quals != TYPE_UNQUALIFIED) - { - /* This was an error in C++98 (cv-qualifiers cannot be added to - a function type), but DR 295 makes the code well-formed by - dropping the extra qualifiers. */ - if (pedantic) - { - tree bad_type = build_qualified_type (type, type_quals); - pedwarn (input_location, OPT_pedantic, - "ignoring %qV qualifiers added to function type %qT", - bad_type, type); - } - - TREE_TYPE (decl) = TYPE_MAIN_VARIANT (type); - return; - } + gcc_assert (!(TREE_CODE (type) == FUNCTION_TYPE + && type_quals != TYPE_UNQUALIFIED)); /* Avoid setting TREE_READONLY incorrectly. */ if (/* If the object has a constructor, the constructor may modify @@ -7991,3 +8322,4 @@ lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain) return win; } + diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 7ec4374a709..b9c027a68cf 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1,7 +1,7 @@ /* Report error messages, build initializers, and perform some front-end optimizations for C++ compiler. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) @@ -37,8 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "toplev.h" #include "output.h" -#include "diagnostic.h" -#include "real.h" +#include "diagnostic-core.h" static tree process_init_constructor (tree type, tree init); @@ -353,7 +352,7 @@ abstract_virtuals_error (tree decl, tree type) slot = htab_find_slot_with_hash (abstract_pending_vars, type, (hashval_t)TYPE_UID (type), INSERT); - pat = GGC_NEW (struct pending_abstract_type); + pat = ggc_alloc_pending_abstract_type (); pat->type = type; pat->decl = decl; pat->locus = ((decl && DECL_P (decl)) @@ -413,7 +412,7 @@ abstract_virtuals_error (tree decl, tree type) " because the following virtual functions are pure within %qT:", type); - for (ix = 0; VEC_iterate (tree, pure, ix, fn); ix++) + FOR_EACH_VEC_ELT (tree, pure, ix, fn) inform (input_location, "\t%+#D", fn); /* Now truncate the vector. This leaves it non-null, so we know there are pure virtuals, but empty so we don't list them out @@ -515,7 +514,8 @@ cxx_incomplete_type_diagnostic (const_tree value, const_tree type, "invalid use of dependent type %qT", type); break; - case UNKNOWN_TYPE: + case LANG_TYPE: + gcc_assert (type == unknown_type_node); if (value && TREE_CODE (value) == COMPONENT_REF) goto bad_member; else if (value && TREE_CODE (value) == ADDR_EXPR) @@ -549,13 +549,15 @@ cxx_incomplete_type_error (const_tree value, const_tree type) expression to which INIT should be assigned. INIT is a CONSTRUCTOR. */ static void -split_nonconstant_init_1 (tree dest, tree init) +split_nonconstant_init_1 (tree dest, tree *initp) { unsigned HOST_WIDE_INT idx; + tree init = *initp; tree field_index, value; tree type = TREE_TYPE (dest); tree inner_type = NULL; bool array_type_p = false; + HOST_WIDE_INT num_type_elements, num_initialized_elements; switch (TREE_CODE (type)) { @@ -567,6 +569,7 @@ split_nonconstant_init_1 (tree dest, tree init) case RECORD_TYPE: case UNION_TYPE: case QUAL_UNION_TYPE: + num_initialized_elements = 0; FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, field_index, value) { @@ -589,12 +592,13 @@ split_nonconstant_init_1 (tree dest, tree init) sub = build3 (COMPONENT_REF, inner_type, dest, field_index, NULL_TREE); - split_nonconstant_init_1 (sub, value); + split_nonconstant_init_1 (sub, &value); } else if (!initializer_constant_valid_p (value, inner_type)) { tree code; tree sub; + HOST_WIDE_INT inner_elements; /* FIXME: Ordered removal is O(1) so the whole function is worst-case quadratic. This could be fixed using an aside @@ -617,9 +621,22 @@ split_nonconstant_init_1 (tree dest, tree init) code = build2 (INIT_EXPR, inner_type, sub, value); code = build_stmt (input_location, EXPR_STMT, code); add_stmt (code); + + inner_elements = count_type_elements (inner_type, true); + if (inner_elements < 0) + num_initialized_elements = -1; + else if (num_initialized_elements >= 0) + num_initialized_elements += inner_elements; continue; } } + + num_type_elements = count_type_elements (type, true); + /* If all elements of the initializer are non-constant and + have been split out, we don't need the empty CONSTRUCTOR. */ + if (num_type_elements > 0 + && num_type_elements == num_initialized_elements) + *initp = NULL; break; case VECTOR_TYPE: @@ -655,7 +672,7 @@ split_nonconstant_init (tree dest, tree init) if (TREE_CODE (init) == CONSTRUCTOR) { code = push_stmt_list (); - split_nonconstant_init_1 (dest, init); + split_nonconstant_init_1 (dest, &init); code = pop_stmt_list (code); DECL_INITIAL (dest) = init; TREE_READONLY (dest) = 0; @@ -697,7 +714,7 @@ store_init_value (tree decl, tree init, int flags) if (MAYBE_CLASS_TYPE_P (type)) { - gcc_assert (TYPE_HAS_TRIVIAL_INIT_REF (type) + gcc_assert (!type_has_nontrivial_copy_init (type) || TREE_CODE (init) == CONSTRUCTOR); if (TREE_CODE (init) == TREE_LIST) @@ -710,10 +727,9 @@ store_init_value (tree decl, tree init, int flags) else if (TREE_CODE (init) == TREE_LIST && TREE_TYPE (init) != unknown_type_node) { - if (TREE_CODE (decl) == RESULT_DECL) - init = build_x_compound_expr_from_list (init, - "return value initializer"); - else if (TREE_CODE (init) == TREE_LIST + gcc_assert (TREE_CODE (decl) != RESULT_DECL); + + if (TREE_CODE (init) == TREE_LIST && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) { error ("cannot initialize arrays using this syntax"); @@ -721,7 +737,8 @@ store_init_value (tree decl, tree init, int flags) } else /* We get here with code like `int a (2);' */ - init = build_x_compound_expr_from_list (init, "initializer"); + init = build_x_compound_expr_from_list (init, ELK_INIT, + tf_warning_or_error); } /* End of special C++ code. */ @@ -892,7 +909,7 @@ digest_init_r (tree type, tree init, bool nested, int flags) if (cxx_dialect != cxx98 && nested) check_narrowing (type, init); init = convert_for_initialization (0, type, init, flags, - "initialization", NULL_TREE, 0, + ICR_INIT, NULL_TREE, 0, tf_warning_or_error); exp = &init; @@ -946,7 +963,7 @@ digest_init_r (tree type, tree init, bool nested, int flags) return convert_for_initialization (NULL_TREE, type, init, flags, - "initialization", NULL_TREE, 0, + ICR_INIT, NULL_TREE, 0, tf_warning_or_error); } } @@ -1018,7 +1035,7 @@ process_init_constructor_array (tree type, tree init) if (!unbounded && VEC_length (constructor_elt, v) > len) error ("too many initializers for %qT", type); - for (i = 0; VEC_iterate (constructor_elt, v, i, ce); ++i) + FOR_EACH_VEC_ELT (constructor_elt, v, i, ce) { if (ce->index) { @@ -1099,7 +1116,7 @@ process_init_constructor_record (tree type, tree init) /* Generally, we will always have an index for each initializer (which is a FIELD_DECL, put by reshape_init), but compound literals don't go trough reshape_init. So we need to handle both cases. */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { tree next; tree type; @@ -1148,11 +1165,15 @@ process_init_constructor_record (tree type, tree init) default-initialization, we can't rely on the back end to do it for us, so build up TARGET_EXPRs. If the type in question is a class, just build one up; if it's an array, recurse. */ + next = build_constructor (init_list_type_node, NULL); if (MAYBE_CLASS_TYPE_P (TREE_TYPE (field))) - next = build_functional_cast (TREE_TYPE (field), NULL_TREE, - tf_warning_or_error); - else - next = build_constructor (init_list_type_node, NULL); + { + next = finish_compound_literal (TREE_TYPE (field), next); + /* direct-initialize the target. No temporary is going + to be involved. */ + if (TREE_CODE (next) == TARGET_EXPR) + TARGET_EXPR_DIRECT_INIT_P (next) = true; + } next = digest_init_r (TREE_TYPE (field), next, true, LOOKUP_IMPLICIT); @@ -1377,9 +1398,9 @@ tree build_x_arrow (tree expr) { tree orig_expr = expr; - tree types_memoized = NULL_TREE; tree type = TREE_TYPE (expr); tree last_rval = NULL_TREE; + VEC(tree,gc) *types_memoized = NULL; if (type == error_mark_node) return error_mark_node; @@ -1401,16 +1422,13 @@ build_x_arrow (tree expr) if (expr == error_mark_node) return error_mark_node; - if (value_member (TREE_TYPE (expr), types_memoized)) + if (vec_member (TREE_TYPE (expr), types_memoized)) { error ("circular pointer delegation detected"); return error_mark_node; } - else - { - types_memoized = tree_cons (NULL_TREE, TREE_TYPE (expr), - types_memoized); - } + + VEC_safe_push (tree, gc, types_memoized, TREE_TYPE (expr)); last_rval = expr; } @@ -1461,6 +1479,9 @@ build_m_component_ref (tree datum, tree component) if (error_operand_p (datum) || error_operand_p (component)) return error_mark_node; + datum = mark_lvalue_use (datum); + component = mark_rvalue_use (component); + ptrmem_type = TREE_TYPE (component); if (!TYPE_PTR_TO_MEMBER_P (ptrmem_type)) { @@ -1556,7 +1577,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain) if (TREE_CODE (type) == REFERENCE_TYPE && !parms) { - error ("invalid value-initialization of reference types"); + error ("invalid value-initialization of reference type"); return error_mark_node; } @@ -1574,7 +1595,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain) return cp_convert (type, integer_zero_node); /* This must build a C cast. */ - parms = build_x_compound_expr_from_list (parms, "functional cast"); + parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain); return cp_build_c_cast (type, parms, complain); } @@ -1585,7 +1606,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain) then the slot being initialized will be filled in. */ - if (!complete_type_or_else (type, NULL_TREE)) + if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)) return error_mark_node; if (abstract_virtuals_error (NULL_TREE, type)) return error_mark_node; @@ -1610,7 +1631,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain) just calling the constructor, so fall through. */ && !TYPE_HAS_USER_CONSTRUCTOR (type)) { - exp = build_value_init (type); + exp = build_value_init (type, complain); return get_target_expr (exp); } @@ -1699,10 +1720,14 @@ merge_exception_specifiers (tree list, tree add) { if (!list || !add) return NULL_TREE; - else if (!TREE_VALUE (list)) - return add; + /* For merging noexcept(true) and throw(), take the more recent one (LIST). + A throw(type-list) spec takes precedence over a noexcept(false) spec. + Any other noexcept-spec should only be merged with an equivalent one. + So the !TREE_VALUE code below is correct for all cases. */ else if (!TREE_VALUE (add)) return list; + else if (!TREE_VALUE (list)) + return add; else { tree orig_list = list; |