summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog180
-rw-r--r--gcc/cp/call.c24
-rw-r--r--gcc/cp/class.c13
-rw-r--r--gcc/cp/constexpr.c24
-rw-r--r--gcc/cp/constraint.cc2
-rw-r--r--gcc/cp/cp-objcp-common.c5
-rw-r--r--gcc/cp/cp-tree.h7
-rw-r--r--gcc/cp/decl.c19
-rw-r--r--gcc/cp/decl2.c8
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/except.c4
-rw-r--r--gcc/cp/init.c2
-rw-r--r--gcc/cp/lambda.c8
-rw-r--r--gcc/cp/name-lookup.c22
-rw-r--r--gcc/cp/parser.c24
-rw-r--r--gcc/cp/pt.c59
-rw-r--r--gcc/cp/semantics.c1
-rw-r--r--gcc/cp/tree.c7
-rw-r--r--gcc/cp/typeck.c3
19 files changed, 356 insertions, 58 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7c52edeeab6..58710a91787 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,183 @@
+2018-02-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/70468 - ICE with constructor delegation via typedef.
+ * pt.c (tsubst_initializer_list): Check for other mem-initializers
+ with constructor delegation.
+
+2018-02-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/84424 - ICE with constexpr and __builtin_shuffle.
+ * constexpr.c (reduced_constant_expression_p): Handle CONSTRUCTOR of
+ VECTOR_TYPE.
+
+2018-02-22 Marek Polacek <polacek@redhat.com>
+
+ PR c++/84493
+ * parser.c (cp_parser_braced_list): Use require_open instead of
+ consume_open.
+
+2018-02-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/84454 - ICE with pack expansion in signature.
+ * error.c (find_typenames_r): Also stop on EXPR_PACK_EXPANSION.
+
+2018-02-20 Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+ * cp-objcp-common.c (cxx_block_may_fallthru): Add case for
+ IF_STMT.
+
+2018-02-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/84446
+ * parser.c (cp_parser_init_declarator): Don't call start_lambda_scope
+ on error_mark_node.
+
+2018-02-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84445
+ * class.c (fixed_type_or_null) <case CALL_EXPR>: Only test
+ TREE_HAS_CONSTRUCTOR if instance is not an internal function call.
+
+ PR c++/84449
+ * tree.c (bot_manip): If build_cplus_new or break_out_target_exprs
+ returns error_mark_node, return it immediately.
+ (break_out_target_exprs): If cp_walk_tree with bot_manip returns
+ error_mark_node, return error_mark_node.
+
+ PR c++/84455
+ * pt.c (tsubst_lambda_expr): If not nested, increment temporarily
+ function_depth to avoid GC during finish_lambda_function.
+
+2018-02-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/84429 - ICE capturing VLA.
+ * lambda.c (build_capture_proxy): Handle reference refs.
+
+2018-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84448
+ * parser.c (cp_parser_binary_expression): For no_toplevel_fold_p, if
+ either operand is error_mark_node, set current.lhs to that instead of
+ creating a binary op with error_mark_node operands.
+
+ PR c++/84430
+ * constexpr.c (potential_constant_expression_1): Handle OMP_SIMD.
+
+2018-02-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/84348
+ * decl.c (grokdeclarator): Early return error_mark_node upon
+ ill-formed friend declaration.
+
+2018-02-16 Marek Polacek <polacek@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84192
+ * constexpr.c (cxx_eval_constant_expression) <case RETURN_EXPR>: Don't
+ set *jump_target to anything if jump_target is NULL.
+
+2018-02-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/84151 - unnecessary volatile load with static member.
+ * call.c (build_new_method_call_1): Avoid loading from a volatile
+ lvalue used as the object argument for a static member function.
+
+ PR c++/81853 - using-directive and constexpr.
+ * constexpr.c (cxx_eval_constant_expression): Handle USING_STMT.
+
+ PR c++/84420 - ICE with structured binding in lambda.
+ * lambda.c (is_capture_proxy): Check DECL_DECOMPOSITION_P.
+
+ PR c++/83835 - C++17 error with constructor ctors.
+ * call.c (build_special_member_call): Set TARGET_EXPR_DIRECT_INIT_P.
+
+ PR c++/82664 - ICE with reference to function template parm.
+ * pt.c (convert_nontype_argument_function): Avoid obfuscationg
+ NOP_EXPRs.
+
+ PR c++/82764 - C++17 ICE with empty base
+ * class.c (build_base_field_1): Set DECL_SIZE to zero for empty base.
+
+2018-02-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/84421 - type-dependent if constexpr
+ * semantics.c (finish_if_stmt_cond): Check type_dependent_expression_p.
+
+2018-02-16 Nathan Sidwell <nathan@acm.org>
+
+ Deprecate -ffriend-injection.
+ * decl.c (cxx_init_decl_processing): Emit warning on option.
+ * name-lookup.c (do_pushdecl): Emit warning if we push a visible
+ friend.
+
+2018-02-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/82468
+ * decl.c (check_special_function_return_type): Reject template
+ template parameter in deduction guide.
+
+2018-02-16 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/84375
+ * name-lookup.c (do_pushdecl): Bail out on bad local friend injection.
+
+2018-02-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/83227 - C++17 ICE with init-list derived-to-base conversion.
+ * call.c (convert_like_real): Don't use the copy-list-initialization
+ shortcut for ck_base.
+
+ PR c++/84045 - ICE with typedef and noexcept.
+ * except.c (build_noexcept_spec): Use strip_typedefs_expr.
+
+ PR c++/84376 - ICE with omitted template arguments.
+ * pt.c (dguide_name_p): Check for IDENTIFIER_NODE.
+
+ PR c++/84368 - wrong error with local variable in variadic lambda.
+ * pt.c (tsubst_pack_expansion): Fix handling of non-packs in
+ local_specializations.
+
+2018-02-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/84330
+ * constraint.cc (tsubst_constraint_info): Handle an error_mark_node
+ as first argument.
+
+2018-02-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/84350
+ * pt.c (do_auto_deduction): Don't check the TREE_TYPE of a null
+ init, early return.
+
+2018-02-14 Nathan Sidwell <nathan@acm.org>
+
+ * decl2.c (mark_vtable_entries): Set input_location to decl's.
+ (c_parse_final_cleanups): Restore input_location after emitting
+ vtables.
+
+2018-02-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cp-tree.h (do_auto_deduction (tree, tree, tree)): Remove.
+ (do_auto_deduction (tree, tree, tree, tsubst_flags_t,
+ auto_deduction_context, tree, int): Add defaults.
+ * pt.c (do_auto_deduction (tree, tree, tree)): Remove definition.
+ (tsubst_omp_for_iterator): Adjust do_auto_deduction call, forward
+ tsubst_flags_t argument.
+ * init.c (build_new): Likewise.
+
+2018-02-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84364
+ * typeck.c (check_return_expr): Don't emit -Weffc++ warning
+ about return other than *this in assignment operators if
+ retval is type dependent expression.
+
+2018-02-13 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/84333
+ * call.c (build_conditional_expr_1): Use cp_save_expr instead of
+ save_expr for the G++ extension.
+
2018-02-13 Jason Merrill <jason@redhat.com>
PR c++/84080 - ICE with return type deduction and specialization.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 15b723ad2b0..7c93c6d8290 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4805,7 +4805,7 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
if (lvalue_p (arg1))
arg2 = arg1 = cp_stabilize_reference (arg1);
else
- arg2 = arg1 = save_expr (arg1);
+ arg2 = arg1 = cp_save_expr (arg1);
}
/* If something has already gone wrong, just pass that fact up the
@@ -6938,6 +6938,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
&& DECL_INHERITED_CTOR (current_function_decl))
return expr;
+ if (TREE_CODE (expr) == TARGET_EXPR
+ && TARGET_EXPR_LIST_INIT_P (expr))
+ /* Copy-list-initialization doesn't actually involve a copy. */
+ return expr;
+
/* Fall through. */
case ck_base:
if (convs->kind == ck_base && !convs->need_temporary_p)
@@ -6964,10 +6969,6 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
if (convs->rvaluedness_matches_p)
/* standard_conversion got LOOKUP_PREFER_RVALUE. */
flags |= LOOKUP_PREFER_RVALUE;
- if (TREE_CODE (expr) == TARGET_EXPR
- && TARGET_EXPR_LIST_INIT_P (expr))
- /* Copy-list-initialization doesn't actually involve a copy. */
- return expr;
expr = build_temp (expr, totype, flags, &diag_kind, complain);
if (diag_kind && complain)
{
@@ -8833,6 +8834,9 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
{
if (is_dummy_object (instance))
return arg;
+ else if (TREE_CODE (arg) == TARGET_EXPR)
+ TARGET_EXPR_DIRECT_INIT_P (arg) = true;
+
if ((complain & tf_error)
&& (flags & LOOKUP_DELEGATING_CONS))
check_self_delegation (arg);
@@ -9280,8 +9284,14 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
&& !is_dummy_object (instance)
&& TREE_SIDE_EFFECTS (instance))
- call = build2 (COMPOUND_EXPR, TREE_TYPE (call),
- instance, call);
+ {
+ /* But avoid the implicit lvalue-rvalue conversion when 'a'
+ is volatile. */
+ tree a = instance;
+ if (TREE_THIS_VOLATILE (a))
+ a = build_this (a);
+ call = build2 (COMPOUND_EXPR, TREE_TYPE (call), a, call);
+ }
else if (call != error_mark_node
&& DECL_DESTRUCTOR_P (cand->fn)
&& !VOID_TYPE_P (TREE_TYPE (call)))
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index e48a04ade7d..afa5c41bfff 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4216,8 +4216,14 @@ build_base_field_1 (tree t, tree basetype, tree *&next_field)
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
DECL_FIELD_CONTEXT (decl) = t;
- DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
- DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
+ if (is_empty_class (basetype))
+ /* CLASSTYPE_SIZE is one byte, but the field needs to have size zero. */
+ DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = size_zero_node;
+ else
+ {
+ DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
+ DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
+ }
SET_DECL_ALIGN (decl, CLASSTYPE_ALIGN (basetype));
DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
SET_DECL_MODE (decl, TYPE_MODE (basetype));
@@ -7122,7 +7128,8 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
case CALL_EXPR:
/* This is a call to a constructor, hence it's never zero. */
- if (TREE_HAS_CONSTRUCTOR (instance))
+ if (CALL_EXPR_FN (instance)
+ && TREE_HAS_CONSTRUCTOR (instance))
{
if (nonnull)
*nonnull = 1;
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index d89bdd5a6a4..47ff90cb055 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1763,7 +1763,13 @@ reduced_constant_expression_p (tree t)
/* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */
tree idx, val, field; unsigned HOST_WIDE_INT i;
if (CONSTRUCTOR_NO_IMPLICIT_ZERO (t))
- field = next_initializable_field (TYPE_FIELDS (TREE_TYPE (t)));
+ {
+ if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+ /* An initialized vector would have a VECTOR_CST. */
+ return false;
+ else
+ field = next_initializable_field (TYPE_FIELDS (TREE_TYPE (t)));
+ }
else
field = NULL_TREE;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, idx, val)
@@ -4254,7 +4260,16 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
lval,
non_constant_p, overflow_p);
- *jump_target = t;
+ if (jump_target)
+ *jump_target = t;
+ else
+ {
+ /* Can happen with ({ return true; }) && false; passed to
+ maybe_constant_value. There is nothing to jump over in this
+ case, and the bug will be diagnosed later. */
+ gcc_assert (ctx->quiet);
+ *non_constant_p = true;
+ }
break;
case SAVE_EXPR:
@@ -4726,6 +4741,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
jump_target);
break;
+ case USING_STMT:
+ r = void_node;
+ break;
+
default:
if (STATEMENT_CODE_P (TREE_CODE (t)))
{
@@ -5591,6 +5610,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case OMP_PARALLEL:
case OMP_TASK:
case OMP_FOR:
+ case OMP_SIMD:
case OMP_DISTRIBUTE:
case OMP_TASKLOOP:
case OMP_TEAMS:
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 622c9fe97a5..37eded17c94 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1918,7 +1918,7 @@ tsubst_constraint_info (tree t, tree args,
tree
tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
- if (t == NULL_TREE)
+ if (t == NULL_TREE || t == error_mark_node)
return t;
switch (TREE_CODE (t))
{
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index a45dda4d012..5289a89e486 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -349,6 +349,11 @@ cxx_block_may_fallthru (const_tree stmt)
case THROW_EXPR:
return false;
+ case IF_STMT:
+ if (block_may_fallthru (THEN_CLAUSE (stmt)))
+ return true;
+ return block_may_fallthru (ELSE_CLAUSE (stmt));
+
case SWITCH_STMT:
return (!SWITCH_STMT_ALL_CASES_P (stmt)
|| !SWITCH_STMT_NO_BREAK_P (stmt)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9a9e9f0bbcb..9038d677b2d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6470,10 +6470,11 @@ extern tree make_auto (void);
extern tree make_decltype_auto (void);
extern tree make_template_placeholder (tree);
extern bool template_placeholder_p (tree);
-extern tree do_auto_deduction (tree, tree, tree);
extern tree do_auto_deduction (tree, tree, tree,
- tsubst_flags_t,
- auto_deduction_context,
+ tsubst_flags_t
+ = tf_warning_or_error,
+ auto_deduction_context
+ = adc_unspecified,
tree = NULL_TREE,
int = LOOKUP_NORMAL);
extern tree type_uses_auto (tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 3ccea9e6a45..f91f311a117 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4091,8 +4091,14 @@ cxx_init_decl_processing (void)
pop_namespace ();
flag_noexcept_type = (cxx_dialect >= cxx17);
+ /* There's no fixed location for <command-line>, the current
+ location is <builtins>, which is somewhat confusing. */
if (!flag_new_for_scope)
- warning (OPT_Wdeprecated, "%<-fno-for-scope%> is deprecated");
+ warning_at (UNKNOWN_LOCATION, OPT_Wdeprecated,
+ "%<-fno-for-scope%> is deprecated");
+ if (flag_friend_injection)
+ warning_at (UNKNOWN_LOCATION, OPT_Wdeprecated,
+ "%<-ffriend-injection%> is deprecated");
c_common_nodes_and_builtins ();
@@ -9834,7 +9840,14 @@ check_special_function_return_type (special_function_kind sfk,
error_at (smallest_type_quals_location (type_quals, locations),
"qualifiers are not allowed on declaration of "
"deduction guide");
- type = make_template_placeholder (CLASSTYPE_TI_TEMPLATE (optype));
+ if (TREE_CODE (optype) == TEMPLATE_TEMPLATE_PARM)
+ {
+ error ("template template parameter %qT in declaration of "
+ "deduction guide", optype);
+ type = error_mark_node;
+ }
+ else
+ type = make_template_placeholder (CLASSTYPE_TI_TEMPLATE (optype));
for (int i = 0; i < ds_last; ++i)
if (i != ds_explicit && locations[i])
error_at (locations[i],
@@ -12128,7 +12141,7 @@ grokdeclarator (const cp_declarator *declarator,
{
error ("%qE is neither function nor member function; "
"cannot be declared friend", unqualified_id);
- friendp = 0;
+ return error_mark_node;
}
decl = NULL_TREE;
}
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 2da6f9023c5..d2693ce458b 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1825,6 +1825,11 @@ mark_vtable_entries (tree decl)
function, so we emit the thunks there instead. */
if (DECL_THUNK_P (fn))
use_thunk (fn, /*emit_p=*/0);
+ /* Set the location, as marking the function could cause
+ instantiation. We do not need to preserve the incoming
+ location, as we're called from c_parse_final_cleanups, which
+ takes care of that. */
+ input_location = DECL_SOURCE_LOCATION (fn);
mark_used (fn);
}
}
@@ -4727,6 +4732,9 @@ c_parse_final_cleanups (void)
reconsider = true;
keyed_classes->unordered_remove (i);
}
+ /* The input_location may have been changed during marking of
+ vtable entries. */
+ input_location = locus_at_end_of_parsing;
/* Write out needed type info variables. We have to be careful
looping through unemitted decls, because emit_tinfo_decl may
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index cb1dcf36201..75e853a1428 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1472,7 +1472,7 @@ find_typenames_r (tree *tp, int *walk_subtrees, void *data)
/* Add the typename without any cv-qualifiers. */
mv = TYPE_MAIN_VARIANT (*tp);
- if (TREE_CODE (*tp) == TYPE_PACK_EXPANSION)
+ if (PACK_EXPANSION_P (*tp))
{
/* Don't mess with parameter packs since we don't remember
the pack expansion context for a particular typename. */
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 669bf9f6eaf..0b46698b974 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -1217,6 +1217,10 @@ build_noexcept_spec (tree expr, int complain)
{
gcc_assert (processing_template_decl
|| TREE_CODE (expr) == DEFERRED_NOEXCEPT);
+ if (TREE_CODE (expr) != DEFERRED_NOEXCEPT)
+ /* Avoid problems with a function type built with a dependent typedef
+ being reused in another scope (c++/84045). */
+ expr = strip_typedefs_expr (expr);
return build_tree_list (expr, NULL_TREE);
}
}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 233f41c2592..d0d14abdc9f 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3593,7 +3593,7 @@ build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
d_init = (**init)[0];
d_init = resolve_nondeduced_context (d_init, complain);
}
- type = do_auto_deduction (type, d_init, auto_node);
+ type = do_auto_deduction (type, d_init, auto_node, complain);
}
}
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 6b5bd800741..a0a80dfde5c 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -261,6 +261,7 @@ is_capture_proxy (tree decl)
return (VAR_P (decl)
&& DECL_HAS_VALUE_EXPR_P (decl)
&& !DECL_ANON_UNION_VAR_P (decl)
+ && !DECL_DECOMPOSITION_P (decl)
&& LAMBDA_FUNCTION_P (DECL_CONTEXT (decl)));
}
@@ -450,11 +451,12 @@ build_capture_proxy (tree member, tree init)
{
if (PACK_EXPANSION_P (init))
init = PACK_EXPANSION_PATTERN (init);
- if (INDIRECT_REF_P (init))
- init = TREE_OPERAND (init, 0);
- STRIP_NOPS (init);
}
+ if (INDIRECT_REF_P (init))
+ init = TREE_OPERAND (init, 0);
+ STRIP_NOPS (init);
+
gcc_assert (VAR_P (init) || TREE_CODE (init) == PARM_DECL);
while (is_normal_capture_proxy (init))
init = DECL_CAPTURED_VARIABLE (init);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index e5a34003702..9117e0b30eb 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3071,6 +3071,7 @@ do_pushdecl (tree decl, bool is_friend)
old = OVL_CHAIN (old);
check_template_shadow (decl);
+ bool visible_injection = false;
if (DECL_DECLARES_FUNCTION_P (decl))
{
@@ -3079,14 +3080,20 @@ do_pushdecl (tree decl, bool is_friend)
if (is_friend)
{
if (level->kind != sk_namespace)
- /* In a local class, a friend function declaration must
- find a matching decl in the innermost non-class scope.
- [class.friend/11] */
- error ("friend declaration %qD in local class without "
- "prior local declaration", decl);
- else if (!flag_friend_injection)
+ {
+ /* In a local class, a friend function declaration must
+ find a matching decl in the innermost non-class scope.
+ [class.friend/11] */
+ error ("friend declaration %qD in local class without "
+ "prior local declaration", decl);
+ /* Don't attempt to push it. */
+ return error_mark_node;
+ }
+ if (!flag_friend_injection)
/* Hide it from ordinary lookup. */
DECL_ANTICIPATED (decl) = DECL_HIDDEN_FRIEND_P (decl) = true;
+ else
+ visible_injection = true;
}
}
@@ -3138,6 +3145,9 @@ do_pushdecl (tree decl, bool is_friend)
}
else if (VAR_P (decl))
maybe_register_incomplete_var (decl);
+ else if (visible_injection)
+ warning (0, "injected friend %qD is visible"
+ " due to %<-ffriend-injection%>", decl);
if ((VAR_P (decl) || TREE_CODE (decl) == FUNCTION_DECL)
&& DECL_EXTERN_C_P (decl))
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 81c6f0128e6..4fa546a086c 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -9331,12 +9331,18 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
&& lookahead_prec <= current.prec
&& sp == stack)
{
- current.lhs
- = build_min (current.tree_type,
- TREE_CODE_CLASS (current.tree_type) == tcc_comparison
- ? boolean_type_node : TREE_TYPE (current.lhs),
- current.lhs.get_value (), rhs.get_value ());
- SET_EXPR_LOCATION (current.lhs, combined_loc);
+ if (current.lhs == error_mark_node || rhs == error_mark_node)
+ current.lhs = error_mark_node;
+ else
+ {
+ current.lhs
+ = build_min (current.tree_type,
+ TREE_CODE_CLASS (current.tree_type)
+ == tcc_comparison
+ ? boolean_type_node : TREE_TYPE (current.lhs),
+ current.lhs.get_value (), rhs.get_value ());
+ SET_EXPR_LOCATION (current.lhs, combined_loc);
+ }
}
else
{
@@ -19644,12 +19650,12 @@ cp_parser_init_declarator (cp_parser* parser,
member templates. The former involves deferring
parsing of the initializer until end of class as with default
arguments. So right here we only handle the latter. */
- if (!member_p && processing_template_decl)
+ if (!member_p && processing_template_decl && decl != error_mark_node)
start_lambda_scope (decl);
initializer = cp_parser_initializer (parser,
&is_direct_init,
&is_non_constant_init);
- if (!member_p && processing_template_decl)
+ if (!member_p && processing_template_decl && decl != error_mark_node)
finish_lambda_scope ();
if (initializer == error_mark_node)
cp_parser_skip_to_end_of_statement (parser);
@@ -21919,7 +21925,7 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
/* Consume the `{' token. */
matching_braces braces;
- braces.consume_open (parser);
+ braces.require_open (parser);
/* Create a CONSTRUCTOR to represent the braced-initializer. */
initializer = make_node (CONSTRUCTOR);
/* If it's not a `}', then there is a non-trivial initializer. */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 222084df4cb..85d1adbbe3c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6143,7 +6143,12 @@ convert_nontype_argument_function (tree type, tree expr,
accept:
if (TREE_CODE (type) == REFERENCE_TYPE)
- fn = build_address (fn);
+ {
+ if (REFERENCE_REF_P (fn))
+ fn = TREE_OPERAND (fn, 0);
+ else
+ fn = build_address (fn);
+ }
if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (fn)))
fn = build_nop (type, fn);
@@ -11521,8 +11526,9 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
context. */
tree gen = TREE_PURPOSE (elt);
tree inst = TREE_VALUE (elt);
- if (DECL_PACK_P (inst))
- inst = retrieve_local_specialization (inst);
+ if (DECL_P (inst))
+ if (tree local = retrieve_local_specialization (inst))
+ inst = local;
/* else inst is already a full instantiation of the pack. */
register_local_specialization (inst, gen);
}
@@ -15785,7 +15791,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
tree auto_node = type_uses_auto (TREE_TYPE (decl));
if (auto_node && init)
TREE_TYPE (decl)
- = do_auto_deduction (TREE_TYPE (decl), init, auto_node);
+ = do_auto_deduction (TREE_TYPE (decl), init, auto_node, complain);
gcc_assert (!type_dependent_expression_p (decl));
@@ -17064,6 +17070,10 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
bool nested = cfun;
if (nested)
push_function_context ();
+ else
+ /* Still increment function_depth so that we don't GC in the
+ middle of an expression. */
+ ++function_depth;
local_specialization_stack s (lss_copy);
@@ -17078,6 +17088,8 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (nested)
pop_function_context ();
+ else
+ --function_depth;
/* The capture list was built up in reverse order; fix that now. */
LAMBDA_EXPR_CAPTURE_LIST (r)
@@ -23546,6 +23558,7 @@ static tree
tsubst_initializer_list (tree t, tree argvec)
{
tree inits = NULL_TREE;
+ tree target_ctor = error_mark_node;
for (; t; t = TREE_CHAIN (t))
{
@@ -23662,6 +23675,28 @@ tsubst_initializer_list (tree t, tree argvec)
in_base_initializer = 0;
}
+ if (target_ctor != error_mark_node
+ && init != error_mark_node)
+ {
+ error ("mem-initializer for %qD follows constructor delegation",
+ decl);
+ return inits;
+ }
+ /* Look for a target constructor. */
+ if (init != error_mark_node
+ && decl && CLASS_TYPE_P (decl)
+ && same_type_p (decl, current_class_type))
+ {
+ maybe_warn_cpp0x (CPP0X_DELEGATING_CTORS);
+ if (inits)
+ {
+ error ("constructor delegation follows mem-initializer for %qD",
+ TREE_PURPOSE (inits));
+ continue;
+ }
+ target_ctor = init;
+ }
+
if (decl)
{
init = build_tree_list (decl, init);
@@ -25453,7 +25488,8 @@ dguide_name (tree tmpl)
bool
dguide_name_p (tree name)
{
- return (TREE_TYPE (name)
+ return (TREE_CODE (name) == IDENTIFIER_NODE
+ && TREE_TYPE (name)
&& !strncmp (IDENTIFIER_POINTER (name), dguide_base,
strlen (dguide_base)));
}
@@ -25941,17 +25977,6 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
}
/* Replace occurrences of 'auto' in TYPE with the appropriate type deduced
- from INIT. AUTO_NODE is the TEMPLATE_TYPE_PARM used for 'auto' in TYPE. */
-
-tree
-do_auto_deduction (tree type, tree init, tree auto_node)
-{
- return do_auto_deduction (type, init, auto_node,
- tf_warning_or_error,
- adc_unspecified);
-}
-
-/* Replace occurrences of 'auto' in TYPE with the appropriate type deduced
from INIT. AUTO_NODE is the TEMPLATE_TYPE_PARM used for 'auto' in TYPE.
The CONTEXT determines the context in which auto deduction is performed
and is used to control error diagnostics. FLAGS are the LOOKUP_* flags.
@@ -25986,7 +26011,7 @@ do_auto_deduction (tree type, tree init, tree auto_node,
/* C++17 class template argument deduction. */
return do_class_deduction (type, tmpl, init, flags, complain);
- if (TREE_TYPE (init) == NULL_TREE)
+ if (init == NULL_TREE || TREE_TYPE (init) == NULL_TREE)
/* Nothing we can do with this, even in deduction context. */
return type;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index f0cee68e46f..35569d0cb0d 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -731,6 +731,7 @@ finish_if_stmt_cond (tree cond, tree if_stmt)
{
cond = maybe_convert_cond (cond);
if (IF_STMT_CONSTEXPR_P (if_stmt)
+ && !type_dependent_expression_p (cond)
&& require_constant_expression (cond)
&& !value_dependent_expression_p (cond))
{
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a53bddf2ef0..39c1ef28b2d 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2896,6 +2896,8 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
{
u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1),
tf_warning_or_error);
+ if (u == error_mark_node)
+ return u;
if (AGGR_INIT_ZERO_FIRST (TREE_OPERAND (t, 1)))
AGGR_INIT_ZERO_FIRST (TREE_OPERAND (u, 1)) = true;
}
@@ -2913,6 +2915,8 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
(splay_tree_value) TREE_OPERAND (u, 0));
TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1));
+ if (TREE_OPERAND (u, 1) == error_mark_node)
+ return error_mark_node;
/* Replace the old expression with the new version. */
*tp = u;
@@ -3025,7 +3029,8 @@ break_out_target_exprs (tree t)
target_remap = splay_tree_new (splay_tree_compare_pointers,
/*splay_tree_delete_key_fn=*/NULL,
/*splay_tree_delete_value_fn=*/NULL);
- cp_walk_tree (&t, bot_manip, target_remap, NULL);
+ if (cp_walk_tree (&t, bot_manip, target_remap, NULL) == error_mark_node)
+ t = error_mark_node;
cp_walk_tree (&t, bot_replace, target_remap, NULL);
if (!--target_remap_count)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index dfcf71689c6..0e7c63dd197 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -9232,7 +9232,8 @@ check_return_expr (tree retval, bool *no_warning)
/* Effective C++ rule 15. See also start_function. */
if (warn_ecpp
- && DECL_NAME (current_function_decl) == assign_op_identifier)
+ && DECL_NAME (current_function_decl) == assign_op_identifier
+ && !type_dependent_expression_p (retval))
{
bool warn = true;