diff options
author | Jason Merrill <jason@redhat.com> | 2012-07-02 15:14:23 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2012-07-02 15:14:23 -0400 |
commit | 8d0d1915d9f96a4c9d9418b21b38cfa9c386d7a3 (patch) | |
tree | 8becd43c0137d4c13ec1df45fe08c64cceb0a023 /gcc/cp | |
parent | 531b10fcb0fe5c86576bda5fd201d8acc7db4525 (diff) | |
download | gcc-8d0d1915d9f96a4c9d9418b21b38cfa9c386d7a3.zip gcc-8d0d1915d9f96a4c9d9418b21b38cfa9c386d7a3.tar.gz gcc-8d0d1915d9f96a4c9d9418b21b38cfa9c386d7a3.tar.bz2 |
re PR c++/53524 (Bogus enum comparison warning)
PR c++/53524
gcc/cp/
* call.c (build_conditional_expr_1): Don't warn about comparison of
two enumerators before their enumeration is complete.
(build_new_op_1): Call decay_conversion before warn_logical_operator.
* decl.c (build_enumerator): Set DECL_CONTEXT of an enumerator to
its enumeration.
* decl2.c (mark_used): Call used_types_insert for enums.
* semantics.c (finish_id_expression): Don't decay CONST_DECL.
(finish_member_declaration): Don't change DECL_CONTEXT of enumerators.
* class.c (check_field_decls): Don't change DECL_CONTEXT of enums.
* typeck.c (convert_for_assignment): Don't decay CONST_DECL.
(build_class_member_access_expr): Look through unscoped enums.
* search.c (context_for_name_lookup): Look through unscoped enums.
* pt.c (tsubst_copy_and_build): Don't decay CONST_DECL.
(tsubst_copy): Use DECL_CONTEXT to find the enumeration.
* tree.c (decl_linkage): Likewise.
* cvt.c (ocp_convert): Check decayed expr for enum range warning.
gcc/c-family/
* c-common.c (get_priority): Call default_conversion.
From-SVN: r189174
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/cp/call.c | 22 | ||||
-rw-r--r-- | gcc/cp/class.c | 3 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 2 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 13 | ||||
-rw-r--r-- | gcc/cp/search.c | 7 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 25 | ||||
-rw-r--r-- | gcc/cp/tree.c | 2 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 6 |
11 files changed, 62 insertions, 46 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9b5b7c1..448dd5c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,23 @@ +2012-07-02 Jason Merrill <jason@redhat.com> + + PR c++/53524 + * call.c (build_conditional_expr_1): Don't warn about comparison of + two enumerators before their enumeration is complete. + (build_new_op_1): Call decay_conversion before warn_logical_operator. + * decl.c (build_enumerator): Set DECL_CONTEXT of an enumerator to + its enumeration. + * decl2.c (mark_used): Call used_types_insert for enums. + * semantics.c (finish_id_expression): Don't decay CONST_DECL. + (finish_member_declaration): Don't change DECL_CONTEXT of enumerators. + * class.c (check_field_decls): Don't change DECL_CONTEXT of enums. + * typeck.c (convert_for_assignment): Don't decay CONST_DECL. + (build_class_member_access_expr): Look through unscoped enums. + * search.c (context_for_name_lookup): Look through unscoped enums. + * pt.c (tsubst_copy_and_build): Don't decay CONST_DECL. + (tsubst_copy): Use DECL_CONTEXT to find the enumeration. + * tree.c (decl_linkage): Likewise. + * cvt.c (ocp_convert): Check decayed expr for enum range warning. + 2012-06-29 Steven Bosscher <steven@gcc.gnu.org> * Make-lang.in: Remove tree-mudflap.o from CXX_AND_OBJCXX_OBJS. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 09965b3..72394f4 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4365,6 +4365,7 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3, struct z_candidate *candidates = 0; struct z_candidate *cand; void *p; + tree orig_arg2, orig_arg3; /* As a G++ extension, the second argument to the conditional can be omitted. (So that `a ? : c' is roughly equivalent to `a ? a : @@ -4404,6 +4405,8 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3, array-to-pointer (_conv.array_), and function-to-pointer (_conv.func_) standard conversions are performed on the second and third operands. */ + orig_arg2 = arg2; + orig_arg3 = arg3; arg2_type = unlowered_expr_type (arg2); arg3_type = unlowered_expr_type (arg3); if (VOID_TYPE_P (arg2_type) || VOID_TYPE_P (arg3_type)) @@ -4701,7 +4704,12 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3, if (TREE_CODE (arg2_type) == ENUMERAL_TYPE && TREE_CODE (arg3_type) == ENUMERAL_TYPE) { - if (complain & tf_warning) + if (TREE_CODE (orig_arg2) == CONST_DECL + && TREE_CODE (orig_arg3) == CONST_DECL + && DECL_CONTEXT (orig_arg2) == DECL_CONTEXT (orig_arg3)) + /* Two enumerators from the same enumeration can have different + types when the enumeration is still being defined. */; + else if (complain & tf_warning) warning (OPT_Wenum_compare, "enumeral mismatch in conditional expression: %qT vs %qT", arg2_type, arg3_type); @@ -5221,16 +5229,20 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1, if (arg2) { + conv = cand->convs[1]; + if (conv->kind == ck_ref_bind) + conv = next_conversion (conv); + else + arg2 = decay_conversion (arg2, complain); + /* We need to call warn_logical_operator before - converting arg2 to a boolean_type. */ + converting arg2 to a boolean_type, but after + decaying an enumerator to its value. */ if (complain & tf_warning) warn_logical_operator (loc, code, boolean_type_node, code_orig_arg1, arg1, code_orig_arg2, arg2); - conv = cand->convs[1]; - if (conv->kind == ck_ref_bind) - conv = next_conversion (conv); arg2 = convert_like (conv, arg2, complain); } if (arg3) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 6307e84..264258c 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3114,7 +3114,8 @@ check_field_decls (tree t, tree *access_decls, /* If we've gotten this far, it's a data member, possibly static, or an enumerator. */ - DECL_CONTEXT (x) = t; + if (TREE_CODE (x) != CONST_DECL) + DECL_CONTEXT (x) = t; /* When this goes into scope, it will be a non-local reference. */ DECL_NONLOCAL (x) = 1; diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 998d4eb..9550f15 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -741,8 +741,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags, values. Otherwise, the resulting enumeration value is unspecified. */ if ((complain & tf_warning) - && TREE_CODE (expr) == INTEGER_CST - && !int_fits_type_p (expr, ENUM_UNDERLYING_TYPE (type))) + && TREE_CODE (e) == INTEGER_CST + && !int_fits_type_p (e, ENUM_UNDERLYING_TYPE (type))) warning_at (loc, OPT_Wconversion, "the result of the conversion is unspecified because " "%qE is outside the range of type %qT", diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index ab56019..18beaa9 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -12570,7 +12570,7 @@ incremented enumerator value is too large for %<long%>"); a function could mean local to a class method. */ decl = build_decl (loc, CONST_DECL, name, type); - DECL_CONTEXT (decl) = FROB_CONTEXT (context); + DECL_CONTEXT (decl) = enumtype; TREE_CONSTANT (decl) = 1; TREE_READONLY (decl) = 1; DECL_INITIAL (decl) = value; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index d8c7260..cbb1053 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4205,6 +4205,10 @@ mark_used (tree decl) if (DECL_CLONED_FUNCTION_P (decl)) TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1; + /* Mark enumeration types as used. */ + if (TREE_CODE (decl) == CONST_DECL) + used_types_insert (DECL_CONTEXT (decl)); + if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DELETED_FN (decl)) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7e1c46f..f8f416a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12128,7 +12128,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) When we instantiate f<7>::S::g(), say, lookup_name is not clever enough to find f<7>::a. */ enum_type - = tsubst_aggr_type (TREE_TYPE (t), args, complain, in_decl, + = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl, /*entering_scope=*/0); for (v = TYPE_VALUES (enum_type); @@ -14385,17 +14385,6 @@ tsubst_copy_and_build (tree t, return stmt_expr; } - case CONST_DECL: - t = tsubst_copy (t, args, complain, in_decl); - /* As in finish_id_expression, we resolve enumeration constants - to their underlying values. */ - if (TREE_CODE (t) == CONST_DECL && !processing_template_decl) - { - used_types_insert (TREE_TYPE (t)); - return DECL_INITIAL (t); - } - return t; - case LAMBDA_EXPR: { tree r = build_lambda_expr (); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index e6d6be8..d112c05 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -579,7 +579,8 @@ context_for_name_lookup (tree decl) declared. */ tree context = DECL_CONTEXT (decl); - while (context && TYPE_P (context) && ANON_AGGR_TYPE_P (context)) + while (context && TYPE_P (context) + && (ANON_AGGR_TYPE_P (context) || UNSCOPED_ENUM_P (context))) context = TYPE_CONTEXT (context); if (!context) context = global_namespace; @@ -623,9 +624,7 @@ dfs_access_in_type (tree binfo, void *data) else { /* First, check for an access-declaration that gives us more - access to the DECL. The CONST_DECL for an enumeration - constant will not have DECL_LANG_SPECIFIC, and thus no - DECL_ACCESS. */ + access to the DECL. */ if (DECL_LANG_SPECIFIC (decl) && !DECL_DISCRIMINATOR_P (decl)) { tree decl_access = purpose_member (type, DECL_ACCESS (decl)); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index d45a6e2..f1a94c1 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2631,8 +2631,10 @@ finish_member_declaration (tree decl) TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl); } - /* Mark the DECL as a member of the current class. */ - DECL_CONTEXT (decl) = current_class_type; + /* Mark the DECL as a member of the current class, unless it's + a member of an enumeration. */ + if (TREE_CODE (decl) != CONST_DECL) + DECL_CONTEXT (decl) = current_class_type; /* Check for bare parameter packs in the member variable declaration. */ if (TREE_CODE (decl) == FIELD_DECL) @@ -3060,18 +3062,6 @@ finish_id_expression (tree id_expression, } return r; } - /* Similarly, we resolve enumeration constants to their - underlying values. */ - else if (TREE_CODE (decl) == CONST_DECL) - { - *idk = CP_ID_KIND_NONE; - if (!processing_template_decl) - { - used_types_insert (TREE_TYPE (decl)); - return DECL_INITIAL (decl); - } - return decl; - } else { bool dependent_p; @@ -3100,6 +3090,9 @@ finish_id_expression (tree id_expression, if (!processing_template_decl) /* No names are dependent outside a template. */ ; + else if (TREE_CODE (decl) == CONST_DECL) + /* We don't want to treat enumerators as dependent. */ + ; /* A template-id where the name of the template was not resolved is definitely dependent. */ else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR @@ -3234,15 +3227,17 @@ finish_id_expression (tree id_expression, marked either below or after overload resolution. */ if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL + || TREE_CODE (decl) == CONST_DECL || TREE_CODE (decl) == RESULT_DECL) mark_used (decl); /* Only certain kinds of names are allowed in constant - expression. Enumerators and template parameters have already + expression. Template parameters have already been handled above. */ if (! error_operand_p (decl) && integral_constant_expression_p && ! decl_constant_var_p (decl) + && TREE_CODE (decl) != CONST_DECL && ! builtin_valid_in_constant_expr_p (decl)) { if (!allow_non_integral_constant_expression_p) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 2b541cd..a03f845 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -3212,7 +3212,7 @@ decl_linkage (tree decl) /* Linkage of a CONST_DECL depends on the linkage of the enumeration type. */ if (TREE_CODE (decl) == CONST_DECL) - return decl_linkage (TYPE_NAME (TREE_TYPE (decl))); + return decl_linkage (TYPE_NAME (DECL_CONTEXT (decl))); /* Some things that are not TREE_PUBLIC have external linkage, too. For example, on targets that don't have weak symbols, we make all diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 971f386..3bc3ead 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2199,7 +2199,7 @@ build_class_member_access_expr (tree object, tree member, /* If MEMBER is from an anonymous aggregate, MEMBER_SCOPE will presently be the anonymous union. Go outwards until we find a type related to OBJECT_TYPE. */ - while (ANON_AGGR_TYPE_P (member_scope) + while ((ANON_AGGR_TYPE_P (member_scope) || UNSCOPED_ENUM_P (member_scope)) && !same_type_ignoring_top_level_qualifiers_p (member_scope, object_type)) member_scope = TYPE_CONTEXT (member_scope); @@ -7582,10 +7582,6 @@ convert_for_assignment (tree type, tree rhs, return error_mark_node; } - /* Simplify the RHS if possible. */ - if (TREE_CODE (rhs) == CONST_DECL) - rhs = DECL_INITIAL (rhs); - if (c_dialect_objc ()) { int parmno; |