diff mbox

[C++] PR 29273

Message ID 4F0308B9.3040005@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Jan. 3, 2012, 1:55 p.m. UTC
Hi,

in this issue, filed by Martin Sebor and confirmed at the time by the 
EDG people (indeed ICC accepts the testcase), we reject an array as 
source v of a dynamic_cast, because we don't decay it to pointer, as we 
should when T is a pointer type, per 5, p8 in C++03 about an lvalue 
expression as operand of an operator which expects an rvalue (I get 
C++11 as not changing anything in terms of decay, modulo talking about 
glvalue, prvalue, etc).

I also tweaked a bit the code to make sure that in any case we output 
the original v in error messages.

Tested x86_64-linux.

Thanks,
Paolo.

///////////////////////
/cp
2012-02-03  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/29273
	* rtti.c (build_dynamic_cast_1): In case of T a pointer type,
	call decay_conversion on v.

/testsuite
2012-02-03  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/29273
	* g++.dg/rtti/dyncast5.C: New.

Comments

Jason Merrill Jan. 3, 2012, 2:52 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

Index: testsuite/g++.dg/rtti/dyncast5.C
===================================================================
--- testsuite/g++.dg/rtti/dyncast5.C	(revision 0)
+++ testsuite/g++.dg/rtti/dyncast5.C	(revision 0)
@@ -0,0 +1,9 @@ 
+// PR c++/29273
+
+struct A { virtual ~A () { } };
+struct B: A { } b [1];
+
+void foo ()
+{
+  dynamic_cast<B*>(b);
+}
Index: cp/rtti.c
===================================================================
--- cp/rtti.c	(revision 182832)
+++ cp/rtti.c	(working copy)
@@ -515,7 +515,7 @@  static tree
 build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
 {
   enum tree_code tc = TREE_CODE (type);
-  tree exprtype = TREE_TYPE (expr);
+  tree exprtype;
   tree dcast_fn;
   tree old_expr = expr;
   const char *errstr = NULL;
@@ -551,6 +551,9 @@  build_dynamic_cast_1 (tree type, tree expr, tsubst
 
   if (tc == POINTER_TYPE)
     {
+      expr = decay_conversion (expr);
+      exprtype = TREE_TYPE (expr);
+
       /* If T is a pointer type, v shall be an rvalue of a pointer to
 	 complete class type, and the result is an rvalue of type T.  */
 
@@ -576,7 +579,7 @@  build_dynamic_cast_1 (tree type, tree expr, tsubst
     {
       expr = mark_lvalue_use (expr);
 
-      exprtype = build_reference_type (exprtype);
+      exprtype = build_reference_type (TREE_TYPE (expr));
 
       /* 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.  */
@@ -764,7 +767,7 @@  build_dynamic_cast_1 (tree type, tree expr, tsubst
  fail:
   if (complain & tf_error)
     error ("cannot dynamic_cast %qE (of type %q#T) to type %q#T (%s)",
-           expr, exprtype, type, errstr);
+           old_expr, TREE_TYPE (old_expr), type, errstr);
   return error_mark_node;
 }