This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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" }
+}
===================================================================



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]