Commit 58fc93fb by Jason Merrill Committed by Jason Merrill

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
parent c990877a
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
......
......@@ -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
......
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
......
// 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();
}
// 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" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment