It's not allowed to do a goto into an expression statement. For exemple, it's not well defined what should happen if such an expression is not evaluated because unnneded and optimized away at expand time. For such situations GCC issues an error, clang doesn't and produces a valid IR. Spare produces an invalid IR with branches to unexisting BBs. Fix this by: *) detecting this situation at evaluation time *) issue an error *) mark the function to not be linearized. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- evaluate.c | 9 +++++++++ validation/label-stmt-expr1.c | 1 - validation/linear/goto-and-expr-stmt0.c | 9 +++++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/evaluate.c b/evaluate.c index 99a9ee72d11f..2b845a301d6b 100644 --- a/evaluate.c +++ b/evaluate.c @@ -42,6 +42,7 @@ #include "symbol.h" #include "target.h" #include "expression.h" +#include "scope.h" struct symbol *current_fn; @@ -3751,6 +3752,14 @@ static void evaluate_goto_statement(struct statement *stmt) sparse_error(stmt->pos, "label '%s' was not declared", show_ident(label->ident)); current_fn->bogus_linear = 1; } + if (label->namespace == NS_LABEL && label->stmt) { + if (is_in_scope(label->label_scope, stmt->goto_scope)) + return; + sparse_error(stmt->pos, "goto into statement expression"); + info(label->stmt->pos," label '%s' is defined here", + show_ident(label->ident)); + current_fn->bogus_linear = 1; + } if (label->namespace == NS_NONE) current_fn->bogus_linear = 1; } diff --git a/validation/label-stmt-expr1.c b/validation/label-stmt-expr1.c index 47ba54ae7305..f4f178c9d951 100644 --- a/validation/label-stmt-expr1.c +++ b/validation/label-stmt-expr1.c @@ -19,7 +19,6 @@ l: /* * check-name: label-stmt-expr1 - * check-known-to-fail * * check-error-start label-stmt-expr1.c:3:9: error: goto into statement expression diff --git a/validation/linear/goto-and-expr-stmt0.c b/validation/linear/goto-and-expr-stmt0.c index 548813531779..c6b6621a6a81 100644 --- a/validation/linear/goto-and-expr-stmt0.c +++ b/validation/linear/goto-and-expr-stmt0.c @@ -20,9 +20,14 @@ a: /* * check-name: goto-and-expr-stmt0 * check-command: test-linearize -Wno-decl $file - * check-known-to-fail * * check-output-ignore * check-output-excludes: END - * check-error-ignore + * + * check-error-start +linear/goto-and-expr-stmt0.c:3:9: error: goto into statement expression +linear/goto-and-expr-stmt0.c:5:1: label 'inside' is defined here +linear/goto-and-expr-stmt0.c:17:9: error: goto into statement expression +linear/goto-and-expr-stmt0.c:14:1: label 'a' is defined here + * check-error-end */ -- 2.26.0