Skip to content

Commit efab897

Browse files
alexmarkovCommit Queue
authored and
Commit Queue
committed
[vm,aot] Fix type check in implicit setter of a covariant field
Inferred type of a covariant field should not be used as an argument type of an implicit setter, as setter of a covariant field performs a type check before assigning value to the field. Correct such uses of covariant field types in unboxing and AOT type propagation in order to avoid incorrect removal of a type check in the implicit setter of a covariant field. TEST=runtime/tests/vm/dart/regress_56051_test.dart Fixes #56051 Change-Id: I55bfedfd96e918aac9597706c6eab1b81e1202ee Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372721 Reviewed-by: Slava Egorov <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent 874c610 commit efab897

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

pkg/vm/lib/transformations/type_flow/unboxing_info.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ class UnboxingInfoManager {
176176
final inferredType = typeFlowAnalysis.getFieldValue(member).value;
177177
if (member.hasSetter) {
178178
_applyToArg(member, unboxingInfo, 0, inferredType);
179+
// Arguments of implicit setters for covariant fields
180+
// cannot be unboxed based on the field type as setter
181+
// performs a type check before value is assigned to the field.
182+
if (member.isCovariantByDeclaration) {
183+
unboxingInfo.argsInfo.length = 0;
184+
} else {
185+
_applyToArg(member, unboxingInfo, 0, inferredType);
186+
}
179187
}
180188
_applyToReturn(member, unboxingInfo, inferredType);
181189
} else {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Regression test for https://github.com/dart-lang/sdk/issues/56051.
6+
7+
// VMOptions=--compiler-passes=-Inlining
8+
9+
import 'package:expect/expect.dart';
10+
11+
class Foo {
12+
covariant late num a;
13+
}
14+
15+
class Bar extends Foo {
16+
@override
17+
late int a;
18+
}
19+
20+
void main() {
21+
Foo bar = Bar();
22+
bar.a = 2;
23+
Expect.equals(2, bar.a);
24+
Expect.throws(() {
25+
bar.a = 3.14 as dynamic;
26+
print('bar.a is now ${bar.a}');
27+
});
28+
print("success!");
29+
}

runtime/vm/compiler/frontend/scope_builder.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,15 +300,17 @@ ScopeBuildingResult* ScopeBuilder::BuildScopes() {
300300
if (is_setter) {
301301
if (CompilerState::Current().is_aot()) {
302302
const intptr_t kernel_offset = field.kernel_offset();
303-
const InferredTypeMetadata parameter_type =
303+
const InferredTypeMetadata inferred_field_type =
304304
inferred_type_metadata_helper_.GetInferredType(kernel_offset);
305305
result_->setter_value = MakeVariable(
306306
TokenPosition::kNoSource, TokenPosition::kNoSource,
307307
Symbols::Value(),
308308
AbstractType::ZoneHandle(Z, function.ParameterTypeAt(pos)),
309309
LocalVariable::kNoKernelOffset, /*is_late=*/false,
310310
/*inferred_type=*/nullptr,
311-
/*inferred_arg_type=*/&parameter_type);
311+
/*inferred_arg_type=*/field.is_covariant()
312+
? nullptr
313+
: &inferred_field_type);
312314
} else {
313315
result_->setter_value = MakeVariable(
314316
TokenPosition::kNoSource, TokenPosition::kNoSource,

0 commit comments

Comments
 (0)