Commit 498ad15e by Paolo Carlini Committed by Paolo Carlini

parser.c (struct cp_parser_expression_stack_entry): Add location_t field.

/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.

From-SVN: r187424
parent 819dc461
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> 2012-05-11 Alexandre Oliva <aoliva@redhat.com>
PR c++/53209 PR c++/53209
......
...@@ -163,7 +163,7 @@ static void op_error (location_t, enum tree_code, enum tree_code, tree, ...@@ -163,7 +163,7 @@ static void op_error (location_t, enum tree_code, enum tree_code, tree,
tree, tree, bool); tree, tree, bool);
static struct z_candidate *build_user_type_conversion_1 (tree, tree, int, static struct z_candidate *build_user_type_conversion_1 (tree, tree, int,
tsubst_flags_t); 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 void print_z_candidates (location_t, struct z_candidate *);
static tree build_this (tree); static tree build_this (tree);
static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *); 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) ...@@ -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. */ life simpler in print_z_candidates and for the translators. */
static void 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 const char *msg = (msgstr == NULL
? "" ? ""
: ACONCAT ((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) if (TREE_CODE (candidate->fn) == IDENTIFIER_NODE)
{ {
cloc = loc;
if (candidate->num_convs == 3) 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[0]->type,
candidate->convs[1]->type, candidate->convs[1]->type,
candidate->convs[2]->type); candidate->convs[2]->type);
else if (candidate->num_convs == 2) 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[0]->type,
candidate->convs[1]->type); candidate->convs[1]->type);
else 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); candidate->convs[0]->type);
} }
else if (TYPE_P (candidate->fn)) 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) 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))) 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 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. */ /* Give the user some information about why this candidate failed. */
if (candidate->reason != NULL) if (candidate->reason != NULL)
{ {
...@@ -3197,23 +3199,23 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate) ...@@ -3197,23 +3199,23 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
switch (r->code) switch (r->code)
{ {
case rr_arity: case rr_arity:
print_arity_information (loc, r->u.arity.actual, print_arity_information (cloc, r->u.arity.actual,
r->u.arity.expected); r->u.arity.expected);
break; break;
case rr_arg_conversion: case rr_arg_conversion:
print_conversion_rejection (loc, &r->u.conversion); print_conversion_rejection (cloc, &r->u.conversion);
break; break;
case rr_bad_arg_conversion: case rr_bad_arg_conversion:
print_conversion_rejection (loc, &r->u.bad_conversion); print_conversion_rejection (cloc, &r->u.bad_conversion);
break; break;
case rr_explicit_conversion: 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 " "cannot be converted to %qT with a qualification "
"conversion", r->u.conversion.from_type, "conversion", r->u.conversion.from_type,
r->u.conversion.to_type); r->u.conversion.to_type);
break; break;
case rr_template_conversion: 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 " "conversion function specialization to %qT is not an "
"exact match", r->u.conversion.from_type, "exact match", r->u.conversion.from_type,
r->u.conversion.to_type); r->u.conversion.to_type);
...@@ -3224,12 +3226,12 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate) ...@@ -3224,12 +3226,12 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
them here. */ them here. */
if (r->u.template_unification.tmpl == NULL_TREE) 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"); "resulted in errors seen above");
break; break;
} }
/* Re-run template unification with diagnostics. */ /* 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, fn_type_unification (r->u.template_unification.tmpl,
r->u.template_unification.explicit_targs, r->u.template_unification.explicit_targs,
r->u.template_unification.targs, r->u.template_unification.targs,
...@@ -3247,7 +3249,7 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate) ...@@ -3247,7 +3249,7 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
tf_warning_or_error); tf_warning_or_error);
break; break;
case rr_invalid_copy: case rr_invalid_copy:
inform (loc, inform (cloc,
" a constructor taking a single argument of its own " " a constructor taking a single argument of its own "
"class type is invalid"); "class type is invalid");
break; break;
...@@ -3312,7 +3314,7 @@ print_z_candidates (location_t loc, struct z_candidate *candidates) ...@@ -3312,7 +3314,7 @@ print_z_candidates (location_t loc, struct z_candidate *candidates)
inform_n (loc, n_candidates, "candidate is:", "candidates are:"); inform_n (loc, n_candidates, "candidate is:", "candidates are:");
for (; candidates; candidates = candidates->next) 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 /* 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, ...@@ -5678,7 +5680,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
{ {
permerror (loc, "invalid user-defined conversion " permerror (loc, "invalid user-defined conversion "
"from %qT to %qT", TREE_TYPE (expr), totype); "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, expr = convert_like_real (t, expr, fn, argnum, 1,
/*issue_conversion_warnings=*/false, /*issue_conversion_warnings=*/false,
/*c_cast_p=*/false, /*c_cast_p=*/false,
...@@ -8405,8 +8407,8 @@ tweak: ...@@ -8405,8 +8407,8 @@ tweak:
"ISO C++ says that these are ambiguous, even " "ISO C++ says that these are ambiguous, even "
"though the worst conversion for the first is better than " "though the worst conversion for the first is better than "
"the worst conversion for the second:"); "the worst conversion for the second:");
print_z_candidate (_("candidate 1:"), w); print_z_candidate (input_location, _("candidate 1:"), w);
print_z_candidate (_("candidate 2:"), l); print_z_candidate (input_location, _("candidate 2:"), l);
} }
else else
add_warning (w, l); add_warning (w, l);
......
...@@ -1621,6 +1621,8 @@ typedef struct cp_parser_expression_stack_entry ...@@ -1621,6 +1621,8 @@ typedef struct cp_parser_expression_stack_entry
enum tree_code tree_type; enum tree_code tree_type;
/* Precedence of the binary operation we are parsing. */ /* Precedence of the binary operation we are parsing. */
enum cp_parser_prec prec; enum cp_parser_prec prec;
/* Location of the binary operation we are parsing. */
location_t loc;
} cp_parser_expression_stack_entry; } cp_parser_expression_stack_entry;
/* The stack for storing partial expressions. We only need NUM_PREC_VALUES /* 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, ...@@ -7275,30 +7277,33 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
{ {
cp_parser_expression_stack stack; cp_parser_expression_stack stack;
cp_parser_expression_stack_entry *sp = &stack[0]; cp_parser_expression_stack_entry *sp = &stack[0];
tree lhs, rhs; cp_parser_expression_stack_entry current;
tree rhs;
cp_token *token; cp_token *token;
location_t loc; enum tree_code rhs_type;
enum tree_code tree_type, lhs_type, rhs_type;
enum cp_parser_prec new_prec, lookahead_prec; enum cp_parser_prec new_prec, lookahead_prec;
tree overload; tree overload;
/* Parse the first expression. */ /* Parse the first expression. */
lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p, pidk); current.lhs = cp_parser_cast_expression (parser, /*address_p=*/false,
lhs_type = ERROR_MARK; cast_p, pidk);
current.lhs_type = ERROR_MARK;
current.prec = prec;
for (;;) for (;;)
{ {
/* Get an operator token. */ /* Get an operator token. */
token = cp_lexer_peek_token (parser->lexer); token = cp_lexer_peek_token (parser->lexer);
loc = token->location;
if (warn_cxx0x_compat if (warn_cxx0x_compat
&& token->type == CPP_RSHIFT && token->type == CPP_RSHIFT
&& !parser->greater_than_is_operator_p) && !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")) " 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); new_prec = TOKEN_PRECEDENCE (token);
...@@ -7310,7 +7315,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, ...@@ -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 - or, we found an operator which has lower priority. This is the case
where the recursive descent *ascends*, as in `3 * 4 + 5' after where the recursive descent *ascends*, as in `3 * 4 + 5' after
parsing `3 * 4'. */ parsing `3 * 4'. */
if (new_prec <= prec) if (new_prec <= current.prec)
{ {
if (sp == stack) if (sp == stack)
break; break;
...@@ -7319,17 +7324,18 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, ...@@ -7319,17 +7324,18 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
} }
get_rhs: 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. */ /* We used the operator token. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* For "false && x" or "true || x", x will never be executed; /* For "false && x" or "true || x", x will never be executed;
disable warnings while evaluating it. */ disable warnings while evaluating it. */
if (tree_type == TRUTH_ANDIF_EXPR) if (current.tree_type == TRUTH_ANDIF_EXPR)
c_inhibit_evaluation_warnings += lhs == truthvalue_false_node; c_inhibit_evaluation_warnings += current.lhs == truthvalue_false_node;
else if (tree_type == TRUTH_ORIF_EXPR) else if (current.tree_type == TRUTH_ORIF_EXPR)
c_inhibit_evaluation_warnings += lhs == truthvalue_true_node; c_inhibit_evaluation_warnings += current.lhs == truthvalue_true_node;
/* Extract another operand. It may be the RHS of this expression /* Extract another operand. It may be the RHS of this expression
or the LHS of a new, higher priority expression. */ or the LHS of a new, higher priority expression. */
...@@ -7347,14 +7353,11 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, ...@@ -7347,14 +7353,11 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
expression. Since precedence levels on the stack are expression. Since precedence levels on the stack are
monotonically increasing, we do not have to care about monotonically increasing, we do not have to care about
stack overflows. */ stack overflows. */
sp->prec = prec; *sp = current;
sp->tree_type = tree_type; ++sp;
sp->lhs = lhs; current.lhs = rhs;
sp->lhs_type = lhs_type; current.lhs_type = rhs_type;
sp++; current.prec = new_prec;
lhs = rhs;
lhs_type = rhs_type;
prec = new_prec;
new_prec = lookahead_prec; new_prec = lookahead_prec;
goto get_rhs; goto get_rhs;
...@@ -7367,20 +7370,17 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, ...@@ -7367,20 +7370,17 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
the precedence of the higher level subexpression the precedence of the higher level subexpression
(`PREC_ADDITIVE_EXPRESSION'). TOKEN is the CPP_PLUS token, (`PREC_ADDITIVE_EXPRESSION'). TOKEN is the CPP_PLUS token,
which will be used to actually build the additive expression. */ which will be used to actually build the additive expression. */
rhs = current.lhs;
rhs_type = current.lhs_type;
--sp; --sp;
prec = sp->prec; current = *sp;
tree_type = sp->tree_type;
rhs = lhs;
rhs_type = lhs_type;
lhs = sp->lhs;
lhs_type = sp->lhs_type;
} }
/* Undo the disabling of warnings done above. */ /* Undo the disabling of warnings done above. */
if (tree_type == TRUTH_ANDIF_EXPR) if (current.tree_type == TRUTH_ANDIF_EXPR)
c_inhibit_evaluation_warnings -= lhs == truthvalue_false_node; c_inhibit_evaluation_warnings -= current.lhs == truthvalue_false_node;
else if (tree_type == TRUTH_ORIF_EXPR) else if (current.tree_type == TRUTH_ORIF_EXPR)
c_inhibit_evaluation_warnings -= lhs == truthvalue_true_node; c_inhibit_evaluation_warnings -= current.lhs == truthvalue_true_node;
overload = NULL; overload = NULL;
/* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type == /* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type ==
...@@ -7391,14 +7391,17 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, ...@@ -7391,14 +7391,17 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
surrounded by parentheses. surrounded by parentheses.
*/ */
if (no_toplevel_fold_p if (no_toplevel_fold_p
&& lookahead_prec <= prec && lookahead_prec <= current.prec
&& sp == stack && sp == stack
&& TREE_CODE_CLASS (tree_type) == tcc_comparison) && TREE_CODE_CLASS (current.tree_type) == tcc_comparison)
lhs = build2 (tree_type, boolean_type_node, lhs, rhs); current.lhs = build2 (current.tree_type, boolean_type_node,
current.lhs, rhs);
else else
lhs = build_x_binary_op (loc, tree_type, lhs, lhs_type, rhs, rhs_type, current.lhs = build_x_binary_op (current.loc, current.tree_type,
&overload, tf_warning_or_error); current.lhs, current.lhs_type,
lhs_type = tree_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, /* If the binary operator required the use of an overloaded operator,
then this expression cannot be an integral constant-expression. then this expression cannot be an integral constant-expression.
...@@ -7412,7 +7415,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, ...@@ -7412,7 +7415,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
return error_mark_node; return error_mark_node;
} }
return lhs; return current.lhs;
} }
......
2012-05-12 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/parse/error47.C: New.
2012-05-11 Thomas Koenig <tkoenig@gcc.gnu.org> 2012-05-11 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/52537 PR fortran/52537
......
struct T { };
T foo();
void bar(int a, int b)
{
if (foo() && a < b) // { dg-error "13:no match for 'operator&&'" }
;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment