diff options
author | Andrew Pinski <apinski@marvell.com> | 2021-09-17 04:59:03 +0000 |
---|---|---|
committer | Andrew Pinski <apinski@marvell.com> | 2021-09-28 20:01:14 +0000 |
commit | e12f66d96fe41c8ef8a0d01b6a8394cd6bce3978 (patch) | |
tree | fa2b27371e00155ebf3f6ee89a78f8cee7ffb4a1 /gcc | |
parent | c44c5f3d9f46705a262911c2098c1568d7e8ac2d (diff) | |
download | gcc-e12f66d96fe41c8ef8a0d01b6a8394cd6bce3978.zip gcc-e12f66d96fe41c8ef8a0d01b6a8394cd6bce3978.tar.gz gcc-e12f66d96fe41c8ef8a0d01b6a8394cd6bce3978.tar.bz2 |
c: [PR32122] Require pointer types for computed gotos
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c/c-parser.c | 2 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 2 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/comp-goto-5.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/comp-goto-6.c | 6 |
5 files changed, 29 insertions, 3 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index fa29d2c..21ff25d 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 d50d0cb..a046c6b 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 49d1bb0..b472e44 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 0000000..d487729 --- /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 0000000..497f6cd --- /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; } + |