This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR c++/10385: ICE on invalid dynamic_cast
- From: Volker Reichelt <reichelt at igpm dot rwth-aachen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 19 Apr 2006 11:26:56 +0200 (CEST)
- Subject: [patch] Fix PR c++/10385: ICE on invalid dynamic_cast
The C++ frontend ICEs on the following invalid testcase:
struct A
{
void foo();
};
A& bar();
void baz()
{
dynamic_cast<A&>( bar().foo );
}
The offending code is in build_dynamic_cast_1: We first call
convert_to_reference for the entity we want to cast into a different
reference and later decide whether it is possible at all to perform
the cast. This works in most cases, but utterly fails in the case above.
This is actually a regression as GCC 2.95.3 did not ICE.
The patch below fixes the ICE by just moving the call to
convert_to_reference after the sanity-tests.
For good measure I also added a gcc_assert in convert_to_reference
to check that the parameter reftype is really of REFERENCE_TYPE.
Bootstrapped and regtested on x86_64-unknown-linux-gnu.
Ok for mainline, 4.1 branch, and 4.0 branch?
Regards,
Volker
:ADDPATCH C++:
2006-04-18 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/10385
* rtti.c (build_dynamic_cast_1): Check for invalid conversions
before calling convert_to_reference.
* cvt.c (convert_to_reference): Assert that reftype is a
REFERENCE_TYPE.
===================================================================
--- gcc/gcc/cp/rtti.c 2006-04-18 15:45:03 +0200
+++ gcc/gcc/cp/rtti.c 2006-04-18 15:56:33 +0200
@@ -513,10 +513,7 @@ build_dynamic_cast_1 (tree type, tree ex
}
else
{
- /* Apply trivial conversion T -> T& for dereferenced ptrs. */
exprtype = build_reference_type (exprtype);
- expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
- LOOKUP_NORMAL, NULL_TREE);
/* T is a reference type, v shall be an lvalue of a complete class
type, and the result is an lvalue of the type referred to by T. */
@@ -532,6 +529,9 @@ build_dynamic_cast_1 (tree type, tree ex
goto fail;
}
+ /* Apply trivial conversion T -> T& for dereferenced ptrs. */
+ expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
+ LOOKUP_NORMAL, NULL_TREE);
}
/* The dynamic_cast operator shall not cast away constness. */
===================================================================
--- gcc/gcc/cp/cvt.c 2006-04-18 15:53:53 +0200
+++ gcc/gcc/cp/cvt.c 2006-04-18 15:54:03 +0200
@@ -460,6 +460,7 @@ convert_to_reference (tree reftype, tree
intype = TREE_TYPE (expr);
gcc_assert (TREE_CODE (intype) != REFERENCE_TYPE);
+ gcc_assert (TREE_CODE (reftype) == REFERENCE_TYPE);
intype = TYPE_MAIN_VARIANT (intype);
===================================================================
2006-04-18 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/10385
* g++.dg/conversion/dynamic1.C: New test.
===================================================================
--- gcc/gcc/testsuite/g++.dg/conversion/dynamic1.C 2003-09-23 19:59:22 +0200
+++ gcc/gcc/testsuite/g++.dg/conversion/dynamic1.C 2006-04-18 16:34:51 +0200
@@ -0,0 +1,15 @@
+// PR c++/10385
+// Origin: <douglas@coc.ufrj.br>
+// { dg-do compile }
+
+struct A
+{
+ void foo();
+};
+
+A& bar();
+
+void baz()
+{
+ dynamic_cast<A&>( bar().foo ); // { dg-error "cannot dynamic_cast" }
+}
===================================================================