Skip to content

Commit

Permalink
Version 2.18.1
Browse files Browse the repository at this point in the history
* Cherry-pick 6ad3805 to stable
* Cherry-pick f38a280 to stable
  • Loading branch information
sortie committed Sep 13, 2022
2 parents 63c2197 + 71ec88a commit c42a304
Show file tree
Hide file tree
Showing 13 changed files with 293 additions and 115 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
## 2.18.0
## 2.18.1 - 2022-09-14

This is a patch release that fixes a crash caused by incorrect type inference
(issues [flutter/flutter#110715][] and [flutter/flutter#111088][]).

[flutter/flutter#110715]: https://github.com/flutter/flutter/issues/110715
[flutter/flutter#111088]: https://github.com/flutter/flutter/issues/111088

## 2.18.0 - 2022-08-30

### Language

Expand Down
69 changes: 69 additions & 0 deletions runtime/tests/vm/dart/flutter_regress_109261_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// 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.

// Regression test for https://github.com/flutter/flutter/issues/109261.
// Varifies that uninitialized final late local variable can be correctly
// used in a catch block.

import 'package:expect/expect.dart';

void testWriteToUninitialized() {
late final int computationResult;

try {
throw 'bye';
} catch (e, s) {
computationResult = 42;
}

Expect.equals(42, computationResult);
}

void testWriteToInitialized() {
Expect.throws(() {
late final int computationResult;

try {
computationResult = 10;
throw 'bye';
} catch (e, s) {
computationResult = 42;
}
});
}

void testReadFromUninitialized() {
Expect.throws(() {
late final int computationResult;

try {
if (int.parse('1') == 2) {
// Unreachable, just to avoid compile-time error "Late variable '...'
// without initializer is definitely unassigned."
computationResult = 10;
}
throw 'bye';
} catch (e, s) {
print(computationResult);
}
});
}

void testReadFromInitialized() {
late final int computationResult;

try {
computationResult = 10;
throw 'bye';
} catch (e, s) {
Expect.equals(10, computationResult);
}
}

main() {
testWriteToUninitialized();
testWriteToInitialized();
testReadFromUninitialized();
testReadFromInitialized();
}
96 changes: 96 additions & 0 deletions runtime/tests/vm/dart/regress_flutter110715_il_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// 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.

// Regression test for https://github.com/flutter/flutter/issues/110715.
// Verifies that compiler doesn't elide null check for a parameter in
// a catch block in async/async* methods.

import 'dart:async';
import 'package:vm/testing/il_matchers.dart';

@pragma('vm:never-inline')
@pragma('vm:testing:print-flow-graph')
Stream<Object> bug1(void Function()? f, void Function() g) async* {
try {
g();
throw 'error';
} catch (e) {
// Should not crash when 'f' is null.
f?.call();
}
}

@pragma('vm:never-inline')
@pragma('vm:testing:print-flow-graph')
Future<Object> bug2(void Function()? f, void Function() g) async {
try {
g();
throw 'error';
} catch (e) {
// Should not crash when 'f' is null.
f?.call();
}
return '';
}

void main() async {
print(await bug1(null, () {}).toList());
print(await bug1(() {}, () {}).toList());
print(await bug2(null, () {}));
print(await bug2(() {}, () {}));
}

void matchIL$bug1(FlowGraph graph) {
graph.dump();
graph.match([
match.block('Graph'),
match.block('Function'),
match.block('Join'),
match.block('CatchBlock', [
'v0' << match.Parameter(),
match.Branch(match.StrictCompare('v0', match.any, kind: '==='),
ifTrue: 'B6', ifFalse: 'B7'),
]),
'B6' <<
match.block('Target', [
match.Goto('B4'),
]),
'B7' <<
match.block('Target', [
match.ClosureCall(),
match.Goto('B4'),
]),
'B4' <<
match.block('Join', [
match.Return(),
]),
]);
}

void matchIL$bug2(FlowGraph graph) {
graph.dump();
graph.match([
match.block('Graph'),
match.block('Function'),
match.block('Join'),
match.block('CatchBlock', [
'v0' << match.Parameter(),
match.Branch(match.StrictCompare('v0', match.any, kind: '==='),
ifTrue: 'B6', ifFalse: 'B7'),
]),
'B6' <<
match.block('Target', [
match.Goto('B4'),
]),
'B7' <<
match.block('Target', [
match.ClosureCall(),
match.Goto('B4'),
]),
'B4' <<
match.block('Join', [
match.Return(),
]),
]);
}
2 changes: 2 additions & 0 deletions runtime/vm/compiler/backend/compile_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ class CompileType : public ZoneAllocated {
// represent unknown type.
static CompileType Dynamic();

static CompileType DynamicOrSentinel();

static CompileType Null();

// Create non-nullable Bool type.
Expand Down
12 changes: 2 additions & 10 deletions runtime/vm/compiler/backend/constant_propagator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,8 @@ static void ConstantPropagatorUnboxedOpTest(
using compiler::BlockBuilder;

CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
FlowGraphBuilderHelper H;

// Add a variable into the scope which would provide static type for the
// parameter.
LocalVariable* v0_var =
new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
String::Handle(Symbols::New(thread, "v0")),
AbstractType::ZoneHandle(Type::IntType()));
v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
H.flow_graph()->parsed_function().scope()->AddVariable(v0_var);
FlowGraphBuilderHelper H(/*num_parameters=*/1);
H.AddVariable("v0", AbstractType::ZoneHandle(Type::IntType()));

// We are going to build the following graph:
//
Expand Down
14 changes: 3 additions & 11 deletions runtime/vm/compiler/backend/flow_graph_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,9 @@ ISOLATE_UNIT_TEST_CASE(FlowGraph_UnboxInt64Phi) {

CompilerState S(thread, /*is_aot=*/true, /*is_optimizing=*/true);

FlowGraphBuilderHelper H;

// Add a variable into the scope which would provide static type for the
// parameter.
LocalVariable* v0_var =
new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
String::Handle(Symbols::New(thread, "v0")),
AbstractType::ZoneHandle(Type::IntType()),
new CompileType(CompileType::Int()));
v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
H.flow_graph()->parsed_function().scope()->AddVariable(v0_var);
FlowGraphBuilderHelper H(/*num_parameters=*/1);
H.AddVariable("v0", AbstractType::ZoneHandle(Type::IntType()),
new CompileType(CompileType::Int()));

auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
auto loop_header = H.JoinEntry();
Expand Down
4 changes: 2 additions & 2 deletions runtime/vm/compiler/backend/il.h
Original file line number Diff line number Diff line change
Expand Up @@ -2696,8 +2696,8 @@ class ParameterInstr : public Definition {
virtual Representation representation() const { return representation_; }

virtual Representation RequiredInputRepresentation(intptr_t index) const {
ASSERT(index == 0);
return representation();
UNREACHABLE();
return kTagged;
}

virtual bool ComputeCanDeoptimize() const { return false; }
Expand Down
23 changes: 10 additions & 13 deletions runtime/vm/compiler/backend/il_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,16 +207,8 @@ bool TestIntConverterCanonicalizationRule(Thread* thread,

CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);

FlowGraphBuilderHelper H;

// Add a variable into the scope which would provide static type for the
// parameter.
LocalVariable* v0_var =
new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
String::Handle(Symbols::New(thread, "v0")),
AbstractType::ZoneHandle(Type::IntType()));
v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
H.flow_graph()->parsed_function().scope()->AddVariable(v0_var);
FlowGraphBuilderHelper H(/*num_parameters=*/1);
H.AddVariable("v0", AbstractType::ZoneHandle(Type::IntType()));

auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();

Expand Down Expand Up @@ -269,7 +261,8 @@ ISOLATE_UNIT_TEST_CASE(IL_PhiCanonicalization) {

CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);

FlowGraphBuilderHelper H;
FlowGraphBuilderHelper H(/*num_parameters=*/1);
H.AddVariable("v0", AbstractType::ZoneHandle(Type::DynamicType()));

auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
auto b2 = H.JoinEntry();
Expand Down Expand Up @@ -322,7 +315,9 @@ ISOLATE_UNIT_TEST_CASE(IL_UnboxIntegerCanonicalization) {

CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);

FlowGraphBuilderHelper H;
FlowGraphBuilderHelper H(/*num_parameters=*/2);
H.AddVariable("v0", AbstractType::ZoneHandle(Type::DynamicType()));
H.AddVariable("v1", AbstractType::ZoneHandle(Type::DynamicType()));

auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
Definition* unbox;
Expand Down Expand Up @@ -397,7 +392,9 @@ static void TestNullAwareEqualityCompareCanonicalization(

CompilerState S(thread, /*is_aot=*/true, /*is_optimizing=*/true);

FlowGraphBuilderHelper H;
FlowGraphBuilderHelper H(/*num_parameters=*/2);
H.AddVariable("v0", AbstractType::ZoneHandle(Type::IntType()));
H.AddVariable("v1", AbstractType::ZoneHandle(Type::IntType()));

auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();

Expand Down
20 changes: 17 additions & 3 deletions runtime/vm/compiler/backend/il_test_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,9 @@ class ILMatcher : public ValueObject {

class FlowGraphBuilderHelper {
public:
FlowGraphBuilderHelper()
explicit FlowGraphBuilderHelper(intptr_t num_parameters = 0)
: state_(CompilerState::Current()),
flow_graph_(MakeDummyGraph(Thread::Current())) {
flow_graph_(MakeDummyGraph(Thread::Current(), num_parameters)) {
flow_graph_.CreateCommonConstants();
}

Expand All @@ -286,6 +286,19 @@ class FlowGraphBuilderHelper {
return flow_graph_.GetConstant(Double::Handle(Double::NewCanonical(value)));
}

// Adds a variable into the scope which would provide static type for the
// parameter.
void AddVariable(const char* name,
const AbstractType& static_type,
CompileType* param_type = nullptr) {
LocalVariable* v =
new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
String::Handle(Symbols::New(Thread::Current(), name)),
static_type, param_type);
v->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
flow_graph()->parsed_function().scope()->AddVariable(v);
}

enum class IncomingDefKind {
kImmediate,
kDelayed,
Expand Down Expand Up @@ -349,9 +362,10 @@ class FlowGraphBuilderHelper {
FlowGraph* flow_graph() { return &flow_graph_; }

private:
static FlowGraph& MakeDummyGraph(Thread* thread) {
static FlowGraph& MakeDummyGraph(Thread* thread, intptr_t num_parameters) {
const FunctionType& signature =
FunctionType::ZoneHandle(FunctionType::New());
signature.set_num_fixed_parameters(num_parameters);
const Function& func = Function::ZoneHandle(Function::New(
signature, String::Handle(Symbols::New(thread, "dummy")),
UntaggedFunction::kRegularFunction,
Expand Down
4 changes: 3 additions & 1 deletion runtime/vm/compiler/backend/redundancy_elimination_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1381,7 +1381,9 @@ ISOLATE_UNIT_TEST_CASE(CSE_Redefinitions) {

using compiler::BlockBuilder;
CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
FlowGraphBuilderHelper H;
FlowGraphBuilderHelper H(/*num_parameters=*/2);
H.AddVariable("v0", AbstractType::ZoneHandle(Type::DynamicType()));
H.AddVariable("v1", AbstractType::ZoneHandle(Type::DynamicType()));

auto b1 = H.flow_graph()->graph_entry()->normal_entry();

Expand Down
Loading

0 comments on commit c42a304

Please sign in to comment.