diff --git a/compiler/src/dmd/parse.d b/compiler/src/dmd/parse.d index 121f9900f2..5c5cc7f5b7 100644 --- a/compiler/src/dmd/parse.d +++ b/compiler/src/dmd/parse.d @@ -1041,6 +1041,30 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer nextToken(); continue; + // The following are all errors, the cases are just for better error messages than the default case + case TOK.return_: + case TOK.goto_: + case TOK.break_: + case TOK.continue_: + error("`%s` statement must be inside function scope", token.toChars()); + goto Lerror; + case TOK.asm_: + case TOK.do_: + case TOK.for_: + case TOK.foreach_: + case TOK.foreach_reverse_: + case TOK.if_: + case TOK.switch_: + case TOK.try_: + case TOK.while_: + error("`%s` statement must be inside function scope", token.toChars()); + if (peekNext() == TOK.leftParenthesis || peekNext() == TOK.leftCurly) + { + parseStatement(0); + s = null; + continue; + } + goto Lerror; default: error("declaration expected, not `%s`", token.toChars()); Lerror: @@ -1504,28 +1528,26 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer if (token.value != TOK.identifier) { error("identifier expected following `template`"); - goto Lerr; + return null; } id = token.ident; nextToken(); tpl = parseTemplateParameterList(); if (!tpl) - goto Lerr; + return null; constraint = parseConstraint(); if (token.value != TOK.leftCurly) { error("`{` expected after template parameter list, not `%s`", token.toChars()); /* } */ - goto Lerr; + nextToken(); + return null; } decldefs = parseBlock(null); tempdecl = new AST.TemplateDeclaration(loc, id, tpl, constraint, decldefs, ismixin); return tempdecl; - - Lerr: - return null; } /****************************************** @@ -4571,6 +4593,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer default: error("semicolon expected to close `alias` declaration, not `%s`", token.toChars()); + nextToken(); break; } } @@ -5016,6 +5039,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer default: error("semicolon expected to close `alias` declaration, not `%s`", token.toChars()); + nextToken(); break; } break; @@ -5356,9 +5380,14 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer error("template constraint must follow parameter lists and attributes"); else error("cannot use function constraints for non-template functions. Use `static if` instead"); + + parseConstraint(); } else + { error("semicolon expected following function declaration, not `%s`", token.toChars()); + nextToken(); + } } break; } diff --git a/compiler/test/fail_compilation/code_global_scope.d b/compiler/test/fail_compilation/code_global_scope.d new file mode 100644 index 0000000000..4db84c02e7 --- /dev/null +++ b/compiler/test/fail_compilation/code_global_scope.d @@ -0,0 +1,26 @@ +/** +TEST_OUTPUT: +--- +fail_compilation/code_global_scope.d(18): Error: `switch` statement must be inside function scope +fail_compilation/code_global_scope.d(19): Error: `do` statement must be inside function scope +fail_compilation/code_global_scope.d(20): Error: `foreach` statement must be inside function scope +fail_compilation/code_global_scope.d(21): Error: `while` statement must be inside function scope +fail_compilation/code_global_scope.d(22): Error: `if` statement must be inside function scope +fail_compilation/code_global_scope.d(23): Error: `return` statement must be inside function scope +fail_compilation/code_global_scope.d(24): Error: `goto` statement must be inside function scope +fail_compilation/code_global_scope.d(25): Error: `continue` statement must be inside function scope +fail_compilation/code_global_scope.d(26): Error: `break` statement must be inside function scope +--- +*/ + + + +switch s; +do d; +foreach (i; 0 .. 4) {} +while (x) {} +if (y) {} +return 0; +goto A; +continue B; +break; diff --git a/compiler/test/fail_compilation/diag_template_alias.d b/compiler/test/fail_compilation/diag_template_alias.d index 151bb42657..fd17852f6b 100644 --- a/compiler/test/fail_compilation/diag_template_alias.d +++ b/compiler/test/fail_compilation/diag_template_alias.d @@ -4,7 +4,7 @@ TEST_OUTPUT: fail_compilation/diag_template_alias.d(1): Error: identifier expected for template `alias` parameter fail_compilation/diag_template_alias.d(1): Error: found `alias` when expecting `(` fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration, not `(` -fail_compilation/diag_template_alias.d(1): Error: declaration expected, not `(` +fail_compilation/diag_template_alias.d(1): Error: declaration expected, not `)` --- */ #line 1 diff --git a/compiler/test/fail_compilation/diag_template_this.d b/compiler/test/fail_compilation/diag_template_this.d index 25de03ce19..d4250f77e3 100644 --- a/compiler/test/fail_compilation/diag_template_this.d +++ b/compiler/test/fail_compilation/diag_template_this.d @@ -4,7 +4,7 @@ TEST_OUTPUT: fail_compilation/diag_template_this.d(1): Error: identifier expected for template `this` parameter fail_compilation/diag_template_this.d(1): Error: found `this` when expecting `(` fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration, not `(` -fail_compilation/diag_template_this.d(1): Error: declaration expected, not `(` +fail_compilation/diag_template_this.d(1): Error: declaration expected, not `)` --- */ #line 1 diff --git a/compiler/test/fail_compilation/fail17570.d b/compiler/test/fail_compilation/fail17570.d index 9be7cd4b05..9cb3fa0d44 100644 --- a/compiler/test/fail_compilation/fail17570.d +++ b/compiler/test/fail_compilation/fail17570.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/fail17570.d(12): Error: cannot use function constraints for non-template functions. Use `static if` instead -fail_compilation/fail17570.d(12): Error: declaration expected, not `if` +fail_compilation/fail17570.d(13): Error: declaration expected, not `{` fail_compilation/fail17570.d(15): Error: `}` expected following members in `struct` declaration fail_compilation/fail17570.d(11): struct `S` starts here --- diff --git a/compiler/test/fail_compilation/fnconstraint.d b/compiler/test/fail_compilation/fnconstraint.d index 21603f725f..6369bdc5ba 100644 --- a/compiler/test/fail_compilation/fnconstraint.d +++ b/compiler/test/fail_compilation/fnconstraint.d @@ -2,9 +2,9 @@ TEST_OUTPUT: --- fail_compilation/fnconstraint.d(14): Error: template constraint must follow parameter lists and attributes -fail_compilation/fnconstraint.d(14): Error: declaration expected, not `if` +fail_compilation/fnconstraint.d(15): Error: declaration expected, not `{` fail_compilation/fnconstraint.d(23): Error: template constraint must follow parameter lists and attributes -fail_compilation/fnconstraint.d(23): Error: declaration expected, not `if` +fail_compilation/fnconstraint.d(23): Error: declaration expected, not `{` fail_compilation/fnconstraint.d(27): Error: `}` expected following members in `struct` declaration fail_compilation/fnconstraint.d(19): struct `S` starts here --- diff --git a/compiler/test/fail_compilation/issue16020.d b/compiler/test/fail_compilation/issue16020.d index 79eda2ea08..9f1f377638 100644 --- a/compiler/test/fail_compilation/issue16020.d +++ b/compiler/test/fail_compilation/issue16020.d @@ -1,10 +1,11 @@ /* TEST_OUTPUT: --- -fail_compilation/issue16020.d(13): Error: user-defined attributes not allowed for `alias` declarations -fail_compilation/issue16020.d(14): Error: semicolon expected to close `alias` declaration, not `(` -fail_compilation/issue16020.d(14): Error: declaration expected, not `(` -fail_compilation/issue16020.d(15): Deprecation: storage class `final` has no effect in type aliases +fail_compilation/issue16020.d(14): Error: user-defined attributes not allowed for `alias` declarations +fail_compilation/issue16020.d(15): Error: semicolon expected to close `alias` declaration, not `(` +fail_compilation/issue16020.d(15): Error: semicolon needed to end declaration of `t` instead of `)` +fail_compilation/issue16020.d(15): Error: declaration expected, not `)` +fail_compilation/issue16020.d(16): Deprecation: storage class `final` has no effect in type aliases --- */ module issue16020; diff --git a/compiler/test/fail_compilation/template_decl.d b/compiler/test/fail_compilation/template_decl.d index d986dd6506..a28284b9e4 100644 --- a/compiler/test/fail_compilation/template_decl.d +++ b/compiler/test/fail_compilation/template_decl.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/template_decl.d(8): Error: `{` expected after template parameter list, not `(` -fail_compilation/template_decl.d(8): Error: declaration expected, not `(` +fail_compilation/template_decl.d(8): Error: declaration expected, not `)` --- */ template b(alias d)() { diff --git a/compiler/test/fail_compilation/udaparams.d b/compiler/test/fail_compilation/udaparams.d index 76df55fcfd..0f3e4c8168 100644 --- a/compiler/test/fail_compilation/udaparams.d +++ b/compiler/test/fail_compilation/udaparams.d @@ -15,19 +15,19 @@ fail_compilation/udaparams.d(45): Error: `@nogc` attribute for function paramete fail_compilation/udaparams.d(51): Error: cannot put a storage-class in an `alias` declaration. fail_compilation/udaparams.d(52): Error: cannot put a storage-class in an `alias` declaration. fail_compilation/udaparams.d(53): Error: semicolon expected to close `alias` declaration, not `=>` -fail_compilation/udaparams.d(53): Error: declaration expected, not `=>` +fail_compilation/udaparams.d(53): Error: declaration expected, not `1` fail_compilation/udaparams.d(54): Error: semicolon expected to close `alias` declaration, not `=>` -fail_compilation/udaparams.d(54): Error: declaration expected, not `=>` +fail_compilation/udaparams.d(54): Error: declaration expected, not `1` fail_compilation/udaparams.d(57): Error: basic type expected, not `@` fail_compilation/udaparams.d(57): Error: identifier expected for template value parameter fail_compilation/udaparams.d(57): Error: found `@` when expecting `)` fail_compilation/udaparams.d(57): Error: basic type expected, not `3` fail_compilation/udaparams.d(57): Error: found `3` when expecting `)` fail_compilation/udaparams.d(57): Error: semicolon expected following function declaration, not `)` +fail_compilation/udaparams.d(57): Error: no identifier for declarator `T` fail_compilation/udaparams.d(57): Error: declaration expected, not `)` --- */ - void vararg1(int a, @(10) ...); extern(C) void vararg2(int a, @(10) ...);