summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-12 08:41:29 +0000
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-12 08:41:29 +0000
commit1e6d0c169fdb66874b628c5faa94163ccf624650 (patch)
tree7a51c8397aaffd62e9daad7cd15a348cb1e73167 /gcc/cp
parent68c77b544fd2779a86e740a469537a0beeaac68a (diff)
downloadgcc-1e6d0c169fdb66874b628c5faa94163ccf624650.tar.gz
/cp
2012-05-12 Paolo Carlini <paolo.carlini@oracle.com> * parser.c (struct cp_parser_expression_stack_entry): Add location_t field. (cp_parser_binary_expression): Rework to always update at the same time tree_type and loc. * call.c (print_z_candidate): Add location_t parameter. (print_z_candidates, convert_like_real, joust): Adjust. /testsuite 2012-05-12 Paolo Carlini <paolo.carlini@oracle.com> * g++.dg/parse/error47.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187424 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/call.c46
-rw-r--r--gcc/cp/parser.c81
3 files changed, 75 insertions, 61 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a36aaf6508d..bf9dc573547 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2012-05-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * parser.c (struct cp_parser_expression_stack_entry): Add location_t
+ field.
+ (cp_parser_binary_expression): Rework to always update at the same
+ time tree_type and loc.
+ * call.c (print_z_candidate): Add location_t parameter.
+ (print_z_candidates, convert_like_real, joust): Adjust.
+
2012-05-11 Alexandre Oliva <aoliva@redhat.com>
PR c++/53209
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 53ff78bf9ef..8497bfa3cb4 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -163,7 +163,7 @@ static void op_error (location_t, enum tree_code, enum tree_code, tree,
tree, tree, bool);
static struct z_candidate *build_user_type_conversion_1 (tree, tree, int,
tsubst_flags_t);
-static void print_z_candidate (const char *, struct z_candidate *);
+static void print_z_candidate (location_t, const char *, struct z_candidate *);
static void print_z_candidates (location_t, struct z_candidate *);
static tree build_this (tree);
static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
@@ -3159,36 +3159,38 @@ print_arity_information (location_t loc, unsigned int have, unsigned int want)
life simpler in print_z_candidates and for the translators. */
static void
-print_z_candidate (const char *msgstr, struct z_candidate *candidate)
+print_z_candidate (location_t loc, const char *msgstr,
+ struct z_candidate *candidate)
{
const char *msg = (msgstr == NULL
? ""
: ACONCAT ((msgstr, " ", NULL)));
- location_t loc = location_of (candidate->fn);
+ location_t cloc = location_of (candidate->fn);
if (TREE_CODE (candidate->fn) == IDENTIFIER_NODE)
{
+ cloc = loc;
if (candidate->num_convs == 3)
- inform (input_location, "%s%D(%T, %T, %T) <built-in>", msg, candidate->fn,
+ inform (cloc, "%s%D(%T, %T, %T) <built-in>", msg, candidate->fn,
candidate->convs[0]->type,
candidate->convs[1]->type,
candidate->convs[2]->type);
else if (candidate->num_convs == 2)
- inform (input_location, "%s%D(%T, %T) <built-in>", msg, candidate->fn,
+ inform (cloc, "%s%D(%T, %T) <built-in>", msg, candidate->fn,
candidate->convs[0]->type,
candidate->convs[1]->type);
else
- inform (input_location, "%s%D(%T) <built-in>", msg, candidate->fn,
+ inform (cloc, "%s%D(%T) <built-in>", msg, candidate->fn,
candidate->convs[0]->type);
}
else if (TYPE_P (candidate->fn))
- inform (loc, "%s%T <conversion>", msg, candidate->fn);
+ inform (cloc, "%s%T <conversion>", msg, candidate->fn);
else if (candidate->viable == -1)
- inform (loc, "%s%#D <near match>", msg, candidate->fn);
+ inform (cloc, "%s%#D <near match>", msg, candidate->fn);
else if (DECL_DELETED_FN (STRIP_TEMPLATE (candidate->fn)))
- inform (loc, "%s%#D <deleted>", msg, candidate->fn);
+ inform (cloc, "%s%#D <deleted>", msg, candidate->fn);
else
- inform (loc, "%s%#D", msg, candidate->fn);
+ inform (cloc, "%s%#D", msg, candidate->fn);
/* Give the user some information about why this candidate failed. */
if (candidate->reason != NULL)
{
@@ -3197,23 +3199,23 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
switch (r->code)
{
case rr_arity:
- print_arity_information (loc, r->u.arity.actual,
+ print_arity_information (cloc, r->u.arity.actual,
r->u.arity.expected);
break;
case rr_arg_conversion:
- print_conversion_rejection (loc, &r->u.conversion);
+ print_conversion_rejection (cloc, &r->u.conversion);
break;
case rr_bad_arg_conversion:
- print_conversion_rejection (loc, &r->u.bad_conversion);
+ print_conversion_rejection (cloc, &r->u.bad_conversion);
break;
case rr_explicit_conversion:
- inform (loc, " return type %qT of explicit conversion function "
+ inform (cloc, " return type %qT of explicit conversion function "
"cannot be converted to %qT with a qualification "
"conversion", r->u.conversion.from_type,
r->u.conversion.to_type);
break;
case rr_template_conversion:
- inform (loc, " conversion from return type %qT of template "
+ inform (cloc, " conversion from return type %qT of template "
"conversion function specialization to %qT is not an "
"exact match", r->u.conversion.from_type,
r->u.conversion.to_type);
@@ -3224,12 +3226,12 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
them here. */
if (r->u.template_unification.tmpl == NULL_TREE)
{
- inform (loc, " substitution of deduced template arguments "
+ inform (cloc, " substitution of deduced template arguments "
"resulted in errors seen above");
break;
}
/* Re-run template unification with diagnostics. */
- inform (loc, " template argument deduction/substitution failed:");
+ inform (cloc, " template argument deduction/substitution failed:");
fn_type_unification (r->u.template_unification.tmpl,
r->u.template_unification.explicit_targs,
r->u.template_unification.targs,
@@ -3247,7 +3249,7 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
tf_warning_or_error);
break;
case rr_invalid_copy:
- inform (loc,
+ inform (cloc,
" a constructor taking a single argument of its own "
"class type is invalid");
break;
@@ -3312,7 +3314,7 @@ print_z_candidates (location_t loc, struct z_candidate *candidates)
inform_n (loc, n_candidates, "candidate is:", "candidates are:");
for (; candidates; candidates = candidates->next)
- print_z_candidate (NULL, candidates);
+ print_z_candidate (loc, NULL, candidates);
}
/* USER_SEQ is a user-defined conversion sequence, beginning with a
@@ -5678,7 +5680,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
{
permerror (loc, "invalid user-defined conversion "
"from %qT to %qT", TREE_TYPE (expr), totype);
- print_z_candidate ("candidate is:", t->cand);
+ print_z_candidate (loc, "candidate is:", t->cand);
expr = convert_like_real (t, expr, fn, argnum, 1,
/*issue_conversion_warnings=*/false,
/*c_cast_p=*/false,
@@ -8405,8 +8407,8 @@ tweak:
"ISO C++ says that these are ambiguous, even "
"though the worst conversion for the first is better than "
"the worst conversion for the second:");
- print_z_candidate (_("candidate 1:"), w);
- print_z_candidate (_("candidate 2:"), l);
+ print_z_candidate (input_location, _("candidate 1:"), w);
+ print_z_candidate (input_location, _("candidate 2:"), l);
}
else
add_warning (w, l);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 20597fddc8c..dc64fa1f62a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1621,6 +1621,8 @@ typedef struct cp_parser_expression_stack_entry
enum tree_code tree_type;
/* Precedence of the binary operation we are parsing. */
enum cp_parser_prec prec;
+ /* Location of the binary operation we are parsing. */
+ location_t loc;
} cp_parser_expression_stack_entry;
/* The stack for storing partial expressions. We only need NUM_PREC_VALUES
@@ -7275,30 +7277,33 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
{
cp_parser_expression_stack stack;
cp_parser_expression_stack_entry *sp = &stack[0];
- tree lhs, rhs;
+ cp_parser_expression_stack_entry current;
+ tree rhs;
cp_token *token;
- location_t loc;
- enum tree_code tree_type, lhs_type, rhs_type;
+ enum tree_code rhs_type;
enum cp_parser_prec new_prec, lookahead_prec;
tree overload;
/* Parse the first expression. */
- lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p, pidk);
- lhs_type = ERROR_MARK;
+ current.lhs = cp_parser_cast_expression (parser, /*address_p=*/false,
+ cast_p, pidk);
+ current.lhs_type = ERROR_MARK;
+ current.prec = prec;
for (;;)
{
/* Get an operator token. */
token = cp_lexer_peek_token (parser->lexer);
- loc = token->location;
if (warn_cxx0x_compat
&& token->type == CPP_RSHIFT
&& !parser->greater_than_is_operator_p)
{
- if (warning_at (loc, OPT_Wc__0x_compat, "%<>>%> operator is treated"
+ if (warning_at (token->location, OPT_Wc__0x_compat,
+ "%<>>%> operator is treated"
" as two right angle brackets in C++11"))
- inform (loc, "suggest parentheses around %<>>%> expression");
+ inform (token->location,
+ "suggest parentheses around %<>>%> expression");
}
new_prec = TOKEN_PRECEDENCE (token);
@@ -7310,7 +7315,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
- or, we found an operator which has lower priority. This is the case
where the recursive descent *ascends*, as in `3 * 4 + 5' after
parsing `3 * 4'. */
- if (new_prec <= prec)
+ if (new_prec <= current.prec)
{
if (sp == stack)
break;
@@ -7319,17 +7324,18 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
}
get_rhs:
- tree_type = binops_by_token[token->type].tree_type;
+ current.tree_type = binops_by_token[token->type].tree_type;
+ current.loc = token->location;
/* We used the operator token. */
cp_lexer_consume_token (parser->lexer);
/* For "false && x" or "true || x", x will never be executed;
disable warnings while evaluating it. */
- if (tree_type == TRUTH_ANDIF_EXPR)
- c_inhibit_evaluation_warnings += lhs == truthvalue_false_node;
- else if (tree_type == TRUTH_ORIF_EXPR)
- c_inhibit_evaluation_warnings += lhs == truthvalue_true_node;
+ if (current.tree_type == TRUTH_ANDIF_EXPR)
+ c_inhibit_evaluation_warnings += current.lhs == truthvalue_false_node;
+ else if (current.tree_type == TRUTH_ORIF_EXPR)
+ c_inhibit_evaluation_warnings += current.lhs == truthvalue_true_node;
/* Extract another operand. It may be the RHS of this expression
or the LHS of a new, higher priority expression. */
@@ -7347,14 +7353,11 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
expression. Since precedence levels on the stack are
monotonically increasing, we do not have to care about
stack overflows. */
- sp->prec = prec;
- sp->tree_type = tree_type;
- sp->lhs = lhs;
- sp->lhs_type = lhs_type;
- sp++;
- lhs = rhs;
- lhs_type = rhs_type;
- prec = new_prec;
+ *sp = current;
+ ++sp;
+ current.lhs = rhs;
+ current.lhs_type = rhs_type;
+ current.prec = new_prec;
new_prec = lookahead_prec;
goto get_rhs;
@@ -7367,20 +7370,17 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
the precedence of the higher level subexpression
(`PREC_ADDITIVE_EXPRESSION'). TOKEN is the CPP_PLUS token,
which will be used to actually build the additive expression. */
+ rhs = current.lhs;
+ rhs_type = current.lhs_type;
--sp;
- prec = sp->prec;
- tree_type = sp->tree_type;
- rhs = lhs;
- rhs_type = lhs_type;
- lhs = sp->lhs;
- lhs_type = sp->lhs_type;
+ current = *sp;
}
/* Undo the disabling of warnings done above. */
- if (tree_type == TRUTH_ANDIF_EXPR)
- c_inhibit_evaluation_warnings -= lhs == truthvalue_false_node;
- else if (tree_type == TRUTH_ORIF_EXPR)
- c_inhibit_evaluation_warnings -= lhs == truthvalue_true_node;
+ if (current.tree_type == TRUTH_ANDIF_EXPR)
+ c_inhibit_evaluation_warnings -= current.lhs == truthvalue_false_node;
+ else if (current.tree_type == TRUTH_ORIF_EXPR)
+ c_inhibit_evaluation_warnings -= current.lhs == truthvalue_true_node;
overload = NULL;
/* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type ==
@@ -7391,14 +7391,17 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
surrounded by parentheses.
*/
if (no_toplevel_fold_p
- && lookahead_prec <= prec
+ && lookahead_prec <= current.prec
&& sp == stack
- && TREE_CODE_CLASS (tree_type) == tcc_comparison)
- lhs = build2 (tree_type, boolean_type_node, lhs, rhs);
+ && TREE_CODE_CLASS (current.tree_type) == tcc_comparison)
+ current.lhs = build2 (current.tree_type, boolean_type_node,
+ current.lhs, rhs);
else
- lhs = build_x_binary_op (loc, tree_type, lhs, lhs_type, rhs, rhs_type,
- &overload, tf_warning_or_error);
- lhs_type = tree_type;
+ current.lhs = build_x_binary_op (current.loc, current.tree_type,
+ current.lhs, current.lhs_type,
+ rhs, rhs_type, &overload,
+ tf_warning_or_error);
+ current.lhs_type = current.tree_type;
/* If the binary operator required the use of an overloaded operator,
then this expression cannot be an integral constant-expression.
@@ -7412,7 +7415,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
return error_mark_node;
}
- return lhs;
+ return current.lhs;
}