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:
Jason Merrill 1998-11-16 20:45:16 +00:00 committed by Jason Merrill
parent efc97ef076
commit 6a8f78d52c
9 changed files with 724 additions and 691 deletions

View file

@ -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.

View file

@ -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));

View file

@ -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));

View file

@ -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)

File diff suppressed because it is too large Load diff

View file

@ -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 '{' '}'

View file

@ -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 ();
}
}

View file

@ -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)),

View file

@ -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.");
}