re PR c++/17642 (internal compiler error: in invert_truthvalue, at fold-const.c:2997)

PR c++/17642
	* stor-layout.c (layout_decl): Use fold_convert, not convert.
	(bit_from_pos): Likewise.
	(byte_from_pos): Likewise.
	(pos_from_bit): Likewise.
	(normalize_offset): Likewise.
	(place_field): Likewise.
	(finalize_type_size): Likewise.
	(layout_type): Likewise.
	* tree.c (build_index_type): Likewise.

	PR c++/17642
	* cp-tree.h (fold_if_not_in_template): New function.
	* call.c (build_conditional_expr): Use fold_if_not_in_template.
	(build_cxx_call): Likewise.
	* cvt.c (convert_to_complex): Likewise.
	(ocp_convert): Likewise.
	(convert): Likewise.
	(convert_force): Likewise.
	* decl.c (compute_array_index_type): Clear
	processing_template_decl while folding array bounds.
	* pt.c (convert_nontype_argument): Clear
	processing_template_decl while processing non-type argument
	initialization.
	* tree.c (fold_if_not_in_template): New function.
	* typeck.c (build_class_member_access_expr): Use
	fold_if_not_in_template.
	(build_array_ref): Likewise.
	(build_binary_op): Likewise.  Do not try to optimize computations
	when processing templates.
	(cp_pointer_int_sum): Use fold_if_not_in_template.
	(pointer_diff): Likewise.
	(build_unary_op): Likewise.
	(build_reinterpret_cast): Likewise.
	(get_delta_difference): Likewise.
	(expand_ptrmemfunc_cst): Likewise.
	(dubious_conversion_warnings): Likewise.

	* g++.dg/template/crash23.C: New test.

From-SVN: r88217
This commit is contained in:
Mark Mitchell 2004-09-28 02:56:11 +00:00 committed by Mark Mitchell
parent 081077002d
commit 455f19cb1c
13 changed files with 205 additions and 90 deletions

View File

@ -1,3 +1,16 @@
2004-09-27 Mark Mitchell <mark@codesourcery.com>
PR c++/17642
* stor-layout.c (layout_decl): Use fold_convert, not convert.
(bit_from_pos): Likewise.
(byte_from_pos): Likewise.
(pos_from_bit): Likewise.
(normalize_offset): Likewise.
(place_field): Likewise.
(finalize_type_size): Likewise.
(layout_type): Likewise.
* tree.c (build_index_type): Likewise.
2004-09-27 Devang Patel <dpatel@apple.com>
* expr.c (expand_expr_real_1): Handle VEC_COND_EXPR.

View File

@ -1,3 +1,32 @@
2004-09-27 Mark Mitchell <mark@codesourcery.com>
PR c++/17642
* cp-tree.h (fold_if_not_in_template): New function.
* call.c (build_conditional_expr): Use fold_if_not_in_template.
(build_cxx_call): Likewise.
* cvt.c (convert_to_complex): Likewise.
(ocp_convert): Likewise.
(convert): Likewise.
(convert_force): Likewise.
* decl.c (compute_array_index_type): Clear
processing_template_decl while folding array bounds.
* pt.c (convert_nontype_argument): Clear
processing_template_decl while processing non-type argument
initialization.
* tree.c (fold_if_not_in_template): New function.
* typeck.c (build_class_member_access_expr): Use
fold_if_not_in_template.
(build_array_ref): Likewise.
(build_binary_op): Likewise. Do not try to optimize computations
when processing templates.
(cp_pointer_int_sum): Use fold_if_not_in_template.
(pointer_diff): Likewise.
(build_unary_op): Likewise.
(build_reinterpret_cast): Likewise.
(get_delta_difference): Likewise.
(expand_ptrmemfunc_cst): Likewise.
(dubious_conversion_warnings): Likewise.
2004-09-27 Matt Austern <austern@apple.com>
* cp/parser.c (struct cp_token): new one-bit field , implicit_extern_c

View File

@ -3442,7 +3442,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
}
valid_operands:
result = fold (build3 (COND_EXPR, result_type, arg1, arg2, arg3));
result = fold_if_not_in_template (build3 (COND_EXPR, result_type, arg1,
arg2, arg3));
/* We can't use result_type below, as fold might have returned a
throw_expr. */
@ -4869,7 +4870,7 @@ build_cxx_call (tree fn, tree args)
/* Some built-in function calls will be evaluated at compile-time in
fold (). */
fn = fold (fn);
fn = fold_if_not_in_template (fn);
if (VOID_TYPE_P (TREE_TYPE (fn)))
return fn;

View File

@ -4207,6 +4207,7 @@ extern tree cp_add_pending_fn_decls (void*,tree);
extern int cp_is_overload_p (tree);
extern int cp_auto_var_in_fn_p (tree,tree);
extern void cp_update_decl_after_saving (tree, void *);
extern tree fold_if_not_in_template (tree);
/* in typeck.c */
extern int string_conv_p (tree, tree, int);

View File

@ -643,7 +643,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
/* For complex data types, we need to perform componentwise
conversion. */
else if (TREE_CODE (type) == COMPLEX_TYPE)
return fold (convert_to_complex (type, e));
return fold_if_not_in_template (convert_to_complex (type, e));
else if (TREE_CODE (e) == TARGET_EXPR)
{
/* Don't build a NOP_EXPR of class type. Instead, change the
@ -659,7 +659,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
/* We shouldn't be treating objects of ADDRESSABLE type as
rvalues. */
gcc_assert (!TREE_ADDRESSABLE (type));
return fold (build1 (NOP_EXPR, type, e));
return fold_if_not_in_template (build_nop (type, e));
}
}
@ -696,10 +696,10 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
if (code == BOOLEAN_TYPE)
return cp_truthvalue_conversion (e);
return fold (convert_to_integer (type, e));
return fold_if_not_in_template (convert_to_integer (type, e));
}
if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type))
return fold (cp_convert_to_pointer (type, e, false));
return fold_if_not_in_template (cp_convert_to_pointer (type, e, false));
if (code == VECTOR_TYPE)
{
tree in_vtype = TREE_TYPE (e);
@ -713,7 +713,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
error ("`%#T' used where a `%T' was expected", in_vtype, type);
return error_mark_node;
}
return fold (convert_to_vector (type, e));
return fold_if_not_in_template (convert_to_vector (type, e));
}
if (code == REAL_TYPE || code == COMPLEX_TYPE)
{
@ -729,9 +729,9 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
TREE_TYPE (e));
}
if (code == REAL_TYPE)
return fold (convert_to_real (type, e));
return fold_if_not_in_template (convert_to_real (type, e));
else if (code == COMPLEX_TYPE)
return fold (convert_to_complex (type, e));
return fold_if_not_in_template (convert_to_complex (type, e));
}
/* New C++ semantics: since assignment is now based on
@ -945,7 +945,7 @@ convert (tree type, tree expr)
if (POINTER_TYPE_P (type) && POINTER_TYPE_P (intype))
{
expr = decl_constant_value (expr);
return fold (build1 (NOP_EXPR, type, expr));
return fold_if_not_in_template (build_nop (type, expr));
}
return ocp_convert (type, expr, CONV_OLD_CONVERT,
@ -963,13 +963,14 @@ convert_force (tree type, tree expr, int convtype)
enum tree_code code = TREE_CODE (type);
if (code == REFERENCE_TYPE)
return fold (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN,
NULL_TREE));
return (fold_if_not_in_template
(convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN,
NULL_TREE)));
else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
e = convert_from_reference (e);
if (code == POINTER_TYPE)
return fold (convert_to_pointer_force (type, e));
return fold_if_not_in_template (convert_to_pointer_force (type, e));
/* From typeck.c convert_for_assignment */
if (((TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE && TREE_CODE (e) == ADDR_EXPR

View File

@ -6196,12 +6196,20 @@ compute_array_index_type (tree name, tree size)
itype = build_min (MINUS_EXPR, sizetype, size, integer_one_node);
else
{
HOST_WIDE_INT saved_processing_template_decl;
/* Compute the index of the largest element in the array. It is
one less than the number of elements in the array. */
itype
= fold (cp_build_binary_op (MINUS_EXPR,
cp_convert (ssizetype, size),
cp_convert (ssizetype, integer_one_node)));
one less than the number of elements in the array. We save
and restore PROCESSING_TEMPLATE_DECL so that computations in
cp_build_binary_op will be appropriately folded. */
saved_processing_template_decl = processing_template_decl;
processing_template_decl = 0;
itype = cp_build_binary_op (MINUS_EXPR,
cp_convert (ssizetype, size),
cp_convert (ssizetype, integer_one_node));
itype = fold (itype);
processing_template_decl = saved_processing_template_decl;
if (!TREE_CONSTANT (itype))
/* A variable sized array. */
itype = variable_size (itype);

View File

@ -3381,6 +3381,8 @@ convert_nontype_argument (tree type, tree expr)
switch (TREE_CODE (type))
{
HOST_WIDE_INT saved_processing_template_decl;
case INTEGER_TYPE:
case BOOLEAN_TYPE:
case ENUMERAL_TYPE:
@ -3398,8 +3400,12 @@ convert_nontype_argument (tree type, tree expr)
return error_mark_node;
/* It's safe to call digest_init in this case; we know we're
just converting one integral constant expression to another. */
just converting one integral constant expression to another.
*/
saved_processing_template_decl = processing_template_decl;
processing_template_decl = 0;
expr = digest_init (type, expr, (tree*) 0);
processing_template_decl = saved_processing_template_decl;
if (TREE_CODE (expr) != INTEGER_CST)
/* Curiously, some TREE_CONSTANT integral expressions do not

View File

@ -2331,6 +2331,19 @@ stabilize_init (tree init, tree *initp)
return true;
}
/* Like "fold", but should be used whenever we might be processing the
body of a template. */
tree
fold_if_not_in_template (tree expr)
{
/* In the body of a template, there is never any need to call
"fold". We will call fold later when actually instantiating the
template. Integral constant expressions in templates will be
evaluted via fold_non_dependent_expr, as necessary. */
return (processing_template_decl ? expr : fold (expr));
}
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
/* Complain that some language-specific thing hanging off a tree

View File

@ -1768,8 +1768,9 @@ build_class_member_access_expr (tree object, tree member,
member_type = cp_build_qualified_type (member_type, type_quals);
}
result = fold (build3 (COMPONENT_REF, member_type, object, member,
NULL_TREE));
result = build3 (COMPONENT_REF, member_type, object, member,
NULL_TREE);
result = fold_if_not_in_template (result);
/* Mark the expression const or volatile, as appropriate. Even
though we've dealt with the type above, we still have to mark the
@ -2272,7 +2273,7 @@ build_array_ref (tree array, tree idx)
|= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
TREE_THIS_VOLATILE (rval)
|= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
return require_complete_type (fold (rval));
return require_complete_type (fold_if_not_in_template (rval));
}
{
@ -2762,6 +2763,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
convert it to this type. */
tree final_type = 0;
tree result;
/* Nonzero if this is an operation like MIN or MAX which can
safely be computed in short if both args are promoted shorts.
Also implies COMMON.
@ -2782,6 +2785,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
/* Nonzero means set RESULT_TYPE to the common type of the args. */
int common = 0;
/* True if both operands have arithmetic type. */
bool arithmetic_types_p;
/* Apply default conversions. */
op0 = orig_op0;
op1 = orig_op1;
@ -3169,15 +3175,32 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
break;
}
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
&&
(code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
arithmetic_types_p =
((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == COMPLEX_TYPE));
/* Determine the RESULT_TYPE, if it is not already known. */
if (!result_type
&& arithmetic_types_p
&& (shorten || common || short_compare))
result_type = common_type (type0, type1);
if (!result_type)
{
error ("invalid operands of types `%T' and `%T' to binary `%O'",
TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
return error_mark_node;
}
/* If we're in a template, the only thing we need to know is the
RESULT_TYPE. */
if (processing_template_decl)
return build2 (resultcode, result_type, op0, op1);
if (arithmetic_types_p)
{
int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
if (shorten || common || short_compare)
result_type = common_type (type0, type1);
/* For certain operations (which identify themselves by shorten != 0)
if both args were extended from the same smaller type,
do the arithmetic in that type and then extend.
@ -3419,19 +3442,11 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
}
}
/* At this point, RESULT_TYPE must be nonzero to avoid an error message.
If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
/* If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
Then the expression will be built.
It will be given type FINAL_TYPE if that is nonzero;
otherwise, it will be given type RESULT_TYPE. */
if (!result_type)
{
error ("invalid operands of types `%T' and `%T' to binary `%O'",
TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
return error_mark_node;
}
/* Issue warnings about peculiar, but valid, uses of NULL. */
if (/* It's reasonable to use pointer values as operands of &&
and ||, so NULL is no exception. */
@ -3465,12 +3480,11 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
if (build_type == NULL_TREE)
build_type = result_type;
{
tree result = fold (build2 (resultcode, build_type, op0, op1));
if (final_type != 0)
result = cp_convert (final_type, result);
return result;
}
result = build2 (resultcode, build_type, op0, op1);
result = fold_if_not_in_template (result);
if (final_type != 0)
result = cp_convert (final_type, result);
return result;
}
/* Return a tree for the sum or difference (RESULTCODE says which)
@ -3488,7 +3502,8 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
pointer_int_sum() anyway. */
complete_type (TREE_TYPE (res_type));
return pointer_int_sum (resultcode, ptrop, fold (intop));
return pointer_int_sum (resultcode, ptrop,
fold_if_not_in_template (intop));
}
/* Return a tree for the difference of pointers OP0 and OP1.
@ -3532,7 +3547,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype)
/* Do the division. */
result = build2 (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1));
return fold (result);
return fold_if_not_in_template (result);
}
/* Construct and perhaps optimize a tree representation
@ -3782,7 +3797,10 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
if (TREE_CODE (arg) == COMPLEX_CST)
return TREE_REALPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
{
arg = build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
return fold_if_not_in_template (arg);
}
else
return arg;
@ -3790,7 +3808,10 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
if (TREE_CODE (arg) == COMPLEX_CST)
return TREE_IMAGPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
{
arg = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
return fold_if_not_in_template (arg);
}
else
return cp_convert (TREE_TYPE (arg), integer_zero_node);
@ -4133,7 +4154,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
{
if (argtype == 0)
argtype = TREE_TYPE (arg);
return fold (build1 (code, argtype, arg));
return fold_if_not_in_template (build1 (code, argtype, arg));
}
error ("%s", errstring);
@ -4721,21 +4742,21 @@ build_reinterpret_cast (tree type, tree expr)
|| (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
{
expr = decl_constant_value (expr);
return fold (build1 (NOP_EXPR, type, expr));
return fold_if_not_in_template (build_nop (type, expr));
}
else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
|| (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
{
check_for_casting_away_constness (intype, type, "reinterpret_cast");
expr = decl_constant_value (expr);
return fold (build1 (NOP_EXPR, type, expr));
return fold_if_not_in_template (build_nop (type, expr));
}
else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
|| (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
{
pedwarn ("ISO C++ forbids casting between pointer-to-function and pointer-to-object");
expr = decl_constant_value (expr);
return fold (build1 (NOP_EXPR, type, expr));
return fold_if_not_in_template (build_nop (type, expr));
}
else
{
@ -5382,7 +5403,8 @@ get_delta_difference (tree from, tree to, int force)
}
}
return fold (convert_to_integer (ptrdiff_type_node, result));
return fold_if_not_in_template (convert_to_integer (ptrdiff_type_node,
result));
}
/* Return a constructor for the pointer-to-member-function TYPE using
@ -5540,36 +5562,41 @@ expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn)
fn; the call will do the opposite adjustment. */
tree orig_class = DECL_CONTEXT (fn);
tree binfo = binfo_or_else (orig_class, fn_class);
*delta = fold (build2 (PLUS_EXPR, TREE_TYPE (*delta),
*delta, BINFO_OFFSET (binfo)));
*delta = build2 (PLUS_EXPR, TREE_TYPE (*delta),
*delta, BINFO_OFFSET (binfo));
*delta = fold_if_not_in_template (*delta);
/* We set PFN to the vtable offset at which the function can be
found, plus one (unless ptrmemfunc_vbit_in_delta, in which
case delta is shifted left, and then incremented). */
*pfn = DECL_VINDEX (fn);
*pfn = fold (build2 (MULT_EXPR, integer_type_node, *pfn,
TYPE_SIZE_UNIT (vtable_entry_type)));
*pfn = build2 (MULT_EXPR, integer_type_node, *pfn,
TYPE_SIZE_UNIT (vtable_entry_type));
*pfn = fold_if_not_in_template (*pfn);
switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
{
case ptrmemfunc_vbit_in_pfn:
*pfn = fold (build2 (PLUS_EXPR, integer_type_node, *pfn,
integer_one_node));
*pfn = build2 (PLUS_EXPR, integer_type_node, *pfn,
integer_one_node);
*pfn = fold_if_not_in_template (*pfn);
break;
case ptrmemfunc_vbit_in_delta:
*delta = fold (build2 (LSHIFT_EXPR, TREE_TYPE (*delta),
*delta, integer_one_node));
*delta = fold (build2 (PLUS_EXPR, TREE_TYPE (*delta),
*delta, integer_one_node));
*delta = build2 (LSHIFT_EXPR, TREE_TYPE (*delta),
*delta, integer_one_node);
*delta = fold_if_not_in_template (*delta);
*delta = build2 (PLUS_EXPR, TREE_TYPE (*delta),
*delta, integer_one_node);
*delta = fold_if_not_in_template (*delta);
break;
default:
gcc_unreachable ();
}
*pfn = fold (build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type),
*pfn));
*pfn = build_nop (TYPE_PTRMEMFUNC_FN_TYPE (type), *pfn);
*pfn = fold_if_not_in_template (*pfn);
}
}
@ -5639,7 +5666,7 @@ dubious_conversion_warnings (tree type, tree expr,
overflow_warning (expr);
if (TREE_CONSTANT (expr))
expr = fold (expr);
expr = fold_if_not_in_template (expr);
}
return expr;
}

