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 %<*%>");
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);
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);
--- /dev/null
+/* PR c/32122 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+enum {a=1};
+void foo()
+{
+ goto *
+ a; /* { dg-error "computed goto must be pointer type" } */
+}
+
--- /dev/null
+/* 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; }
+