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:
parent
081077002d
commit
455f19cb1c
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
23
gcc/cp/cvt.c
23
gcc/cp/cvt.c
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
119
gcc/cp/typeck.c
119
gcc/cp/typeck.c
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
9
gcc/testsuite/g++.dg/template/crash23.C
Normal file
9
gcc/testsuite/g++.dg/template/crash23.C
Normal 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]);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user