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.
This commit is contained in:
parent
9f4c41147a
commit
07f56824fd
4 changed files with 10 additions and 14 deletions
|
@ -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;
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue