* [PATCH] PR c/71171: Fix uninitialized source_range in c_parser_postfix_expression
@ 2016-05-19 0:42 David Malcolm
2016-05-19 17:22 ` Jeff Law
0 siblings, 1 reply; 2+ messages in thread
From: David Malcolm @ 2016-05-19 0:42 UTC (permalink / raw)
To: gcc-patches; +Cc: David Malcolm
PR c/71171 reports yet another instance of the src_range of a
c_expr being used without initialization. Investigation shows
that this was due to error-handling, where the "value" field of
a c_expr is set to error_mark_node without touching the
src_range, leading to complaints from valgrind.
This seems to be a common mistake, so this patch introduces a
new method, c_expr::set_error, which sets the value to
error_mark_node whilst initializing the src_range to
UNKNOWN_LOCATION.
This fixes the valgrind issue seen in PR c/71171, along with various
similar issues seen when running the testsuite using the checker
patch I posted here:
https://gcc.gnu.org/ml/gcc-patches/2015-12/msg00887.html
(this checker still doesn't fully work yet, but it seems to be good
for easily detecting these issues without needing Valgrind).
Successfully bootstrapped®rtested on x86_64-pc-linux-gnu.
OK for trunk and for gcc-6-branch?
gcc/c/ChangeLog:
PR c/71171
* c-parser.c (c_parser_generic_selection): Use c_expr::set_error
in error-handling.
(c_parser_postfix_expression): Likewise.
* c-tree.h (c_expr::set_error): New method.
* c-typeck.c (parser_build_binary_op): In error-handling, ensure
that result's range is initialized.
---
gcc/c/c-parser.c | 72 ++++++++++++++++++++++++++++----------------------------
gcc/c/c-tree.h | 9 +++++++
gcc/c/c-typeck.c | 7 +++++-
3 files changed, 51 insertions(+), 37 deletions(-)
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 5703989..5edeb64 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -7200,7 +7200,7 @@ c_parser_generic_selection (c_parser *parser)
error_expr.original_code = ERROR_MARK;
error_expr.original_type = NULL;
- error_expr.value = error_mark_node;
+ error_expr.set_error ();
matched_assoc.type_location = UNKNOWN_LOCATION;
matched_assoc.type = NULL_TREE;
matched_assoc.expression = error_expr;
@@ -7511,13 +7511,13 @@ c_parser_postfix_expression (c_parser *parser)
gcc_assert (c_dialect_objc ());
if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
if (c_parser_next_token_is_not (parser, CPP_NAME))
{
c_parser_error (parser, "expected identifier");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
c_token *component_tok = c_parser_peek_token (parser);
@@ -7531,7 +7531,7 @@ c_parser_postfix_expression (c_parser *parser)
}
default:
c_parser_error (parser, "expected expression");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
break;
@@ -7553,7 +7553,7 @@ c_parser_postfix_expression (c_parser *parser)
parser->error = true;
c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
stmt = c_begin_stmt_expr ();
@@ -7582,7 +7582,7 @@ c_parser_postfix_expression (c_parser *parser)
"expected %<)%>");
if (type_name == NULL)
{
- expr.value = error_mark_node;
+ expr.set_error ();
}
else
expr = c_parser_postfix_expression_after_paren_type (parser,
@@ -7642,7 +7642,7 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
e1 = c_parser_expr_no_commas (parser, NULL);
@@ -7651,7 +7651,7 @@ c_parser_postfix_expression (c_parser *parser)
if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
loc = c_parser_peek_token (parser)->location;
@@ -7661,7 +7661,7 @@ c_parser_postfix_expression (c_parser *parser)
"expected %<)%>");
if (t1 == NULL)
{
- expr.value = error_mark_node;
+ expr.set_error ();
}
else
{
@@ -7683,7 +7683,7 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
t1 = c_parser_type_name (parser);
@@ -7694,7 +7694,7 @@ c_parser_postfix_expression (c_parser *parser)
if (parser->error)
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7783,7 +7783,7 @@ c_parser_postfix_expression (c_parser *parser)
&cexpr_list, true,
&close_paren_loc))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7791,7 +7791,7 @@ c_parser_postfix_expression (c_parser *parser)
{
error_at (loc, "wrong number of arguments to "
"%<__builtin_choose_expr%>");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7816,25 +7816,25 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
t1 = c_parser_type_name (parser);
if (t1 == NULL)
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
t2 = c_parser_type_name (parser);
if (t2 == NULL)
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
{
@@ -7846,7 +7846,7 @@ c_parser_postfix_expression (c_parser *parser)
e2 = groktypename (t2, NULL, NULL);
if (e1 == error_mark_node || e2 == error_mark_node)
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7871,14 +7871,14 @@ c_parser_postfix_expression (c_parser *parser)
&cexpr_list, false,
&close_paren_loc))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
if (vec_safe_length (cexpr_list) != 2)
{
error_at (loc, "wrong number of arguments to "
"%<__builtin_call_with_static_chain%>");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7913,7 +7913,7 @@ c_parser_postfix_expression (c_parser *parser)
&cexpr_list, false,
&close_paren_loc))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7921,7 +7921,7 @@ c_parser_postfix_expression (c_parser *parser)
{
error_at (loc, "wrong number of arguments to "
"%<__builtin_complex%>");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7943,7 +7943,7 @@ c_parser_postfix_expression (c_parser *parser)
{
error_at (loc, "%<__builtin_complex%> operand "
"not of real binary floating-point type");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
@@ -7951,7 +7951,7 @@ c_parser_postfix_expression (c_parser *parser)
{
error_at (loc,
"%<__builtin_complex%> operands of different types");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
pedwarn_c90 (loc, OPT_Wpedantic,
@@ -7977,7 +7977,7 @@ c_parser_postfix_expression (c_parser *parser)
&cexpr_list, false,
&close_paren_loc))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -8000,7 +8000,7 @@ c_parser_postfix_expression (c_parser *parser)
{
error_at (loc, "wrong number of arguments to "
"%<__builtin_shuffle%>");
- expr.value = error_mark_node;
+ expr.set_error ();
}
set_c_expr_source_range (&expr, loc, close_paren_loc);
break;
@@ -8010,7 +8010,7 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
{
@@ -8027,14 +8027,14 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
if (c_parser_next_token_is_not (parser, CPP_NAME))
{
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
{
@@ -8053,13 +8053,13 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
t1 = c_parser_type_name (parser);
if (t1 == NULL)
{
- expr.value = error_mark_node;
+ expr.set_error ();
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
break;
}
@@ -8082,7 +8082,7 @@ c_parser_postfix_expression (c_parser *parser)
error_at (loc, "-fcilkplus must be enabled to use "
"%<_Cilk_spawn%>");
expr = c_parser_cast_expression (parser, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
}
else if (c_parser_peek_token (parser)->keyword == RID_CILK_SPAWN)
{
@@ -8101,7 +8101,7 @@ c_parser_postfix_expression (c_parser *parser)
break;
default:
c_parser_error (parser, "expected expression");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
break;
@@ -8122,7 +8122,7 @@ c_parser_postfix_expression (c_parser *parser)
/* Else fall through to report error. */
default:
c_parser_error (parser, "expected expression");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
return c_parser_postfix_expression_after_primary
@@ -8337,7 +8337,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
else
{
c_parser_error (parser, "expected identifier");
- expr.value = error_mark_node;
+ expr.set_error ();
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
return expr;
@@ -8369,7 +8369,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
else
{
c_parser_error (parser, "expected identifier");
- expr.value = error_mark_node;
+ expr.set_error ();
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
return expr;
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index d9c4c5d..a00882a 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -169,6 +169,15 @@ struct c_expr
of this expression. */
location_t get_start () const { return src_range.m_start; }
location_t get_finish () const { return src_range.m_finish; }
+
+ /* Set the value to error_mark_node whilst ensuring that src_range
+ is initialized. */
+ void set_error ()
+ {
+ value = error_mark_node;
+ src_range.m_start = UNKNOWN_LOCATION;
+ src_range.m_finish = UNKNOWN_LOCATION;
+ }
};
/* Type alias for struct c_expr. This allows to use the structure
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 8405c3d..390959f 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -3533,7 +3533,12 @@ parser_build_binary_op (location_t location, enum tree_code code,
result.original_type = NULL;
if (TREE_CODE (result.value) == ERROR_MARK)
- return result;
+ {
+ set_c_expr_source_range (&result,
+ arg1.get_start (),
+ arg2.get_finish ());
+ return result;
+ }
if (location != UNKNOWN_LOCATION)
protected_set_expr_location (result.value, location);
--
1.8.5.3
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] PR c/71171: Fix uninitialized source_range in c_parser_postfix_expression
2016-05-19 0:42 [PATCH] PR c/71171: Fix uninitialized source_range in c_parser_postfix_expression David Malcolm
@ 2016-05-19 17:22 ` Jeff Law
0 siblings, 0 replies; 2+ messages in thread
From: Jeff Law @ 2016-05-19 17:22 UTC (permalink / raw)
To: David Malcolm, gcc-patches
On 05/18/2016 07:08 PM, David Malcolm wrote:
> PR c/71171 reports yet another instance of the src_range of a
> c_expr being used without initialization. Investigation shows
> that this was due to error-handling, where the "value" field of
> a c_expr is set to error_mark_node without touching the
> src_range, leading to complaints from valgrind.
>
> This seems to be a common mistake, so this patch introduces a
> new method, c_expr::set_error, which sets the value to
> error_mark_node whilst initializing the src_range to
> UNKNOWN_LOCATION.
>
> This fixes the valgrind issue seen in PR c/71171, along with various
> similar issues seen when running the testsuite using the checker
> patch I posted here:
> https://gcc.gnu.org/ml/gcc-patches/2015-12/msg00887.html
> (this checker still doesn't fully work yet, but it seems to be good
> for easily detecting these issues without needing Valgrind).
>
> Successfully bootstrapped®rtested on x86_64-pc-linux-gnu.
>
> OK for trunk and for gcc-6-branch?
>
> gcc/c/ChangeLog:
> PR c/71171
> * c-parser.c (c_parser_generic_selection): Use c_expr::set_error
> in error-handling.
> (c_parser_postfix_expression): Likewise.
> * c-tree.h (c_expr::set_error): New method.
> * c-typeck.c (parser_build_binary_op): In error-handling, ensure
> that result's range is initialized.
OK.
jeff
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-05-19 17:22 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-19 0:42 [PATCH] PR c/71171: Fix uninitialized source_range in c_parser_postfix_expression David Malcolm
2016-05-19 17:22 ` Jeff Law
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).