diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2013-06-14 09:22:03 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2013-06-14 09:22:03 +0000 |
commit | ffe7516f004d3ad9d5453b6c8c42ad23309ec6e0 (patch) | |
tree | 25ead3d0a0e22f49b61c9a05056f6044b7d9c21f /gcc | |
parent | 8f7fa4ba7274bf6f55737b44d58cb1d214b79f81 (diff) | |
download | gcc-ffe7516f004d3ad9d5453b6c8c42ad23309ec6e0.zip gcc-ffe7516f004d3ad9d5453b6c8c42ad23309ec6e0.tar.gz gcc-ffe7516f004d3ad9d5453b6c8c42ad23309ec6e0.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/dyncast1.C | 31 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/rtti/dyncast6.C | 59 |
5 files changed, 105 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 48a9310..d4cded5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 9010440..f309498 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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). */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a209086..119a764 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/g++.dg/cpp0x/dyncast1.C b/gcc/testsuite/g++.dg/cpp0x/dyncast1.C new file mode 100644 index 0000000..1224f36 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/dyncast1.C @@ -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"); diff --git a/gcc/testsuite/g++.dg/rtti/dyncast6.C b/gcc/testsuite/g++.dg/rtti/dyncast6.C new file mode 100644 index 0000000..a6329e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/rtti/dyncast6.C @@ -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); +} |