mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
92a6fb2cf2
commit
7b6d72fcfb
|
|
@ -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>
|
2003-07-28 Zack Weinberg <zack@codesourcery.com>
|
||||||
|
|
||||||
* c-decl.c: Update commentary, adjust blank lines throughout.
|
* c-decl.c: Update commentary, adjust blank lines throughout.
|
||||||
|
|
|
||||||
|
|
@ -2214,10 +2214,12 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
|
||||||
type = c_common_signed_or_unsigned_type (unsignedp0,
|
type = c_common_signed_or_unsigned_type (unsignedp0,
|
||||||
TREE_TYPE (primop0));
|
TREE_TYPE (primop0));
|
||||||
|
|
||||||
/* If TYPE is an enumeration, then we need to get its min/max
|
/* In C, if TYPE is an enumeration, then we need to get its
|
||||||
values from it's underlying integral type, not the enumerated
|
min/max values from it's underlying integral type, not the
|
||||||
type itself. */
|
enumerated type itself. In C++, TYPE_MAX_VALUE and
|
||||||
if (TREE_CODE (type) == ENUMERAL_TYPE)
|
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);
|
type = c_common_type_for_size (TYPE_PRECISION (type), unsignedp0);
|
||||||
|
|
||||||
maxval = TYPE_MAX_VALUE (type);
|
maxval = TYPE_MAX_VALUE (type);
|
||||||
|
|
|
||||||
|
|
@ -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>
|
Mon Jul 28 23:55:10 CEST 2003 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
* decl2.c (mark_member_pointers): Verify that member pointer points to
|
* decl2.c (mark_member_pointers): Verify that member pointer points to
|
||||||
|
|
|
||||||
|
|
@ -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) \
|
cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h output.h $(TM_P_H) \
|
||||||
diagnostic.h
|
diagnostic.h
|
||||||
cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
|
cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
|
||||||
diagnostic.h
|
diagnostic.h convert.h
|
||||||
cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(TARGET_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) \
|
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/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 \
|
cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
|
||||||
except.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) \
|
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)
|
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/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/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/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 \
|
cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "diagnostic.h"
|
#include "diagnostic.h"
|
||||||
#include "intl.h"
|
#include "intl.h"
|
||||||
|
#include "convert.h"
|
||||||
|
|
||||||
static tree build_field_call (tree, tree, tree);
|
static tree build_field_call (tree, tree, tree);
|
||||||
static struct z_candidate * tourney (struct z_candidate *);
|
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);
|
conv = build_conv (STD_CONV, to, conv);
|
||||||
ICS_BAD_FLAG (conv) = 1;
|
ICS_BAD_FLAG (conv) = 1;
|
||||||
}
|
}
|
||||||
else if (tcode == ENUMERAL_TYPE && fcode == INTEGER_TYPE
|
else if (tcode == ENUMERAL_TYPE && fcode == INTEGER_TYPE)
|
||||||
&& TYPE_PRECISION (to) == TYPE_PRECISION (from))
|
|
||||||
{
|
{
|
||||||
/* For backwards brain damage compatibility, allow interconversion of
|
/* For backwards brain damage compatibility, allow interconversion of
|
||||||
enums and integers with a pedwarn. */
|
enums and integers with a pedwarn. */
|
||||||
|
|
@ -4201,7 +4201,7 @@ convert_arg_to_ellipsis (tree arg)
|
||||||
if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
|
if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
|
||||||
&& (TYPE_PRECISION (TREE_TYPE (arg))
|
&& (TYPE_PRECISION (TREE_TYPE (arg))
|
||||||
< TYPE_PRECISION (double_type_node)))
|
< 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)))
|
else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
|
||||||
arg = perform_integral_promotions (arg);
|
arg = perform_integral_promotions (arg);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ Boston, MA 02111-1307, USA. */
|
||||||
#include "toplev.h"
|
#include "toplev.h"
|
||||||
#include "lex.h"
|
#include "lex.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
#include "convert.h"
|
||||||
|
|
||||||
/* The number of nested classes being processed. If we are not in the
|
/* The number of nested classes being processed. If we are not in the
|
||||||
scope of any class, this is zero. */
|
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);
|
v_offset = build_indirect_ref (v_offset, NULL);
|
||||||
TREE_CONSTANT (v_offset) = 1;
|
TREE_CONSTANT (v_offset) = 1;
|
||||||
|
|
||||||
offset = cp_convert (ptrdiff_type_node,
|
offset = convert_to_integer (ptrdiff_type_node,
|
||||||
size_diffop (offset, BINFO_OFFSET (v_binfo)));
|
size_diffop (offset,
|
||||||
|
BINFO_OFFSET (v_binfo)));
|
||||||
|
|
||||||
if (!integer_zerop (offset))
|
if (!integer_zerop (offset))
|
||||||
v_offset = build (code, ptrdiff_type_node, v_offset, offset);
|
v_offset = build (code, ptrdiff_type_node, v_offset, offset);
|
||||||
|
|
|
||||||
118
gcc/cp/decl.c
118
gcc/cp/decl.c
|
|
@ -13028,7 +13028,9 @@ start_enum (tree name)
|
||||||
void
|
void
|
||||||
finish_enum (tree enumtype)
|
finish_enum (tree enumtype)
|
||||||
{
|
{
|
||||||
tree pair;
|
tree values;
|
||||||
|
tree decl;
|
||||||
|
tree value;
|
||||||
tree minnode;
|
tree minnode;
|
||||||
tree maxnode;
|
tree maxnode;
|
||||||
tree t;
|
tree t;
|
||||||
|
|
@ -13036,6 +13038,8 @@ finish_enum (tree enumtype)
|
||||||
int lowprec;
|
int lowprec;
|
||||||
int highprec;
|
int highprec;
|
||||||
int precision;
|
int precision;
|
||||||
|
integer_type_kind itk;
|
||||||
|
tree underlying_type;
|
||||||
|
|
||||||
/* We built up the VALUES in reverse order. */
|
/* We built up the VALUES in reverse order. */
|
||||||
TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
|
TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
|
||||||
|
|
@ -13046,21 +13050,25 @@ finish_enum (tree enumtype)
|
||||||
works. */
|
works. */
|
||||||
if (processing_template_decl)
|
if (processing_template_decl)
|
||||||
{
|
{
|
||||||
for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
|
for (values = TYPE_VALUES (enumtype);
|
||||||
TREE_TYPE (TREE_VALUE (pair)) = enumtype;
|
values;
|
||||||
|
values = TREE_CHAIN (values))
|
||||||
|
TREE_TYPE (TREE_VALUE (values)) = enumtype;
|
||||||
if (at_function_scope_p ())
|
if (at_function_scope_p ())
|
||||||
add_stmt (build_min (TAG_DEFN, enumtype));
|
add_stmt (build_min (TAG_DEFN, enumtype));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Determine the minimum and maximum values of the enumerators. */
|
||||||
if (TYPE_VALUES (enumtype))
|
if (TYPE_VALUES (enumtype))
|
||||||
{
|
{
|
||||||
minnode = maxnode = NULL_TREE;
|
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);
|
decl = TREE_VALUE (values);
|
||||||
tree value = DECL_INITIAL (decl);
|
|
||||||
|
|
||||||
/* [dcl.enum]: Following the closing brace of an enum-specifier,
|
/* [dcl.enum]: Following the closing brace of an enum-specifier,
|
||||||
each enumerator has the type of its enumeration. Prior to the
|
each enumerator has the type of its enumeration. Prior to the
|
||||||
|
|
@ -13068,6 +13076,8 @@ finish_enum (tree enumtype)
|
||||||
initializing value. */
|
initializing value. */
|
||||||
TREE_TYPE (decl) = enumtype;
|
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
|
/* Figure out what the minimum and maximum values of the
|
||||||
enumerators are. */
|
enumerators are. */
|
||||||
if (!minnode)
|
if (!minnode)
|
||||||
|
|
@ -13086,13 +13096,13 @@ finish_enum (tree enumtype)
|
||||||
value = DECL_INITIAL (decl) = copy_node (value);
|
value = DECL_INITIAL (decl) = copy_node (value);
|
||||||
TREE_TYPE (value) = enumtype;
|
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
|
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;
|
minnode = maxnode = integer_zero_node;
|
||||||
|
|
||||||
/* Compute the number of bits require to represent all values of the
|
/* 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);
|
highprec = min_precision (maxnode, unsignedp);
|
||||||
precision = MAX (lowprec, highprec);
|
precision = MAX (lowprec, highprec);
|
||||||
|
|
||||||
/* DR 377
|
/* Determine the underlying type of the enumeration.
|
||||||
|
|
||||||
IF no integral type can represent all the enumerator values, the
|
[dcl.enum]
|
||||||
enumeration is ill-formed. */
|
|
||||||
if (precision > TYPE_PRECISION (long_long_integer_type_node))
|
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 "
|
error ("no integral type can represent all of the enumerator values "
|
||||||
"for `%T'", enumtype);
|
"for `%T'", enumtype);
|
||||||
precision = TYPE_PRECISION (long_long_integer_type_node);
|
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
|
/* Compute the minium and maximum values for the type.
|
||||||
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);
|
|
||||||
|
|
||||||
/* We use "int" or "unsigned int" as the underlying type, unless all
|
[dcl.enum]
|
||||||
the values will not fit or the user has requested that we try to
|
|
||||||
use shorter types where possible. */
|
For an enumeration where emin is the smallest enumerator and emax
|
||||||
if (precision < TYPE_PRECISION (integer_type_node)
|
is the largest, the values of the enumeration are the values of the
|
||||||
&& !flag_short_enums)
|
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);
|
decl = TREE_VALUE (values);
|
||||||
TYPE_SIZE (enumtype) = NULL_TREE;
|
value = perform_implicit_conversion (underlying_type,
|
||||||
layout_type (enumtype);
|
DECL_INITIAL (decl));
|
||||||
|
TREE_TYPE (value) = enumtype;
|
||||||
|
DECL_INITIAL (decl) = value;
|
||||||
|
TREE_VALUE (values) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix up all variant types of this enum type. */
|
/* 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. */
|
/* C++ associates enums with global, function, or class declarations. */
|
||||||
context = current_scope ();
|
context = current_scope ();
|
||||||
|
if (!context)
|
||||||
|
context = current_namespace;
|
||||||
|
|
||||||
/* Build the actual enumeration constant. Note that the enumeration
|
/* Build the actual enumeration constant. Note that the enumeration
|
||||||
constants have the type of their initializers until the
|
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)
|
if (context && context == current_class_type)
|
||||||
/* In something like `struct S { enum E { i = 7 }; };' we put `i'
|
/* 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
|
on the TYPE_FIELDS list for `S'. (That's so that you can say
|
||||||
things like `S::i' later.) */
|
things like `S::i' later.) */
|
||||||
finish_member_declaration (decl);
|
finish_member_declaration (decl);
|
||||||
else
|
else
|
||||||
pushdecl (decl);
|
pushdecl (decl);
|
||||||
|
|
|
||||||
15
gcc/cp/pt.c
15
gcc/cp/pt.c
|
|
@ -7214,8 +7214,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||||
|
|
||||||
if (DECL_TEMPLATE_PARM_P (t))
|
if (DECL_TEMPLATE_PARM_P (t))
|
||||||
return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
|
return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
|
||||||
if (!DECL_CONTEXT (t))
|
/* There is no need to substitute into namespace-scope
|
||||||
/* This is a global enumeration constant. */
|
enumerators. */
|
||||||
|
if (DECL_NAMESPACE_SCOPE_P (t))
|
||||||
return t;
|
return t;
|
||||||
|
|
||||||
/* Unfortunately, we cannot just call lookup_name here.
|
/* 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))
|
for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e))
|
||||||
{
|
{
|
||||||
tree value;
|
tree value;
|
||||||
|
tree decl;
|
||||||
|
|
||||||
|
decl = TREE_VALUE (e);
|
||||||
/* Note that in a template enum, the TREE_VALUE is the
|
/* Note that in a template enum, the TREE_VALUE is the
|
||||||
CONST_DECL, not the corresponding INTEGER_CST. */
|
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,
|
args, tf_error | tf_warning,
|
||||||
NULL_TREE);
|
NULL_TREE);
|
||||||
|
|
||||||
/* Give this enumeration constant the correct access. */
|
/* 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. */
|
/* Actually build the enumerator itself. */
|
||||||
build_enumerator (TREE_PURPOSE (e), value, newtag);
|
build_enumerator (DECL_NAME (decl), value, newtag);
|
||||||
}
|
}
|
||||||
|
|
||||||
finish_enum (newtag);
|
finish_enum (newtag);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA. */
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "toplev.h"
|
#include "toplev.h"
|
||||||
|
#include "convert.h"
|
||||||
|
|
||||||
/* C++ returns type information to the user in struct type_info
|
/* C++ returns type information to the user in struct type_info
|
||||||
objects. We also use type information to implement dynamic_cast and
|
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,
|
type = build_qualified_type (ptr_type_node,
|
||||||
cp_type_quals (TREE_TYPE (exp)));
|
cp_type_quals (TREE_TYPE (exp)));
|
||||||
return build (PLUS_EXPR, type, exp,
|
return build (PLUS_EXPR, type, exp,
|
||||||
cp_convert (ptrdiff_type_node, offset));
|
convert_to_integer (ptrdiff_type_node, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a bad_cast node for the program to throw...
|
/* Get a bad_cast node for the program to throw...
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ Boston, MA 02111-1307, USA. */
|
||||||
#include "toplev.h"
|
#include "toplev.h"
|
||||||
#include "diagnostic.h"
|
#include "diagnostic.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
#include "convert.h"
|
||||||
|
|
||||||
static tree convert_for_assignment (tree, tree, const char *, tree, int);
|
static tree convert_for_assignment (tree, tree, const char *, tree, int);
|
||||||
static tree cp_pointer_int_sum (enum tree_code, tree, tree);
|
static tree cp_pointer_int_sum (enum tree_code, tree, tree);
|
||||||
|
|
@ -1291,20 +1292,8 @@ decay_conversion (tree exp)
|
||||||
tree ptrtype;
|
tree ptrtype;
|
||||||
|
|
||||||
if (TREE_CODE (exp) == INDIRECT_REF)
|
if (TREE_CODE (exp) == INDIRECT_REF)
|
||||||
{
|
return build_nop (build_pointer_type (TREE_TYPE (type)),
|
||||||
/* Stripping away the INDIRECT_REF is not the right
|
TREE_OPERAND (exp, 0));
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TREE_CODE (exp) == COMPOUND_EXPR)
|
if (TREE_CODE (exp) == COMPOUND_EXPR)
|
||||||
{
|
{
|
||||||
|
|
@ -4007,8 +3996,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
|
||||||
ba_check, NULL);
|
ba_check, NULL);
|
||||||
|
|
||||||
rval = build_base_path (PLUS_EXPR, rval, binfo, 1);
|
rval = build_base_path (PLUS_EXPR, rval, binfo, 1);
|
||||||
rval = build1 (NOP_EXPR, argtype, rval);
|
rval = build_nop (argtype, rval);
|
||||||
TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0));
|
|
||||||
addr = fold (build (PLUS_EXPR, argtype, rval,
|
addr = fold (build (PLUS_EXPR, argtype, rval,
|
||||||
cp_convert (argtype, byte_position (field))));
|
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
|
/* Get difference in deltas for different pointer to member function
|
||||||
types. Return integer_zero_node, if FROM cannot be converted to a
|
types. Returns an integer constant of type PTRDIFF_TYPE_NODE. If
|
||||||
TO type. If FORCE is true, then allow reverse conversions as well.
|
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
|
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
|
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
|
static tree
|
||||||
get_delta_difference (tree from, tree to, int force)
|
get_delta_difference (tree from, tree to, int force)
|
||||||
{
|
{
|
||||||
tree delta = integer_zero_node;
|
|
||||||
tree binfo;
|
tree binfo;
|
||||||
tree virt_binfo;
|
tree virt_binfo;
|
||||||
base_kind kind;
|
base_kind kind;
|
||||||
|
|
@ -5212,7 +5200,7 @@ get_delta_difference (tree from, tree to, int force)
|
||||||
if (kind == bk_inaccessible || kind == bk_ambig)
|
if (kind == bk_inaccessible || kind == bk_ambig)
|
||||||
{
|
{
|
||||||
error (" in pointer to member function conversion");
|
error (" in pointer to member function conversion");
|
||||||
return delta;
|
goto error;
|
||||||
}
|
}
|
||||||
if (!binfo)
|
if (!binfo)
|
||||||
{
|
{
|
||||||
|
|
@ -5220,44 +5208,38 @@ get_delta_difference (tree from, tree to, int force)
|
||||||
{
|
{
|
||||||
error_not_base_type (from, to);
|
error_not_base_type (from, to);
|
||||||
error (" in pointer to member conversion");
|
error (" in pointer to member conversion");
|
||||||
return delta;
|
goto error;
|
||||||
}
|
}
|
||||||
binfo = lookup_base (from, to, ba_check, &kind);
|
binfo = lookup_base (from, to, ba_check, &kind);
|
||||||
if (binfo == 0)
|
if (!binfo)
|
||||||
return delta;
|
goto error;
|
||||||
virt_binfo = binfo_from_vbase (binfo);
|
virt_binfo = binfo_from_vbase (binfo);
|
||||||
|
|
||||||
if (virt_binfo)
|
if (virt_binfo)
|
||||||
{
|
{
|
||||||
/* This is a reinterpret cast, we choose to do nothing. */
|
/* This is a reinterpret cast, we choose to do nothing. */
|
||||||
warning ("pointer to member cast via virtual base `%T'",
|
warning ("pointer to member cast via virtual base `%T'",
|
||||||
BINFO_TYPE (virt_binfo));
|
BINFO_TYPE (virt_binfo));
|
||||||
return delta;
|
goto error;
|
||||||
}
|
}
|
||||||
delta = BINFO_OFFSET (binfo);
|
return convert_to_integer (ptrdiff_type_node,
|
||||||
delta = cp_convert (ptrdiff_type_node, delta);
|
size_diffop (size_zero_node,
|
||||||
delta = cp_build_binary_op (MINUS_EXPR,
|
BINFO_OFFSET (binfo)));
|
||||||
integer_zero_node,
|
|
||||||
delta);
|
|
||||||
|
|
||||||
return delta;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virt_binfo = binfo_from_vbase (binfo);
|
virt_binfo = binfo_from_vbase (binfo);
|
||||||
if (virt_binfo)
|
if (!virt_binfo)
|
||||||
{
|
return convert_to_integer (ptrdiff_type_node, BINFO_OFFSET (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);
|
|
||||||
|
|
||||||
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
|
/* 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. */
|
/* 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)
|
if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
|
||||||
n = cp_build_binary_op (LSHIFT_EXPR, n, integer_one_node);
|
n = cp_build_binary_op (LSHIFT_EXPR, n, integer_one_node);
|
||||||
delta = cp_build_binary_op (PLUS_EXPR, delta, n);
|
delta = cp_build_binary_op (PLUS_EXPR, delta, n);
|
||||||
|
|
|
||||||
|
|
@ -1957,6 +1957,58 @@ set_sizetype (tree type)
|
||||||
sizetype_set = 1;
|
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,
|
/* Set the extreme values of TYPE based on its precision in bits,
|
||||||
then lay it out. Used when make_signed_type won't do
|
then lay it out. Used when make_signed_type won't do
|
||||||
because the tree code is not INTEGER_TYPE.
|
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)
|
if (precision > HOST_BITS_PER_WIDE_INT * 2)
|
||||||
precision = HOST_BITS_PER_WIDE_INT * 2;
|
precision = HOST_BITS_PER_WIDE_INT * 2;
|
||||||
|
|
||||||
TYPE_MIN_VALUE (type)
|
set_min_and_max_values_for_integral_type (type, precision,
|
||||||
= build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
|
/*is_unsigned=*/false);
|
||||||
? 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;
|
|
||||||
|
|
||||||
/* Lay out the type: set its alignment, size, etc. */
|
/* Lay out the type: set its alignment, size, etc. */
|
||||||
layout_type (type);
|
layout_type (type);
|
||||||
|
|
@ -2010,17 +2047,8 @@ fixup_unsigned_type (tree type)
|
||||||
if (precision > HOST_BITS_PER_WIDE_INT * 2)
|
if (precision > HOST_BITS_PER_WIDE_INT * 2)
|
||||||
precision = HOST_BITS_PER_WIDE_INT * 2;
|
precision = HOST_BITS_PER_WIDE_INT * 2;
|
||||||
|
|
||||||
TYPE_MIN_VALUE (type) = build_int_2 (0, 0);
|
set_min_and_max_values_for_integral_type (type, precision,
|
||||||
TYPE_MAX_VALUE (type)
|
/*is_unsigned=*/true);
|
||||||
= 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;
|
|
||||||
|
|
||||||
/* Lay out the type: set its alignment, size, etc. */
|
/* Lay out the type: set its alignment, size, etc. */
|
||||||
layout_type (type);
|
layout_type (type);
|
||||||
|
|
|
||||||
|
|
@ -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>
|
2003-07-28 <hp@bitrange.com>
|
||||||
|
|
||||||
* gcc.dg/Wdeclaration-after-statement-1.c,
|
* gcc.dg/Wdeclaration-after-statement-1.c,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include <limits.h>
|
||||||
|
enum test {
|
||||||
|
z = 0,
|
||||||
|
c = UINT_MAX + 1LL
|
||||||
|
} x = z;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return x != z;
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// { dg-options "-w" }
|
||||||
// PR c++/9420
|
// PR c++/9420
|
||||||
// Bug: We were instantiating B<int> during overload resolution for E<0.
|
// 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
|
// This is wrong; the contents of B<int> are not relevant, since we can't
|
||||||
|
|
|
||||||
|
|
@ -2909,6 +2909,7 @@ extern void output_inline_function (tree);
|
||||||
extern void set_decl_origin_self (tree);
|
extern void set_decl_origin_self (tree);
|
||||||
|
|
||||||
/* In stor-layout.c */
|
/* 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 fixup_signed_type (tree);
|
||||||
extern void internal_reference_types (void);
|
extern void internal_reference_types (void);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue