diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-03-16 22:18:11 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-03-16 22:18:11 +0000 |
commit | ec835fb2bfc25fb747550aec56d261042659bc54 (patch) | |
tree | c0d3485bbb98b41f57f677cc06f2b3179fd1f192 /gcc | |
parent | 1e0f07d3952be55a453ad3ac7c326481b82f0d59 (diff) | |
download | gcc-ec835fb2bfc25fb747550aec56d261042659bc54.zip gcc-ec835fb2bfc25fb747550aec56d261042659bc54.tar.gz gcc-ec835fb2bfc25fb747550aec56d261042659bc54.tar.bz2 |
re PR c++/14586 (Bogus warning in templates about taking address of a temporary in a template)
PR c++/14586
* cp-tree.h (build_new_op): Change prototype.
(build_x_binary_op): Likewise.
* call.c (build_new_op): Add overloaded_p parameter.
* decl2.c (grok_array_decl): Adjust call to build_new_op.
* parser.c (cp_parser_binary_expression): Note that uses of
overloaded operators prevents an expression from being considered
an integral constant.
* pt.c (tsubst_copy_and_build): Adjust calls to build_new_op and/or
build_x_binary_op.
* semantics.c (finish_call_expr): Likewise.
* typeck.c (rationalize_conditional_expr): Likewise.
(build_x_indirect_ref): Likewise.
(build_x_binary_op): Likewise.
(build_x_unary_op): Likewise.
(build_x_compound_expr): Likewise.
(build_modify_expr): Likewise.
* typeck2.c (build_x_arrow): Likewise.
PR c++/14586
* g++.dg/parse/non-dependent3.C: New test.
From-SVN: r79553
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/cp/call.c | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 3 | ||||
-rw-r--r-- | gcc/cp/parser.c | 16 | ||||
-rw-r--r-- | gcc/cp/pt.c | 3 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 3 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 23 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/non-dependent3.C | 17 |
11 files changed, 91 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3b4ae33..408fa1c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,24 @@ +2004-03-16 Mark Mitchell <mark@codesourcery.com> + + PR c++/14586 + * cp-tree.h (build_new_op): Change prototype. + (build_x_binary_op): Likewise. + * call.c (build_new_op): Add overloaded_p parameter. + * decl2.c (grok_array_decl): Adjust call to build_new_op. + * parser.c (cp_parser_binary_expression): Note that uses of + overloaded operators prevents an expression from being considered + an integral constant. + * pt.c (tsubst_copy_and_build): Adjust calls to build_new_op and/or + build_x_binary_op. + * semantics.c (finish_call_expr): Likewise. + * typeck.c (rationalize_conditional_expr): Likewise. + (build_x_indirect_ref): Likewise. + (build_x_binary_op): Likewise. + (build_x_unary_op): Likewise. + (build_x_compound_expr): Likewise. + (build_modify_expr): Likewise. + * typeck2.c (build_x_arrow): Likewise. + 2004-03-15 Kazu Hirata <kazu@cs.umass.edu> * cp-lang.c, ptree.c: Update copyright. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4eeb5e5..62182f3 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3555,7 +3555,8 @@ add_candidates (tree fns, tree args, } tree -build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3) +build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, + bool *overloaded_p) { struct z_candidate *candidates = 0, *cand; tree arglist, fnname; @@ -3707,7 +3708,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3) code = PREINCREMENT_EXPR; else code = PREDECREMENT_EXPR; - result = build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE); + result = build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE, + overloaded_p); break; /* The caller will deal with these. */ @@ -3742,6 +3744,9 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3) } else if (TREE_CODE (cand->fn) == FUNCTION_DECL) { + if (overloaded_p) + *overloaded_p = true; + if (warn_synth && fnname == ansi_assopname (NOP_EXPR) && DECL_ARTIFICIAL (cand->fn) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6ccfcc8..16e0abe 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3491,7 +3491,7 @@ extern tree build_new_function_call (tree, tree); extern tree build_operator_new_call (tree, tree, tree *, tree *); extern tree build_new_method_call (tree, tree, tree, tree, int); extern tree build_special_member_call (tree, tree, tree, tree, int); -extern tree build_new_op (enum tree_code, int, tree, tree, tree); +extern tree build_new_op (enum tree_code, int, tree, tree, tree, bool *); extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree); extern bool can_convert (tree, tree); extern bool can_convert_arg (tree, tree, tree); @@ -4177,7 +4177,8 @@ extern tree build_indirect_ref (tree, const char *); extern tree build_array_ref (tree, tree); extern tree get_member_function_from_ptrfunc (tree *, tree); extern tree convert_arguments (tree, tree, tree, int); -extern tree build_x_binary_op (enum tree_code, tree, tree); +extern tree build_x_binary_op (enum tree_code, tree, tree, + bool *); extern tree build_x_unary_op (enum tree_code, tree); extern tree unary_complex_lvalue (enum tree_code, tree); extern tree build_x_conditional_expr (tree, tree, tree); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 7310d09..baf1adf 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -380,7 +380,8 @@ grok_array_decl (tree array_expr, tree index_exp) /* If they have an `operator[]', use that. */ if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp))) expr = build_new_op (ARRAY_REF, LOOKUP_NORMAL, - array_expr, index_exp, NULL_TREE); + array_expr, index_exp, NULL_TREE, + /*overloaded_p=*/NULL); else { tree p1, p2, i1, i2; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 20588b0..db40252 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13975,12 +13975,26 @@ cp_parser_binary_expression (cp_parser* parser, ++map_node) if (map_node->token_type == token->type) { + /* Assume that an overloaded operator will not be used. */ + bool overloaded_p = false; + /* Consume the operator token. */ cp_lexer_consume_token (parser->lexer); /* Parse the right-hand side of the expression. */ rhs = (*fn) (parser); /* Build the binary tree node. */ - lhs = build_x_binary_op (map_node->tree_type, lhs, rhs); + lhs = build_x_binary_op (map_node->tree_type, lhs, rhs, + &overloaded_p); + /* If the binary operator required the use of an + overloaded operator, then this expression cannot be an + integral constant-expression. An overloaded operator + can be used even if both operands are otherwise + permissible in an integral constant-expression if at + least one of the operands is of enumeration type. */ + if (overloaded_p + && (cp_parser_non_integral_constant_expression + (parser, "calls to overloaded operators"))) + lhs = error_mark_node; break; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 45fa012..6001b1c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8271,7 +8271,8 @@ tsubst_copy_and_build (tree t, return build_x_binary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)), - RECUR (TREE_OPERAND (t, 1))); + RECUR (TREE_OPERAND (t, 1)), + /*overloaded_p=*/NULL); case SCOPE_REF: return tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true, diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b7a7f4a..9142a2c 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1729,7 +1729,8 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p) else if (CLASS_TYPE_P (TREE_TYPE (fn))) /* If the "function" is really an object of class type, it might have an overloaded `operator ()'. */ - result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE); + result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE, + /*overloaded_p=*/NULL); if (!result) /* A call where the function is unknown. */ result = build_function_call (fn, args); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index b7a66c2..31ca3e0 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1493,7 +1493,8 @@ rationalize_conditional_expr (enum tree_code code, tree t) build_conditional_expr (build_x_binary_op ((TREE_CODE (t) == MIN_EXPR ? LE_EXPR : GE_EXPR), TREE_OPERAND (t, 0), - TREE_OPERAND (t, 1)), + TREE_OPERAND (t, 1), + /*overloaded_p=*/NULL), build_unary_op (code, TREE_OPERAND (t, 0), 0), build_unary_op (code, TREE_OPERAND (t, 1), 0)); } @@ -2026,7 +2027,7 @@ build_x_indirect_ref (tree expr, const char *errorstring) } rval = build_new_op (INDIRECT_REF, LOOKUP_NORMAL, expr, NULL_TREE, - NULL_TREE); + NULL_TREE, /*overloaded_p=*/NULL); if (!rval) rval = build_indirect_ref (expr, errorstring); @@ -2653,7 +2654,8 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags) conversions on the operands. CODE is the kind of expression to build. */ tree -build_x_binary_op (enum tree_code code, tree arg1, tree arg2) +build_x_binary_op (enum tree_code code, tree arg1, tree arg2, + bool *overloaded_p) { tree orig_arg1; tree orig_arg2; @@ -2674,7 +2676,8 @@ build_x_binary_op (enum tree_code code, tree arg1, tree arg2) if (code == DOTSTAR_EXPR) expr = build_m_component_ref (arg1, arg2); else - expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE); + expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE, + overloaded_p); if (processing_template_decl && expr != error_mark_node) return build_min_non_dep (code, expr, orig_arg1, orig_arg2); @@ -3531,7 +3534,8 @@ build_x_unary_op (enum tree_code code, tree xarg) || (TREE_CODE (xarg) == OFFSET_REF))) /* Don't look for a function. */; else - exp = build_new_op (code, LOOKUP_NORMAL, xarg, NULL_TREE, NULL_TREE); + exp = build_new_op (code, LOOKUP_NORMAL, xarg, NULL_TREE, NULL_TREE, + /*overloaded_p=*/NULL); if (!exp && code == ADDR_EXPR) { /* A pointer to member-function can be formed only by saying @@ -4371,7 +4375,8 @@ build_x_compound_expr (tree op1, tree op2) op2 = build_non_dependent_expr (op2); } - result = build_new_op (COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2, NULL_TREE); + result = build_new_op (COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2, NULL_TREE, + /*overloaded_p=*/NULL); if (!result) result = build_compound_expr (op1, op2); @@ -5065,7 +5070,8 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) else { result = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL, - lhs, rhs, make_node (NOP_EXPR)); + lhs, rhs, make_node (NOP_EXPR), + /*overloaded_p=*/NULL); if (result == NULL_TREE) return error_mark_node; return result; @@ -5232,7 +5238,8 @@ build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) if (modifycode != NOP_EXPR) { tree rval = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs, - make_node (modifycode)); + make_node (modifycode), + /*overloaded_p=*/NULL); if (rval) return rval; } diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 4687486..6314456 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1091,7 +1091,8 @@ build_x_arrow (tree expr) if (IS_AGGR_TYPE (type)) { while ((expr = build_new_op (COMPONENT_REF, LOOKUP_NORMAL, expr, - NULL_TREE, NULL_TREE))) + NULL_TREE, NULL_TREE, + /*overloaded_p=*/NULL))) { if (expr == error_mark_node) return error_mark_node; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 62764c2..09f98bf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-03-16 Mark Mitchell <mark@codesourcery.com> + + PR c++/14586 + * g++.dg/parse/non-dependent3.C: New test. + 2004-03-16 Paolo Bonzini <bonzini@gnu.org> * g++.dg/eh/simd-1.C: Use vector_size attribute, not mode. diff --git a/gcc/testsuite/g++.dg/parse/non-dependent3.C b/gcc/testsuite/g++.dg/parse/non-dependent3.C new file mode 100644 index 0000000..9dfb996 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/non-dependent3.C @@ -0,0 +1,17 @@ +// PR c++/14586 + +enum E { e }; + +E & operator |= (E &f1, const E &f2); + +E operator | (const E &f1, const E &f2) { + E result = f1; + result |= f2; + return result; +} + +template <typename> void foo () { + const E flags = e | e; +} + +template void foo<double> (); |