re PR c++/11667 (wider-than-int enums never compare equal to 0)

PR c++/11667
	* c-common.c (shorten_compare): Take into account differences
	between C and C++ representation for enumeration types.
	* tree.h (set_min_and_max_values_for_integral_type): Declare.
	* stor-layout.c (set_min_and_max_values_for_integral_type): New
	function, broken out from ...
	(fixup_signed_type): ... here and ...
	(fixup_unsigned_type): ... here.

	PR c++/11667
	* call.c (standard_conversion): Allow all integral->enumeral
	conversions, after marking them as bad.
	* decl.c (finish_enum): Make sure that all enumerators are
	properly converted to the underlying type.
	(build_enumerator): Set DECL_CONTEXT for namespace-scope
	enumeration types.
	* pt.c (tsubst_copy): Adjust handling of CONST_DECLs accordingly.
	(tsubst_enum): Tidy.

	* Make-lang.in (typeck.o): Depend on convert.h.
	(class.o): Likewise.
	(rtti.o): Likewise.
	* call.c: Include convert.h.
	(convert_arg_to_ellipsis): Use convert_to_real.
	* class.c: Include convert.h.
	(build_base_path): Use convert_to_integer.
	* rtti.c: Include convert.h.
	(build_headof): Use convert_to_integer.
	* typeck.c: Include convert.h.
	(decay_conversion): Use convert_to_integer.
	(build_unary_op): Use build_nop.
	(get_delta_difference): Use convert_to_integer.
	(build_ptrmemfunc): Avoid unncessary conversions.

From-SVN: r69909
This commit is contained in:
Mark Mitchell 2003-07-29 01:14:24 +00:00
parent 92a6fb2cf2
commit 7b6d72fcfb
15 changed files with 253 additions and 128 deletions

View File

@ -1,3 +1,14 @@
2003-07-28 Mark Mitchell <mark@codesourcery.com>
PR c++/11667
* c-common.c (shorten_compare): Take into account differences
between C and C++ representation for enumeration types.
* tree.h (set_min_and_max_values_for_integral_type): Declare.
* stor-layout.c (set_min_and_max_values_for_integral_type): New
function, broken out from ...
(fixup_signed_type): ... here and ...
(fixup_unsigned_type): ... here.
2003-07-28 Zack Weinberg <zack@codesourcery.com>
* c-decl.c: Update commentary, adjust blank lines throughout.

View File

@ -2214,10 +2214,12 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
type = c_common_signed_or_unsigned_type (unsignedp0,
TREE_TYPE (primop0));
/* If TYPE is an enumeration, then we need to get its min/max
values from it's underlying integral type, not the enumerated
type itself. */
if (TREE_CODE (type) == ENUMERAL_TYPE)
/* In C, if TYPE is an enumeration, then we need to get its
min/max values from it's underlying integral type, not the
enumerated type itself. In C++, TYPE_MAX_VALUE and
TYPE_MIN_VALUE have already been set correctly on the
enumeration type. */
if (!c_dialect_cxx() && TREE_CODE (type) == ENUMERAL_TYPE)
type = c_common_type_for_size (TYPE_PRECISION (type), unsignedp0);
maxval = TYPE_MAX_VALUE (type);

View File

@ -1,3 +1,30 @@
2003-07-28 Mark Mitchell <mark@codesourcery.com>
PR c++/11667
* call.c (standard_conversion): Allow all integral->enumeral
conversions, after marking them as bad.
* decl.c (finish_enum): Make sure that all enumerators are
properly converted to the underlying type.
(build_enumerator): Set DECL_CONTEXT for namespace-scope
enumeration types.
* pt.c (tsubst_copy): Adjust handling of CONST_DECLs accordingly.
(tsubst_enum): Tidy.
* Make-lang.in (typeck.o): Depend on convert.h.
(class.o): Likewise.
(rtti.o): Likewise.
* call.c: Include convert.h.
(convert_arg_to_ellipsis): Use convert_to_real.
* class.c: Include convert.h.
(build_base_path): Use convert_to_integer.
* rtti.c: Include convert.h.
(build_headof): Use convert_to_integer.
* typeck.c: Include convert.h.
(decay_conversion): Use convert_to_integer.
(build_unary_op): Use build_nop.
(get_delta_difference): Use convert_to_integer.
(build_ptrmemfunc): Avoid unncessary conversions.
Mon Jul 28 23:55:10 CEST 2003 Jan Hubicka <jh@suse.cz>
* decl2.c (mark_member_pointers): Verify that member pointer points to

