Просмотр исходного кода

Fix crash on incomplete `constraint` (#3542)

Previously would fail with:

```
CHECK failure at toolchain/parse/node_kind.cpp:74: Lex::TokenKind::Error == expected_token_kind || token_kind == expected_token_kind: Created parse node with NodeKind NamedConstraintDecl and has_error 1 for lexical token kind Constraint, but expected token kind Semi
```

Issue found by fuzzing.
josh11b 2 лет назад
Родитель
Сommit
55d853e17f

+ 1 - 1
toolchain/parse/node_kind.def

@@ -706,7 +706,7 @@ CARBON_PARSE_NODE_KIND_BRACKET(NamedConstraintDefinitionStart,
 CARBON_PARSE_NODE_KIND_BRACKET(NamedConstraintDefinition,
                                NamedConstraintDefinitionStart, CloseCurlyBrace)
 CARBON_PARSE_NODE_KIND_BRACKET(NamedConstraintDecl, NamedConstraintIntroducer,
-                               Semi)
+                               CARBON_IF_VALID(Semi))
 
 #undef CARBON_PARSE_NODE_KIND
 #undef CARBON_PARSE_NODE_KIND_BRACKET

+ 5 - 0
toolchain/parse/testdata/generics/named_constraint/basic.carbon

@@ -8,6 +8,8 @@ constraint Foo {
   fn Baz();
 }
 
+constraint ForwardDeclared;
+
 // CHECK:STDOUT: - filename: basic.carbon
 // CHECK:STDOUT:   parse_tree: [
 // CHECK:STDOUT:     {kind: 'FileStart', text: ''},
@@ -20,5 +22,8 @@ constraint Foo {
 // CHECK:STDOUT:         {kind: 'TuplePattern', text: ')', subtree_size: 2},
 // CHECK:STDOUT:       {kind: 'FunctionDecl', text: ';', subtree_size: 5},
 // CHECK:STDOUT:     {kind: 'NamedConstraintDefinition', text: '}', subtree_size: 9},
+// CHECK:STDOUT:       {kind: 'NamedConstraintIntroducer', text: 'constraint'},
+// CHECK:STDOUT:       {kind: 'IdentifierName', text: 'ForwardDeclared'},
+// CHECK:STDOUT:     {kind: 'NamedConstraintDecl', text: ';', subtree_size: 3},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 27 - 0
toolchain/parse/testdata/generics/named_constraint/fail_incomplete.carbon

@@ -0,0 +1,27 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// AUTOUPDATE
+
+// CHECK:STDERR: fail_incomplete.carbon:[[@LINE+3]]:12: ERROR: `constraint` introducer should be followed by a name.
+// CHECK:STDERR: constraint "Foo"
+// CHECK:STDERR:            ^~~~~
+constraint "Foo"
+
+// CHECK:STDERR: fail_incomplete.carbon:[[@LINE+3]]:1: ERROR: `constraint` introducer should be followed by a name.
+// CHECK:STDERR: constraint
+// CHECK:STDERR: ^~~~~~~~~~
+constraint
+
+// CHECK:STDOUT: - filename: fail_incomplete.carbon
+// CHECK:STDOUT:   parse_tree: [
+// CHECK:STDOUT:     {kind: 'FileStart', text: ''},
+// CHECK:STDOUT:       {kind: 'NamedConstraintIntroducer', text: 'constraint'},
+// CHECK:STDOUT:       {kind: 'InvalidParse', text: '"Foo"', has_error: yes},
+// CHECK:STDOUT:     {kind: 'NamedConstraintDecl', text: '"Foo"', has_error: yes, subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'NamedConstraintIntroducer', text: 'constraint'},
+// CHECK:STDOUT:       {kind: 'InvalidParse', text: '', has_error: yes},
+// CHECK:STDOUT:     {kind: 'NamedConstraintDecl', text: 'constraint', has_error: yes, subtree_size: 3},
+// CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
+// CHECK:STDOUT:   ]