View File

@ -330,8 +330,8 @@ layout_decl (tree decl, unsigned int known_align)
}
else if (DECL_SIZE_UNIT (decl) == 0)
DECL_SIZE_UNIT (decl)
= convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
bitsize_unit_node));
= fold_convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
bitsize_unit_node));
if (code != FIELD_DECL)
/* For non-fields, update the alignment from the type. */
@ -540,7 +540,8 @@ tree
bit_from_pos (tree offset, tree bitpos)
{
return size_binop (PLUS_EXPR, bitpos,
size_binop (MULT_EXPR, convert (bitsizetype, offset),
size_binop (MULT_EXPR,
fold_convert (bitsizetype, offset),
bitsize_unit_node));
}
@ -548,9 +549,9 @@ tree
byte_from_pos (tree offset, tree bitpos)
{
return size_binop (PLUS_EXPR, offset,
convert (sizetype,
size_binop (TRUNC_DIV_EXPR, bitpos,
bitsize_unit_node)));
fold_convert (sizetype,
size_binop (TRUNC_DIV_EXPR, bitpos,
bitsize_unit_node)));
}
void
@ -558,9 +559,9 @@ pos_from_bit (tree *poffset, tree *pbitpos, unsigned int off_align,
tree pos)
{
*poffset = size_binop (MULT_EXPR,
convert (sizetype,
size_binop (FLOOR_DIV_EXPR, pos,
bitsize_int (off_align))),
fold_convert (sizetype,
size_binop (FLOOR_DIV_EXPR, pos,
bitsize_int (off_align))),
size_int (off_align / BITS_PER_UNIT));
*pbitpos = size_binop (FLOOR_MOD_EXPR, pos, bitsize_int (off_align));
}
@ -580,7 +581,8 @@ normalize_offset (tree *poffset, tree *pbitpos, unsigned int off_align)
*poffset
= size_binop (PLUS_EXPR, *poffset,
size_binop (MULT_EXPR, convert (sizetype, extra_aligns),
size_binop (MULT_EXPR,
fold_convert (sizetype, extra_aligns),
size_int (off_align / BITS_PER_UNIT)));
*pbitpos
@ -869,9 +871,9 @@ place_field (record_layout_info rli, tree field)
/* First adjust OFFSET by the partial bits, then align. */
rli->offset
= size_binop (PLUS_EXPR, rli->offset,
convert (sizetype,
size_binop (CEIL_DIV_EXPR, rli->bitpos,
bitsize_unit_node)));
fold_convert (sizetype,
size_binop (CEIL_DIV_EXPR, rli->bitpos,
bitsize_unit_node)));
rli->bitpos = bitsize_zero_node;
rli->offset = round_up (rli->offset, desired_align / BITS_PER_UNIT);
@ -1147,9 +1149,9 @@ place_field (record_layout_info rli, tree field)
{
rli->offset
= size_binop (PLUS_EXPR, rli->offset,
convert (sizetype,
size_binop (CEIL_DIV_EXPR, rli->bitpos,
bitsize_unit_node)));
fold_convert (sizetype,
size_binop (CEIL_DIV_EXPR, rli->bitpos,
bitsize_unit_node)));
rli->offset
= size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field));
rli->bitpos = bitsize_zero_node;
@ -1353,9 +1355,9 @@ finalize_type_size (tree type)
result will fit in sizetype. We will get more efficient code using
sizetype, so we force a conversion. */
TYPE_SIZE_UNIT (type)
= convert (sizetype,
size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (type),
bitsize_unit_node));
= fold_convert (sizetype,
size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (type),
bitsize_unit_node));
if (TYPE_SIZE (type) != 0)
{
@ -1638,10 +1640,10 @@ layout_type (tree type)
/* The initial subtraction should happen in the original type so
that (possible) negative values are handled appropriately. */
length = size_binop (PLUS_EXPR, size_one_node,
convert (sizetype,
fold (build2 (MINUS_EXPR,
TREE_TYPE (lb),
ub, lb))));
fold_convert (sizetype,
fold (build2 (MINUS_EXPR,
TREE_TYPE (lb),
ub, lb))));
/* Special handling for arrays of bits (for Chill). */
element_size = TYPE_SIZE (element);
@ -1670,7 +1672,8 @@ layout_type (tree type)
length = size_binop (MAX_EXPR, length, size_zero_node);
TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
convert (bitsizetype, length));
fold_convert (bitsizetype,
length));
/* If we know the size of the element, calculate the total
size directly, rather than do some division thing below.

View File

@ -8,6 +8,10 @@
PR fortran/16938
* gfortran.dg/pr16938.f90: New test.
2004-09-27 Mark Mitchell <mark@codesourcery.com>
* g++.dg/template/crash23.C: New test.
2004-09-27 Mark Mitchell <mark@codesourcery.com>
PR c++/17585

View File

@ -0,0 +1,9 @@
// PR c++/17642
template<int dim>
int f(const int* const lsh, const int* const bbox, const int* const nghostzones, int d)
{
for (int d=0; d<dim; ++d)
lsh[d] - (bbox[2*d+1] ? 0 : nghostzones[d]);
}

View File

@ -4218,7 +4218,7 @@ build_index_type (tree maxval)
TREE_TYPE (itype) = sizetype;
TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
TYPE_MIN_VALUE (itype) = size_zero_node;
TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);
TYPE_MAX_VALUE (itype) = fold_convert (sizetype, maxval);
TYPE_MODE (itype) = TYPE_MODE (sizetype);
TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (sizetype);