re PR c++/51406 ([c++0x] Incorrect result of static_cast to rvalue reference to base class.)

PR c++/51406
	PR c++/51161
	* typeck.c (build_static_cast_1): Fix cast of lvalue to
	base rvalue reference.

From-SVN: r182322
This commit is contained in:
Jason Merrill 2011-12-14 00:18:39 -05:00 committed by Jason Merrill
parent c990877a41
commit 58fc93fb00
5 changed files with 57 additions and 3 deletions

View File

@ -1,3 +1,10 @@
2011-12-13 Jason Merrill <jason@redhat.com>
PR c++/51406
PR c++/51161
* typeck.c (build_static_cast_1): Fix cast of lvalue to
base rvalue reference.
2011-12-13 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/51464

View File

@ -5856,12 +5856,22 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)." */
if (TREE_CODE (type) == REFERENCE_TYPE
&& TYPE_REF_IS_RVALUE (type)
&& lvalue_or_rvalue_with_address_p (expr)
&& real_lvalue_p (expr)
&& reference_related_p (TREE_TYPE (type), intype)
&& (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
{
expr = build_typed_address (expr, type);
return convert_from_reference (expr);
/* Handle the lvalue case here by casting to lvalue reference and
then changing it to an rvalue reference. Casting an xvalue to
rvalue reference will be handled by the main code path. */
tree lref = cp_build_reference_type (TREE_TYPE (type), false);
result = (perform_direct_initialization_if_possible
(lref, expr, c_cast_p, complain));
result = cp_fold_convert (type, result);
/* Make sure we don't fold back down to a named rvalue reference,
because that would be an lvalue. */
if (DECL_P (result))
result = build1 (NON_LVALUE_EXPR, type, result);
return convert_from_reference (result);
}
/* Resolve overloaded address here rather than once in

View File

@ -1,3 +1,10 @@
2011-12-13 Jason Merrill <jason@redhat.com>
PR c++/51406
PR c++/51161
* g++.dg/cpp0x/rv-cast3.C: New.
* g++.dg/cpp0x/rv-cast4.C: New.
2011-12-13 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/51464

View File

@ -0,0 +1,17 @@
// PR c++/51406
// { dg-do run { target c++11 } }
extern "C" int printf(const char *,...);
extern "C" void abort();
struct A { int a; A() : a(1) {} };
struct B { int b; B() : b(2) {} };
struct X : A, B {};
int main() {
X x;
int a=static_cast<A&&>(x).a;
int b=static_cast<B&&>(x).b;
// printf ("%d %d\n", a, b);
if (a!=1 || b!=2) abort();
}

View File

@ -0,0 +1,13 @@
// PR c++/51161
// { dg-do compile { target c++11 } }
struct A{};
struct B : A{};
struct C : A{};
struct D : B, C{};
int main()
{
D d;
static_cast<A &&>(d); // { dg-error "ambiguous" }
}