View File

@ -244,10 +244,10 @@ cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h $(EXPR_H
cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h output.h $(TM_P_H) \
diagnostic.h
cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
diagnostic.h
cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(TARGET_H)
diagnostic.h convert.h
cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(TARGET_H) convert.h
cp/call.o: cp/call.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(EXPR_H) \
diagnostic.h intl.h gt-cp-call.h
diagnostic.h intl.h gt-cp-call.h convert.h
cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) toplev.h $(EXPR_H)
cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
except.h
@ -258,7 +258,7 @@ cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) stack.h flags.h toplev.h $(RTL_H)
cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \
insn-config.h integrate.h tree-inline.h real.h gt-cp-tree.h $(TARGET_H)
cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(TM_H)
cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h
cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h convert.h
cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) except.h toplev.h \
cp/cfns.h $(EXPR_H) libfuncs.h tree-inline.h
cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \

View File

@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */
#include "expr.h"
#include "diagnostic.h"
#include "intl.h"
#include "convert.h"
static tree build_field_call (tree, tree, tree);
static struct z_candidate * tourney (struct z_candidate *);
@ -653,8 +654,7 @@ standard_conversion (tree to, tree from, tree expr)
conv = build_conv (STD_CONV, to, conv);
ICS_BAD_FLAG (conv) = 1;
}
else if (tcode == ENUMERAL_TYPE && fcode == INTEGER_TYPE
&& TYPE_PRECISION (to) == TYPE_PRECISION (from))
else if (tcode == ENUMERAL_TYPE && fcode == INTEGER_TYPE)
{
/* For backwards brain damage compatibility, allow interconversion of
enums and integers with a pedwarn. */
@ -4201,7 +4201,7 @@ convert_arg_to_ellipsis (tree arg)
if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
&& (TYPE_PRECISION (TREE_TYPE (arg))
< TYPE_PRECISION (double_type_node)))
arg = cp_convert (double_type_node, arg);
arg = convert_to_real (double_type_node, arg);
else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
arg = perform_integral_promotions (arg);

View File

