aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog118
-rw-r--r--gcc/cp/call.c24
-rw-r--r--gcc/cp/constexpr.c14
-rw-r--r--gcc/cp/cp-gimplify.c12
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/decl.c59
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/name-lookup.c6
-rw-r--r--gcc/cp/parser.c28
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/cp/rtti.c2
-rw-r--r--gcc/cp/semantics.c5
-rw-r--r--gcc/cp/tree.c5
-rw-r--r--gcc/cp/typeck.c51
-rw-r--r--gcc/cp/typeck2.c45
15 files changed, 272 insertions, 106 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0fbd8167a04..6ecd48dfac8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,115 @@
+2018-08-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/87095
+ * decl.c (begin_destructor_body): If current_class_type has
+ virtual bases and the primary base is nearly empty virtual base,
+ voidify clearing of vptr and make it conditional on in-charge
+ argument.
+
+2018-08-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/85265
+ * parser.c (cp_parser_introduction_list): If cp_parser_identifier
+ returns error_mark_node early exit the loop.
+ (cp_parser_template_introduction): Improve error-recovery, remove
+ error call about empty introduction-list.
+
+2018-08-29 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/85110
+ * call.c (print_conversion_rejection): Add "fn" param and use it
+ for "no known conversion" messages to underline the pertinent
+ param.
+ (print_z_candidate): Supply "fn" to the new param above.
+
+2018-08-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/87122
+ * pt.c (tsubst_expr) <case RANGE_FOR_STMT>: If
+ processing_template_decl and decl is structured binding decl, call
+ cp_finish_decomp.
+
+2018-08-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/86546
+ * decl.c (finish_case_label): If the type is erroneous early
+ return error_mark_node.
+
+2018-08-27 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/63392
+ * parser.c (cp_parser_diagnose_invalid_type_name): Add fix-it
+ hint.
+
+2018-08-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/86993
+ * cp-tree.h (cxx_readonly_error): Add location_t argument.
+ * typeck2.c (cxx_readonly_error): Add LOC argument, pass it to
+ ERROR_FOR_ASSIGNMENT macro and readonly_error. Add LOC argument
+ to ERROR_FOR_ASSIGNMENT macro, use error_at instead of error and
+ pass LOC to it. Formatting fixes.
+ * typeck.c (cp_build_unary_op): Pass location to cxx_readonly_error.
+ (cp_build_modify_expr): Pass loc to cxx_readonly_error.
+ * semantics.c (finish_asm_stmt): Pass input_location to
+ cxx_readonly_error.
+
+2018-08-27 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/87091
+ * decl.c (grokdeclarator): Update for conversion of show_caret_p
+ to a tri-state.
+ * error.c (cp_printer): Likewise.
+ * name-lookup.c (maybe_suggest_missing_std_header): Update call to
+ maybe_add_include_fixit to suggest overriding the location, as it
+ is for a note.
+ * parser.c (cp_parser_string_literal): Update for conversion of
+ show_caret_p to a tri-state.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (set_and_check_decl_spec_loc): Likewise.
+ * pt.c (listify): Update call to maybe_add_include_fixit to not
+ override the location, as it is for an error.
+ * rtti.c (typeid_ok_p): Likewise.
+
+2018-08-27 Martin Liska <mliska@suse.cz>
+
+ * call.c (build_call_a): Use new function
+ fndecl_built_in_p and remove check for FUNCTION_DECL if
+ possible.
+ (build_cxx_call): Likewise.
+ * constexpr.c (constexpr_fn_retval): Likewise.
+ (cxx_eval_builtin_function_call): Likewise.
+ (cxx_eval_call_expression): Likewise.
+ (potential_constant_expression_1): Likewise.
+ * cp-gimplify.c (cp_gimplify_expr): Likewise.
+ (cp_fold): Likewise.
+ * decl.c (decls_match): Likewise.
+ (validate_constexpr_redeclaration): Likewise.
+ (duplicate_decls): Likewise.
+ (make_rtl_for_nonlocal_decl): Likewise.
+ * name-lookup.c (consider_binding_level): Likewise.
+ (cp_emit_debug_info_for_using): Likewise.
+ * semantics.c (finish_call_expr): Likewise.
+ * tree.c (builtin_valid_in_constant_expr_p): Likewise.
+
+2018-08-26 Marek Polacek <polacek@redhat.com>
+
+ PR c++/87080
+ * typeck.c (maybe_warn_pessimizing_move): Do nothing in a template.
+
+ PR c++/87029, Implement -Wredundant-move.
+ * typeck.c (treat_lvalue_as_rvalue_p): New function.
+ (maybe_warn_pessimizing_move): Call convert_from_reference.
+ Warn about redundant moves.
+
+2018-08-24 Marek Polacek <polacek@redhat.com>
+
+ PR c++/67012
+ PR c++/86942
+ * decl.c (grokdeclarator): Disallow functions with trailing return
+ type with decltype(auto) as its type. Also check the function if
+ it's inner declarator doesn't exist
+
2018-08-21 Marek Polacek <polacek@redhat.com>
PR c++/86499
@@ -278,9 +390,9 @@
2018-07-31 Martin Liska <mliska@suse.cz>
- PR c++/86653
+ PR c++/86653
* parser.c (cp_parser_condition): Initialize non_constant_p
- to false.
+ to false.
2018-07-28 David Malcolm <dmalcolm@redhat.com>
@@ -3527,7 +3639,7 @@
2018-01-10 Paolo Carlini <paolo.carlini@oracle.com>
* parser.c (cp_parser_std_attribute_spec): When
- token_pair::require_open / require_close return false simply
+ token_pair::require_open / require_close return false simply
return error_mark_node, avoid duplicate cp_parser_error about
expected '(' / ')', respectively.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 626830c0d9a..a1567026975 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -389,7 +389,7 @@ build_call_a (tree function, int n, tree *argarray)
/* Don't pass empty class objects by value. This is useful
for tags in STL, which are used to control overload resolution.
We don't need to handle other cases of copying empty classes. */
- if (! decl || ! DECL_BUILT_IN (decl))
+ if (!decl || !fndecl_built_in_p (decl))
for (i = 0; i < n; i++)
{
tree arg = CALL_EXPR_ARG (function, i);
@@ -3432,10 +3432,11 @@ equal_functions (tree fn1, tree fn2)
return fn1 == fn2;
}
-/* Print information about a candidate being rejected due to INFO. */
+/* Print information about a candidate FN being rejected due to INFO. */
static void
-print_conversion_rejection (location_t loc, struct conversion_info *info)
+print_conversion_rejection (location_t loc, struct conversion_info *info,
+ tree fn)
{
tree from = info->from;
if (!TYPE_P (from))
@@ -3466,8 +3467,12 @@ print_conversion_rejection (location_t loc, struct conversion_info *info)
inform (loc, " no known conversion from %qH to %qI",
from, info->to_type);
else
- inform (loc, " no known conversion for argument %d from %qH to %qI",
- info->n_arg + 1, from, info->to_type);
+ {
+ if (TREE_CODE (fn) == FUNCTION_DECL)
+ loc = get_fndecl_argument_location (fn, info->n_arg);
+ inform (loc, " no known conversion for argument %d from %qH to %qI",
+ info->n_arg + 1, from, info->to_type);
+ }
}
/* Print information about a candidate with WANT parameters and we found
@@ -3542,10 +3547,10 @@ print_z_candidate (location_t loc, const char *msgstr,
r->u.arity.expected);
break;
case rr_arg_conversion:
- print_conversion_rejection (cloc, &r->u.conversion);
+ print_conversion_rejection (cloc, &r->u.conversion, fn);
break;
case rr_bad_arg_conversion:
- print_conversion_rejection (cloc, &r->u.bad_conversion);
+ print_conversion_rejection (cloc, &r->u.bad_conversion, fn);
break;
case rr_explicit_conversion:
inform (cloc, " return type %qT of explicit conversion function "
@@ -7922,7 +7927,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
{
/* The implicit move specified in 15.8.3/3 fails "...if the type of
the first parameter of the selected constructor is not an rvalue
- reference to the object’s type (possibly cv-qualified)...." */
+ reference to the object's type (possibly cv-qualified)...." */
gcc_assert (!(complain & tf_error));
tree ptype = convs[0]->type;
if (!TYPE_REF_P (ptype)
@@ -8869,8 +8874,7 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
/* Check that arguments to builtin functions match the expectations. */
if (fndecl
&& !processing_template_decl
- && DECL_BUILT_IN (fndecl)
- && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
{
int i;
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 54c8b5edf8d..f646519135f 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -721,8 +721,7 @@ constexpr_fn_retval (tree body)
{
tree fun = get_function_named_in_call (body);
if (fun != NULL_TREE
- && DECL_BUILT_IN_CLASS (fun) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE)
+ && fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE))
return NULL_TREE;
}
/* Fallthru. */
@@ -1198,8 +1197,8 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
/* For __builtin_is_constant_evaluated, defer it if not
ctx->pretend_const_required, otherwise fold it to true. */
- if (DECL_BUILT_IN_CLASS (fun) == BUILT_IN_FRONTEND
- && (int) DECL_FUNCTION_CODE (fun) == CP_BUILT_IN_IS_CONSTANT_EVALUATED)
+ if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+ BUILT_IN_FRONTEND))
{
if (!ctx->pretend_const_required)
{
@@ -1242,8 +1241,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
/* Do not allow__builtin_unreachable in constexpr function.
The __builtin_unreachable call with BUILTINS_LOCATION
comes from cp_maybe_instrument_return. */
- if (DECL_BUILT_IN_CLASS (fun) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE
+ if (fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE)
&& EXPR_LOCATION (t) == BUILTINS_LOCATION)
error ("%<constexpr%> call flows off the end of the function");
else
@@ -1528,7 +1526,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
if (is_ubsan_builtin_p (fun))
return void_node;
- if (is_builtin_fn (fun))
+ if (fndecl_built_in_p (fun))
return cxx_eval_builtin_function_call (ctx, t, fun,
lval, non_constant_p, overflow_p);
if (!DECL_DECLARED_CONSTEXPR_P (fun))
@@ -5522,7 +5520,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
if (!DECL_DECLARED_CONSTEXPR_P (fun)
/* Allow any built-in function; if the expansion
isn't constant, we'll deal with that then. */
- && !is_builtin_fn (fun))
+ && !fndecl_built_in_p (fun))
{
if (flags & tf_error)
{
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index f6109914102..90a8f9fef8f 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -797,9 +797,8 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
tree decl = cp_get_callee_fndecl_nofold (*expr_p);
if (decl
- && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_FRONTEND
- && ((int) DECL_FUNCTION_CODE (decl)
- == CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+ && fndecl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+ BUILT_IN_FRONTEND))
*expr_p = boolean_false_node;
}
break;
@@ -2489,7 +2488,7 @@ cp_fold (tree x)
/* Some built-in function calls will be evaluated at compile-time in
fold (). Set optimize to 1 when folding __builtin_constant_p inside
a constexpr function so that fold_builtin_1 doesn't fold it to 0. */
- if (callee && DECL_BUILT_IN (callee) && !optimize
+ if (callee && fndecl_built_in_p (callee) && !optimize
&& DECL_IS_BUILTIN_CONSTANT_P (callee)
&& current_function_decl
&& DECL_DECLARED_CONSTEXPR_P (current_function_decl))
@@ -2497,9 +2496,8 @@ cp_fold (tree x)
/* Defer folding __builtin_is_constant_evaluated. */
if (callee
- && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_FRONTEND
- && ((int) DECL_FUNCTION_CODE (callee)
- == CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+ && fndecl_built_in_p (callee, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+ BUILT_IN_FRONTEND))
break;
x = copy_node (x);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 055f2bc5f2b..43e452cc1a3 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7388,7 +7388,8 @@ cxx_incomplete_type_error (const_tree value, const_tree type)
extern void cxx_incomplete_type_inform (const_tree);
extern tree error_not_base_type (tree, tree);
extern tree binfo_or_else (tree, tree);
-extern void cxx_readonly_error (tree, enum lvalue_use);
+extern void cxx_readonly_error (location_t, tree,
+ enum lvalue_use);
extern void complete_type_check_abstract (tree);
extern int abstract_virtuals_error (tree, tree);
extern int abstract_virtuals_error (abstract_class_use, tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 82ec4af87be..c6711f74177 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -968,7 +968,7 @@ decls_match (tree newdecl, tree olddecl, bool record_versions /* = true */)
if (same_type_p (TREE_TYPE (f1), r2))
{
if (!prototype_p (f2) && DECL_EXTERN_C_P (olddecl)
- && (DECL_BUILT_IN (olddecl)
+ && (fndecl_built_in_p (olddecl)
#ifdef SYSTEM_IMPLICIT_EXTERN_C
|| (DECL_IN_SYSTEM_HEADER (newdecl) && !DECL_CLASS_SCOPE_P (newdecl))
|| (DECL_IN_SYSTEM_HEADER (olddecl) && !DECL_CLASS_SCOPE_P (olddecl))
@@ -1208,7 +1208,7 @@ validate_constexpr_redeclaration (tree old_decl, tree new_decl)
return true;
if (TREE_CODE (old_decl) == FUNCTION_DECL)
{
- if (DECL_BUILT_IN (old_decl))
+ if (fndecl_built_in_p (old_decl))
{
/* Hide a built-in declaration. */
DECL_DECLARED_CONSTEXPR_P (old_decl)
@@ -1442,7 +1442,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
{
warning_at (newdecl_loc,
OPT_Wshadow,
- DECL_BUILT_IN (olddecl)
+ fndecl_built_in_p (olddecl)
? G_("shadowing built-in function %q#D")
: G_("shadowing library function %q#D"), olddecl);
/* Discard the old built-in function. */
@@ -1450,7 +1450,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
}
/* If the built-in is not ansi, then programs can override
it even globally without an error. */
- else if (! DECL_BUILT_IN (olddecl))
+ else if (! fndecl_built_in_p (olddecl))
warning_at (newdecl_loc, 0,
"library function %q#D redeclared as non-function %q#D",
olddecl, newdecl);
@@ -1537,7 +1537,7 @@ next_arg:;
/* Don't really override olddecl for __* prefixed builtins
except for __[^b]*_chk, the compiler might be using those
explicitly. */
- if (DECL_BUILT_IN (olddecl))
+ if (fndecl_built_in_p (olddecl))
{
tree id = DECL_NAME (olddecl);
const char *name = IDENTIFIER_POINTER (id);
@@ -1578,9 +1578,9 @@ next_arg:;
"declaration %q#D", newdecl, olddecl);
else
warning (OPT_Wshadow,
- DECL_BUILT_IN (olddecl)
- ? G_("shadowing built-in function %q#D")
- : G_("shadowing library function %q#D"), olddecl);
+ fndecl_built_in_p (olddecl)
+ ? G_("shadowing built-in function %q#D")
+ : G_("shadowing library function %q#D"), olddecl);
}
else
/* Discard the old built-in function. */
@@ -2522,7 +2522,7 @@ next_arg:;
/* If redeclaring a builtin function, it stays built in
if newdecl is a gnu_inline definition, or if newdecl is just
a declaration. */
- if (DECL_BUILT_IN (olddecl)
+ if (fndecl_built_in_p (olddecl)
&& (new_defines_function ? GNU_INLINE_P (newdecl) : types_match))
{
DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
@@ -3662,6 +3662,8 @@ finish_case_label (location_t loc, tree low_value, tree high_value)
return error_mark_node;
type = SWITCH_STMT_TYPE (switch_stack->switch_stmt);
+ if (type == error_mark_node)
+ return error_mark_node;
low_value = case_conversion (type, low_value);
high_value = case_conversion (type, high_value);
@@ -6611,7 +6613,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
else
{
if (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+ && fndecl_built_in_p (decl, BUILT_IN_NORMAL))
set_builtin_user_assembler_name (decl, asmspec);
set_user_assembler_name (decl, asmspec);
}
@@ -10737,14 +10739,14 @@ grokdeclarator (const cp_declarator *declarator,
if (signed_p && unsigned_p)
{
gcc_rich_location richloc (declspecs->locations[ds_signed]);
- richloc.add_range (declspecs->locations[ds_unsigned], false);
+ richloc.add_range (declspecs->locations[ds_unsigned]);
error_at (&richloc,
"%<signed%> and %<unsigned%> specified together");
}
else if (long_p && short_p)
{
gcc_rich_location richloc (declspecs->locations[ds_long]);
- richloc.add_range (declspecs->locations[ds_short], false);
+ richloc.add_range (declspecs->locations[ds_short]);
error_at (&richloc, "%<long%> and %<short%> specified together");
}
else if (TREE_CODE (type) != INTEGER_TYPE
@@ -10888,7 +10890,7 @@ grokdeclarator (const cp_declarator *declarator,
if (staticp == 2)
{
gcc_rich_location richloc (declspecs->locations[ds_virtual]);
- richloc.add_range (declspecs->locations[ds_storage_class], false);
+ richloc.add_range (declspecs->locations[ds_storage_class]);
error_at (&richloc, "member %qD cannot be declared both %<virtual%> "
"and %<static%>", dname);
storage_class = sc_none;
@@ -10897,7 +10899,7 @@ grokdeclarator (const cp_declarator *declarator,
if (constexpr_p)
{
gcc_rich_location richloc (declspecs->locations[ds_virtual]);
- richloc.add_range (declspecs->locations[ds_constexpr], false);
+ richloc.add_range (declspecs->locations[ds_constexpr]);
error_at (&richloc, "member %qD cannot be declared both %<virtual%> "
"and %<constexpr%>", dname);
}
@@ -11246,7 +11248,10 @@ grokdeclarator (const cp_declarator *declarator,
/* Handle a late-specified return type. */
tree late_return_type = declarator->u.function.late_return_type;
- if (funcdecl_p)
+ if (funcdecl_p
+ /* This is the case e.g. for
+ using T = auto () -> int. */
+ || inner_declarator == NULL)
{
if (tree auto_node = type_uses_auto (type))
{
@@ -11278,6 +11283,16 @@ grokdeclarator (const cp_declarator *declarator,
name, type);
return error_mark_node;
}
+ else if (is_auto (type) && AUTO_IS_DECLTYPE (type))
+ {
+ if (funcdecl_p)
+ error ("%qs function with trailing return type has "
+ "%<decltype(auto)%> as its type rather than "
+ "plain %<auto%>", name);
+ else
+ error ("invalid use of %<decltype(auto)%>");
+ return error_mark_node;
+ }
tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node);
if (!tmpl)
if (tree late_auto = type_uses_auto (late_return_type))
@@ -11435,7 +11450,7 @@ grokdeclarator (const cp_declarator *declarator,
{
/* Cannot be both friend and virtual. */
gcc_rich_location richloc (declspecs->locations[ds_virtual]);
- richloc.add_range (declspecs->locations[ds_friend], false);
+ richloc.add_range (declspecs->locations[ds_friend]);
error_at (&richloc, "virtual functions cannot be friends");
friendp = 0;
}
@@ -15683,6 +15698,18 @@ begin_destructor_body (void)
tree stmt = cp_build_modify_expr (input_location, vtbl_ptr,
NOP_EXPR, vtbl,
tf_warning_or_error);
+ /* If the vptr is shared with some virtual nearly empty base,
+ don't clear it if not in charge, the dtor of the virtual
+ nearly empty base will do that later. */
+ if (CLASSTYPE_VBASECLASSES (current_class_type)
+ && CLASSTYPE_PRIMARY_BINFO (current_class_type)
+ && BINFO_VIRTUAL_P
+ (CLASSTYPE_PRIMARY_BINFO (current_class_type)))
+ {
+ stmt = convert_to_void (stmt, ICV_STATEMENT,
+ tf_warning_or_error);
+ stmt = build_if_in_charge (stmt);
+ }
finish_decl_cleanup (NULL_TREE, stmt);
}
else
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 452ecb95467..5bab3f345ed 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -4119,7 +4119,7 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
pp_string (pp, result);
if (set_locus && t != NULL)
- text->set_location (0, location_of (t), true);
+ text->set_location (0, location_of (t), SHOW_RANGE_WITH_CARET);
return true;
#undef next_tree
#undef next_tcode
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 8c7f68522da..c0a12d74634 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -5630,7 +5630,7 @@ maybe_suggest_missing_std_header (location_t location, tree name)
if (cxx_dialect >= header_hint->min_dialect)
{
const char *header = header_hint->header;
- maybe_add_include_fixit (&richloc, header);
+ maybe_add_include_fixit (&richloc, header, true);
inform (&richloc,
"%<std::%s%> is defined in header %qs;"
" did you forget to %<#include %s%>?",
@@ -5791,7 +5791,7 @@ consider_binding_level (tree name, best_match <tree, const char *> &bm,
/* Skip anticipated decls of builtin functions. */
if (TREE_CODE (d) == FUNCTION_DECL
- && DECL_BUILT_IN (d)
+ && fndecl_built_in_p (d)
&& DECL_ANTICIPATED (d))
continue;
@@ -7274,7 +7274,7 @@ cp_emit_debug_info_for_using (tree t, tree context)
of a builtin function. */
if (TREE_CODE (t) == FUNCTION_DECL
&& DECL_EXTERNAL (t)
- && DECL_BUILT_IN (t))
+ && fndecl_built_in_p (t))
return;
/* Do not supply context to imported_module_or_decl, if
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 49d476b383f..92e6b40efb4 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -3405,8 +3405,10 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
else if (TYPE_P (parser->scope)
&& dependent_scope_p (parser->scope))
{
+ gcc_rich_location richloc (location);
+ richloc.add_fixit_insert_before ("typename ");
if (TREE_CODE (parser->scope) == TYPENAME_TYPE)
- error_at (location,
+ error_at (&richloc,
"need %<typename%> before %<%T::%D::%E%> because "
"%<%T::%D%> is a dependent scope",
TYPE_CONTEXT (parser->scope),
@@ -3415,7 +3417,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
TYPE_CONTEXT (parser->scope),
TYPENAME_TYPE_FULLNAME (parser->scope));
else
- error_at (location, "need %<typename%> before %<%T::%E%> because "
+ error_at (&richloc, "need %<typename%> before %<%T::%E%> because "
"%qT is a dependent scope",
parser->scope, id, parser->scope);
}
@@ -4133,7 +4135,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
else if (curr_type != CPP_STRING)
{
rich_location rich_loc (line_table, tok->location);
- rich_loc.add_range (last_tok_loc, false);
+ rich_loc.add_range (last_tok_loc);
error_at (&rich_loc,
"unsupported non-standard concatenation "
"of string literals");
@@ -15240,11 +15242,15 @@ cp_parser_introduction_list (cp_parser *parser)
if (is_pack)
cp_lexer_consume_token (parser->lexer);
+ tree identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ break;
+
/* Build placeholder. */
tree parm = build_nt (WILDCARD_DECL);
DECL_SOURCE_LOCATION (parm)
= cp_lexer_peek_token (parser->lexer)->location;
- DECL_NAME (parm) = cp_parser_identifier (parser);
+ DECL_NAME (parm) = identifier;
WILDCARD_PACK_P (parm) = is_pack;
vec_safe_push (introduction_vec, parm);
@@ -17755,7 +17761,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
|| cp_parser_is_keyword (token, RID_STRUCT))
{
gcc_rich_location richloc (token->location);
- richloc.add_range (input_location, false);
+ richloc.add_range (input_location);
richloc.add_fixit_remove ();
pedwarn (&richloc, 0, "elaborated-type-specifier for "
"a scoped enum must not use the %qD keyword",
@@ -27176,18 +27182,18 @@ cp_parser_template_introduction (cp_parser* parser, bool member_p)
matching identifiers. */
tree introduction_list = cp_parser_introduction_list (parser);
+ /* Look for closing brace for introduction. */
+ if (!braces.require_close (parser))
+ return true;
+
/* The introduction-list shall not be empty. */
int nargs = TREE_VEC_LENGTH (introduction_list);
if (nargs == 0)
{
- error ("empty introduction-list");
+ /* In cp_parser_introduction_list we have already issued an error. */
return true;
}
- /* Look for closing brace for introduction. */
- if (!braces.require_close (parser))
- return true;
-
if (tmpl_decl == error_mark_node)
{
cp_parser_name_lookup_error (parser, concept_name, tmpl_decl, NLE_NULL,
@@ -28390,7 +28396,7 @@ set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs,
gcc_rich_location richloc (location);
if (gnu != decl_specs->gnu_thread_keyword_p)
{
- richloc.add_range (decl_specs->locations[ds_thread], false);
+ richloc.add_range (decl_specs->locations[ds_thread]);
error_at (&richloc,
"both %<__thread%> and %<thread_local%> specified");
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index efed9a1bf60..0a618a5447d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -16832,6 +16832,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
RANGE_FOR_IVDEP (stmt) = RANGE_FOR_IVDEP (t);
RANGE_FOR_UNROLL (stmt) = RANGE_FOR_UNROLL (t);
finish_range_for_decl (stmt, decl, expr);
+ if (decomp_first && decl != error_mark_node)
+ cp_finish_decomp (decl, decomp_first, decomp_cnt);
}
else
{
@@ -26077,7 +26079,7 @@ listify (tree arg)
if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
{
gcc_rich_location richloc (input_location);
- maybe_add_include_fixit (&richloc, "<initializer_list>");
+ maybe_add_include_fixit (&richloc, "<initializer_list>", false);
error_at (&richloc,
"deducing from brace-enclosed initializer list"
" requires %<#include <initializer_list>%>");
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 6692fb7ff86..94a92198781 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -317,7 +317,7 @@ typeid_ok_p (void)
if (!COMPLETE_TYPE_P (const_type_info_type_node))
{
gcc_rich_location richloc (input_location);
- maybe_add_include_fixit (&richloc, "<typeinfo>");
+ maybe_add_include_fixit (&richloc, "<typeinfo>", false);
error_at (&richloc,
"must %<#include <typeinfo>%> before using"
" %<typeid%>");
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index bfdca5024d3..676de011868 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1532,7 +1532,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
effectively const. */
|| (CLASS_TYPE_P (TREE_TYPE (operand))
&& C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
- cxx_readonly_error (operand, lv_asm);
+ cxx_readonly_error (input_location, operand, lv_asm);
tree *op = &operand;
while (TREE_CODE (*op) == COMPOUND_EXPR)
@@ -2546,8 +2546,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
if ((complain & tf_warning)
&& TREE_CODE (fn) == FUNCTION_DECL
- && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (fn) == BUILT_IN_MEMSET
+ && fndecl_built_in_p (fn, BUILT_IN_MEMSET)
&& vec_safe_length (*args) == 3
&& !any_type_dependent_arguments_p (*args))
{
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 8a1d2993f94..c6f216dab4b 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -420,9 +420,8 @@ builtin_valid_in_constant_expr_p (const_tree decl)
return false;
if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL)
{
- if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_FRONTEND
- && ((int) DECL_FUNCTION_CODE (decl)
- == CP_BUILT_IN_IS_CONSTANT_EVALUATED))
+ if (fndecl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+ BUILT_IN_FRONTEND))
return true;
/* Not a built-in. */
return false;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 122d9dcd4b3..ab088a946b3 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6228,9 +6228,10 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
|| TREE_READONLY (arg))
{
if (complain & tf_error)
- cxx_readonly_error (arg, ((code == PREINCREMENT_EXPR
- || code == POSTINCREMENT_EXPR)
- ? lv_increment : lv_decrement));
+ cxx_readonly_error (location, arg,
+ ((code == PREINCREMENT_EXPR
+ || code == POSTINCREMENT_EXPR)
+ ? lv_increment : lv_decrement));
else
return error_mark_node;
}
@@ -8159,7 +8160,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
&& C_TYPE_FIELDS_READONLY (lhstype))))
{
if (complain & tf_error)
- cxx_readonly_error (lhs, lv_assign);
+ cxx_readonly_error (loc, lhs, lv_assign);
return error_mark_node;
}
@@ -9178,6 +9179,19 @@ can_do_nrvo_p (tree retval, tree functype)
&& !TYPE_VOLATILE (TREE_TYPE (retval)));
}
+/* Returns true if we should treat RETVAL, an expression being returned,
+ as if it were designated by an rvalue. See [class.copy.elision]. */
+
+static bool
+treat_lvalue_as_rvalue_p (tree retval)
+{
+ return ((cxx_dialect != cxx98)
+ && ((VAR_P (retval) && !DECL_HAS_VALUE_EXPR_P (retval))
+ || TREE_CODE (retval) == PARM_DECL)
+ && DECL_CONTEXT (retval) == current_function_decl
+ && !TREE_STATIC (retval));
+}
+
/* Warn about wrong usage of std::move in a return statement. RETVAL
is the expression we are returning; FUNCTYPE is the type the function
is declared to return. */
@@ -9185,13 +9199,20 @@ can_do_nrvo_p (tree retval, tree functype)
static void
maybe_warn_pessimizing_move (tree retval, tree functype)
{
- if (!warn_pessimizing_move)
+ if (!(warn_pessimizing_move || warn_redundant_move))
return;
+ location_t loc = cp_expr_loc_or_loc (retval, input_location);
+
/* C++98 doesn't know move. */
if (cxx_dialect < cxx11)
return;
+ /* Wait until instantiation time, since we can't gauge if we should do
+ the NRVO until then. */
+ if (processing_template_decl)
+ return;
+
/* This is only interesting for class types. */
if (!CLASS_TYPE_P (functype))
return;
@@ -9207,14 +9228,24 @@ maybe_warn_pessimizing_move (tree retval, tree functype)
STRIP_NOPS (arg);
if (TREE_CODE (arg) == ADDR_EXPR)
arg = TREE_OPERAND (arg, 0);
+ arg = convert_from_reference (arg);
/* Warn if we could do copy elision were it not for the move. */
if (can_do_nrvo_p (arg, functype))
{
auto_diagnostic_group d;
- if (warning_at (location_of (retval), OPT_Wpessimizing_move,
+ if (warning_at (loc, OPT_Wpessimizing_move,
"moving a local object in a return statement "
"prevents copy elision"))
- inform (location_of (retval), "remove %<std::move%> call");
+ inform (loc, "remove %<std::move%> call");
+ }
+ /* Warn if the move is redundant. It is redundant when we would
+ do maybe-rvalue overload resolution even without std::move. */
+ else if (treat_lvalue_as_rvalue_p (arg))
+ {
+ auto_diagnostic_group d;
+ if (warning_at (loc, OPT_Wredundant_move,
+ "redundant move in return statement"))
+ inform (loc, "remove %<std::move%> call");
}
}
}
@@ -9494,11 +9525,7 @@ check_return_expr (tree retval, bool *no_warning)
Note that these conditions are similar to, but not as strict as,
the conditions for the named return value optimization. */
bool converted = false;
- if ((cxx_dialect != cxx98)
- && ((VAR_P (retval) && !DECL_HAS_VALUE_EXPR_P (retval))
- || TREE_CODE (retval) == PARM_DECL)
- && DECL_CONTEXT (retval) == current_function_decl
- && !TREE_STATIC (retval)
+ if (treat_lvalue_as_rvalue_p (retval)
/* This is only interesting for class type. */
&& CLASS_TYPE_P (functype))
{
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 1e899ab17a1..71fbff167a5 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -67,28 +67,28 @@ binfo_or_else (tree base, tree type)
value may not be changed thereafter. */
void
-cxx_readonly_error (tree arg, enum lvalue_use errstring)
+cxx_readonly_error (location_t loc, tree arg, enum lvalue_use errstring)
{
/* This macro is used to emit diagnostics to ensure that all format
strings are complete sentences, visible to gettext and checked at
compile time. */
-#define ERROR_FOR_ASSIGNMENT(AS, ASM, IN, DE, ARG) \
+#define ERROR_FOR_ASSIGNMENT(LOC, AS, ASM, IN, DE, ARG) \
do { \
switch (errstring) \
{ \
case lv_assign: \
- error(AS, ARG); \
+ error_at (LOC, AS, ARG); \
break; \
case lv_asm: \
- error(ASM, ARG); \
+ error_at (LOC, ASM, ARG); \
break; \
case lv_increment: \
- error (IN, ARG); \
+ error_at (LOC, IN, ARG); \
break; \
- case lv_decrement: \
- error (DE, ARG); \
+ case lv_decrement: \
+ error_at (LOC, DE, ARG); \
break; \
default: \
gcc_unreachable (); \
@@ -101,32 +101,25 @@ cxx_readonly_error (tree arg, enum lvalue_use errstring)
&& DECL_LANG_SPECIFIC (arg)
&& DECL_IN_AGGR_P (arg)
&& !TREE_STATIC (arg))
- ERROR_FOR_ASSIGNMENT (G_("assignment of "
- "constant field %qD"),
- G_("constant field %qD "
- "used as %<asm%> output"),
- G_("increment of "
- "constant field %qD"),
- G_("decrement of "
- "constant field %qD"),
+ ERROR_FOR_ASSIGNMENT (loc,
+ G_("assignment of constant field %qD"),
+ G_("constant field %qD used as %<asm%> output"),
+ G_("increment of constant field %qD"),
+ G_("decrement of constant field %qD"),
arg);
else if (INDIRECT_REF_P (arg)
&& TYPE_REF_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
&& (VAR_P (TREE_OPERAND (arg, 0))
|| TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL))
- ERROR_FOR_ASSIGNMENT (G_("assignment of "
- "read-only reference %qD"),
- G_("read-only reference %qD "
- "used as %<asm%> output"),
- G_("increment of "
- "read-only reference %qD"),
- G_("decrement of "
- "read-only reference %qD"),
- TREE_OPERAND (arg, 0));
+ ERROR_FOR_ASSIGNMENT (loc,
+ G_("assignment of read-only reference %qD"),
+ G_("read-only reference %qD used as %<asm%> output"),
+ G_("increment of read-only reference %qD"),
+ G_("decrement of read-only reference %qD"),
+ TREE_OPERAND (arg, 0));
else
- readonly_error (input_location, arg, errstring);
+ readonly_error (loc, arg, errstring);
}
-
/* Structure that holds information about declarations whose type was
incomplete and we could not check whether it was abstract or not. */