diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc index aeb0cabb134..ff0c9bc4d4d 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc @@ -1169,7 +1169,9 @@ Fragment StreamingFlowGraphBuilder::BuildStatementAt(intptr_t kernel_offset) { return BuildStatement(); // read statement. } -Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) { +Fragment StreamingFlowGraphBuilder::BuildExpression( + TokenPosition* position, + bool allow_late_uninitialized) { ++num_ast_nodes_; uint8_t payload = 0; Tag tag = ReadTag(&payload); // read tag. @@ -1177,9 +1179,9 @@ Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) { case kInvalidExpression: return BuildInvalidExpression(position); case kVariableGet: - return BuildVariableGet(position); + return BuildVariableGet(position, allow_late_uninitialized); case kSpecializedVariableGet: - return BuildVariableGet(payload, position); + return BuildVariableGet(payload, position, allow_late_uninitialized); case kVariableSet: return BuildVariableSet(position); case kSpecializedVariableSet: @@ -5818,26 +5820,12 @@ Fragment StreamingFlowGraphBuilder::BuildReachabilityFence() { ASSERT(positional_count == 1); // The CFE transform only generates a subset of argument expressions: - // either variable get or `this`. - uint8_t payload = 0; - Tag tag = ReadTag(&payload); + // either variable get or `this`. However, subsequent transforms can + // generate different expressions, including: constant expressions. + // So, build an arbitrary expression here instead. TokenPosition* position = nullptr; const bool allow_late_uninitialized = true; - Fragment code; - switch (tag) { - case kVariableGet: - code = BuildVariableGet(position, allow_late_uninitialized); - break; - case kSpecializedVariableGet: - code = BuildVariableGet(payload, position, allow_late_uninitialized); - break; - case kThisExpression: - code = BuildThisExpression(position); - break; - default: - // The transformation should not be generating anything else. - FATAL1("Unexpected tag %i", tag); - } + Fragment code = BuildExpression(position, allow_late_uninitialized); const intptr_t named_args_len = ReadListLength(); ASSERT(named_args_len == 0); diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h index 4547f0e8fb1..feb6d488850 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h @@ -70,7 +70,8 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper { Fragment BuildInitializers(const Class& parent_class); FlowGraph* BuildGraphOfFunction(bool constructor); - Fragment BuildExpression(TokenPosition* position = nullptr); + Fragment BuildExpression(TokenPosition* position = nullptr, + bool allow_late_uninitialized = false); Fragment BuildStatement(TokenPosition* position = nullptr); Fragment BuildStatementWithBranchCoverage(TokenPosition* position = nullptr); diff --git a/tests/ffi/regress_49402_test.dart b/tests/ffi/regress_49402_test.dart new file mode 100644 index 00000000000..e31384bfcb5 --- /dev/null +++ b/tests/ffi/regress_49402_test.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2022, 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. + +import 'dart:ffi'; + +class A implements Finalizable {} + +void b([A? a]) {} + +void main() { + b(); +} diff --git a/tests/ffi_2/regress_49402_test.dart b/tests/ffi_2/regress_49402_test.dart new file mode 100644 index 00000000000..e9a71ba7512 --- /dev/null +++ b/tests/ffi_2/regress_49402_test.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2022, 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. + +// @dart=2.9 + +import 'dart:ffi'; + +class A implements Finalizable {} + +void b([A a]) {} + +void main() { + b(); +}