@ -35,6 +35,7 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "lex.h"
#include "target.h"
#include "convert.h"
/* The number of nested classes being processed. If we are not in the
scope of any class, this is zero. */
@ -328,8 +329,9 @@ build_base_path (enum tree_code code,
v_offset = build_indirect_ref (v_offset, NULL);
TREE_CONSTANT (v_offset) = 1;
offset = cp_convert (ptrdiff_type_node,
size_diffop (offset, BINFO_OFFSET (v_binfo)));
offset = convert_to_integer (ptrdiff_type_node,
size_diffop (offset,
BINFO_OFFSET (v_binfo)));
if (!integer_zerop (offset))
v_offset = build (code, ptrdiff_type_node, v_offset, offset);

View File

@ -13028,7 +13028,9 @@ start_enum (tree name)
void
finish_enum (tree enumtype)
{
tree pair;
tree values;
tree decl;
tree value;
tree minnode;
tree maxnode;
tree t;
@ -13036,6 +13038,8 @@ finish_enum (tree enumtype)
int lowprec;
int highprec;
int precision;
integer_type_kind itk;
tree underlying_type;
/* We built up the VALUES in reverse order. */
TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
@ -13046,21 +13050,25 @@ finish_enum (tree enumtype)
works. */
if (processing_template_decl)
{
for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
TREE_TYPE (TREE_VALUE (pair)) = enumtype;
for (values = TYPE_VALUES (enumtype);
values;
values = TREE_CHAIN (values))
TREE_TYPE (TREE_VALUE (values)) = enumtype;
if (at_function_scope_p ())
add_stmt (build_min (TAG_DEFN, enumtype));
return;
}
/* Determine the minimum and maximum values of the enumerators. */
if (TYPE_VALUES (enumtype))
{
minnode = maxnode = NULL_TREE;
for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
for (values = TYPE_VALUES (enumtype);
values;
values = TREE_CHAIN (values))
{
tree decl = TREE_VALUE (pair);
tree value = DECL_INITIAL (decl);
decl = TREE_VALUE (values);
/* [dcl.enum]: Following the closing brace of an enum-specifier,
each enumerator has the type of its enumeration. Prior to the
@ -13068,6 +13076,8 @@ finish_enum (tree enumtype)
initializing value. */
TREE_TYPE (decl) = enumtype;
/* Update the minimum and maximum values, if appropriate. */
value = DECL_INITIAL (decl);
/* Figure out what the minimum and maximum values of the
enumerators are. */
if (!minnode)
@ -13086,13 +13096,13 @@ finish_enum (tree enumtype)
value = DECL_INITIAL (decl) = copy_node (value);
TREE_TYPE (value) = enumtype;
}
/* In addition, transform the TYPE_VALUES list to contain the
values, rather than the CONST_DECLs for them. */
TREE_VALUE (pair) = value;
}
}
else
/* [dcl.enum]
If the enumerator-list is empty, the underlying type is as if
the enumeration had a single enumerator with value 0. */
minnode = maxnode = integer_zero_node;
/* Compute the number of bits require to represent all values of the
@ -13104,35 +13114,75 @@ finish_enum (tree enumtype)
highprec = min_precision (maxnode, unsignedp);
precision = MAX (lowprec, highprec);
/* DR 377
IF no integral type can represent all the enumerator values, the
enumeration is ill-formed. */
if (precision > TYPE_PRECISION (long_long_integer_type_node))
/* Determine the underlying type of the enumeration.
[dcl.enum]
The underlying type of an enumeration is an integral type that
can represent all the enumerator values defined in the
enumeration. It is implementation-defined which integral type is
used as the underlying type for an enumeration except that the
underlying type shall not be larger than int unless the value of
an enumerator cannot fit in an int or unsigned int.
We use "int" or an "unsigned int" as the underlying type, even if
a smaller integral type would work, unless the user has
explicitly requested that we use the smallest possible type. */
for (itk = (flag_short_enums ? itk_char : itk_int);
itk != itk_none;
itk++)
{
underlying_type = integer_types[itk];
if (TYPE_PRECISION (underlying_type) >= precision
&& TREE_UNSIGNED (underlying_type) == unsignedp)
break;
}
if (itk == itk_none)
{
/* DR 377
IF no integral type can represent all the enumerator values, the
enumeration is ill-formed. */
error ("no integral type can represent all of the enumerator values "
"for `%T'", enumtype);
precision = TYPE_PRECISION (long_long_integer_type_node);
underlying_type = integer_types[itk_unsigned_long_long];
}
/* Compute the minium and maximum values for the type, the size of
the type, and so forth. */
TYPE_PRECISION (enumtype) = precision;
TYPE_SIZE (enumtype) = NULL_TREE;
if (unsignedp)
fixup_unsigned_type (enumtype);
else
fixup_signed_type (enumtype);
/* Compute the minium and maximum values for the type.
/* We use "int" or "unsigned int" as the underlying type, unless all
the values will not fit or the user has requested that we try to
use shorter types where possible. */
if (precision < TYPE_PRECISION (integer_type_node)
&& !flag_short_enums)
[dcl.enum]
For an enumeration where emin is the smallest enumerator and emax
is the largest, the values of the enumeration are the values of the
underlying type in the range bmin to bmax, where bmin and bmax are,
respectively, the smallest and largest values of the smallest bit-
field that can store emin and emax. */
TYPE_PRECISION (enumtype) = precision;
set_min_and_max_values_for_integral_type (enumtype, precision, unsignedp);
/* [dcl.enum]
The value of sizeof() applied to an enumeration type, an object
of an enumeration type, or an enumerator, is the value of sizeof()
applied to the underlying type. */
TYPE_SIZE (enumtype) = TYPE_SIZE (underlying_type);
TYPE_SIZE_UNIT (enumtype) = TYPE_SIZE_UNIT (underlying_type);
TYPE_MODE (enumtype) = TYPE_MODE (underlying_type);
TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type);
TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type);
TREE_UNSIGNED (enumtype) = TREE_UNSIGNED (underlying_type);
/* Convert each of the enumerators to the type of the underlying
type of the enumeration. */
for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
{
TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
TYPE_SIZE (enumtype) = NULL_TREE;
layout_type (enumtype);
decl = TREE_VALUE (values);
value = perform_implicit_conversion (underlying_type,
DECL_INITIAL (decl));
TREE_TYPE (value) = enumtype;
DECL_INITIAL (decl) = value;
TREE_VALUE (values) = value;
}
/* Fix up all variant types of this enum type. */
@ -13215,6 +13265,8 @@ build_enumerator (tree name, tree value, tree enumtype)
/* C++ associates enums with global, function, or class declarations. */
context = current_scope ();
if (!context)
context = current_namespace;
/* Build the actual enumeration constant. Note that the enumeration
constants have the type of their initializers until the
@ -13246,8 +13298,8 @@ build_enumerator (tree name, tree value, tree enumtype)
if (context && context == current_class_type)
/* In something like `struct S { enum E { i = 7 }; };' we put `i'
on the TYPE_FIELDS list for `S'. (That's so that you can say
things like `S::i' later.) */
on the TYPE_FIELDS list for `S'. (That's so that you can say
things like `S::i' later.) */
finish_member_declaration (decl);
else
pushdecl (decl);

