mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 09:43:57 +00:00
[cfe/ffi] Handle invalid types in Array
Closes: https://github.com/dart-lang/sdk/issues/47673 TEST=tests/ffi(_2)/regress_47673(_2)_test.dart Change-Id: I8fdafc5378797ed071250b0caed1ab944873a218 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220760 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Clement Skau <cskau@google.com> Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
This commit is contained in:
parent
1ade4ab96f
commit
00ea62f713
|
@ -725,10 +725,16 @@ class FfiTransformer extends Transformer {
|
|||
/// 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 @@ class FfiTransformer extends Transformer {
|
|||
/// 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;
|
||||
|
|
|
@ -146,8 +146,9 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
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 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
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 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
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.");
|
||||
}
|
||||
|
|
18
tests/ffi/regress_47673_2_test.dart
Normal file
18
tests/ffi/regress_47673_2_test.dart
Normal file
|
@ -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() {}
|
16
tests/ffi/regress_47673_test.dart
Normal file
16
tests/ffi/regress_47673_test.dart
Normal file
|
@ -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() {}
|
20
tests/ffi_2/regress_47673_2_test.dart
Normal file
20
tests/ffi_2/regress_47673_2_test.dart
Normal file
|
@ -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() {}
|
23
tests/ffi_2/regress_47673_test.dart
Normal file
23
tests/ffi_2/regress_47673_test.dart
Normal file
|
@ -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() {}
|
Loading…
Reference in a new issue