[cfe] Ensure abstract methods have sync marker

This ensures that abstract methods have sync markers even when they
are erroneously marked with a sync*, async or async* marker. This
ensures that these are verifiable.


Change-Id: I6d5bed9305129c47306ad9fd0e248683a6577800
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307804
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index a8aa068..4f785bd 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1245,7 +1245,7 @@
     if (_context.isConstructor) {
       finishConstructor(asyncModifier, body,
           superParametersAsArguments: superParametersAsArguments);
-    } else {
+    } else if (body != null) {
       _context.setAsyncModifier(asyncModifier);
     }
 
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 48e3a8b..6707ef7 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -1961,6 +1961,10 @@
     }
     TypeBuilder? returnType = pop() as TypeBuilder?;
     bool isAbstract = bodyKind == MethodBody.Abstract;
+    if (isAbstract) {
+      // An error has been reported if this wasn't already sync.
+      asyncModifier = AsyncMarker.Sync;
+    }
     if (getOrSet != null && optional("set", getOrSet)) {
       if (formals == null || formals.length != 1) {
         // This isn't abstract as we'll add an error-recovery node in
diff --git a/pkg/front_end/testcases/general/abstract_async.dart b/pkg/front_end/testcases/general/abstract_async.dart
new file mode 100644
index 0000000..472f484
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_async.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class Class {
+  void abstractSyncStar() sync*;
+  void abstractAsync() async;
+  void abstractAsyncStar() async*;
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/abstract_async.dart.strong.expect b/pkg/front_end/testcases/general/abstract_async.dart.strong.expect
new file mode 100644
index 0000000..e0e76e1
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_async.dart.strong.expect
@@ -0,0 +1,50 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:8: Error: Functions marked 'sync*' can't have return type 'void'.
+//   void abstractSyncStar() sync*;
+//        ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:8: Error: Functions marked 'async*' can't have return type 'void'.
+//   void abstractAsyncStar() async*;
+//        ^^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  abstract method abstractSyncStar() → void;
+  abstract method abstractAsync() → void;
+  abstract method abstractAsyncStar() → void;
+}
diff --git a/pkg/front_end/testcases/general/abstract_async.dart.strong.transformed.expect b/pkg/front_end/testcases/general/abstract_async.dart.strong.transformed.expect
new file mode 100644
index 0000000..e0e76e1
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_async.dart.strong.transformed.expect
@@ -0,0 +1,50 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:8: Error: Functions marked 'sync*' can't have return type 'void'.
+//   void abstractSyncStar() sync*;
+//        ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:8: Error: Functions marked 'async*' can't have return type 'void'.
+//   void abstractAsyncStar() async*;
+//        ^^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  abstract method abstractSyncStar() → void;
+  abstract method abstractAsync() → void;
+  abstract method abstractAsyncStar() → void;
+}
diff --git a/pkg/front_end/testcases/general/abstract_async.dart.textual_outline.expect b/pkg/front_end/testcases/general/abstract_async.dart.textual_outline.expect
new file mode 100644
index 0000000..4dd0374
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_async.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+abstract class Class {
+  void abstractSyncStar() sync*;
+  void abstractAsync() async;
+  void abstractAsyncStar() async*;
+}
diff --git a/pkg/front_end/testcases/general/abstract_async.dart.weak.expect b/pkg/front_end/testcases/general/abstract_async.dart.weak.expect
new file mode 100644
index 0000000..e0e76e1
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_async.dart.weak.expect
@@ -0,0 +1,50 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:8: Error: Functions marked 'sync*' can't have return type 'void'.
+//   void abstractSyncStar() sync*;
+//        ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:8: Error: Functions marked 'async*' can't have return type 'void'.
+//   void abstractAsyncStar() async*;
+//        ^^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  abstract method abstractSyncStar() → void;
+  abstract method abstractAsync() → void;
+  abstract method abstractAsyncStar() → void;
+}
diff --git a/pkg/front_end/testcases/general/abstract_async.dart.weak.modular.expect b/pkg/front_end/testcases/general/abstract_async.dart.weak.modular.expect
new file mode 100644
index 0000000..e0e76e1
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_async.dart.weak.modular.expect
@@ -0,0 +1,50 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:8: Error: Functions marked 'sync*' can't have return type 'void'.
+//   void abstractSyncStar() sync*;
+//        ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:8: Error: Functions marked 'async*' can't have return type 'void'.
+//   void abstractAsyncStar() async*;
+//        ^^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  abstract method abstractSyncStar() → void;
+  abstract method abstractAsync() → void;
+  abstract method abstractAsyncStar() → void;
+}
diff --git a/pkg/front_end/testcases/general/abstract_async.dart.weak.outline.expect b/pkg/front_end/testcases/general/abstract_async.dart.weak.outline.expect
new file mode 100644
index 0000000..c2be419
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_async.dart.weak.outline.expect
@@ -0,0 +1,41 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    ;
+  abstract method abstractSyncStar() → void;
+  abstract method abstractAsync() → void;
+  abstract method abstractAsyncStar() → void;
+}
diff --git a/pkg/front_end/testcases/general/abstract_async.dart.weak.transformed.expect b/pkg/front_end/testcases/general/abstract_async.dart.weak.transformed.expect
new file mode 100644
index 0000000..e0e76e1
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_async.dart.weak.transformed.expect
@@ -0,0 +1,50 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:32: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractSyncStar() sync*;
+//                                ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:7:29: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsync() async;
+//                             ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Abstract methods can't use 'async', 'async*', or 'sync*'.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:34: Error: Expected a function body or '=>'.
+// Try adding {}.
+//   void abstractAsyncStar() async*;
+//                                  ^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:6:8: Error: Functions marked 'sync*' can't have return type 'void'.
+//   void abstractSyncStar() sync*;
+//        ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/abstract_async.dart:8:8: Error: Functions marked 'async*' can't have return type 'void'.
+//   void abstractAsyncStar() async*;
+//        ^^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  abstract method abstractSyncStar() → void;
+  abstract method abstractAsync() → void;
+  abstract method abstractAsyncStar() → void;
+}
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 6b1ca37..77f5ac8 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -52,6 +52,7 @@
 extensions/issue38600: FormatterCrash
 extensions/issue38712: FormatterCrash
 extensions/issue38745: FormatterCrash
+general/abstract_async: FormatterCrash
 general/annotation_eof: FormatterCrash
 general/bad_setter_abstract: FormatterCrash
 general/bug31124: FormatterCrash