This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
patch to improve error messages for dynamic_cast
- To: gcc-patches at gcc dot gnu dot org
- Subject: patch to improve error messages for dynamic_cast
- From: Steven Grady <grady at digitaldeck dot com>
- Date: Tue, 7 Mar 2000 19:47:54 -0800 (PST)
This patch is in response to the following exchange of messages:
>> According to the code (cp/rtti.c: build_dynamic_cast_1), almost all
>> errors result in
>> the same message:
>> cannot dynamic_cast `%E' (of type `%#T') to type `%#T
>
>> This message is not particularly explanatory. In particular, it took
>> me a couple of hours to figure out that a dynamic cast was failing
>> because the type of the expr being cast did not have a vtbl. (I
>> figured out the problem only by looking at the above gcc source
>> code.)
>
>Thanks for your bug report; I fail to see the bug, though. It is not
>the compiler's job to teach the user C++.
>
>Of course, if you can suggest specific patches to improve the quality
>of the g++ diagnostics, they would be much appreciated. Please send
>them to gcc-patches@gcc.gnu.org.
>
>Regards,
>Martin
>
Since I don't understand the internals of gcc, some of the messages
could no doubt be more helpful.
Steven
*** cp/rtti.c.old Tue Apr 27 02:41:31 1999
--- cp/rtti.c Tue Mar 7 15:16:22 2000
***************
*** 476,481 ****
--- 476,482 ----
enum tree_code ec;
tree dcast_fn;
tree old_expr = expr;
+ char* errstr = NULL;
if (TREE_CODE (expr) == OFFSET_REF)
expr = resolve_offset_ref (expr);
***************
*** 493,518 ****
exprtype = TREE_TYPE (expr);
ec = TREE_CODE (exprtype);
}
! if (ec != POINTER_TYPE)
goto fail;
! if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
goto fail;
! if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
goto fail;
if (!at_least_as_qualified_p (TREE_TYPE (type),
! TREE_TYPE (exprtype)))
goto fail;
if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
break;
/* else fall through */
case REFERENCE_TYPE:
! if (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE)
goto fail;
! if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
goto fail;
break;
/* else fall through */
default:
goto fail;
}
--- 494,532 ----
exprtype = TREE_TYPE (expr);
ec = TREE_CODE (exprtype);
}
! if (ec != POINTER_TYPE) {
! errstr = "type is pointer, expr is non-pointer";
goto fail;
! }
! if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE) {
! errstr = "type is pointer, expr is not record";
goto fail;
! }
! if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE) {
! errstr = "type is pointer, expr has null tree";
goto fail;
+ }
if (!at_least_as_qualified_p (TREE_TYPE (type),
! TREE_TYPE (exprtype))) {
! errstr = "type is pointer, but not as qualified as exprtype";
goto fail;
+ }
if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
break;
/* else fall through */
case REFERENCE_TYPE:
! if (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE) {
! errstr = "type is reference, expr is not record";
goto fail;
! }
! if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE) {
! errstr = "type is reference, expr has null tree";
goto fail;
+ }
break;
/* else fall through */
default:
+ errstr = "type is neither pointer nor reference";
goto fail;
}
***************
*** 527,541 ****
if (tc == REFERENCE_TYPE)
{
! if (ec != REFERENCE_TYPE)
goto fail;
! if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)
goto fail;
! if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
goto fail;
if (!at_least_as_qualified_p (TREE_TYPE (type),
! TREE_TYPE (exprtype)))
goto fail;
}
/* If *type is an unambiguous accessible base class of *exprtype,
--- 541,563 ----
if (tc == REFERENCE_TYPE)
{
! if (ec != REFERENCE_TYPE) {
! errstr = "type is reference, expr is not reference";
goto fail;
! }
! if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE) {
! errstr = "type is reference, expr is not record";
goto fail;
! }
! if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE) {
! errstr = "type is reference, expr has null tree";
goto fail;
+ }
if (!at_least_as_qualified_p (TREE_TYPE (type),
! TREE_TYPE (exprtype))) {
! errstr = "type is reference, but not as qualified as exprtype";
goto fail;
+ }
}
/* If *type is an unambiguous accessible base class of *exprtype,
***************
*** 691,701 ****
result = cp_convert (type, result);
return ifnonnull (expr, result);
}
}
fail:
! cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
! expr, exprtype, type);
return error_mark_node;
}
--- 713,725 ----
result = cp_convert (type, result);
return ifnonnull (expr, result);
}
+ } else {
+ errstr = "expr is not polymorphic type";
}
fail:
! cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T' (%s)",
! expr, exprtype, type, errstr);
return error_mark_node;
}