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:
parent
8f7fa4ba72
commit
ffe7516f00
5 changed files with 105 additions and 12 deletions
|
@ -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
|
||||
|
|
|
@ -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). */
|
||||
|
|
|
@ -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
|
||||
|
|
31
gcc/testsuite/g++.dg/cpp0x/dyncast1.C
Normal file
31
gcc/testsuite/g++.dg/cpp0x/dyncast1.C
Normal 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");
|
59
gcc/testsuite/g++.dg/rtti/dyncast6.C
Normal file
59
gcc/testsuite/g++.dg/rtti/dyncast6.C
Normal 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);
|
||||
}
|
Loading…
Add table
Reference in a new issue