aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-04-05 15:50:48 -0400
committerJason Merrill <jason@redhat.com>2021-04-05 17:27:00 -0400
commit07f56824fd4da14a48030e698c8eb58de951c741 (patch)
tree250ead25b891f8a61b1f898b7d0f32d2f9c09555
parent9f4c41147a41d08a74990eafe69a1064a3c13435 (diff)
downloadgcc-07f56824fd4da14a48030e698c8eb58de951c741.zip
gcc-07f56824fd4da14a48030e698c8eb58de951c741.tar.gz
gcc-07f56824fd4da14a48030e698c8eb58de951c741.tar.bz2
c++: reinterpret_cast from prvalue to rvalue ref [PR98440]
In r260622 I allowed this under the general principle that [basic.lval] "Whenever a prvalue appears as an operand of an operator that expects a glvalue for that operand, the temporary materialization conversion (7.3.4) is applied to convert the expression to an xvalue." But [expr.reinterpret.cast] specifically excludes creating a temporary in this case. gcc/cp/ChangeLog: PR c++/98440 * typeck.c (build_reinterpret_cast_1): Don't perform temporary materialization. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/rv-cast6.C: Expect reinterpret_cast error. * g++.dg/cpp0x/reinterpret_cast2.C: Adjust message. * g++.old-deja/g++.jason/rvalue3.C: Likewise.
-rw-r--r--gcc/cp/typeck.c18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/rv-cast6.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C2
4 files changed, 10 insertions, 14 deletions
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index dff4e9b..8535ecc 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -7938,22 +7938,18 @@ build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
type = cv_unqualified (type);
/* [expr.reinterpret.cast]
- A glvalue expression of type T1 can be cast to the type
+ A glvalue of type T1, designating an object x, can be cast to the type
"reference to T2" if an expression of type "pointer to T1" can be
- explicitly converted to the type "pointer to T2" using a
- reinterpret_cast. */
+ explicitly converted to the type "pointer to T2" using a reinterpret_cast.
+ The result is that of *reinterpret_cast<T2 *>(p) where p is a pointer to x
+ of type "pointer to T1". No temporary is created, no copy is made, and no
+ constructors (11.4.4) or conversion functions (11.4.7) are called. */
if (TYPE_REF_P (type))
{
- if (TYPE_REF_IS_RVALUE (type) && !VOID_TYPE_P (intype))
- {
- if (!obvalue_p (expr))
- /* Perform the temporary materialization conversion. */
- expr = get_target_expr_sfinae (expr, complain);
- }
- else if (!lvalue_p (expr))
+ if (!glvalue_p (expr))
{
if (complain & tf_error)
- error_at (loc, "invalid cast of an rvalue expression of type "
+ error_at (loc, "invalid cast of a prvalue expression of type "
"%qT to type %qT",
intype, type);
return error_mark_node;
diff --git a/gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C b/gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C
index c173576..5402e82 100644
--- a/gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C
@@ -6,5 +6,5 @@ struct S { };
void
foo ()
{
- auto a = reinterpret_cast<S&&>(foo ()); // { dg-error "12:invalid cast of an rvalue expression of type 'void' to type" }
+ auto a = reinterpret_cast<S&&>(foo ()); // { dg-error "12:invalid cast of a prvalue expression of type 'void' to type" }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-cast6.C b/gcc/testsuite/g++.dg/cpp0x/rv-cast6.C
index 3ae5691..3adf683 100644
--- a/gcc/testsuite/g++.dg/cpp0x/rv-cast6.C
+++ b/gcc/testsuite/g++.dg/cpp0x/rv-cast6.C
@@ -5,7 +5,7 @@ struct A { virtual void f(); };
struct B : A {};
auto && a = static_cast<A&&>(B());
-auto && b = reinterpret_cast<A&&>(B());
+auto && b = reinterpret_cast<A&&>(B()); // { dg-error "prvalue" }
auto && c = dynamic_cast<A&&>(B());
auto && d = dynamic_cast<B&&>(static_cast<A&&>(B()));
auto && e = const_cast<B&&>(B());
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C b/gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C
index 49191c9..77969bc 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C
@@ -2,5 +2,5 @@
int main ()
{
int i;
- int &ir = (int&)(int)i; // { dg-error "14:invalid cast of an rvalue expression" } casting rvalue to reference type
+ int &ir = (int&)(int)i; // { dg-error "14:invalid cast of a prvalue expression" } casting rvalue to reference type
}