Version 2.16.0-31.0.dev
Merge commit '00ea62f71368306b01f593d055af011bc0d57f1b' into 'dev'
diff --git a/pkg/vm/lib/transformations/ffi/common.dart b/pkg/vm/lib/transformations/ffi/common.dart
index 4d242a7..7627a59 100644
--- a/pkg/vm/lib/transformations/ffi/common.dart
+++ b/pkg/vm/lib/transformations/ffi/common.dart
@@ -725,10 +725,16 @@
/// Returns the single element type nested type argument of `Array`.
///
/// `Array<Array<Array<Int8>>>` -> `Int8`.
+ ///
+ /// `Array<Array<Array<Unknown>>>` -> [InvalidType].
DartType arraySingleElementType(DartType dartType) {
InterfaceType elementType = dartType as InterfaceType;
while (elementType.classNode == arrayClass) {
- elementType = elementType.typeArguments[0] as InterfaceType;
+ final elementTypeAny = elementType.typeArguments[0];
+ if (elementTypeAny is InvalidType) {
+ return elementTypeAny;
+ }
+ elementType = elementTypeAny as InterfaceType;
}
return elementType;
}
@@ -736,11 +742,14 @@
/// Returns the number of dimensions of `Array`.
///
/// `Array<Array<Array<Int8>>>` -> 3.
+ ///
+ /// `Array<Array<Array<Unknown>>>` -> 3.
int arrayDimensions(DartType dartType) {
- InterfaceType elementType = dartType as InterfaceType;
+ DartType elementType = dartType;
int dimensions = 0;
- while (elementType.classNode == arrayClass) {
- elementType = elementType.typeArguments[0] as InterfaceType;
+ while (
+ elementType is InterfaceType && elementType.classNode == arrayClass) {
+ elementType = elementType.typeArguments[0];
dimensions++;
}
return dimensions;
diff --git a/pkg/vm/lib/transformations/ffi/definitions.dart b/pkg/vm/lib/transformations/ffi/definitions.dart
index f87519e..c11b710 100644
--- a/pkg/vm/lib/transformations/ffi/definitions.dart
+++ b/pkg/vm/lib/transformations/ffi/definitions.dart
@@ -146,8 +146,9 @@
final sizeAnnotations = _getArraySizeAnnotations(f);
if (sizeAnnotations.length == 1) {
final singleElementType = arraySingleElementType(type);
- if (isCompoundSubtype(singleElementType)) {
- final clazz = (singleElementType as InterfaceType).classNode;
+ if (singleElementType is InterfaceType &&
+ isCompoundSubtype(singleElementType)) {
+ final clazz = singleElementType.classNode;
dependencies.add(clazz);
}
}
@@ -403,24 +404,31 @@
final sizeAnnotations = _getArraySizeAnnotations(f);
if (sizeAnnotations.length == 1) {
final singleElementType = arraySingleElementType(type);
- if (isCompoundSubtype(singleElementType)) {
- final clazz = (singleElementType as InterfaceType).classNode;
- _checkPacking(node, packing, clazz, f);
- }
- final dimensions = sizeAnnotations.single;
- if (arrayDimensions(type) != dimensions.length) {
- diagnosticReporter.report(
- templateFfiSizeAnnotationDimensions
- .withArguments(f.name.text),
- f.fileOffset,
- f.name.text.length,
- f.fileUri);
- }
- for (var dimension in dimensions) {
- if (dimension < 0) {
- diagnosticReporter.report(messageNonPositiveArrayDimensions,
- f.fileOffset, f.name.text.length, f.fileUri);
- success = false;
+ if (singleElementType is! InterfaceType) {
+ assert(singleElementType is InvalidType);
+ // This class is invalid, but continue reporting other errors on it.
+ // An error on the type will already have been reported.
+ success = false;
+ } else {
+ if (isCompoundSubtype(singleElementType)) {
+ final clazz = singleElementType.classNode;
+ _checkPacking(node, packing, clazz, f);
+ }
+ final dimensions = sizeAnnotations.single;
+ if (arrayDimensions(type) != dimensions.length) {
+ diagnosticReporter.report(
+ templateFfiSizeAnnotationDimensions
+ .withArguments(f.name.text),
+ f.fileOffset,
+ f.name.text.length,
+ f.fileUri);
+ }
+ for (var dimension in dimensions) {
+ if (dimension < 0) {
+ diagnosticReporter.report(messageNonPositiveArrayDimensions,
+ f.fileOffset, f.name.text.length, f.fileUri);
+ success = false;
+ }
}
}
} else {
@@ -568,8 +576,15 @@
if (sizeAnnotations.length == 1) {
final arrayDimensions = sizeAnnotations.single;
if (this.arrayDimensions(dartType) == arrayDimensions.length) {
- type = NativeTypeCfe(this, dartType,
- compoundCache: compoundCache, arrayDimensions: arrayDimensions);
+ final elementType = arraySingleElementType(dartType);
+ if (elementType is! InterfaceType) {
+ assert(elementType is InvalidType);
+ type = InvalidNativeTypeCfe("Invalid element type.");
+ } else {
+ type = NativeTypeCfe(this, dartType,
+ compoundCache: compoundCache,
+ arrayDimensions: arrayDimensions);
+ }
} else {
type = InvalidNativeTypeCfe("Invalid array dimensions.");
}
diff --git a/tests/ffi/regress_47673_2_test.dart b/tests/ffi/regress_47673_2_test.dart
new file mode 100644
index 0000000..9048521
--- /dev/null
+++ b/tests/ffi/regress_47673_2_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2021, 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.
+//
+// SharedObjects=ffi_test_functions
+
+import 'dart:ffi';
+
+class A extends Struct {
+ @Array.multi([16])
+ external Array<Int8> a;
+
+ // This should not crash the FFI transform.
+ @Array.multi([16]) //# 1: compile-time error
+ external Array<Unknown> b; //# 1: compile-time error
+}
+
+main() {}
diff --git a/tests/ffi/regress_47673_test.dart b/tests/ffi/regress_47673_test.dart
new file mode 100644
index 0000000..b372e09
--- /dev/null
+++ b/tests/ffi/regress_47673_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2021, 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.
+//
+// SharedObjects=ffi_test_functions
+
+import 'dart:ffi';
+
+typedef T = Int64;
+
+class A extends Struct {
+ @Array.multi([16])
+ external Array<T> b;
+}
+
+main() {}
diff --git a/tests/ffi_2/regress_47673_2_test.dart b/tests/ffi_2/regress_47673_2_test.dart
new file mode 100644
index 0000000..2258af8
--- /dev/null
+++ b/tests/ffi_2/regress_47673_2_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, 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.
+//
+// SharedObjects=ffi_test_functions
+
+// @dart=2.9
+
+import 'dart:ffi';
+
+class A extends Struct {
+ @Array.multi([16])
+ Array<Int8> a;
+
+ // This should not crash the FFI transform.
+ @Array.multi([16]) //# 1: compile-time error
+ Array<Unknown> b; //# 1: compile-time error
+}
+
+main() {}
diff --git a/tests/ffi_2/regress_47673_test.dart b/tests/ffi_2/regress_47673_test.dart
new file mode 100644
index 0000000..9044ed5
--- /dev/null
+++ b/tests/ffi_2/regress_47673_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2021, 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.
+//
+// SharedObjects=ffi_test_functions
+
+// @dart=2.9
+
+import 'dart:ffi';
+
+typedef T = Int64; //# 1: compile-time error
+
+class A extends Struct {
+ @Array.multi([16])
+ Array<Int8> a;
+
+ // In language version 2.12 we do not support non-function typedefs.
+ // This should not crash the FFI transform.
+ @Array.multi([16]) //# 1: compile-time error
+ Array<T> b; //# 1: compile-time error
+}
+
+main() {}
diff --git a/tools/VERSION b/tools/VERSION
index 59d4a27..9203c16 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 30
+PRERELEASE 31
PRERELEASE_PATCH 0
\ No newline at end of file