aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/cp')
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog165
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20084
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-201020
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20112
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog-20122
-rw-r--r--gcc-4.9/gcc/cp/Make-lang.in2
-rw-r--r--gcc-4.9/gcc/cp/call.c3
-rw-r--r--gcc-4.9/gcc/cp/class.c121
-rw-r--r--gcc-4.9/gcc/cp/decl.c72
-rw-r--r--gcc-4.9/gcc/cp/decl2.c5
-rw-r--r--gcc-4.9/gcc/cp/error.c7
-rw-r--r--gcc-4.9/gcc/cp/init.c35
-rw-r--r--gcc-4.9/gcc/cp/mangle.c23
-rw-r--r--gcc-4.9/gcc/cp/method.c16
-rw-r--r--gcc-4.9/gcc/cp/name-lookup.c8
-rw-r--r--gcc-4.9/gcc/cp/name-lookup.h9
-rw-r--r--gcc-4.9/gcc/cp/parser.c56
-rw-r--r--gcc-4.9/gcc/cp/pt.c139
-rw-r--r--gcc-4.9/gcc/cp/search.c16
-rw-r--r--gcc-4.9/gcc/cp/semantics.c19
-rw-r--r--gcc-4.9/gcc/cp/tree.c12
-rw-r--r--gcc-4.9/gcc/cp/typeck.c8
-rw-r--r--gcc-4.9/gcc/cp/typeck2.c15
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