On Mon, Sep 20, 2021 at 12:15 AM apinski--- via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> From: Andrew Pinski <apin...@marvell.com>
>
> So GCC has always accepted non-pointer types in computed gotos but
> that was wrong based on the documentation:
> Any expression of type void * is allowed.
>
> So this fixes the problem by requiring the type to
> be a pointer type.
>
> OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
>
>         PR c/32122
>
> gcc/c/ChangeLog:
>
>         * c-parser.c (c_parser_statement_after_labels): Pass
>         the c_expr instead of the tree to c_finish_goto_ptr.
>         * c-typeck.c (c_finish_goto_ptr): Change the second
>         argument type to c_expr.
>         * c-tree.h (c_finish_goto_ptr): Likewise.
>         Error out if the expression was not of a pointer type.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/comp-goto-5.c: New test.
>         * gcc.dg/comp-goto-6.c: New test.
> ---
>  gcc/c/c-parser.c                   |  2 +-
>  gcc/c/c-tree.h                     |  2 +-
>  gcc/c/c-typeck.c                   | 11 ++++++++++-
>  gcc/testsuite/gcc.dg/comp-goto-5.c | 11 +++++++++++
>  gcc/testsuite/gcc.dg/comp-goto-6.c |  6 ++++++
>  5 files changed, 29 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/comp-goto-5.c
>  create mode 100644 gcc/testsuite/gcc.dg/comp-goto-6.c
>
> diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
> index fb1399e300d..bcd8a05489f 100644
> --- a/gcc/c/c-parser.c
> +++ b/gcc/c/c-parser.c
> @@ -6141,7 +6141,7 @@ c_parser_statement_after_labels (c_parser *parser, bool 
> *if_p,
>               c_parser_consume_token (parser);
>               val = c_parser_expression (parser);
>               val = convert_lvalue_to_rvalue (loc, val, false, true);
> -             stmt = c_finish_goto_ptr (loc, val.value);
> +             stmt = c_finish_goto_ptr (loc, val);
>             }
>           else
>             c_parser_error (parser, "expected identifier or %<*%>");
> diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
> index d50d0cb7f2d..a046c6b0926 100644
> --- a/gcc/c/c-tree.h
> +++ b/gcc/c/c-tree.h
> @@ -746,7 +746,7 @@ extern tree c_finish_expr_stmt (location_t, tree);
>  extern tree c_finish_return (location_t, tree, tree);
>  extern tree c_finish_bc_stmt (location_t, tree, bool);
>  extern tree c_finish_goto_label (location_t, tree);
> -extern tree c_finish_goto_ptr (location_t, tree);
> +extern tree c_finish_goto_ptr (location_t, c_expr val);
>  extern tree c_expr_to_decl (tree, bool *, bool *);
>  extern tree c_finish_omp_construct (location_t, enum tree_code, tree, tree);
>  extern tree c_finish_oacc_data (location_t, tree, tree);
> diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
> index 49d1bb067a0..b472e448011 100644
> --- a/gcc/c/c-typeck.c
> +++ b/gcc/c/c-typeck.c
> @@ -10783,10 +10783,19 @@ c_finish_goto_label (location_t loc, tree label)
>     the GOTO.  */
>
>  tree
> -c_finish_goto_ptr (location_t loc, tree expr)
> +c_finish_goto_ptr (location_t loc, c_expr val)
>  {
> +  tree expr = val.value;
>    tree t;
>    pedwarn (loc, OPT_Wpedantic, "ISO C forbids %<goto *expr;%>");
> +  if (expr != error_mark_node
> +      && !POINTER_TYPE_P (TREE_TYPE (expr))
> +      && !null_pointer_constant_p (expr))
> +    {
> +      error_at (val.get_location (),
> +               "computed goto must be pointer type");
> +      expr = build_zero_cst (ptr_type_node);
> +    }
>    expr = c_fully_fold (expr, false, NULL);
>    expr = convert (ptr_type_node, expr);
>    t = build1 (GOTO_EXPR, void_type_node, expr);
> diff --git a/gcc/testsuite/gcc.dg/comp-goto-5.c 
> b/gcc/testsuite/gcc.dg/comp-goto-5.c
> new file mode 100644
> index 00000000000..d487729a5d4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/comp-goto-5.c
> @@ -0,0 +1,11 @@
> +/* PR c/32122 */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +enum {a=1};
> +void foo()
> +{
> +  goto *
> +        a; /* { dg-error "computed goto must be pointer type" } */
> +}
> +
> diff --git a/gcc/testsuite/gcc.dg/comp-goto-6.c 
> b/gcc/testsuite/gcc.dg/comp-goto-6.c
> new file mode 100644
> index 00000000000..497f6cd76ca
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/comp-goto-6.c
> @@ -0,0 +1,6 @@
> +/* PR c/32122 */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +void foo(void *a) { goto *10000000; } /* { dg-error "computed goto must be 
> pointer type" } */
> +void foo1(void *a) { goto *a; }
> +
> --
> 2.17.1
>

Maybe add to one of the testcases a test to ensure that the
cast-to-void workaround works successfully?
e.g.
void foo2(void *a) { goto *(void *)10000000; } /* { dg-bogus "computed
goto must be pointer type" } */

Reply via email to