From patchwork Wed Sep 28 21:26:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 1514 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f2ce:0:0:0:0:0 with SMTP id d14csp377464wrp; Wed, 28 Sep 2022 14:27:27 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6Bt4fdhl36Lj4cLl92bLDaXdbjRbbPWpTS/6klRBOB5Rs5vpSxyf7ImlwdeiNSemzONmxO X-Received: by 2002:a05:6402:5190:b0:44f:2924:78f4 with SMTP id q16-20020a056402519000b0044f292478f4mr34589051edd.217.1664400447624; Wed, 28 Sep 2022 14:27:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664400447; cv=none; d=google.com; s=arc-20160816; b=XUDgIT+UewsijiFFjxrPQOH5HUl3ZZYjP39IhA5xYwtO2HMjVfdCeH62hZvC/5MYMs 0pVsCr9HEx6J4McVpI30ZQujaPh/7cypn0nUmXxd9cSPR/LFJeJ98fXO6+i13Yi8MeDH w7LZMFMT/INRX8xFIa4kh1v9Bk2rkDxqq9OMsUS5juvBhY8ZGQQXRGjYCk06TmF+azKf 1cWm1Od8T5EnGjXQqRwYT82t8LOviHkfabBXaTxSBmlmdc4H38/mJGz0owx5SFl9TNAa htGgaZ8aI9mh4b4TAiGtyOqICm67Cx37pUVgnRJt9qNCHvgG3n+V6HiBfujiL5YxtITV 0I1A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:to :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=ff7NbDn2wni7a7ZNTYeujsOnI57DWDHdRKM9UcujHp8=; b=e4exgmgTftrNq/CGaoWTy+4upJwZMpbD8sBhEj1WrT0vLfBqoCWJQCzdlH92VAnbjY cq6TSUpTJCYTb73XTF0klTOwOslL1ZnfKAUA/oKjDv2UslnoIyRpAkZIKXJPpkpd0HF4 XtBZ3/GMOYd9SoKRQ9vKjUDDz/lqb2FP9Kt2PiM8d3BFddMOeMNLqIszLnW5zE3tsm4y v2W7Goe0L3yEYxkq0mHEadmsX2OztYXZIcxE/kz/UY9EJ409yECwnjRVxuLzc4Rkv9Ow 71sv0vdQO0oyhgn708SY/WE8I1iLVjEiVsIVA61Y86cncZfbX0fAFbwUFqUlZX+C1VvB Aq2w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=uy+AYCgL; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id y16-20020a056402359000b00454b9403108si6980370edc.219.2022.09.28.14.27.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Sep 2022 14:27:27 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=uy+AYCgL; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4BB353858424 for ; Wed, 28 Sep 2022 21:27:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4BB353858424 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1664400446; bh=ff7NbDn2wni7a7ZNTYeujsOnI57DWDHdRKM9UcujHp8=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=uy+AYCgLHOpom/CUR0ofXQq3bkD3fpFi8dpeqdLGaqbxvjQj2129UGc4KwnCXn5h1 JWRXimEvHIk3cYT8yUf9HV3vs1UIHT9z8CYZujFRpxixvq983QXpHaP7vL8hnNWWJQ rCS2Kkk0G+Pa2L7IrTEEs7dLYaSMK8ww5AWiM12A= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 5FBD53858D28 for ; Wed, 28 Sep 2022 21:26:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5FBD53858D28 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-663-RekQCamzOPi016OXopRFKQ-1; Wed, 28 Sep 2022 17:26:40 -0400 X-MC-Unique: RekQCamzOPi016OXopRFKQ-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 950A629DD9A0 for ; Wed, 28 Sep 2022 21:26:40 +0000 (UTC) Received: from pdp-11.lan (unknown [10.22.8.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6CB62492B04; Wed, 28 Sep 2022 21:26:40 +0000 (UTC) To: GCC Patches , Jason Merrill Subject: [PATCH] c++: Remove maybe-rvalue OR in implicit move Date: Wed, 28 Sep 2022 17:26:34 -0400 Message-Id: <20220928212634.1275032-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Marek Polacek via Gcc-patches From: Marek Polacek Reply-To: Marek Polacek Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1745250364154493097?= X-GMAIL-MSGID: =?utf-8?q?1745250364154493097?= This patch removes the two-stage overload resolution when performing implicit move, whereby the compiler does two separate overload resolutions: one treating the operand as an rvalue, and then (if that resolution fails) another one treating the operand as an lvalue. In the standard this was introduced via CWG 1579 and implemented in gcc in r251035. In r11-2412, we disabled the fallback OR in C++20 (but not in C++17). Then C++23 P2266 removed the fallback overload resolution, and changed the implicit move rules once again. So we wound up with three different behaviors. The two overload resolutions approach was complicated and quirky, so users should transition to the newer model. Removing the maybe-rvalue OR also allows us to simplify our code, for instance, now we can get rid of LOOKUP_PREFER_RVALUE altogether. This change means that code that previously didn't compile in C++17 will now compile, for example: struct S1 { S1(S1 &&); }; struct S2 : S1 {}; S1 f (S2 s) { return s; // OK, derived-to-base, use S1::S1(S1&&) } And conversely, code that used to work in C++17 may not compile anymore: struct W { W(); }; struct F { F(W&); F(W&&) = delete; }; F fn () { W w; return w; // use w as rvalue -> use of deleted function F::F(W&&) } I plan to add a note to porting_to.html. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? gcc/cp/ChangeLog: * call.cc (standard_conversion): Remove LOOKUP_PREFER_RVALUE code. (reference_binding): Honor clk_implicit_rval even pre-C++20. (implicit_conversion_1): Remove LOOKUP_PREFER_RVALUE code. (build_user_type_conversion_1): Likewise. (convert_like_internal): Likewise. (build_over_call): Likewise. * cp-tree.h (LOOKUP_PREFER_RVALUE): Remove. (LOOKUP_NO_NARROWING): Adjust definition. * except.cc (build_throw): Don't perform two overload resolutions. * typeck.cc (maybe_warn_pessimizing_move): Don't use LOOKUP_PREFER_RVALUE. (check_return_expr): Don't perform two overload resolutions. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/Wredundant-move10.C: Adjust dg-warning. * g++.dg/cpp0x/Wredundant-move7.C: Likewise. * g++.dg/cpp0x/move-return2.C: Remove dg-error. * g++.dg/cpp0x/move-return4.C: Likewise. * g++.dg/cpp0x/ref-qual20.C: Adjust expected return value. * g++.dg/cpp0x/move-return5.C: New test. --- gcc/cp/call.cc | 41 ++----------------- gcc/cp/cp-tree.h | 6 +-- gcc/cp/except.cc | 23 ++--------- gcc/cp/typeck.cc | 34 +++------------ .../g++.dg/cpp0x/Wredundant-move10.C | 2 +- gcc/testsuite/g++.dg/cpp0x/Wredundant-move7.C | 6 +-- gcc/testsuite/g++.dg/cpp0x/move-return2.C | 2 +- gcc/testsuite/g++.dg/cpp0x/move-return4.C | 2 +- gcc/testsuite/g++.dg/cpp0x/move-return5.C | 20 +++++++++ gcc/testsuite/g++.dg/cpp0x/ref-qual20.C | 2 +- 10 files changed, 41 insertions(+), 97 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/move-return5.C base-commit: 9f65eecdbef6027722e93aadf3fa6b3cc342eb4f diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 3506b0fcfbb..e100913ea29 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -1272,9 +1272,6 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, } } conv = build_conv (ck_rvalue, from, conv); - if (flags & LOOKUP_PREFER_RVALUE) - /* Tell convert_like to set LOOKUP_PREFER_RVALUE. */ - conv->rvaluedness_matches_p = true; /* If we're performing copy-initialization, remember to skip explicit constructors. */ if (flags & LOOKUP_ONLYCONVERTING) @@ -1572,9 +1569,6 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, type. A temporary object is created to hold the result of the conversion unless we're binding directly to a reference. */ conv->need_temporary_p = !(flags & LOOKUP_NO_TEMP_BIND); - if (flags & LOOKUP_PREFER_RVALUE) - /* Tell convert_like to set LOOKUP_PREFER_RVALUE. */ - conv->rvaluedness_matches_p = true; /* If we're performing copy-initialization, remember to skip explicit constructors. */ if (flags & LOOKUP_ONLYCONVERTING) @@ -1883,7 +1877,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags, /* Unless it's really a C++20 lvalue being treated as an xvalue. But in C++23, such an expression is just an xvalue, not a special lvalue, so the binding is once again ill-formed. */ - && !(cxx_dialect == cxx20 + && !(cxx_dialect <= cxx20 && (gl_kind & clk_implicit_rval)) && (!CP_TYPE_CONST_NON_VOLATILE_P (to) || (flags & LOOKUP_NO_RVAL_BIND)) @@ -2044,9 +2038,8 @@ implicit_conversion_1 (tree to, tree from, tree expr, bool c_cast_p, /* Other flags only apply to the primary function in overload resolution, or after we've chosen one. */ flags &= (LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION|LOOKUP_COPY_PARM - |LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_PREFER_RVALUE - |LOOKUP_NO_NARROWING|LOOKUP_PROTECT|LOOKUP_NO_NON_INTEGRAL - |LOOKUP_SHORTCUT_BAD_CONVS); + |LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_NO_NARROWING + |LOOKUP_PROTECT|LOOKUP_NO_NON_INTEGRAL|LOOKUP_SHORTCUT_BAD_CONVS); /* FIXME: actually we don't want warnings either, but we can't just have 'complain &= ~(tf_warning|tf_error)' because it would cause @@ -4451,14 +4444,6 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags, if (cand->viable == -1) conv->bad_p = true; - /* We're performing the maybe-rvalue overload resolution and - a conversion function is in play. Reject converting the return - value of the conversion function to a base class. */ - if ((flags & LOOKUP_PREFER_RVALUE) && !DECL_CONSTRUCTOR_P (cand->fn)) - for (conversion *t = cand->second_conv; t; t = next_conversion (t)) - if (t->kind == ck_base) - return NULL; - /* Remember that this was a list-initialization. */ if (flags & LOOKUP_NO_NARROWING) conv->check_narrowing = true; @@ -8281,9 +8266,6 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum, explicit constructors. */ if (convs->copy_init_p) flags |= LOOKUP_ONLYCONVERTING; - if (convs->rvaluedness_matches_p) - /* standard_conversion got LOOKUP_PREFER_RVALUE. */ - flags |= LOOKUP_PREFER_RVALUE; expr = build_temp (expr, totype, flags, &diag_kind, complain); if (diag_kind && complain) { @@ -9529,23 +9511,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ++arg_index; parm = TREE_CHAIN (parm); } - - if (cxx_dialect < cxx20 - && (cand->flags & LOOKUP_PREFER_RVALUE)) - { - /* 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)...." */ - gcc_assert (!(complain & tf_error)); - tree ptype = convs[0]->type; - /* Allow calling a by-value converting constructor even though it - isn't permitted by the above, because we've allowed it since GCC 5 - (PR58051) and it's allowed in C++20. But don't call a copy - constructor. */ - if ((TYPE_REF_P (ptype) && !TYPE_REF_IS_RVALUE (ptype)) - || CONVERSION_RANK (convs[0]) > cr_exact) - return error_mark_node; - } } /* Bypass access control for 'this' parameter. */ else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d0f1b18b015..7acb5373513 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5853,12 +5853,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; #define LOOKUP_DESTRUCTOR (1 << 5) /* Do not permit references to bind to temporaries. */ #define LOOKUP_NO_TEMP_BIND (1 << 6) -/* We're trying to treat an lvalue as an rvalue. */ -/* FIXME remove when we extend the P1825 semantics to all standard modes, the - C++20 approach uses IMPLICIT_RVALUE_P instead. */ -#define LOOKUP_PREFER_RVALUE (LOOKUP_NO_TEMP_BIND << 1) /* We're inside an init-list, so narrowing conversions are ill-formed. */ -#define LOOKUP_NO_NARROWING (LOOKUP_PREFER_RVALUE << 1) +#define LOOKUP_NO_NARROWING (LOOKUP_NO_TEMP_BIND << 1) /* We're looking up a constructor for list-initialization. */ #define LOOKUP_LIST_INIT_CTOR (LOOKUP_NO_NARROWING << 1) /* This is the first parameter of a copy constructor. */ diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc index 048612de400..1d84b451c9f 100644 --- a/gcc/cp/except.cc +++ b/gcc/cp/except.cc @@ -715,25 +715,10 @@ build_throw (location_t loc, tree exp) treated as an rvalue for the purposes of overload resolution to favor move constructors over copy constructors. */ if (tree moved = treat_lvalue_as_rvalue_p (exp, /*return*/false)) - { - if (cxx_dialect < cxx20) - { - releasing_vec exp_vec (make_tree_vector_single (moved)); - moved = (build_special_member_call - (object, complete_ctor_identifier, &exp_vec, - TREE_TYPE (object), flags|LOOKUP_PREFER_RVALUE, - tf_none)); - if (moved != error_mark_node) - { - exp = moved; - converted = true; - } - } - else - /* In C++20 we just treat the return value as an rvalue that - can bind to lvalue refs. */ - exp = moved; - } + /* In C++20 we just treat the return value as an rvalue that + can bind to lvalue refs. In C++23, such an expression is just + an xvalue. */ + exp = moved; /* Call the copy constructor. */ if (!converted) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 5f16c4d2426..c525e880383 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -10692,21 +10692,12 @@ maybe_warn_pessimizing_move (tree expr, tree type, bool return_p) tree t = convert_for_initialization (NULL_TREE, type, moved, (LOOKUP_NORMAL - | LOOKUP_ONLYCONVERTING - | LOOKUP_PREFER_RVALUE), + | LOOKUP_ONLYCONVERTING), ICR_RETURN, NULL_TREE, 0, tf_none); /* If this worked, implicit rvalue would work, so the call to std::move is redundant. */ - if (t != error_mark_node - /* Trying to move something const will never succeed unless - there's T(const T&&), which it almost never is, and if - so, T wouldn't be error_mark_node now: the above convert_ - call with LOOKUP_PREFER_RVALUE returns an error if a const T& - overload is selected. */ - || (CP_TYPE_CONST_P (TREE_TYPE (arg)) - && same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (arg), type))) + if (t != error_mark_node) { auto_diagnostic_group d; if (warning_at (loc, OPT_Wredundant_move, @@ -11049,23 +11040,10 @@ check_return_expr (tree retval, bool *no_warning) ? CLASS_TYPE_P (functype) : !SCALAR_TYPE_P (functype) || !SCALAR_TYPE_P (TREE_TYPE (retval))) && (moved = treat_lvalue_as_rvalue_p (retval, /*return*/true))) - { - if (cxx_dialect < cxx20) - { - moved = convert_for_initialization - (NULL_TREE, functype, moved, flags|LOOKUP_PREFER_RVALUE, - ICR_RETURN, NULL_TREE, 0, tf_none); - if (moved != error_mark_node) - { - retval = moved; - converted = true; - } - } - else - /* In C++20 we just treat the return value as an rvalue that - can bind to lvalue refs. */ - retval = moved; - } + /* In C++20 and earlier we just treat the return value as an rvalue + that can bind to lvalue refs. In C++23, such an expression is just + an xvalue (see reference_binding). */ + retval = moved; /* The call in a (lambda) thunk needs no conversions. */ if (TREE_CODE (retval) == CALL_EXPR diff --git a/gcc/testsuite/g++.dg/cpp0x/Wredundant-move10.C b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move10.C index a215a4774d6..17dd807aea8 100644 --- a/gcc/testsuite/g++.dg/cpp0x/Wredundant-move10.C +++ b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move10.C @@ -57,5 +57,5 @@ struct S2: S1 {}; S1 f3(const S2 s) { - return std::move(s); // { dg-warning "redundant move" "" { target c++20 } } + return std::move(s); // { dg-warning "redundant move" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/Wredundant-move7.C b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move7.C index 3fec525879d..6547777c007 100644 --- a/gcc/testsuite/g++.dg/cpp0x/Wredundant-move7.C +++ b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move7.C @@ -28,7 +28,7 @@ struct S2 : S1 {}; S1 f (S2 s) { - return std::move(s); // { dg-warning "redundant move in return statement" "" { target c++20 } } + return std::move(s); // { dg-warning "redundant move in return statement" } } struct R1 { @@ -40,7 +40,7 @@ struct R2 : R1 {}; R1 f2 (const R2 s) { - return std::move(s); // { dg-warning "redundant move in return statement" "" { target c++20 } } + return std::move(s); // { dg-warning "redundant move in return statement" } } struct T1 { @@ -55,5 +55,5 @@ f3 (const T2 s) { // Without std::move: const T1 & // With std::move: const T1 && - return std::move(s); // { dg-warning "redundant move in return statement" "" { target c++20 } } + return std::move(s); // { dg-warning "redundant move in return statement" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/move-return2.C b/gcc/testsuite/g++.dg/cpp0x/move-return2.C index 999f2c95c49..8e750efb870 100644 --- a/gcc/testsuite/g++.dg/cpp0x/move-return2.C +++ b/gcc/testsuite/g++.dg/cpp0x/move-return2.C @@ -7,5 +7,5 @@ struct S2 : S1 {}; S1 f (S2 s) { - return s; // { dg-error "use of deleted function" "" { target c++17_down } } + return s; } diff --git a/gcc/testsuite/g++.dg/cpp0x/move-return4.C b/gcc/testsuite/g++.dg/cpp0x/move-return4.C index 3fc58089319..0f0ca1fc253 100644 --- a/gcc/testsuite/g++.dg/cpp0x/move-return4.C +++ b/gcc/testsuite/g++.dg/cpp0x/move-return4.C @@ -13,5 +13,5 @@ struct A : Base A foo() { A v; - return v; // { dg-error "cannot bind rvalue reference" "" { target c++17_down } } + return v; } diff --git a/gcc/testsuite/g++.dg/cpp0x/move-return5.C b/gcc/testsuite/g++.dg/cpp0x/move-return5.C new file mode 100644 index 00000000000..695000b2687 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/move-return5.C @@ -0,0 +1,20 @@ +// { dg-do compile { target c++11 } } +// This used to compile in C++11...17 because we performed two +// separate overload resolutions: one treating the operand as +// an rvalue, and then (if that resolution fails) another one +// treating the operand as an lvalue. + +struct W { + W(); +}; + +struct F { + F(W&); + F(W&&) = delete; +}; + +F fn () +{ + W w; + return w; // { dg-error "use of deleted function" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/ref-qual20.C b/gcc/testsuite/g++.dg/cpp0x/ref-qual20.C index cfbef300226..314f19bb864 100644 --- a/gcc/testsuite/g++.dg/cpp0x/ref-qual20.C +++ b/gcc/testsuite/g++.dg/cpp0x/ref-qual20.C @@ -52,7 +52,7 @@ f5 () int main () { - int return_lval = __cplusplus > 201703L ? -1 : 2; + int return_lval = -1; Y y1 = f (A()); if (y1.y != return_lval) __builtin_abort ();