aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-11-11 23:57:29 -0500
committerJason Merrill <jason@gcc.gnu.org>2019-11-11 23:57:29 -0500
commitc9cd5c56fd01ea931308dfb6232a01cd5478bd3d (patch)
tree4f55345662efee8ad0ae92896a795ee80a048114 /gcc/cp
parent6e9a85d5052607c8ed31940ce2794323df9463cc (diff)
downloadgcc-c9cd5c56fd01ea931308dfb6232a01cd5478bd3d.zip
gcc-c9cd5c56fd01ea931308dfb6232a01cd5478bd3d.tar.gz
gcc-c9cd5c56fd01ea931308dfb6232a01cd5478bd3d.tar.bz2
Implement P1946R0, Allow defaulting comparisons by value.
* method.c (early_check_defaulted_comparison): Accept by-value, reject mixed by-value and by-reference parms. * decl.c (grokdeclarator): Set funcdef_flag for defaulted friend. * decl2.c (grokfield): Don't SET_DECL_FRIEND_CONTEXT. From-SVN: r278078
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c5
-rw-r--r--gcc/cp/decl2.c4
-rw-r--r--gcc/cp/method.c50
4 files changed, 44 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7e5e446..23339b6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2019-11-11 Jason Merrill <jason@redhat.com>
+ Implement P1946R0, Allow defaulting comparisons by value.
+ * method.c (early_check_defaulted_comparison): Accept by-value,
+ reject mixed by-value and by-reference parms.
+ * decl.c (grokdeclarator): Set funcdef_flag for defaulted friend.
+ * decl2.c (grokfield): Don't SET_DECL_FRIEND_CONTEXT.
+
* typeck.c (cp_build_binary_op): Sorry about <=> on VECTOR_TYPE.
2019-11-11 Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index caa04af..86e38f4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -13202,6 +13202,11 @@ grokdeclarator (const cp_declarator *declarator,
; /* We already issued a permerror. */
else if (decl && DECL_NAME (decl))
{
+ if (initialized)
+ /* Kludge: We need funcdef_flag to be true in do_friend for
+ in-class defaulted functions, but that breaks grokfndecl.
+ So set it here. */
+ funcdef_flag = true;
if (template_class_depth (current_class_type) == 0)
{
decl = check_explicit_specialization
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 4f0b216..f164494 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -927,10 +927,6 @@ grokfield (const cp_declarator *declarator,
}
else if (init == ridpointers[(int)RID_DEFAULT])
{
- if (friendp)
- /* ??? do_friend doesn't set this because funcdef_flag is false
- for in-class defaulted functions. So set it here. */
- SET_DECL_FRIEND_CONTEXT (value, current_class_type);
if (defaultable_fn_check (value))
{
DECL_DEFAULTED_FN (value) = 1;
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 47441c1..acba6c6 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1094,38 +1094,54 @@ early_check_defaulted_comparison (tree fn)
if (!DECL_OVERLOADED_OPERATOR_IS (fn, SPACESHIP_EXPR)
&& !same_type_p (TREE_TYPE (TREE_TYPE (fn)), boolean_type_node))
{
- error_at (loc, "defaulted %qD must return %<bool%>", fn);
- ok = false;
+ diagnostic_t kind = DK_UNSPECIFIED;
+ int opt = 0;
+ if (is_auto (TREE_TYPE (fn)))
+ kind = DK_PEDWARN;
+ else
+ kind = DK_ERROR;
+ emit_diagnostic (kind, loc, opt,
+ "defaulted %qD must return %<bool%>", fn);
+ if (kind == DK_ERROR)
+ ok = false;
}
- int i = DECL_NONSTATIC_MEMBER_FUNCTION_P (fn);
- if (i && type_memfn_quals (TREE_TYPE (fn)) != TYPE_QUAL_CONST)
+ bool mem = DECL_NONSTATIC_MEMBER_FUNCTION_P (fn);
+ if (mem && type_memfn_quals (TREE_TYPE (fn)) != TYPE_QUAL_CONST)
{
error_at (loc, "defaulted %qD must be %<const%>", fn);
ok = false;
}
tree parmnode = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ bool saw_byval = false;
+ bool saw_byref = mem;
+ bool saw_bad = false;
for (; parmnode != void_list_node; parmnode = TREE_CHAIN (parmnode))
{
- ++i;
tree parmtype = TREE_VALUE (parmnode);
- diagnostic_t kind = DK_UNSPECIFIED;
- int opt = 0;
if (same_type_p (parmtype, ctx))
- /* The draft specifies const reference, but let's also allow by-value
- unless -Wpedantic, hopefully it will be added soon. */
- kind = DK_PEDWARN,
- opt = OPT_Wpedantic;
+ saw_byval = true;
else if (TREE_CODE (parmtype) != REFERENCE_TYPE
|| TYPE_QUALS (TREE_TYPE (parmtype)) != TYPE_QUAL_CONST
|| !(same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (parmtype), ctx)))
- kind = DK_ERROR;
- if (kind)
- emit_diagnostic (kind, loc, opt, "defaulted %qD must have "
- "parameter type %<const %T&%>", fn, ctx);
- if (kind == DK_ERROR)
- ok = false;
+ saw_bad = true;
+ else
+ saw_byref = true;
+ }
+
+ if (saw_bad || (saw_byval && saw_byref))
+ {
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+ error_at (loc, "defaulted member %qD must have parameter type "
+ "%<const %T&%>", fn, ctx);
+ else if (saw_bad)
+ error_at (loc, "defaulted %qD must have parameters of either type "
+ "%<const %T&%> or %qT", fn, ctx, ctx);
+ else
+ error_at (loc, "defaulted %qD must have parameters of either type "
+ "%<const %T&%> or %qT, not both", fn, ctx, ctx);
+ ok = false;
}
/* We still need to deduce deleted/constexpr/noexcept and maybe return. */