View File

@ -7214,8 +7214,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (DECL_TEMPLATE_PARM_P (t))
return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
if (!DECL_CONTEXT (t))
/* This is a global enumeration constant. */
/* There is no need to substitute into namespace-scope
enumerators. */
if (DECL_NAMESPACE_SCOPE_P (t))
return t;
/* Unfortunately, we cannot just call lookup_name here.
@ -11151,18 +11152,20 @@ tsubst_enum (tree tag, tree newtag, tree args)
for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e))
{
tree value;
tree decl;
decl = TREE_VALUE (e);
/* Note that in a template enum, the TREE_VALUE is the
CONST_DECL, not the corresponding INTEGER_CST. */
value = tsubst_expr (DECL_INITIAL (TREE_VALUE (e)),
value = tsubst_expr (DECL_INITIAL (decl),
args, tf_error | tf_warning,
NULL_TREE);
/* Give this enumeration constant the correct access. */
set_current_access_from_decl (TREE_VALUE (e));
set_current_access_from_decl (decl);
/* Actually build the enumerator itself. */
build_enumerator (TREE_PURPOSE (e), value, newtag);
build_enumerator (DECL_NAME (decl), value, newtag);
}
finish_enum (newtag);

View File

@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "assert.h"
#include "toplev.h"
#include "convert.h"
/* C++ returns type information to the user in struct type_info
objects. We also use type information to implement dynamic_cast and
@ -159,8 +160,8 @@ build_headof (tree exp)
type = build_qualified_type (ptr_type_node,
cp_type_quals (TREE_TYPE (exp)));
return build (PLUS_EXPR, type, exp,
cp_convert (ptrdiff_type_node, offset));
return build (PLUS_EXPR, type, exp,
convert_to_integer (ptrdiff_type_node, offset));
}
/* Get a bad_cast node for the program to throw...

View File

@ -44,6 +44,7 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "diagnostic.h"
#include "target.h"
#include "convert.h"
static tree convert_for_assignment (tree, tree, const char *, tree, int);
static tree cp_pointer_int_sum (enum tree_code, tree, tree);
@ -1291,20 +1292,8 @@ decay_conversion (tree exp)
tree ptrtype;
if (TREE_CODE (exp) == INDIRECT_REF)
{
/* Stripping away the INDIRECT_REF is not the right
thing to do for references... */
tree inner = TREE_OPERAND (exp, 0);
if (TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE)
{
inner = build1 (CONVERT_EXPR,
build_pointer_type (TREE_TYPE
(TREE_TYPE (inner))),
inner);
TREE_CONSTANT (inner) = TREE_CONSTANT (TREE_OPERAND (inner, 0));
}
return cp_convert (build_pointer_type (TREE_TYPE (type)), inner);
}
return build_nop (build_pointer_type (TREE_TYPE (type)),
TREE_OPERAND (exp, 0));
if (TREE_CODE (exp) == COMPOUND_EXPR)
{
@ -4007,8 +3996,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
ba_check, NULL);
rval = build_base_path (PLUS_EXPR, rval, binfo, 1);
rval = build1 (NOP_EXPR, argtype, rval);
TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0));
rval = build_nop (argtype, rval);
addr = fold (build (PLUS_EXPR, argtype, rval,
cp_convert (argtype, byte_position (field))));
}
@ -5192,8 +5180,9 @@ build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
/* Get difference in deltas for different pointer to member function
types. Return integer_zero_node, if FROM cannot be converted to a
TO type. If FORCE is true, then allow reverse conversions as well.
types. Returns an integer constant of type PTRDIFF_TYPE_NODE. If
the conversion is invalid, the constant is zero. If FORCE is true,
then allow reverse conversions as well.
Note that the naming of FROM and TO is kind of backwards; the return
value is what we add to a TO in order to get a FROM. They are named
@ -5203,7 +5192,6 @@ build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
static tree
get_delta_difference (tree from, tree to, int force)
{
tree delta = integer_zero_node;
tree binfo;
tree virt_binfo;
base_kind kind;
@ -5212,7 +5200,7 @@ get_delta_difference (tree from, tree to, int force)
if (kind == bk_inaccessible || kind == bk_ambig)
{
error (" in pointer to member function conversion");
return delta;
goto error;
}
if (!binfo)
{
@ -5220,44 +5208,38 @@ get_delta_difference (tree from, tree to, int force)
{
error_not_base_type (from, to);
error (" in pointer to member conversion");
return delta;
goto error;
}
binfo = lookup_base (from, to, ba_check, &kind);
if (binfo == 0)
return delta;
if (!binfo)
goto error;
virt_binfo = binfo_from_vbase (binfo);
if (virt_binfo)
{
/* This is a reinterpret cast, we choose to do nothing. */
warning ("pointer to member cast via virtual base `%T'",
BINFO_TYPE (virt_binfo));
return delta;
goto error;
}
delta = BINFO_OFFSET (binfo);
delta = cp_convert (ptrdiff_type_node, delta);
delta = cp_build_binary_op (MINUS_EXPR,
integer_zero_node,
delta);
return delta;
return convert_to_integer (ptrdiff_type_node,
size_diffop (size_zero_node,
BINFO_OFFSET (binfo)));
}
virt_binfo = binfo_from_vbase (binfo);
if (virt_binfo)
{
/* This is a reinterpret cast, we choose to do nothing. */
if (force)
warning ("pointer to member cast via virtual base `%T'",
BINFO_TYPE (virt_binfo));
else
error ("pointer to member conversion via virtual base `%T'",
BINFO_TYPE (virt_binfo));
return delta;
}
delta = BINFO_OFFSET (binfo);
if (!virt_binfo)
return convert_to_integer (ptrdiff_type_node, BINFO_OFFSET (binfo));
return cp_convert (ptrdiff_type_node, delta);
/* This is a reinterpret cast, we choose to do nothing. */
if (force)
warning ("pointer to member cast via virtual base `%T'",
BINFO_TYPE (virt_binfo));
else
error ("pointer to member conversion via virtual base `%T'",
BINFO_TYPE (virt_binfo));
error:
return convert_to_integer(ptrdiff_type_node, integer_zero_node);
}
/* Return a constructor for the pointer-to-member-function TYPE using
@ -5355,7 +5337,7 @@ build_ptrmemfunc (tree type, tree pfn, int force)
}
/* Just adjust the DELTA field. */
delta = cp_convert (ptrdiff_type_node, delta);
my_friendly_assert (TREE_TYPE (delta) == ptrdiff_type_node, 20030727);
if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
n = cp_build_binary_op (LSHIFT_EXPR, n, integer_one_node);
delta = cp_build_binary_op (PLUS_EXPR, delta, n);

View File

@ -1957,6 +1957,58 @@ set_sizetype (tree type)
sizetype_set = 1;
}
/* TYPE is an integral type, i.e., an INTEGRAL_TYPE, ENUMERAL_TYPE,
BOOLEAN_TYPE, or CHAR_TYPE. Set TYPE_MIN_VALUE and TYPE_MAX_VALUE
for TYPE, based on the PRECISION and whether or not the TYPE
IS_UNSIGNED. PRECISION need not correspond to a width supported
natively by the hardware; for example, on a machine with 8-bit,
16-bit, and 32-bit register modes, PRECISION might be 7, 23, or
61. */
void
set_min_and_max_values_for_integral_type (tree type,
int precision,
bool is_unsigned)
{
tree min_value;
tree max_value;
if (is_unsigned)
{
min_value = build_int_2 (0, 0);
max_value
= build_int_2 (precision - HOST_BITS_PER_WIDE_INT >= 0
? -1 : ((HOST_WIDE_INT) 1 << precision) - 1,
precision - HOST_BITS_PER_WIDE_INT > 0
? ((unsigned HOST_WIDE_INT) ~0
>> (HOST_BITS_PER_WIDE_INT
- (precision - HOST_BITS_PER_WIDE_INT)))
: 0);
}
else
{
min_value
= build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
? 0 : (HOST_WIDE_INT) (-1) << (precision - 1)),
(((HOST_WIDE_INT) (-1)
<< (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
? precision - HOST_BITS_PER_WIDE_INT - 1
: 0))));
max_value
= build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
? -1 : ((HOST_WIDE_INT) 1 << (precision - 1)) - 1),
(precision - HOST_BITS_PER_WIDE_INT - 1 > 0
? (((HOST_WIDE_INT) 1
<< (precision - HOST_BITS_PER_WIDE_INT - 1))) - 1
: 0));
}
TREE_TYPE (min_value) = type;
TREE_TYPE (max_value) = type;
TYPE_MIN_VALUE (type) = min_value;
TYPE_MAX_VALUE (type) = max_value;
}
/* Set the extreme values of TYPE based on its precision in bits,
then lay it out. Used when make_signed_type won't do
because the tree code is not INTEGER_TYPE.
@ -1973,23 +2025,8 @@ fixup_signed_type (tree type)
if (precision > HOST_BITS_PER_WIDE_INT * 2)
precision = HOST_BITS_PER_WIDE_INT * 2;
TYPE_MIN_VALUE (type)
= build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
? 0 : (HOST_WIDE_INT) (-1) << (precision - 1)),
(((HOST_WIDE_INT) (-1)
<< (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
? precision - HOST_BITS_PER_WIDE_INT - 1
: 0))));
TYPE_MAX_VALUE (type)
= build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
? -1 : ((HOST_WIDE_INT) 1 << (precision - 1)) - 1),
(precision - HOST_BITS_PER_WIDE_INT - 1 > 0
? (((HOST_WIDE_INT) 1
<< (precision - HOST_BITS_PER_WIDE_INT - 1))) - 1
: 0));
TREE_TYPE (TYPE_MIN_VALUE (type)) = type;
TREE_TYPE (TYPE_MAX_VALUE (type)) = type;
set_min_and_max_values_for_integral_type (type, precision,
/*is_unsigned=*/false);
/* Lay out the type: set its alignment, size, etc. */
layout_type (type);
@ -2010,17 +2047,8 @@ fixup_unsigned_type (tree type)
if (precision > HOST_BITS_PER_WIDE_INT * 2)
precision = HOST_BITS_PER_WIDE_INT * 2;
TYPE_MIN_VALUE (type) = build_int_2 (0, 0);
TYPE_MAX_VALUE (type)
= build_int_2 (precision - HOST_BITS_PER_WIDE_INT >= 0
? -1 : ((HOST_WIDE_INT) 1 << precision) - 1,
precision - HOST_BITS_PER_WIDE_INT > 0
? ((unsigned HOST_WIDE_INT) ~0
>> (HOST_BITS_PER_WIDE_INT
- (precision - HOST_BITS_PER_WIDE_INT)))
: 0);
TREE_TYPE (TYPE_MIN_VALUE (type)) = type;
TREE_TYPE (TYPE_MAX_VALUE (type)) = type;
set_min_and_max_values_for_integral_type (type, precision,
/*is_unsigned=*/true);
/* Lay out the type: set its alignment, size, etc. */
layout_type (type);

View File

@ -1,3 +1,9 @@
2003-07-28 Alexandre Oliva <aoliva@redhat.com>
PR c++/11667
* g++.dg/init/enum2.C: New test.
* g++.dg/template/overload1.C: Add "-w" option.
2003-07-28 <hp@bitrange.com>
* gcc.dg/Wdeclaration-after-statement-1.c,

View File

@ -0,0 +1,9 @@
#include <limits.h>
enum test {
z = 0,
c = UINT_MAX + 1LL
} x = z;
int main() {
return x != z;
}

View File

@ -1,3 +1,4 @@
// { dg-options "-w" }
// PR c++/9420
// Bug: We were instantiating B<int> during overload resolution for E<0.
// This is wrong; the contents of B<int> are not relevant, since we can't

View File

@ -2909,6 +2909,7 @@ extern void output_inline_function (tree);
extern void set_decl_origin_self (tree);
/* In stor-layout.c */
extern void set_min_and_max_values_for_integral_type (tree, int, bool);
extern void fixup_signed_type (tree);
extern void internal_reference_types (void);