diff options
author | Ben Cheng <bccheng@google.com> | 2014-04-22 13:33:12 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2014-04-22 13:33:12 -0700 |
commit | e3cc64dec20832769406aa38cde83c7dd4194bf4 (patch) | |
tree | ef8e39be37cfe0cb69d850043b7924389ff17164 /gcc-4.9/gcc/cp | |
parent | f33c7b3122b1d7950efa88067c9a156229ba647b (diff) | |
download | toolchain_gcc-e3cc64dec20832769406aa38cde83c7dd4194bf4.tar.gz toolchain_gcc-e3cc64dec20832769406aa38cde83c7dd4194bf4.tar.bz2 toolchain_gcc-e3cc64dec20832769406aa38cde83c7dd4194bf4.zip |
[4.9] GCC 4.9.0 official release refresh
Change-Id: Ic99a7da8b44b789a48aeec93b33e93944d6e6767
Diffstat (limited to 'gcc-4.9/gcc/cp')
-rw-r--r-- | gcc-4.9/gcc/cp/ChangeLog | 165 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/ChangeLog-2008 | 4 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/ChangeLog-2010 | 20 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/ChangeLog-2011 | 2 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/ChangeLog-2012 | 2 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/Make-lang.in | 2 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/call.c | 3 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/class.c | 121 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/decl.c | 72 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/decl2.c | 5 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/error.c | 7 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/init.c | 35 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/mangle.c | 23 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/method.c | 16 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/name-lookup.c | 8 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/name-lookup.h | 9 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/parser.c | 56 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/pt.c | 139 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/search.c | 16 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/semantics.c | 19 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/tree.c | 12 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/typeck.c | 8 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/typeck2.c | 15 |
23 files changed, 539 insertions, 220 deletions
diff --git a/gcc-4.9/gcc/cp/ChangeLog b/gcc-4.9/gcc/cp/ChangeLog index e0229906d..f95944b9b 100644 --- a/gcc-4.9/gcc/cp/ChangeLog +++ b/gcc-4.9/gcc/cp/ChangeLog @@ -1,3 +1,168 @@ +2014-04-22 Release Manager + + * GCC 4.9.0 released. + +2014-04-15 Jakub Jelinek <jakub@redhat.com> + + PR plugins/59335 + * Make-lang.h (CP_PLUGIN_HEADERS): Add type-utils.h. + +2014-04-10 Richard Biener <rguenther@suse.de> + Jakub Jelinek <jakub@redhat.com> + + PR ipa/60761 + * error.c (dump_decl) <case FUNCTION_DECL>: If + DECL_LANG_SPECIFIC is NULL, but DECL_ABSTRACT_ORIGIN is not, + recurse on DECL_ABSTRACT_ORIGIN instead of printing + <built-in>. + +2014-04-09 Fabien Chêne <fabien@gcc.gnu.org> + + * pt.c (check_template_variable): Check for the return of pedwarn + before emitting a note. + * parser.c (cp_parser_lambda_introducer): Likewise. + +2014-04-08 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/59115 + * pt.c (process_template_parm): For an invalid non-type parameter + only set TREE_TYPE to error_mark_node. + (push_inline_template_parms_recursive, comp_template_parms, + redeclare_class_template, coerce_template_template_parm, + coerce_template_template_parms, unify): Use error_operand_p. + +2014-04-08 Nathan Sidwell <nathan@codesourcery.com> + + * class.c (check_bases_and_members): Warn about non-virtual dtors + in public bases only. Check warn_ecpp before complaining about + non-polymorphic bases. + +2014-04-04 Fabien Chêne <fabien@gcc.gnu.org> + + * decl.c (duplicate_decls): Check for the return of warning_at + before emitting a note. + (warn_misplaced_attr_for_class_type): Likewise. + (check_tag_decl): Likewise. + +2014-04-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58207 + * semantics.c (sort_constexpr_mem_initializers): Robustify loop. + +2014-04-04 Patrick Palka <patrick@parcs.ath.cx> + + PR c++/44613 + * semantics.c (add_stmt): Set STATEMENT_LIST_HAS_LABEL. + * decl.c (cp_finish_decl): Create a new BIND_EXPR before + instantiating a variable-sized type. + + PR c++/21113 + * decl.c (decl_jump_unsafe): Consider variably-modified decls. + +2014-04-04 Fabien Chêne <fabien@gcc.gnu.org> + + * class.c (find_abi_tags_r): Check for the return of warning + before emitting a note. + (one_inherited_ctor): Likewise. + +2014-04-04 Fabien Chêne <fabien@gcc.gnu.org> + + * decl.c (duplicate_decls): Check for the return of permerror + before emitting a note. + +2014-04-03 Nathan Sidwell <nathan@codesourcery.com> + + * class.c (accessible_nvdtor_p): New. + (check_bases): Don't check base destructor here ... + (check_bases_and_members): ... check them here. Trigger on + Wnon-virtual-dtor flag. + (finish_struct_1): Use accessible_nvdtor_p. + +2014-04-01 Jason Merrill <jason@redhat.com> + + * pt.c (process_partial_specialization): Say "not deducible" + rather than "not used". Use inform. + + PR c++/60374 + * pt.c (coerce_template_parms): Check that the pack expansion + pattern works with the first matching parameter. + +2014-04-01 Fabien Chêne <fabien@gcc.gnu.org> + + * init.c (perform_member_init): Homogenize uninitialized + diagnostics. + +2014-04-01 Jason Merrill <jason@redhat.com> + + PR c++/60708 + * call.c (build_array_conv): Call complete_type. + + PR c++/60713 + * typeck2.c (PICFLAG_SIDE_EFFECTS): New. + (picflag_from_initializer): Return it. + (process_init_constructor): Handle it. + + PR c++/60642 + * decl2.c (is_late_template_attribute): Don't defer abi_tag. + * mangle.c (write_unqualified_name): Fix abi_tag on templates. + * pt.c (get_template_info): Handle NAMESPACE_DECL. + (most_general_template): Handle more kinds of template. + * tree.c (handle_abi_tag_attribute): Ignore abi_tag on template + instantiations and specializations. + +2014-03-31 Patrick Palka <patrick@parcs.ath.cx> + + PR c++/44859 + * typeck.c (maybe_warn_about_returning_address_of_local): Unwrap + COMPONENT_REFs and ARRAY_REFs sooner. + +2014-03-29 Adam Butcher <adam@jessamine.co.uk> + + PR c++/60626 + * parser.c (cp_parser_init_declarator): Handle erroneous generic type + usage in non-functions with pushed scope. + +2014-03-28 Adam Butcher <adam@jessamine.co.uk> + + PR c++/60573 + * name-lookup.h (cp_binding_level): New transient field defining_class_p + to indicate whether a scope is in the process of defining a class. + * semantics.c (begin_class_definition): Set defining_class_p. + * name-lookup.c (leave_scope): Reset defining_class_p. + * parser.c (synthesize_implicit_template_parm): Use cp_binding_level:: + defining_class_p rather than TYPE_BEING_DEFINED as the predicate for + unwinding to class-defining scope to handle the erroneous definition of + a generic function of an arbitrarily nested class within an enclosing + class. + +2014-03-26 Fabien Chêne <fabien@gcc.gnu.org> + + PR c++/52369 + * method.c (walk_field_subobs): Improve the diagnostic + locations for both REFERENCE_TYPEs and non-static const members. + * init.c (diagnose_uninitialized_cst_or_ref_member): Use %q#D + instead of %qD to be consistent with the c++11 diagnostic. + +2014-03-25 Jason Merrill <jason@redhat.com> + + PR c++/60566 + PR c++/58678 + * class.c (build_vtbl_initializer): Handle abstract dtors here. + * search.c (get_pure_virtuals): Not here. + + PR c++/60375 + * parser.c (cp_parser_lambda_expression): Don't parse the body of + a lambda in unevaluated context. + + PR c++/60628 + * decl.c (create_array_type_for_decl): Complain about array of auto. + +2014-03-25 Jakub Jelinek <jakub@redhat.com> + + PR c++/60331 + * semantics.c (potential_constant_expression_1): Handle + DECL_EXPR. + 2014-03-24 Adam Butcher <adam@jessamine.co.uk> PR c++/60627 diff --git a/gcc-4.9/gcc/cp/ChangeLog-2008 b/gcc-4.9/gcc/cp/ChangeLog-2008 index 5a69a5d20..83fd123a7 100644 --- a/gcc-4.9/gcc/cp/ChangeLog-2008 +++ b/gcc-4.9/gcc/cp/ChangeLog-2008 @@ -307,8 +307,8 @@ * g++spec.c (LIBSTDCXX_STATIC): New. (lang_spec_driver): Use LIBSTDCXX_STATIC when not shared_libgcc. - -2008-11-05 Fabien Chene <fabien.chene@gmail.com> + +2008-11-05 Fabien Chêne <fabien@gcc.gnu.org> PR c++/32519 * cp-tree.h: Fix DECL_NONSTATIC_MEMBER_P to handle member template diff --git a/gcc-4.9/gcc/cp/ChangeLog-2010 b/gcc-4.9/gcc/cp/ChangeLog-2010 index 5f563157c..e706b7cb8 100644 --- a/gcc-4.9/gcc/cp/ChangeLog-2010 +++ b/gcc-4.9/gcc/cp/ChangeLog-2010 @@ -3127,13 +3127,13 @@ * typeck.c (cp_build_modify_expr): Complain about assignment to array from init list. -2010-05-10 Fabien Chêne <fabien.chene@gmail.com> +2010-05-10 Fabien Chêne <fabien@gcc.gnu.org> PR c++/43719 - * decl.c (check_initializer): strip array type before checking for + * 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> +2010-05-07 Fabien Chêne <fabien@gcc.gnu.org> PR c++/43951 * init.c (diagnose_uninitialized_cst_or_ref_member_1): Returns the @@ -3258,12 +3258,12 @@ PR c++/43779 * typeck.c (warn_args_num): New function. (convert_arguments): Use warn_args_num to print the diagnostic - messages. + messages. -2010-04-29 Fabien Chêne <fabien.chene@gmail.com> +2010-04-29 Fabien Chêne <fabien@gcc.gnu.org> PR c++/43890 - * init.c (diagnose_uninitialized_cst_or_ref_member): check for + * 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> @@ -3277,10 +3277,10 @@ * init.c (perform_member_init): Check CLASS_TYPE_P. -2010-04-27 Fabien Chêne <fabien.chene@gmail.com> +2010-04-27 Fabien Chêne <fabien@gcc.gnu.org> PR c++/29043 - * init.c (perform_member_init): check for uninitialized const or + * init.c (perform_member_init): Check for uninitialized const or reference members, including array types. 2010-04-24 Jason Merrill <jason@redhat.com> @@ -3331,7 +3331,7 @@ convert_like_real. * cp-tree.h: Adjust. -2010-04-27 Fabien Chêne <fabien.chene@gmail.com> +2010-04-27 Fabien Chêne <fabien@gcc.gnu.org> Jason Merrill <jason@redhat.com> PR c++/42844 @@ -3403,7 +3403,7 @@ * call.c (type_decays_to): Call cv_unqualified for non-class type. -2010-04-12 Fabien Chene <fabien.chene@gmail.com> +2010-04-12 Fabien Chêne <fabien@gcc.gnu.org>> PR c++/25811 * cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Declare. diff --git a/gcc-4.9/gcc/cp/ChangeLog-2011 b/gcc-4.9/gcc/cp/ChangeLog-2011 index 506598965..02dde6e78 100644 --- a/gcc-4.9/gcc/cp/ChangeLog-2011 +++ b/gcc-4.9/gcc/cp/ChangeLog-2011 @@ -3511,7 +3511,7 @@ 2011-05-07 Fabien Chêne <fabien@gcc.gnu.org> PR c++/48859 - * init.c (diagnose_uninitialized_cst_or_ref_member_1): stop the + * init.c (diagnose_uninitialized_cst_or_ref_member_1): Stop the recursion if there is user defined constructor. 2011-05-09 Jason Merrill <jason@redhat.com> diff --git a/gcc-4.9/gcc/cp/ChangeLog-2012 b/gcc-4.9/gcc/cp/ChangeLog-2012 index a57051ebf..e63a3f79d 100644 --- a/gcc-4.9/gcc/cp/ChangeLog-2012 +++ b/gcc-4.9/gcc/cp/ChangeLog-2012 @@ -2716,7 +2716,7 @@ 2012-02-16 Fabien Chêne <fabien@gcc.gnu.org> PR c++/52126 - * decl.c (xref_basetypes): call dependent_scope_p instead of + * decl.c (xref_basetypes): Call dependent_scope_p instead of dependent_type_p. 2012-02-16 Jason Merrill <jason@redhat.com> diff --git a/gcc-4.9/gcc/cp/Make-lang.in b/gcc-4.9/gcc/cp/Make-lang.in index 5480c4eae..bd1c1d78f 100644 --- a/gcc-4.9/gcc/cp/Make-lang.in +++ b/gcc-4.9/gcc/cp/Make-lang.in @@ -39,7 +39,7 @@ CXX_INSTALL_NAME := $(shell echo c++|sed '$(program_transform_name)') GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)') CXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo c++|sed '$(program_transform_name)') GXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo g++|sed '$(program_transform_name)') -CP_PLUGIN_HEADERS := cp-tree.h cxx-pretty-print.h name-lookup.h +CP_PLUGIN_HEADERS := cp-tree.h cxx-pretty-print.h name-lookup.h type-utils.h # # Define the names for selecting c++ in LANGUAGES. diff --git a/gcc-4.9/gcc/cp/call.c b/gcc-4.9/gcc/cp/call.c index 9a0e3b5a1..98469e9e4 100644 --- a/gcc-4.9/gcc/cp/call.c +++ b/gcc-4.9/gcc/cp/call.c @@ -948,6 +948,9 @@ build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) bool user = false; enum conversion_rank rank = cr_exact; + /* We might need to propagate the size from the element to the array. */ + complete_type (type); + if (TYPE_DOMAIN (type) && !variably_modified_type_p (TYPE_DOMAIN (type), NULL_TREE)) { diff --git a/gcc-4.9/gcc/cp/class.c b/gcc-4.9/gcc/cp/class.c index b46391be1..334bfd5ee 100644 --- a/gcc-4.9/gcc/cp/class.c +++ b/gcc-4.9/gcc/cp/class.c @@ -149,6 +149,7 @@ static tree *build_base_field (record_layout_info, tree, splay_tree, tree *); static void build_base_fields (record_layout_info, splay_tree, tree *); static void check_methods (tree); static void remove_zero_width_bit_fields (tree); +static bool accessible_nvdtor_p (tree); static void check_bases (tree, int *, int *); static void check_bases_and_members (tree); static tree create_vtable_ptr (tree, tree *); @@ -1384,19 +1385,21 @@ find_abi_tags_r (tree *tp, int *walk_subtrees, void *data) /* Otherwise we're diagnosing missing tags. */ else if (TYPE_P (p->subob)) { - warning (OPT_Wabi_tag, "%qT does not have the %E abi tag " - "that base %qT has", p->t, tag, p->subob); - inform (location_of (p->subob), "%qT declared here", - p->subob); + if (warning (OPT_Wabi_tag, "%qT does not have the %E abi tag " + "that base %qT has", p->t, tag, p->subob)) + inform (location_of (p->subob), "%qT declared here", + p->subob); } else { - warning (OPT_Wabi_tag, "%qT does not have the %E abi tag " - "that %qT (used in the type of %qD) has", - p->t, tag, *tp, p->subob); - inform (location_of (p->subob), "%qD declared here", - p->subob); - inform (location_of (*tp), "%qT declared here", *tp); + if (warning (OPT_Wabi_tag, "%qT does not have the %E abi tag " + "that %qT (used in the type of %qD) has", + p->t, tag, *tp, p->subob)) + { + inform (location_of (p->subob), "%qD declared here", + p->subob); + inform (location_of (*tp), "%qT declared here", *tp); + } } } } @@ -1476,6 +1479,33 @@ inherit_targ_abi_tags (tree t) mark_type_abi_tags (t, false); } +/* Return true, iff class T has a non-virtual destructor that is + accessible from outside the class heirarchy (i.e. is public, or + there's a suitable friend. */ + +static bool +accessible_nvdtor_p (tree t) +{ + tree dtor = CLASSTYPE_DESTRUCTORS (t); + + /* An implicitly declared destructor is always public. And, + if it were virtual, we would have created it by now. */ + if (!dtor) + return true; + + if (DECL_VINDEX (dtor)) + return false; /* Virtual */ + + if (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor)) + return true; /* Public */ + + if (CLASSTYPE_FRIEND_CLASSES (t) + || DECL_FRIENDLIST (TYPE_MAIN_DECL (t))) + return true; /* Has friends */ + + return false; +} + /* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P, and NO_CONST_ASN_REF_P. Also set flag bits in T based on properties of the bases. */ @@ -1512,13 +1542,6 @@ check_bases (tree t, if (!CLASSTYPE_LITERAL_P (basetype)) CLASSTYPE_LITERAL_P (t) = false; - /* Effective C++ rule 14. We only need to check TYPE_POLYMORPHIC_P - here because the case of virtual functions but non-virtual - dtor is handled in finish_struct_1. */ - if (!TYPE_POLYMORPHIC_P (basetype)) - warning (OPT_Weffc__, - "base class %q#T has a non-virtual destructor", basetype); - /* If the base class doesn't have copy constructors or assignment operators that take const references, then the derived class cannot have such a member automatically @@ -3062,9 +3085,9 @@ one_inherited_ctor (tree ctor, tree t) one_inheriting_sig (t, ctor, new_parms, i); if (parms == NULL_TREE) { - warning (OPT_Winherited_variadic_ctor, - "the ellipsis in %qD is not inherited", ctor); - inform (DECL_SOURCE_LOCATION (ctor), "%qD declared here", ctor); + if (warning (OPT_Winherited_variadic_ctor, + "the ellipsis in %qD is not inherited", ctor)) + inform (DECL_SOURCE_LOCATION (ctor), "%qD declared here", ctor); } } @@ -5547,6 +5570,30 @@ check_bases_and_members (tree t) TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t); TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t); + /* Warn if a public base of a polymorphic type has an accessible + non-virtual destructor. It is only now that we know the class is + polymorphic. Although a polymorphic base will have a already + been diagnosed during its definition, we warn on use too. */ + if (TYPE_POLYMORPHIC_P (t) && warn_nonvdtor) + { + tree binfo = TYPE_BINFO (t); + vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (binfo); + tree base_binfo; + unsigned i; + + for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + { + tree basetype = TREE_TYPE (base_binfo); + + if ((*accesses)[i] == access_public_node + && (TYPE_POLYMORPHIC_P (basetype) || warn_ecpp) + && accessible_nvdtor_p (basetype)) + warning (OPT_Wnon_virtual_dtor, + "base class %q#T has accessible non-virtual destructor", + basetype); + } + } + /* If the class has no user-declared constructor, but does have non-static const or reference data members that can never be initialized, issue a warning. */ @@ -6597,25 +6644,11 @@ finish_struct_1 (tree t) /* This warning does not make sense for Java classes, since they cannot have destructors. */ - if (!TYPE_FOR_JAVA (t) && warn_nonvdtor && TYPE_POLYMORPHIC_P (t)) - { - tree dtor; - - dtor = CLASSTYPE_DESTRUCTORS (t); - if (/* An implicitly declared destructor is always public. And, - if it were virtual, we would have created it by now. */ - !dtor - || (!DECL_VINDEX (dtor) - && (/* public non-virtual */ - (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor)) - || (/* non-public non-virtual with friends */ - (TREE_PRIVATE (dtor) || TREE_PROTECTED (dtor)) - && (CLASSTYPE_FRIEND_CLASSES (t) - || DECL_FRIENDLIST (TYPE_MAIN_DECL (t))))))) - warning (OPT_Wnon_virtual_dtor, - "%q#T has virtual functions and accessible" - " non-virtual destructor", t); - } + if (!TYPE_FOR_JAVA (t) && warn_nonvdtor + && TYPE_POLYMORPHIC_P (t) && accessible_nvdtor_p (t)) + warning (OPT_Wnon_virtual_dtor, + "%q#T has virtual functions and accessible" + " non-virtual destructor", t); complete_vars (t); @@ -9017,6 +9050,16 @@ build_vtbl_initializer (tree binfo, if (!TARGET_VTABLE_USES_DESCRIPTORS) init = fold_convert (vfunc_ptr_type_node, build_fold_addr_expr (fn)); + /* Don't refer to a virtual destructor from a constructor + vtable or a vtable for an abstract class, since destroying + an object under construction is undefined behavior and we + don't want it to be considered a candidate for speculative + devirtualization. But do create the thunk for ABI + compliance. */ + if (DECL_DESTRUCTOR_P (fn_original) + && (CLASSTYPE_PURE_VIRTUALS (DECL_CONTEXT (fn_original)) + || orig_binfo != binfo)) + init = size_zero_node; } } diff --git a/gcc-4.9/gcc/cp/decl.c b/gcc-4.9/gcc/cp/decl.c index c912ffcb5..340059442 100644 --- a/gcc-4.9/gcc/cp/decl.c +++ b/gcc-4.9/gcc/cp/decl.c @@ -1648,10 +1648,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) && prototype_p (TREE_TYPE (newdecl))) { /* Prototype decl follows defn w/o prototype. */ - warning_at (DECL_SOURCE_LOCATION (newdecl), 0, - "prototype specified for %q#D", newdecl); - inform (DECL_SOURCE_LOCATION (olddecl), - "previous non-prototype definition here"); + if (warning_at (DECL_SOURCE_LOCATION (newdecl), 0, + "prototype specified for %q#D", newdecl)) + inform (DECL_SOURCE_LOCATION (olddecl), + "previous non-prototype definition here"); } else if (VAR_OR_FUNCTION_DECL_P (olddecl) && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)) @@ -1737,9 +1737,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (permerror (input_location, "default argument given for parameter " "%d of %q#D", i, newdecl)) - permerror (DECL_SOURCE_LOCATION (olddecl), - "previous specification in %q#D here", - olddecl); + inform (DECL_SOURCE_LOCATION (olddecl), + "previous specification in %q#D here", + olddecl); } else { @@ -2785,12 +2785,11 @@ decl_jump_unsafe (tree decl) || type == error_mark_node) return 0; - type = strip_array_types (type); - - if (DECL_NONTRIVIALLY_INITIALIZED_P (decl)) + if (DECL_NONTRIVIALLY_INITIALIZED_P (decl) + || variably_modified_type_p (type, NULL_TREE)) return 2; - if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))) + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) return 1; return 0; @@ -4242,12 +4241,12 @@ warn_misplaced_attr_for_class_type (source_location location, { gcc_assert (OVERLOAD_TYPE_P (class_type)); - warning_at (location, OPT_Wattributes, - "attribute ignored in declaration " - "of %q#T", class_type); - inform (location, - "attribute for %q#T must follow the %qs keyword", - class_type, class_key_or_enum_as_string (class_type)); + if (warning_at (location, OPT_Wattributes, + "attribute ignored in declaration " + "of %q#T", class_type)) + inform (location, + "attribute for %q#T must follow the %qs keyword", + class_type, class_key_or_enum_as_string (class_type)); } /* Make sure that a declaration with no declarator is well-formed, i.e. @@ -4374,12 +4373,12 @@ check_tag_decl (cp_decl_specifier_seq *declspecs, No attribute-specifier-seq shall appertain to an explicit instantiation. */ { - warning_at (loc, OPT_Wattributes, - "attribute ignored in explicit instantiation %q#T", - declared_type); - inform (loc, - "no attribute can be applied to " - "an explicit instantiation"); + if (warning_at (loc, OPT_Wattributes, + "attribute ignored in explicit instantiation %q#T", + declared_type)) + inform (loc, + "no attribute can be applied to " + "an explicit instantiation"); } else warn_misplaced_attr_for_class_type (loc, declared_type); @@ -6441,7 +6440,24 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, after the call to check_initializer so that the DECL_EXPR for a reference temp is added before the DECL_EXPR for the reference itself. */ if (DECL_FUNCTION_SCOPE_P (decl)) - add_decl_expr (decl); + { + /* If we're building a variable sized type, and we might be + reachable other than via the top of the current binding + level, then create a new BIND_EXPR so that we deallocate + the object at the right time. */ + if (VAR_P (decl) + && DECL_SIZE (decl) + && !TREE_CONSTANT (DECL_SIZE (decl)) + && STATEMENT_LIST_HAS_LABEL (cur_stmt_list)) + { + tree bind; + bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); + TREE_SIDE_EFFECTS (bind) = 1; + add_stmt (bind); + BIND_EXPR_BODY (bind) = push_stmt_list (); + } + add_decl_expr (decl); + } /* Let the middle end know about variables and functions -- but not static data members in uninstantiated class templates. */ @@ -8534,6 +8550,14 @@ create_array_type_for_decl (tree name, tree type, tree size) && (flag_iso || warn_vla > 0)) pedwarn (input_location, OPT_Wvla, "array of array of runtime bound"); + /* 8.3.4p1: ...if the type of the identifier of D contains the auto + type-specifier, the program is ill-formed. */ + if (type_uses_auto (type)) + { + error ("%qD declared as array of %qT", name, type); + return error_mark_node; + } + /* Figure out the index type for the array. */ if (size) itype = compute_array_index_type (name, size, tf_warning_or_error); diff --git a/gcc-4.9/gcc/cp/decl2.c b/gcc-4.9/gcc/cp/decl2.c index dfc532d5b..6c52e53bc 100644 --- a/gcc-4.9/gcc/cp/decl2.c +++ b/gcc-4.9/gcc/cp/decl2.c @@ -1169,8 +1169,9 @@ is_late_template_attribute (tree attr, tree decl) /* Also defer most attributes on dependent types. This is not necessary in all cases, but is the better default. */ else if (dependent_type_p (type) - /* But attribute visibility specifically works on - templates. */ + /* But attributes abi_tag and visibility specifically apply + to templates. */ + && !is_attribute_p ("abi_tag", name) && !is_attribute_p ("visibility", name)) return true; else diff --git a/gcc-4.9/gcc/cp/error.c b/gcc-4.9/gcc/cp/error.c index 454feb519..699d5458a 100644 --- a/gcc-4.9/gcc/cp/error.c +++ b/gcc-4.9/gcc/cp/error.c @@ -1145,7 +1145,12 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags) case FUNCTION_DECL: if (! DECL_LANG_SPECIFIC (t)) - pp_string (pp, M_("<built-in>")); + { + if (DECL_ABSTRACT_ORIGIN (t)) + dump_decl (pp, DECL_ABSTRACT_ORIGIN (t), flags); + else + pp_string (pp, M_("<built-in>")); + } else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t)) dump_global_iord (pp, t); else diff --git a/gcc-4.9/gcc/cp/init.c b/gcc-4.9/gcc/cp/init.c index a2549575a..1a1f6c0fe 100644 --- a/gcc-4.9/gcc/cp/init.c +++ b/gcc-4.9/gcc/cp/init.c @@ -694,11 +694,14 @@ perform_member_init (tree member, tree init) if (CP_TYPE_CONST_P (type) && init == NULL_TREE && default_init_uninitialized_part (type)) - /* TYPE_NEEDS_CONSTRUCTING can be set just because we have a - vtable; still give this diagnostic. */ - permerror (DECL_SOURCE_LOCATION (current_function_decl), - "uninitialized member %qD with %<const%> type %qT", - member, type); + { + /* TYPE_NEEDS_CONSTRUCTING can be set just because we have a + vtable; still give this diagnostic. */ + if (permerror (DECL_SOURCE_LOCATION (current_function_decl), + "uninitialized const member in %q#T", type)) + inform (DECL_SOURCE_LOCATION (member), + "%q#D should be initialized", member ); + } finish_expr_stmt (build_aggr_init (decl, init, flags, tf_warning_or_error)); } @@ -710,13 +713,19 @@ perform_member_init (tree member, tree init) tree core_type; /* member traversal: note it leaves init NULL */ if (TREE_CODE (type) == REFERENCE_TYPE) - permerror (DECL_SOURCE_LOCATION (current_function_decl), - "uninitialized reference member %qD", - member); + { + if (permerror (DECL_SOURCE_LOCATION (current_function_decl), + "uninitialized reference member in %q#T", type)) + inform (DECL_SOURCE_LOCATION (member), + "%q#D should be initialized", member); + } else if (CP_TYPE_CONST_P (type)) - permerror (DECL_SOURCE_LOCATION (current_function_decl), - "uninitialized member %qD with %<const%> type %qT", - member, type); + { + if (permerror (DECL_SOURCE_LOCATION (current_function_decl), + "uninitialized const member in %q#T", type)) + inform (DECL_SOURCE_LOCATION (member), + "%q#D should be initialized", member ); + } core_type = strip_array_types (type); @@ -2157,7 +2166,7 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, "of %q#T", DECL_CONTEXT (field), origin); } inform (DECL_SOURCE_LOCATION (field), - "%qD should be initialized", field); + "%q#D should be initialized", field); } } @@ -2185,7 +2194,7 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, "of %q#T", DECL_CONTEXT (field), origin); } inform (DECL_SOURCE_LOCATION (field), - "%qD should be initialized", field); + "%q#D should be initialized", field); } } diff --git a/gcc-4.9/gcc/cp/mangle.c b/gcc-4.9/gcc/cp/mangle.c index 251edb14d..da82dd6ac 100644 --- a/gcc-4.9/gcc/cp/mangle.c +++ b/gcc-4.9/gcc/cp/mangle.c @@ -180,7 +180,7 @@ static void write_unscoped_template_name (const tree); static void write_nested_name (const tree); static void write_prefix (const tree); static void write_template_prefix (const tree); -static void write_unqualified_name (const tree); +static void write_unqualified_name (tree); static void write_conversion_operator_name (const tree); static void write_source_name (tree); static void write_literal_operator_name (tree); @@ -1195,7 +1195,7 @@ write_unqualified_id (tree identifier) } static void -write_unqualified_name (const tree decl) +write_unqualified_name (tree decl) { MANGLE_TRACE_TREE ("unqualified-name", decl); @@ -1280,10 +1280,21 @@ write_unqualified_name (const tree decl) write_source_name (DECL_NAME (decl)); } - tree attrs = (TREE_CODE (decl) == TYPE_DECL - ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) - : DECL_ATTRIBUTES (decl)); - write_abi_tags (lookup_attribute ("abi_tag", attrs)); + /* We use the ABI tags from the primary template, ignoring tags on any + specializations. This is necessary because C++ doesn't require a + specialization to be declared before it is used unless the use + requires a complete type, but we need to get the tags right on + incomplete types as well. */ + if (tree tmpl = most_general_template (decl)) + decl = DECL_TEMPLATE_RESULT (tmpl); + /* Don't crash on an unbound class template. */ + if (decl) + { + tree attrs = (TREE_CODE (decl) == TYPE_DECL + ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) + : DECL_ATTRIBUTES (decl)); + write_abi_tags (lookup_attribute ("abi_tag", attrs)); + } } /* Write the unqualified-name for a conversion operator to TYPE. */ diff --git a/gcc-4.9/gcc/cp/method.c b/gcc-4.9/gcc/cp/method.c index d72b564a4..11bff7f45 100644 --- a/gcc-4.9/gcc/cp/method.c +++ b/gcc-4.9/gcc/cp/method.c @@ -1110,15 +1110,23 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk, && default_init_uninitialized_part (mem_type)) { if (diag) - error ("uninitialized non-static const member %q#D", - field); + { + error ("uninitialized const member in %q#T", + current_class_type); + inform (DECL_SOURCE_LOCATION (field), + "%q#D should be initialized", field); + } bad = true; } else if (TREE_CODE (mem_type) == REFERENCE_TYPE) { if (diag) - error ("uninitialized non-static reference member %q#D", - field); + { + error ("uninitialized reference member in %q#T", + current_class_type); + inform (DECL_SOURCE_LOCATION (field), + "%q#D should be initialized", field); + } bad = true; } diff --git a/gcc-4.9/gcc/cp/name-lookup.c b/gcc-4.9/gcc/cp/name-lookup.c index 53f14f3ee..0137c3f4a 100644 --- a/gcc-4.9/gcc/cp/name-lookup.c +++ b/gcc-4.9/gcc/cp/name-lookup.c @@ -1630,10 +1630,14 @@ leave_scope (void) free_binding_level = scope; } - /* Find the innermost enclosing class scope, and reset - CLASS_BINDING_LEVEL appropriately. */ if (scope->kind == sk_class) { + /* Reset DEFINING_CLASS_P to allow for reuse of a + class-defining scope in a non-defining context. */ + scope->defining_class_p = 0; + + /* Find the innermost enclosing class scope, and reset + CLASS_BINDING_LEVEL appropriately. */ class_binding_level = NULL; for (scope = current_binding_level; scope; scope = scope->level_chain) if (scope->kind == sk_class) diff --git a/gcc-4.9/gcc/cp/name-lookup.h b/gcc-4.9/gcc/cp/name-lookup.h index a63442f85..40e0338ca 100644 --- a/gcc-4.9/gcc/cp/name-lookup.h +++ b/gcc-4.9/gcc/cp/name-lookup.h @@ -255,7 +255,14 @@ struct GTY(()) cp_binding_level { unsigned more_cleanups_ok : 1; unsigned have_cleanups : 1; - /* 24 bits left to fill a 32-bit word. */ + /* Transient state set if this scope is of sk_class kind + and is in the process of defining 'this_entity'. Reset + on leaving the class definition to allow for the scope + to be subsequently re-used as a non-defining scope for + 'this_entity'. */ + unsigned defining_class_p : 1; + + /* 23 bits left to fill a 32-bit word. */ }; /* The binding level currently in effect. */ diff --git a/gcc-4.9/gcc/cp/parser.c b/gcc-4.9/gcc/cp/parser.c index 4ca08a13d..f386eed27 100644 --- a/gcc-4.9/gcc/cp/parser.c +++ b/gcc-4.9/gcc/cp/parser.c @@ -8718,14 +8718,17 @@ cp_parser_lambda_expression (cp_parser* parser) { tree lambda_expr = build_lambda_expr (); tree type; - bool ok; + bool ok = true; 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"); + { + error_at (LAMBDA_EXPR_LOCATION (lambda_expr), + "lambda-expression in unevaluated context"); + ok = false; + } /* We may be in the middle of deferred access check. Disable it now. */ @@ -8770,12 +8773,15 @@ cp_parser_lambda_expression (cp_parser* parser) /* By virtue of defining a local class, a lambda expression has access to the private variables of enclosing classes. */ - ok = cp_parser_lambda_declarator_opt (parser, lambda_expr); + ok &= cp_parser_lambda_declarator_opt (parser, lambda_expr); if (ok) cp_parser_lambda_body (parser, lambda_expr); else if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE)) - cp_parser_skip_to_end_of_block_or_statement (parser); + { + if (cp_parser_skip_to_closing_brace (parser)) + cp_lexer_consume_token (parser->lexer); + } /* The capture list was built up in reverse order; fix that now. */ LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) @@ -8955,10 +8961,10 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) if (VAR_P (capture_init_expr) && decl_storage_duration (capture_init_expr) != dk_auto) { - pedwarn (capture_token->location, 0, "capture of variable " - "%qD with non-automatic storage duration", - capture_init_expr); - inform (0, "%q+#D declared here", capture_init_expr); + if (pedwarn (capture_token->location, 0, "capture of variable " + "%qD with non-automatic storage duration", + capture_init_expr)) + inform (0, "%q+#D declared here", capture_init_expr); continue; } @@ -16823,7 +16829,14 @@ cp_parser_init_declarator (cp_parser* parser, been issued. */ if (parser->fully_implicit_function_template_p) if (!function_declarator_p (declarator)) - finish_fully_implicit_template (parser, /*member_decl_opt=*/0); + { + if (pushed_scope) + { + pop_scope (pushed_scope); + pushed_scope = 0; + } + finish_fully_implicit_template (parser, /*member_decl_opt=*/0); + } /* For an in-class declaration, use `grokfield' to create the declaration. */ @@ -31993,7 +32006,7 @@ synthesize_implicit_template_parm (cp_parser *parser) { /* If not defining a class, then any class scope is a scope level in an out-of-line member definition. In this case simply wind back - beyond the first such scope to inject the template argument list. + beyond the first such scope to inject the template parameter list. Otherwise wind back to the class being defined. The latter can occur in class member friend declarations such as: @@ -32004,12 +32017,23 @@ synthesize_implicit_template_parm (cp_parser *parser) friend void A::foo (auto); }; - The template argument list synthesized for the friend declaration - must be injected in the scope of 'B', just beyond the scope of 'A' - introduced by 'A::'. */ + The template parameter list synthesized for the friend declaration + must be injected in the scope of 'B'. This can also occur in + erroneous cases such as: + + struct A { + struct B { + void foo (auto); + }; + void B::foo (auto) {} + }; + + Here the attempted definition of 'B::foo' within 'A' is ill-formed + but, nevertheless, the template parameter list synthesized for the + declarator should be injected into the scope of 'A' as if the + ill-formed template was specified explicitly. */ - while (scope->kind == sk_class - && !TYPE_BEING_DEFINED (scope->this_entity)) + while (scope->kind == sk_class && !scope->defining_class_p) { parent_scope = scope; scope = scope->level_chain; diff --git a/gcc-4.9/gcc/cp/pt.c b/gcc-4.9/gcc/cp/pt.c index c791d031a..318c32507 100644 --- a/gcc-4.9/gcc/cp/pt.c +++ b/gcc-4.9/gcc/cp/pt.c @@ -320,6 +320,9 @@ get_template_info (const_tree t) if (!t || t == error_mark_node) return NULL; + if (TREE_CODE (t) == NAMESPACE_DECL) + return NULL; + if (DECL_P (t) && DECL_LANG_SPECIFIC (t)) tinfo = DECL_TEMPLATE_INFO (t); @@ -411,7 +414,7 @@ push_inline_template_parms_recursive (tree parmlist, int levels) { tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); - if (parm == error_mark_node) + if (error_operand_p (parm)) continue; gcc_assert (DECL_P (parm)); @@ -2301,10 +2304,10 @@ check_template_variable (tree decl) "%qD is not a static data member of a class template", decl); else if (template_header_count > wanted) { - pedwarn (DECL_SOURCE_LOCATION (decl), 0, - "too many template headers for %D (should be %d)", - decl, wanted); - if (CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx)) + bool warned = pedwarn (DECL_SOURCE_LOCATION (decl), 0, + "too many template headers for %D (should be %d)", + decl, wanted); + if (warned && CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx)) inform (DECL_SOURCE_LOCATION (decl), "members of an explicitly specialized class are defined " "without a template header"); @@ -2826,7 +2829,7 @@ comp_template_parms (const_tree parms1, const_tree parms2) /* If either of the template parameters are invalid, assume they match for the sake of error recovery. */ - if (parm1 == error_mark_node || parm2 == error_mark_node) + if (error_operand_p (parm1) || error_operand_p (parm2)) return 1; if (TREE_CODE (parm1) != TREE_CODE (parm2)) @@ -3637,11 +3640,7 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args, to the LIST being built. This new parameter is a non-type parameter iff IS_NON_TYPE is true. This new parameter is a parameter pack iff IS_PARAMETER_PACK is true. The location of PARM - is in PARM_LOC. NUM_TEMPLATE_PARMS is the size of the template - parameter list PARM belongs to. This is used used to create a - proper canonical type for the type of PARM that is to be created, - iff PARM is a type. If the size is not known, this parameter shall - be set to 0. */ + is in PARM_LOC. */ tree process_template_parm (tree list, location_t parm_loc, tree parm, @@ -3649,7 +3648,6 @@ process_template_parm (tree list, location_t parm_loc, tree parm, { tree decl = 0; tree defval; - tree err_parm_list; int idx = 0; gcc_assert (TREE_CODE (parm) == TREE_LIST); @@ -3670,8 +3668,6 @@ process_template_parm (tree list, location_t parm_loc, tree parm, ++idx; } - else - idx = 0; if (is_non_type) { @@ -3679,39 +3675,29 @@ process_template_parm (tree list, location_t parm_loc, tree parm, SET_DECL_TEMPLATE_PARM_P (parm); - if (TREE_TYPE (parm) == error_mark_node) - { - err_parm_list = build_tree_list (defval, parm); - TREE_VALUE (err_parm_list) = error_mark_node; - return chainon (list, err_parm_list); - } - else - { - /* [temp.param] - - The top-level cv-qualifiers on the template-parameter are - ignored when determining its type. */ - TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); - if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1)) - { - err_parm_list = build_tree_list (defval, parm); - TREE_VALUE (err_parm_list) = error_mark_node; - return chainon (list, err_parm_list); - } + if (TREE_TYPE (parm) != error_mark_node) + { + /* [temp.param] + + The top-level cv-qualifiers on the template-parameter are + ignored when determining its type. */ + TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); + if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1)) + TREE_TYPE (parm) = error_mark_node; + else if (uses_parameter_packs (TREE_TYPE (parm)) + && !is_parameter_pack + /* If we're in a nested template parameter list, the template + template parameter could be a parameter pack. */ + && processing_template_parmlist == 1) + { + /* This template parameter is not a parameter pack, but it + should be. Complain about "bare" parameter packs. */ + check_for_bare_parameter_packs (TREE_TYPE (parm)); - if (uses_parameter_packs (TREE_TYPE (parm)) && !is_parameter_pack - /* If we're in a nested template parameter list, the template - template parameter could be a parameter pack. */ - && processing_template_parmlist == 1) - { - /* This template parameter is not a parameter pack, but it - should be. Complain about "bare" parameter packs. */ - check_for_bare_parameter_packs (TREE_TYPE (parm)); - - /* Recover by calling this a parameter pack. */ - is_parameter_pack = true; - } - } + /* Recover by calling this a parameter pack. */ + is_parameter_pack = true; + } + } /* A template parameter is not modifiable. */ TREE_CONSTANT (parm) = 1; @@ -4136,15 +4122,17 @@ process_partial_specialization (tree decl) for (i = 0; i < ntparms; ++i) if (tpd.parms[i] == 0) { - /* One of the template parms was not used in the + /* One of the template parms was not used in a deduced context in the specialization. */ if (!did_error_intro) { - error ("template parameters not used in partial specialization:"); + error ("template parameters not deducible in " + "partial specialization:"); did_error_intro = true; } - error (" %qD", TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); + inform (input_location, " %qD", + TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); } if (did_error_intro) @@ -5122,7 +5110,7 @@ redeclare_class_template (tree type, tree parms) continue; tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i)); - if (tmpl_parm == error_mark_node) + if (error_operand_p (tmpl_parm)) return false; parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); @@ -6082,8 +6070,8 @@ coerce_template_template_parm (tree parm, tree in_decl, tree outer_args) { - if (arg == NULL_TREE || arg == error_mark_node - || parm == NULL_TREE || parm == error_mark_node) + if (arg == NULL_TREE || error_operand_p (arg) + || parm == NULL_TREE || error_operand_p (parm)) return 0; if (TREE_CODE (arg) != TREE_CODE (parm)) @@ -6176,7 +6164,7 @@ coerce_template_template_parms (tree parm_parms, { parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, nparms - 1)); - if (parm == error_mark_node) + if (error_operand_p (parm)) return 0; switch (TREE_CODE (parm)) @@ -6930,6 +6918,26 @@ coerce_template_parms (tree parms, { if (PACK_EXPANSION_P (arg)) { + /* "If every valid specialization of a variadic template + requires an empty template parameter pack, the template is + ill-formed, no diagnostic required." So check that the + pattern works with this parameter. */ + tree pattern = PACK_EXPANSION_PATTERN (arg); + tree conv = convert_template_argument (TREE_VALUE (parm), + pattern, new_args, + complain, parm_idx, + in_decl); + if (conv == error_mark_node) + { + inform (input_location, "so any instantiation with a " + "non-empty parameter pack would be ill-formed"); + ++lost; + } + else if (TYPE_P (conv) && !TYPE_P (pattern)) + /* Recover from missing typename. */ + TREE_VEC_ELT (inner_args, arg_idx) + = make_pack_expansion (conv); + /* We don't know how many args we have yet, just use the unconverted ones for now. */ new_inner_args = inner_args; @@ -17492,7 +17500,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, case TEMPLATE_TEMPLATE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM: tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0)); - if (tparm == error_mark_node) + if (error_operand_p (tparm)) return unify_invalid (explain_p); if (TEMPLATE_TYPE_LEVEL (parm) @@ -17510,7 +17518,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, idx = TEMPLATE_TYPE_IDX (parm); targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx); tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx)); - if (tparm == error_mark_node) + if (error_operand_p (tparm)) return unify_invalid (explain_p); /* Check for mixed types and values. */ @@ -17693,7 +17701,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, case TEMPLATE_PARM_INDEX: tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0)); - if (tparm == error_mark_node) + if (error_operand_p (tparm)) return unify_invalid (explain_p); if (TEMPLATE_PARM_LEVEL (parm) @@ -18758,23 +18766,18 @@ most_specialized_instantiation (tree templates) tree most_general_template (tree decl) { - /* If DECL is a FUNCTION_DECL, find the TEMPLATE_DECL of which it is - an immediate specialization. */ - if (TREE_CODE (decl) == FUNCTION_DECL) + if (TREE_CODE (decl) != TEMPLATE_DECL) { - if (DECL_TEMPLATE_INFO (decl)) { - decl = DECL_TI_TEMPLATE (decl); - - /* The DECL_TI_TEMPLATE can be an IDENTIFIER_NODE for a - template friend. */ - if (TREE_CODE (decl) != TEMPLATE_DECL) - return NULL_TREE; - } else + if (tree tinfo = get_template_info (decl)) + decl = TI_TEMPLATE (tinfo); + /* The TI_TEMPLATE can be an IDENTIFIER_NODE for a + template friend, or a FIELD_DECL for a capture pack. */ + if (TREE_CODE (decl) != TEMPLATE_DECL) return NULL_TREE; } /* Look for more and more general templates. */ - while (DECL_TEMPLATE_INFO (decl)) + while (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)) { /* The DECL_TI_TEMPLATE can be an IDENTIFIER_NODE in some cases. (See cp-tree.h for details.) */ diff --git a/gcc-4.9/gcc/cp/search.c b/gcc-4.9/gcc/cp/search.c index d99e18215..c3eed90f6 100644 --- a/gcc-4.9/gcc/cp/search.c +++ b/gcc-4.9/gcc/cp/search.c @@ -2115,22 +2115,6 @@ get_pure_virtuals (tree type) which it is a primary base will contain vtable entries for the pure virtuals in the base class. */ dfs_walk_once (TYPE_BINFO (type), NULL, dfs_get_pure_virtuals, type); - - /* Treat a virtual destructor in an abstract class as pure even if it - isn't declared as pure; there is no way it would be called through the - vtable except during construction, which causes undefined behavior. */ - if (CLASSTYPE_PURE_VIRTUALS (type) - && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) - { - tree dtor = CLASSTYPE_DESTRUCTORS (type); - if (dtor && DECL_VIRTUAL_P (dtor) && !DECL_PURE_VIRTUAL_P (dtor)) - { - tree clone; - DECL_PURE_VIRTUAL_P (dtor) = true; - FOR_EACH_CLONE (clone, dtor) - DECL_PURE_VIRTUAL_P (clone) = true; - } - } } /* Debug info for C++ classes can get very large; try to avoid diff --git a/gcc-4.9/gcc/cp/semantics.c b/gcc-4.9/gcc/cp/semantics.c index 886fbb88b..3619e271d 100644 --- a/gcc-4.9/gcc/cp/semantics.c +++ b/gcc-4.9/gcc/cp/semantics.c @@ -386,6 +386,9 @@ add_stmt (tree t) STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p (); } + if (code == LABEL_EXPR || code == CASE_LABEL_EXPR) + STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1; + /* Add T to the statement-tree. Non-side-effect statements need to be recorded during statement expressions. */ gcc_checking_assert (!stmt_list_stack->is_empty ()); @@ -2777,6 +2780,7 @@ begin_class_definition (tree t) maybe_process_partial_specialization (t); pushclass (t); TYPE_BEING_DEFINED (t) = 1; + class_binding_level->defining_class_p = 1; if (flag_pack_struct) { @@ -7716,8 +7720,8 @@ sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v) { tree pri = CLASSTYPE_PRIMARY_BINFO (type); tree field_type; - constructor_elt elt; - int i; + unsigned i; + constructor_elt *ce; if (pri) field_type = BINFO_TYPE (pri); @@ -7728,14 +7732,14 @@ sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v) /* Find the element for the primary base or vptr and move it to the beginning of the vec. */ - vec<constructor_elt, va_gc> &vref = *v; - for (i = 0; ; ++i) - if (TREE_TYPE (vref[i].index) == field_type) + for (i = 0; vec_safe_iterate (v, i, &ce); ++i) + if (TREE_TYPE (ce->index) == field_type) break; - if (i > 0) + if (i > 0 && i < vec_safe_length (v)) { - elt = vref[i]; + vec<constructor_elt, va_gc> &vref = *v; + constructor_elt elt = vref[i]; for (; i > 0; --i) vref[i] = vref[i-1]; vref[0] = elt; @@ -10253,6 +10257,7 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags) case DO_STMT: case FOR_STMT: case WHILE_STMT: + case DECL_EXPR: if (flags & tf_error) error ("expression %qE is not a constant-expression", t); return false; diff --git a/gcc-4.9/gcc/cp/tree.c b/gcc-4.9/gcc/cp/tree.c index 5567253a6..3429d2396 100644 --- a/gcc-4.9/gcc/cp/tree.c +++ b/gcc-4.9/gcc/cp/tree.c @@ -3364,6 +3364,18 @@ handle_abi_tag_attribute (tree* node, tree name, tree args, name, *node); goto fail; } + else if (CLASSTYPE_TEMPLATE_INSTANTIATION (*node)) + { + warning (OPT_Wattributes, "ignoring %qE attribute applied to " + "template instantiation %qT", name, *node); + goto fail; + } + else if (CLASSTYPE_TEMPLATE_SPECIALIZATION (*node)) + { + warning (OPT_Wattributes, "ignoring %qE attribute applied to " + "template specialization %qT", name, *node); + goto fail; + } tree attributes = TYPE_ATTRIBUTES (*node); tree decl = TYPE_NAME (*node); diff --git a/gcc-4.9/gcc/cp/typeck.c b/gcc-4.9/gcc/cp/typeck.c index 559f19b55..9a80727dd 100644 --- a/gcc-4.9/gcc/cp/typeck.c +++ b/gcc-4.9/gcc/cp/typeck.c @@ -8283,6 +8283,10 @@ maybe_warn_about_returning_address_of_local (tree retval) return; whats_returned = TREE_OPERAND (whats_returned, 0); + while (TREE_CODE (whats_returned) == COMPONENT_REF + || TREE_CODE (whats_returned) == ARRAY_REF) + whats_returned = TREE_OPERAND (whats_returned, 0); + if (TREE_CODE (valtype) == REFERENCE_TYPE) { if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR @@ -8300,10 +8304,6 @@ maybe_warn_about_returning_address_of_local (tree retval) } } - while (TREE_CODE (whats_returned) == COMPONENT_REF - || TREE_CODE (whats_returned) == ARRAY_REF) - whats_returned = TREE_OPERAND (whats_returned, 0); - if (DECL_P (whats_returned) && DECL_NAME (whats_returned) && DECL_FUNCTION_SCOPE_P (whats_returned) diff --git a/gcc-4.9/gcc/cp/typeck2.c b/gcc-4.9/gcc/cp/typeck2.c index bd21ad8c3..68e518a5c 100644 --- a/gcc-4.9/gcc/cp/typeck2.c +++ b/gcc-4.9/gcc/cp/typeck2.c @@ -1103,6 +1103,7 @@ digest_init_flags (tree type, tree init, int flags) #define PICFLAG_ERRONEOUS 1 #define PICFLAG_NOT_ALL_CONSTANT 2 #define PICFLAG_NOT_ALL_SIMPLE 4 +#define PICFLAG_SIDE_EFFECTS 8 /* Given an initializer INIT, return the flag (PICFLAG_*) which better describe it. */ @@ -1113,7 +1114,12 @@ picflag_from_initializer (tree init) if (init == error_mark_node) return PICFLAG_ERRONEOUS; else if (!TREE_CONSTANT (init)) - return PICFLAG_NOT_ALL_CONSTANT; + { + if (TREE_SIDE_EFFECTS (init)) + return PICFLAG_SIDE_EFFECTS; + else + return PICFLAG_NOT_ALL_CONSTANT; + } else if (!initializer_constant_valid_p (init, TREE_TYPE (init))) return PICFLAG_NOT_ALL_SIMPLE; return 0; @@ -1493,7 +1499,12 @@ process_init_constructor (tree type, tree init, tsubst_flags_t complain) TREE_TYPE (init) = type; if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE) cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0); - if (flags & PICFLAG_NOT_ALL_CONSTANT) + if (flags & PICFLAG_SIDE_EFFECTS) + { + TREE_CONSTANT (init) = false; + TREE_SIDE_EFFECTS (init) = true; + } + else if (flags & PICFLAG_NOT_ALL_CONSTANT) /* Make sure TREE_CONSTANT isn't set from build_constructor. */ TREE_CONSTANT (init) = false; else |