typeck2.c (my_friendly_abort): Don't fatal twice in a row.
* typeck2.c (my_friendly_abort): Don't fatal twice in a row. * typeck.c (c_expand_start_case): Use build_expr_type_conversion. Simplify. Fixes Sec6/4_2/G06164.gr * parse.y (structsp): Fix cut-and-paste error. Fixes Sec6/4_2/C06166.cm * init.c (build_new): Complain about non-integral size. Fixes Sec5/3_4/E05276.C * parse.y (unary_expr): Complain about defining types in sizeof. Fixes Sec5/3_3/S05178.C * typeck.c (expr_sizeof): Complain about sizeof an overloaded fn. Fixes Sec5/3_3/S05161.C * rtti.c (build_x_typeid): Complain about typeid without including <typeinfo>. (get_typeid): Likewise. Complain about typeid of incomplete type. (get_tinfo_fn_dynamic): Likewise. (get_typeid_1): Not static anymore. * except.c (build_eh_type_type): Use get_typeid_1. Fixes Sec5/2_8/C05517.cm * rtti.c (build_dynamic_cast_1): Give errors for dynamic_cast to ambiguous or private bases. Fix warning for reference cast. Fixes Sec5/2_7/C05516.cm From-SVN: r23678
This commit is contained in:
parent
efc97ef076
commit
6a8f78d52c
9 changed files with 724 additions and 691 deletions
|
@ -1,3 +1,28 @@
|
|||
1998-11-16 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* typeck2.c (my_friendly_abort): Don't fatal twice in a row.
|
||||
|
||||
* typeck.c (c_expand_start_case): Use build_expr_type_conversion.
|
||||
Simplify.
|
||||
|
||||
* parse.y (structsp): Fix cut-and-paste error.
|
||||
|
||||
* init.c (build_new): Complain about non-integral size.
|
||||
|
||||
* parse.y (unary_expr): Complain about defining types in sizeof.
|
||||
|
||||
* typeck.c (expr_sizeof): Complain about sizeof an overloaded fn.
|
||||
|
||||
* rtti.c (build_x_typeid): Complain about typeid without
|
||||
including <typeinfo>.
|
||||
(get_typeid): Likewise. Complain about typeid of incomplete type.
|
||||
(get_tinfo_fn_dynamic): Likewise.
|
||||
(get_typeid_1): Not static anymore.
|
||||
* except.c (build_eh_type_type): Use get_typeid_1.
|
||||
|
||||
* rtti.c (build_dynamic_cast_1): Give errors for dynamic_cast to
|
||||
ambiguous or private bases. Fix warning for reference cast.
|
||||
|
||||
1998-11-16 Mark Mitchell <mark@markmitchell.com>
|
||||
|
||||
* cp-tree.h (DECL_TEMPLATE_INSTANTIATED): New macro.
|
||||
|
|
|
@ -2984,6 +2984,7 @@ extern tree build_typeid PROTO((tree));
|
|||
extern tree build_x_typeid PROTO((tree));
|
||||
extern tree get_tinfo_fn PROTO((tree));
|
||||
extern tree get_typeid PROTO((tree));
|
||||
extern tree get_typeid_1 PROTO((tree));
|
||||
extern tree build_dynamic_cast PROTO((tree, tree));
|
||||
extern void synthesize_tinfo_fn PROTO((tree));
|
||||
|
||||
|
|
|
@ -411,9 +411,7 @@ build_eh_type_type (type)
|
|||
type = TYPE_MAIN_VARIANT (type);
|
||||
|
||||
if (flag_rtti)
|
||||
{
|
||||
return build1 (ADDR_EXPR, ptr_type_node, get_typeid (type));
|
||||
}
|
||||
return build1 (ADDR_EXPR, ptr_type_node, get_typeid_1 (type));
|
||||
|
||||
typestring = build_overload_name (type, 1, 1);
|
||||
exp = combine_strings (build_string (strlen (typestring)+1, typestring));
|
||||
|
|
|
@ -1960,6 +1960,11 @@ build_new (placement, decl, init, use_global_new)
|
|||
}
|
||||
else
|
||||
{
|
||||
int flags = pedantic ? WANT_INT : (WANT_INT | WANT_ENUM);
|
||||
if (build_expr_type_conversion (flags, this_nelts, 0)
|
||||
== NULL_TREE)
|
||||
pedwarn ("size in array new must have integral type");
|
||||
|
||||
this_nelts = save_expr (cp_convert (sizetype, this_nelts));
|
||||
absdcl = TREE_OPERAND (absdcl, 0);
|
||||
if (this_nelts == integer_zero_node)
|
||||
|
|
1249
gcc/cp/parse.c
1249
gcc/cp/parse.c
File diff suppressed because it is too large
Load diff
|
@ -1096,7 +1096,8 @@ unary_expr:
|
|||
| SIZEOF unary_expr %prec UNARY
|
||||
{ $$ = expr_sizeof ($2); }
|
||||
| SIZEOF '(' type_id ')' %prec HYPERUNARY
|
||||
{ $$ = c_sizeof (groktypename ($3.t)); }
|
||||
{ $$ = c_sizeof (groktypename ($3.t));
|
||||
check_for_new_type ("sizeof", $3); }
|
||||
| ALIGNOF unary_expr %prec UNARY
|
||||
{ $$ = grok_alignof ($2); }
|
||||
| ALIGNOF '(' type_id ')' %prec HYPERUNARY
|
||||
|
@ -2092,7 +2093,7 @@ structsp:
|
|||
{ TYPE_VALUES (current_enum_type) = $4;
|
||||
$$.t = finish_enum (current_enum_type);
|
||||
$$.new_type_flag = 1;
|
||||
current_enum_type = $<ttype>4;
|
||||
current_enum_type = $<ttype>3;
|
||||
resume_momentary ((int) $<itype>1);
|
||||
check_for_missing_semicolon ($$.t); }
|
||||
| ENUM '{' '}'
|
||||
|
|
|
@ -39,7 +39,6 @@ static tree call_void_fn PROTO((char *));
|
|||
static tree build_headof_sub PROTO((tree));
|
||||
static tree build_headof PROTO((tree));
|
||||
static tree get_tinfo_var PROTO((tree));
|
||||
static tree get_typeid_1 PROTO((tree));
|
||||
static tree ifnonnull PROTO((tree, tree));
|
||||
static tree build_dynamic_cast_1 PROTO((tree, tree));
|
||||
static void expand_si_desc PROTO((tree, tree));
|
||||
|
@ -204,6 +203,12 @@ get_tinfo_fn_dynamic (exp)
|
|||
/* Peel off cv qualifiers. */
|
||||
type = TYPE_MAIN_VARIANT (type);
|
||||
|
||||
if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
|
||||
{
|
||||
cp_error ("taking typeid of incomplete type `%T'", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* If exp is a reference to polymorphic type, get the real type_info. */
|
||||
if (TYPE_VIRTUAL_P (type) && ! resolves_to_fixed_type_p (exp, 0))
|
||||
{
|
||||
|
@ -211,13 +216,7 @@ get_tinfo_fn_dynamic (exp)
|
|||
tree t;
|
||||
|
||||
if (! flag_rtti)
|
||||
{
|
||||
warning ("taking dynamic typeid of object without -frtti");
|
||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
||||
init_rtti_processing ();
|
||||
pop_obstacks ();
|
||||
flag_rtti = 1;
|
||||
}
|
||||
error ("taking dynamic typeid of object with -fno-rtti");
|
||||
|
||||
/* If we don't have rtti stuff, get to a sub-object that does. */
|
||||
if (! CLASSTYPE_VFIELDS (type))
|
||||
|
@ -256,6 +255,12 @@ build_x_typeid (exp)
|
|||
tree type = TREE_TYPE (tinfo_fn_type);
|
||||
int nonnull;
|
||||
|
||||
if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
|
||||
{
|
||||
error ("must #include <typeinfo> before using typeid");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (TYPEID_EXPR, exp);
|
||||
|
||||
|
@ -379,11 +384,13 @@ get_tinfo_fn (type)
|
|||
return d;
|
||||
}
|
||||
|
||||
static tree
|
||||
tree
|
||||
get_typeid_1 (type)
|
||||
tree type;
|
||||
{
|
||||
tree t = build_call
|
||||
tree t;
|
||||
|
||||
t = build_call
|
||||
(get_tinfo_fn (type), TREE_TYPE (tinfo_fn_type), NULL_TREE);
|
||||
return convert_from_reference (t);
|
||||
}
|
||||
|
@ -396,15 +403,15 @@ get_typeid (type)
|
|||
{
|
||||
if (type == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
|
||||
{
|
||||
error ("must #include <typeinfo> before using typeid");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (! flag_rtti)
|
||||
{
|
||||
warning ("requesting typeid of object without -frtti");
|
||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
||||
init_rtti_processing ();
|
||||
pop_obstacks ();
|
||||
flag_rtti = 1;
|
||||
}
|
||||
error ("requesting typeid with -fno-rtti");
|
||||
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (TYPEID_EXPR, type);
|
||||
|
@ -419,6 +426,12 @@ get_typeid (type)
|
|||
that is the operand of typeid are always ignored. */
|
||||
type = TYPE_MAIN_VARIANT (type);
|
||||
|
||||
if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
|
||||
{
|
||||
cp_error ("taking typeid of incomplete type `%T'", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
return get_typeid_1 (type);
|
||||
}
|
||||
|
||||
|
@ -446,6 +459,7 @@ build_dynamic_cast_1 (type, expr)
|
|||
tree exprtype = TREE_TYPE (expr);
|
||||
enum tree_code ec;
|
||||
tree dcast_fn;
|
||||
tree old_expr = expr;
|
||||
|
||||
assert (exprtype != NULL_TREE);
|
||||
ec = TREE_CODE (exprtype);
|
||||
|
@ -512,6 +526,20 @@ build_dynamic_cast_1 (type, expr)
|
|||
|
||||
distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,
|
||||
&path);
|
||||
|
||||
if (distance == -2)
|
||||
{
|
||||
cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
|
||||
TREE_TYPE (exprtype), TREE_TYPE (type));
|
||||
return error_mark_node;
|
||||
}
|
||||
if (distance == -3)
|
||||
{
|
||||
cp_error ("dynamic_cast from `%T' to private base class `%T'",
|
||||
TREE_TYPE (exprtype), TREE_TYPE (type));
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (distance >= 0)
|
||||
return build_vbase_path (PLUS_EXPR, type, expr, path, 0);
|
||||
}
|
||||
|
@ -547,11 +575,11 @@ build_dynamic_cast_1 (type, expr)
|
|||
dynamic_cast<D&>(b) (b an object) cannot succeed. */
|
||||
if (ec == REFERENCE_TYPE)
|
||||
{
|
||||
if (TREE_CODE (expr) == VAR_DECL
|
||||
&& TREE_CODE (TREE_TYPE (expr)) == RECORD_TYPE)
|
||||
if (TREE_CODE (old_expr) == VAR_DECL
|
||||
&& TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
|
||||
{
|
||||
cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
|
||||
expr, type);
|
||||
old_expr, type);
|
||||
return throw_bad_cast ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1520,15 +1520,12 @@ expr_sizeof (e)
|
|||
&& (TREE_CODE (TREE_TYPE (e)) == ARRAY_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (e)) == FUNCTION_TYPE))
|
||||
e = default_conversion (e);
|
||||
else if (TREE_CODE (e) == TREE_LIST)
|
||||
else if (is_overloaded_fn (e))
|
||||
{
|
||||
tree t = TREE_VALUE (e);
|
||||
if (t != NULL_TREE
|
||||
&& ((TREE_TYPE (t)
|
||||
&& TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
|
||||
|| is_overloaded_fn (t)))
|
||||
pedwarn ("ANSI C++ forbids taking the sizeof a function type");
|
||||
pedwarn ("ANSI C++ forbids taking the sizeof a function type");
|
||||
return size_int (1);
|
||||
}
|
||||
|
||||
return c_sizeof (TREE_TYPE (e));
|
||||
}
|
||||
|
||||
|
@ -7290,45 +7287,26 @@ tree
|
|||
c_expand_start_case (exp)
|
||||
tree exp;
|
||||
{
|
||||
tree type;
|
||||
register enum tree_code code;
|
||||
|
||||
/* Convert from references, etc. */
|
||||
exp = default_conversion (exp);
|
||||
type = TREE_TYPE (exp);
|
||||
code = TREE_CODE (type);
|
||||
|
||||
if (IS_AGGR_TYPE_CODE (code))
|
||||
exp = build_type_conversion (CONVERT_EXPR, integer_type_node, exp, 1);
|
||||
tree type, idx;
|
||||
|
||||
exp = build_expr_type_conversion (WANT_INT | WANT_ENUM, exp, 1);
|
||||
if (exp == NULL_TREE)
|
||||
{
|
||||
error ("switch quantity not an integer");
|
||||
exp = error_mark_node;
|
||||
}
|
||||
if (exp == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
exp = default_conversion (exp);
|
||||
type = TREE_TYPE (exp);
|
||||
code = TREE_CODE (type);
|
||||
|
||||
if (code != INTEGER_TYPE && code != ENUMERAL_TYPE && code != ERROR_MARK)
|
||||
{
|
||||
error ("switch quantity not an integer");
|
||||
exp = error_mark_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree idx;
|
||||
|
||||
exp = default_conversion (exp);
|
||||
type = TREE_TYPE (exp);
|
||||
idx = get_unwidened (exp, 0);
|
||||
/* We can't strip a conversion from a signed type to an unsigned,
|
||||
because if we did, int_fits_type_p would do the wrong thing
|
||||
when checking case values for being in range,
|
||||
and it's too hard to do the right thing. */
|
||||
if (TREE_UNSIGNED (TREE_TYPE (exp))
|
||||
== TREE_UNSIGNED (TREE_TYPE (idx)))
|
||||
exp = idx;
|
||||
}
|
||||
idx = get_unwidened (exp, 0);
|
||||
/* We can't strip a conversion from a signed type to an unsigned,
|
||||
because if we did, int_fits_type_p would do the wrong thing
|
||||
when checking case values for being in range,
|
||||
and it's too hard to do the right thing. */
|
||||
if (TREE_UNSIGNED (TREE_TYPE (exp)) == TREE_UNSIGNED (TREE_TYPE (idx)))
|
||||
exp = idx;
|
||||
|
||||
expand_start_case
|
||||
(1, fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp)),
|
||||
|
|
|
@ -395,7 +395,7 @@ my_friendly_abort (i)
|
|||
else
|
||||
error ("Internal compiler error %d.", i);
|
||||
|
||||
fatal ("Please submit a full bug report to `egcs-bugs@cygnus.com'.");
|
||||
error ("Please submit a full bug report to `egcs-bugs@cygnus.com'.");
|
||||
fatal ("See <URL:http://egcs.cygnus.com/faq.html#bugreport> for details.");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue