diff options
author | Jason Merrill <jason@redhat.com> | 2009-05-25 19:01:02 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-05-25 19:01:02 -0400 |
commit | 550a799d5383a73b52192b71b9234c3efb8be6a9 (patch) | |
tree | 583bc6fb72a9ca524446f8aa253888d047949f48 | |
parent | 85057983ac31039dff4e0963b789ee6684351868 (diff) | |
download | gcc-550a799d5383a73b52192b71b9234c3efb8be6a9.zip gcc-550a799d5383a73b52192b71b9234c3efb8be6a9.tar.gz gcc-550a799d5383a73b52192b71b9234c3efb8be6a9.tar.bz2 |
re PR c++/38064 ([c++0x] operator== doesn't work for enum classes)
PR c++/38064
* typeck.c (cp_build_binary_op): Allow ENUMERAL_TYPE in
arithmetic comparisons.
(cp_common_type): Handle scoped enums.
* call.c (promoted_arithmetic_type_p): Don't use INTEGRAL_TYPE_P.
(add_builtin_candidate, add_builtin_candidates): Likewise.
(convert_like_real): Likewise.
* class.c (check_bitfield_decl): Likewise.
* decl.c (check_static_variable_definition): Likewise.
(compute_array_index_type): Likewise.
* decl2.c (grokbitfield): Likewise.
* init.c (build_new_1): Likewise.
* pt.c (convert_nontype_argument): Likewise.
(current_instantiation): Likewise.
* tree.c (pod_type_p): Likewise.
* typeck.c (build_static_cast_1): Likewise.
(build_reinterpret_cast_1): Likewise.
From-SVN: r147854
-rw-r--r-- | gcc/cp/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/cp/call.c | 25 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 4 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/init.c | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 6 | ||||
-rw-r--r-- | gcc/cp/tree.c | 2 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 36 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/enum3.C | 17 |
11 files changed, 89 insertions, 33 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index aeab9a1..7e22a4f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,24 @@ +2009-05-22 Jason Merrill <jason@redhat.com> + + PR c++/38064 + * typeck.c (cp_build_binary_op): Allow ENUMERAL_TYPE in + arithmetic comparisons. + (cp_common_type): Handle scoped enums. + + * call.c (promoted_arithmetic_type_p): Don't use INTEGRAL_TYPE_P. + (add_builtin_candidate, add_builtin_candidates): Likewise. + (convert_like_real): Likewise. + * class.c (check_bitfield_decl): Likewise. + * decl.c (check_static_variable_definition): Likewise. + (compute_array_index_type): Likewise. + * decl2.c (grokbitfield): Likewise. + * init.c (build_new_1): Likewise. + * pt.c (convert_nontype_argument): Likewise. + (current_instantiation): Likewise. + * tree.c (pod_type_p): Likewise. + * typeck.c (build_static_cast_1): Likewise. + (build_reinterpret_cast_1): Likewise. + 2009-05-22 Richard Guenther <rguenther@suse.de> PR middle-end/38964 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 0d5ae6a..a9c0367 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1781,7 +1781,7 @@ promoted_arithmetic_type_p (tree type) (including e.g. int and long but excluding e.g. char). Similarly, the term promoted arithmetic type refers to promoted integral types plus floating types. */ - return ((INTEGRAL_TYPE_P (type) + return ((CP_INTEGRAL_TYPE_P (type) && same_type_p (type_promotes_to (type), type)) || TREE_CODE (type) == REAL_TYPE); } @@ -1883,7 +1883,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, T operator~(T); */ case BIT_NOT_EXPR: - if (INTEGRAL_TYPE_P (type1)) + if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1)) break; return; @@ -1953,7 +1953,8 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, case MINUS_EXPR: if (TYPE_PTROB_P (type1) && TYPE_PTROB_P (type2)) break; - if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2)) + if (TYPE_PTROB_P (type1) + && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2)) { type2 = ptrdiff_type_node; break; @@ -2013,12 +2014,12 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) break; case ARRAY_REF: - if (INTEGRAL_TYPE_P (type1) && TYPE_PTROB_P (type2)) + if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && TYPE_PTROB_P (type2)) { type1 = ptrdiff_type_node; break; } - if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2)) + if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2)) { type2 = ptrdiff_type_node; break; @@ -2042,7 +2043,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, case BIT_XOR_EXPR: case LSHIFT_EXPR: case RSHIFT_EXPR: - if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)) + if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2)) break; return; @@ -2087,7 +2088,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, { case PLUS_EXPR: case MINUS_EXPR: - if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2)) + if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2)) { type2 = ptrdiff_type_node; break; @@ -2104,7 +2105,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, case BIT_XOR_EXPR: case LSHIFT_EXPR: case RSHIFT_EXPR: - if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)) + if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2)) break; return; @@ -2329,7 +2330,7 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, type = TYPE_MAIN_VARIANT (type_decays_to (type)); if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE) types[i] = tree_cons (NULL_TREE, type, types[i]); - if (INTEGRAL_TYPE_P (type)) + if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type)) type = type_promotes_to (type); } @@ -2346,9 +2347,9 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, if (i != 0 || ! ref1) { type = TYPE_MAIN_VARIANT (type_decays_to (type)); - if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE) + if (enum_p && UNSCOPED_ENUM_P (type)) types[i] = tree_cons (NULL_TREE, type, types[i]); - if (INTEGRAL_TYPE_P (type)) + if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type)) type = type_promotes_to (type); } types[i] = tree_cons (NULL_TREE, type, types[i]); @@ -4755,7 +4756,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, if (inner >= 0) { expr = decl_constant_value (expr); - if (expr == null_node && INTEGRAL_TYPE_P (totype)) + if (expr == null_node && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (totype)) /* If __null has been converted to an integer type, we do not want to warn about uses of EXPR as an integer, rather than as a pointer. */ diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 049e980..20ceb65 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2705,7 +2705,7 @@ check_bitfield_decl (tree field) DECL_INITIAL (field) = NULL_TREE; /* Detect invalid bit-field type. */ - if (!INTEGRAL_TYPE_P (type)) + if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type)) { error ("bit-field %q+#D with non-integral type", field); w = error_mark_node; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 433d089..a626a71 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7154,7 +7154,7 @@ check_static_variable_definition (tree decl, tree type) error ("ISO C++ forbids in-class initialization of non-const " "static member %qD", decl); - else if (!INTEGRAL_TYPE_P (type)) + else if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type)) pedwarn (input_location, OPT_pedantic, "ISO C++ forbids initialization of member constant " "%qD of non-integral type %qT", decl, type); @@ -7177,7 +7177,7 @@ compute_array_index_type (tree name, tree size) type = TREE_TYPE (size); /* The array bound must be an integer type. */ - if (!dependent_type_p (type) && !INTEGRAL_TYPE_P (type)) + if (!dependent_type_p (type) && !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type)) { if (name) error ("size of array %qD has non-integral type %qT", name, type); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 1b8aa49..d368ea8 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -964,7 +964,7 @@ grokbitfield (const cp_declarator *declarator, if (TREE_CODE (value) == VOID_TYPE) return void_type_node; - if (!INTEGRAL_TYPE_P (TREE_TYPE (value)) + if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value)) && (POINTER_TYPE_P (value) || !dependent_type_p (TREE_TYPE (value)))) { diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 25cfd52..a99983e 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1963,7 +1963,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, { tree placement_arg = CALL_EXPR_ARG (alloc_call, 1); - if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg))) + if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg))) || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg)))) { placement_expr = get_target_expr (placement_first); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ed6b031..f8a6e7e 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4415,9 +4415,9 @@ convert_nontype_argument (tree type, tree expr) For a non-type template-parameter of integral or enumeration type, integral promotions (_conv.prom_) and integral conversions (_conv.integral_) are applied. */ - if (INTEGRAL_TYPE_P (type)) + if (INTEGRAL_OR_ENUMERATION_TYPE_P (type)) { - if (!INTEGRAL_TYPE_P (expr_type)) + if (!INTEGRAL_OR_ENUMERATION_TYPE_P (expr_type)) return error_mark_node; expr = fold_decl_constant_value (expr); @@ -16153,7 +16153,7 @@ current_instantiation (void) static int invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain) { - if (INTEGRAL_TYPE_P (type)) + if (INTEGRAL_OR_ENUMERATION_TYPE_P (type)) return 0; else if (POINTER_TYPE_P (type)) return 0; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 8c51e0b..dece159 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2156,7 +2156,7 @@ pod_type_p (const_tree t) if (t == error_mark_node) return 1; - if (INTEGRAL_TYPE_P (t)) + if (INTEGRAL_OR_ENUMERATION_TYPE_P (t)) return 1; /* integral, character or enumeral type */ if (FLOAT_TYPE_P (t)) return 1; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 074d619..d7fddb1 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -260,6 +260,19 @@ cp_common_type (tree t1, tree t2) enum tree_code code2 = TREE_CODE (t2); tree attributes; + /* In what follows, we slightly generalize the rules given in [expr] so + as to deal with `long long' and `complex'. First, merge the + attributes. */ + attributes = (*targetm.merge_type_attributes) (t1, t2); + + if (SCOPED_ENUM_P (t1) || SCOPED_ENUM_P (t2)) + { + if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) + return build_type_attribute_variant (t1, attributes); + else + return NULL_TREE; + } + /* FIXME: Attributes. */ gcc_assert (ARITHMETIC_TYPE_P (t1) || TREE_CODE (t1) == VECTOR_TYPE @@ -268,11 +281,6 @@ cp_common_type (tree t1, tree t2) || TREE_CODE (t2) == VECTOR_TYPE || UNSCOPED_ENUM_P (t2)); - /* In what follows, we slightly generalize the rules given in [expr] so - as to deal with `long long' and `complex'. First, merge the - attributes. */ - attributes = (*targetm.merge_type_attributes) (t1, t2); - /* If one type is complex, form the common type of the non-complex components, then make that complex. Use T1 or T2 if it is the required type. */ @@ -3636,9 +3644,9 @@ cp_build_binary_op (location_t location, build_type = boolean_type_node; if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == COMPLEX_TYPE) + || code0 == COMPLEX_TYPE || code0 == ENUMERAL_TYPE) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE)) + || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE)) short_compare = 1; else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE) || (TYPE_PTRMEM_P (type0) && TYPE_PTRMEM_P (type1))) @@ -3910,9 +3918,10 @@ cp_build_binary_op (location_t location, break; } - if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) + if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE + || code0 == ENUMERAL_TYPE) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE))) + || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE))) arithmetic_types_p = 1; else { @@ -5348,8 +5357,10 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, /* The effect of all that is that any conversion between any two types which are integral, floating, or enumeration types can be performed. */ - if ((INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type)) - && (INTEGRAL_TYPE_P (intype) || SCALAR_FLOAT_TYPE_P (intype))) + if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type) + || SCALAR_FLOAT_TYPE_P (type)) + && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype) + || SCALAR_FLOAT_TYPE_P (intype))) { expr = ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL); @@ -5649,7 +5660,8 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, } else if (TREE_CODE (type) == VECTOR_TYPE) return fold_if_not_in_template (convert_to_vector (type, expr)); - else if (TREE_CODE (intype) == VECTOR_TYPE && INTEGRAL_TYPE_P (type)) + else if (TREE_CODE (intype) == VECTOR_TYPE + && INTEGRAL_OR_ENUMERATION_TYPE_P (type)) return fold_if_not_in_template (convert_to_integer (type, expr)); else { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 578bbee..03aa116 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-05-25 Jason Merrill <jason@redhat.com> + + PR c++/38064 + * g++.dg/cpp0x/enum3.C: New test. + 2009-05-25 Richard Guenther <rguenther@suse.de> PR tree-optimization/36327 diff --git a/gcc/testsuite/g++.dg/cpp0x/enum3.C b/gcc/testsuite/g++.dg/cpp0x/enum3.C new file mode 100644 index 0000000..5555ab2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum3.C @@ -0,0 +1,17 @@ +// PR c++/38064 +// { dg-options "-std=c++0x" } +// { dg-do run } + +enum class E { elem }; + +template <class T> +void f (T t); + +bool f (bool b) { return b; } + +int main() +{ + E e = E::elem; + if (!f (e == E::elem)) + return 1; +} |