re PR c++/57599 (result of dynamic_cast<cv T> is just T)

/cp
2013-06-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/57599
	* rtti.c (build_dynamic_cast_1): In case of cast to an unambiguous
	accessible base simply forward to build_static_cast.

/testsuite
2013-06-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/57599
	* g++.dg/rtti/dyncast6.C: New.
	* g++.dg/cpp0x/dyncast1.C: Likewise.

From-SVN: r200088
This commit is contained in:
Paolo Carlini 2013-06-14 09:22:03 +00:00 committed by Paolo Carlini
parent 8f7fa4ba72
commit ffe7516f00
5 changed files with 105 additions and 12 deletions

View File

@ -1,3 +1,9 @@
2013-06-14 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57599
* rtti.c (build_dynamic_cast_1): In case of cast to an unambiguous
accessible base simply forward to build_static_cast.
2013-06-12 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/38958

View File

@ -622,19 +622,10 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
/* If *type is an unambiguous accessible base class of *exprtype,
convert statically. */
{
tree binfo;
binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type),
ba_check, NULL, complain);
tree binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type),
ba_check, NULL, complain);
if (binfo)
{
expr = build_base_path (PLUS_EXPR, convert_from_reference (expr),
binfo, 0, complain);
if (TYPE_PTR_P (exprtype))
expr = rvalue (expr);
return expr;
}
return build_static_cast (type, expr, complain);
}
/* Otherwise *exprtype must be a polymorphic class (have a vtbl). */

View File

@ -1,3 +1,9 @@
2013-06-14 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57599
* g++.dg/rtti/dyncast6.C: New.
* g++.dg/cpp0x/dyncast1.C: Likewise.
2013-06-14 Alan Modra <amodra@gmail.com>
PR middle-end/57134

View File

@ -0,0 +1,31 @@
// PR c++/57599
// { dg-do compile { target c++11 } }
struct A { };
struct B : public A { };
template<class, class>
struct is_same { static constexpr bool value = false; };
template<class T>
struct is_same<T, T> { static constexpr bool value = true; };
template<class T>
T val();
static_assert(is_same<decltype(dynamic_cast<A*>(val<B*>())),
A*>::value, "Ouch");
static_assert(is_same<decltype(dynamic_cast<A&>(val<B&>())),
A&>::value, "Ouch");
static_assert(is_same<decltype(dynamic_cast<const A*>(val<B*>())),
const A*>::value, "Ouch");
static_assert(is_same<decltype(dynamic_cast<const A&>(val<B&>())),
const A&>::value, "Ouch");
static_assert(is_same<decltype(dynamic_cast<volatile A*>(val<B*>())),
volatile A*>::value, "Ouch");
static_assert(is_same<decltype(dynamic_cast<volatile A&>(val<B&>())),
volatile A&>::value, "Ouch");
static_assert(is_same<decltype(dynamic_cast<const volatile A*>(val<B*>())),
const volatile A*>::value, "Ouch");
static_assert(is_same<decltype(dynamic_cast<const volatile A&>(val<B&>())),
const volatile A&>::value, "Ouch");

View File

@ -0,0 +1,59 @@
// PR c++/57599
class A { };
class B : public A { };
void p()
{
B* b;
A* a1;
a1 = dynamic_cast<A*>(b);
a1 = dynamic_cast<const A*>(b); // { dg-error "invalid" }
a1 = dynamic_cast<volatile A*>(b); // { dg-error "invalid" }
a1 = dynamic_cast<const volatile A*>(b); // { dg-error "invalid" }
const A* a2;
a2 = dynamic_cast<A*>(b);
a2 = dynamic_cast<const A*>(b);
a2 = dynamic_cast<volatile A*>(b); // { dg-error "invalid" }
a2 = dynamic_cast<const volatile A*>(b); // { dg-error "invalid" }
volatile A* a3;
a3 = dynamic_cast<A*>(b);
a3 = dynamic_cast<const A*>(b); // { dg-error "invalid" }
a3 = dynamic_cast<volatile A*>(b);
a3 = dynamic_cast<const volatile A*>(b); // { dg-error "invalid" }
const volatile A* a4;
a4 = dynamic_cast<A*>(b);
a4 = dynamic_cast<const A*>(b);
a4 = dynamic_cast<volatile A*>(b);
a4 = dynamic_cast<const volatile A*>(b);
}
void r()
{
B b;
A& a1 = dynamic_cast<A&>(b);
A& a2 = dynamic_cast<const A&>(b); // { dg-error "invalid" }
A& a3 = dynamic_cast<volatile A&>(b); // { dg-error "invalid" }
A& a4 = dynamic_cast<const volatile A&>(b); // { dg-error "invalid" }
const A& ca1 = dynamic_cast<A&>(b);
const A& ca2 = dynamic_cast<const A&>(b);
const A& ca3 = dynamic_cast<volatile A&>(b); // { dg-error "invalid" }
const A& ca4 = dynamic_cast<const volatile A&>(b); // { dg-error "invalid" }
volatile A& va1 = dynamic_cast<A&>(b);
volatile A& va2 = dynamic_cast<const A&>(b); // { dg-error "invalid" }
volatile A& va3 = dynamic_cast<volatile A&>(b);
volatile A& va4 = dynamic_cast<const volatile A&>(b);// { dg-error "invalid" }
const volatile A& cva1 = dynamic_cast<A&>(b);
const volatile A& cva2 = dynamic_cast<const A&>(b);
const volatile A& cva3 = dynamic_cast<volatile A&>(b);
const volatile A& cva4 = dynamic_cast<const volatile A&>(b);
}