[vm/ffi] Add fields to `Struct`s which should not be empty
This CL adds fields to `Struct`s which should not be empty or removes
the structs.
Issue: https://github.com/dart-lang/sdk/issues/44622
Issue: https://github.com/dart-lang/sdk/issues/43974
TEST=tests/ffi/vmspecific_static_checks_test.dart
Change-Id: I4a684bd96e3ed16a3fd0dd17019aeabf64ef074a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/179182
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
diff --git a/pkg/analyzer/test/src/diagnostics/field_in_struct_with_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/field_in_struct_with_initializer_test.dart
index da75f22..9c908b5 100644
--- a/pkg/analyzer/test/src/diagnostics/field_in_struct_with_initializer_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/field_in_struct_with_initializer_test.dart
@@ -39,6 +39,7 @@
await assertNoErrorsInCode(r'''
import 'dart:ffi';
class C extends Struct {
+ Pointer p;
static String str = '';
}
''');
diff --git a/pkg/analyzer/test/src/diagnostics/generic_struct_subclass_test.dart b/pkg/analyzer/test/src/diagnostics/generic_struct_subclass_test.dart
index 8b4aef4..710a812 100644
--- a/pkg/analyzer/test/src/diagnostics/generic_struct_subclass_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/generic_struct_subclass_test.dart
@@ -18,7 +18,9 @@
test_genericStruct() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
-class S<T> extends Struct {}
+class S<T> extends Struct {
+ Pointer notEmpty;
+}
''', [
error(FfiCode.GENERIC_STRUCT_SUBCLASS, 25, 1),
]);
@@ -27,7 +29,9 @@
test_validStruct() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
-class S extends Struct {}
+class S extends Struct {
+ Pointer notEmpty;
+}
''');
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_field_type_in_struct_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_field_type_in_struct_test.dart
index 06cd7f3..6fec555 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_field_type_in_struct_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_field_type_in_struct_test.dart
@@ -15,11 +15,14 @@
@reflectiveTest
class InvalidFieldTypeInStructTest extends PubPackageResolutionTest {
+ // TODO(https://dartbug.com/44677): Remove Pointer notEmpty field.
test_instance_invalid() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
class C extends Struct {
String str;
+
+ Pointer notEmpty;
}
''', [
error(FfiCode.INVALID_FIELD_TYPE_IN_STRUCT, 46, 6),
@@ -35,11 +38,14 @@
''');
}
+ // TODO(https://dartbug.com/44677): Remove Pointer notEmpty field.
test_static() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
class C extends Struct {
static String str;
+
+ Pointer notEmpty;
}
''');
}
diff --git a/pkg/analyzer/test/src/diagnostics/missing_field_type_in_struct_test.dart b/pkg/analyzer/test/src/diagnostics/missing_field_type_in_struct_test.dart
index cfae21f..c5ae82c 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_field_type_in_struct_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_field_type_in_struct_test.dart
@@ -20,6 +20,8 @@
import 'dart:ffi';
class C extends Struct {
var str;
+
+ Pointer notEmpty;
}
''', [
error(FfiCode.MISSING_FIELD_TYPE_IN_STRUCT, 50, 3),
diff --git a/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart b/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart
index a5aed99..7073a39 100644
--- a/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart
@@ -84,7 +84,9 @@
test_Struct() async {
await assertNoErrorsInCode(r'''
import 'dart:ffi';
-class C extends Struct {}
+class C extends Struct {
+ Pointer notEmpty;
+}
''');
}
diff --git a/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart b/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart
index 66f4192..d5ca275 100644
--- a/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart
@@ -21,10 +21,12 @@
test_extends() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
-class S extends Struct {}
+class S extends Struct {
+ Pointer notEmpty;
+}
class C extends S {}
''', [
- error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS, 61, 1),
+ error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS, 82, 1),
]);
}
}
diff --git a/runtime/bin/ffi_test/ffi_test_functions_generated.cc b/runtime/bin/ffi_test/ffi_test_functions_generated.cc
index a77bff1..65d06a5 100644
--- a/runtime/bin/ffi_test/ffi_test_functions_generated.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions_generated.cc
@@ -34,8 +34,6 @@
CHECK(((EXPECTED * 0.99) <= (ACTUAL) && (EXPECTED * 1.01) >= (ACTUAL)) || \
((EXPECTED * 0.99) >= (ACTUAL) && (EXPECTED * 1.01) <= (ACTUAL)))
-struct Struct0Bytes {};
-
struct Struct1ByteInt {
int8_t a0;
};
diff --git a/tests/ffi/function_structs_by_value_generated_test.dart b/tests/ffi/function_structs_by_value_generated_test.dart
index c8b91cb..ba98841 100644
--- a/tests/ffi/function_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_structs_by_value_generated_test.dart
@@ -106,10 +106,6 @@
}
}
-class Struct0Bytes extends Struct {
- String toString() => "()";
-}
-
class Struct1ByteInt extends Struct {
@Int8()
external int a0;
diff --git a/tests/ffi/generator/structs_by_value_tests_configuration.dart b/tests/ffi/generator/structs_by_value_tests_configuration.dart
index 718caea..bc1b8a1 100644
--- a/tests/ffi/generator/structs_by_value_tests_configuration.dart
+++ b/tests/ffi/generator/structs_by_value_tests_configuration.dart
@@ -421,7 +421,6 @@
];
final structs = [
- struct0bytes,
struct1byteInt,
struct3bytesInt,
struct3bytesInt2,
@@ -462,9 +461,6 @@
structNestedEvenBigger,
];
-/// Using empty structs is undefined behavior in C.
-final struct0bytes = StructType([]);
-
final struct1byteInt = StructType([int8]);
final struct3bytesInt = StructType(List.filled(3, uint8));
final struct3bytesInt2 = StructType.disambiguate([int16, int8], "2ByteAligned");
diff --git a/tests/ffi/regress_43016_test.dart b/tests/ffi/regress_43016_test.dart
index f1489e0..db3d816 100644
--- a/tests/ffi/regress_43016_test.dart
+++ b/tests/ffi/regress_43016_test.dart
@@ -10,7 +10,10 @@
import 'dylib_utils.dart';
-class MyStruct extends Struct {}
+class MyStruct extends Struct {
+ @Int8()
+ external int a;
+}
typedef _c_pass_struct = Int32 Function(Pointer<MyStruct>);
diff --git a/tests/ffi/vmspecific_regress_38993_test.dart b/tests/ffi/vmspecific_regress_38993_test.dart
index 8c9972f..4391b00 100644
--- a/tests/ffi/vmspecific_regress_38993_test.dart
+++ b/tests/ffi/vmspecific_regress_38993_test.dart
@@ -8,6 +8,8 @@
class C extends Struct {
dynamic x; //# 1: compile-time error
+
+ external Pointer notEmpty;
}
main() {}
diff --git a/tests/ffi/vmspecific_static_checks_test.dart b/tests/ffi/vmspecific_static_checks_test.dart
index cbce8e6..ff194bd 100644
--- a/tests/ffi/vmspecific_static_checks_test.dart
+++ b/tests/ffi/vmspecific_static_checks_test.dart
@@ -358,24 +358,32 @@
class TestStruct5 extends Struct {
@Int64() //# 54: compile-time error
external double z; //# 54: compile-time error
+
+ external Pointer notEmpty;
}
// error on annotation not matching up
class TestStruct6 extends Struct {
@Void() //# 55: compile-time error
external double z; //# 55: compile-time error
+
+ external Pointer notEmpty;
}
// error on annotation not matching up
class TestStruct7 extends Struct {
@NativeType() //# 56: compile-time error
external double z; //# 56: compile-time error
+
+ external Pointer notEmpty;
}
// error on field initializer on field
class TestStruct8 extends Struct {
@Double() //# 57: compile-time error
double z = 10.0; //# 57: compile-time error
+
+ external Pointer notEmpty;
}
// error on field initializer in constructor
@@ -383,6 +391,8 @@
@Double() //# 58: compile-time error
double z; //# 58: compile-time error
+ external Pointer notEmpty;
+
TestStruct9() : z = 0.0 {} //# 58: compile-time error
}
@@ -395,6 +405,8 @@
class TestStruct12 extends Struct {
@Pointer //# 61: compile-time error
external TestStruct9 struct; //# 61: compile-time error
+
+ external Pointer notEmpty;
}
class DummyAnnotation {
@@ -500,12 +512,16 @@
}
class TestStruct1001 extends Struct {
- Handle handle; //# 1001: compile-time error
+ external Handle handle; //# 1001: compile-time error
+
+ external Pointer notEmpty;
}
class TestStruct1002 extends Struct {
@Handle() //# 1002: compile-time error
- Object handle; //# 1002: compile-time error
+ external Object handle; //# 1002: compile-time error
+
+ external Pointer notEmpty;
}
class EmptyStruct extends Struct {}
@@ -554,6 +570,8 @@
class HasNestedEmptyStruct extends Struct {
external EmptyStruct nestedEmptyStruct; //# 1106: compile-time error
+
+ external Pointer notEmpty;
}
void testAllocateGeneric() {
diff --git a/tests/ffi_2/function_structs_by_value_generated_test.dart b/tests/ffi_2/function_structs_by_value_generated_test.dart
index e00f3fa..6867406 100644
--- a/tests/ffi_2/function_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_test.dart
@@ -106,10 +106,6 @@
}
}
-class Struct0Bytes extends Struct {
- String toString() => "()";
-}
-
class Struct1ByteInt extends Struct {
@Int8()
int a0;
diff --git a/tests/ffi_2/generator/structs_by_value_tests_configuration.dart b/tests/ffi_2/generator/structs_by_value_tests_configuration.dart
index 718caea..bc1b8a1 100644
--- a/tests/ffi_2/generator/structs_by_value_tests_configuration.dart
+++ b/tests/ffi_2/generator/structs_by_value_tests_configuration.dart
@@ -421,7 +421,6 @@
];
final structs = [
- struct0bytes,
struct1byteInt,
struct3bytesInt,
struct3bytesInt2,
@@ -462,9 +461,6 @@
structNestedEvenBigger,
];
-/// Using empty structs is undefined behavior in C.
-final struct0bytes = StructType([]);
-
final struct1byteInt = StructType([int8]);
final struct3bytesInt = StructType(List.filled(3, uint8));
final struct3bytesInt2 = StructType.disambiguate([int16, int8], "2ByteAligned");
diff --git a/tests/ffi_2/regress_43016_test.dart b/tests/ffi_2/regress_43016_test.dart
index b0ebc0c..997e451 100644
--- a/tests/ffi_2/regress_43016_test.dart
+++ b/tests/ffi_2/regress_43016_test.dart
@@ -10,7 +10,10 @@
import 'dylib_utils.dart';
-class MyStruct extends Struct {}
+class MyStruct extends Struct {
+ @Int8()
+ int a;
+}
typedef _c_pass_struct = Int32 Function(Pointer<MyStruct> arg0);
diff --git a/tests/ffi_2/vmspecific_regress_38993_test.dart b/tests/ffi_2/vmspecific_regress_38993_test.dart
index 8c9972f..e7c4315 100644
--- a/tests/ffi_2/vmspecific_regress_38993_test.dart
+++ b/tests/ffi_2/vmspecific_regress_38993_test.dart
@@ -8,6 +8,8 @@
class C extends Struct {
dynamic x; //# 1: compile-time error
+
+ Pointer notEmpty;
}
main() {}
diff --git a/tests/ffi_2/vmspecific_static_checks_test.dart b/tests/ffi_2/vmspecific_static_checks_test.dart
index f1db86e..8883658 100644
--- a/tests/ffi_2/vmspecific_static_checks_test.dart
+++ b/tests/ffi_2/vmspecific_static_checks_test.dart
@@ -358,24 +358,32 @@
class TestStruct5 extends Struct {
@Int64() //# 54: compile-time error
double z; //# 54: compile-time error
+
+ Pointer notEmpty;
}
// error on annotation not matching up
class TestStruct6 extends Struct {
@Void() //# 55: compile-time error
double z; //# 55: compile-time error
+
+ Pointer notEmpty;
}
// error on annotation not matching up
class TestStruct7 extends Struct {
@NativeType() //# 56: compile-time error
double z; //# 56: compile-time error
+
+ Pointer notEmpty;
}
// error on field initializer on field
class TestStruct8 extends Struct {
@Double() //# 57: compile-time error
double z = 10.0; //# 57: compile-time error
+
+ Pointer notEmpty;
}
// error on field initializer in constructor
@@ -395,6 +403,8 @@
class TestStruct12 extends Struct {
@Pointer //# 61: compile-time error
TestStruct9 struct; //# 61: compile-time error
+
+ Pointer notEmpty;
}
class DummyAnnotation {
@@ -501,11 +511,15 @@
class TestStruct1001 extends Struct {
Handle handle; //# 1001: compile-time error
+
+ Pointer notEmpty;
}
class TestStruct1002 extends Struct {
@Handle() //# 1002: compile-time error
Object handle; //# 1002: compile-time error
+
+ Pointer notEmpty;
}
class EmptyStruct extends Struct {}
@@ -554,6 +568,8 @@
class HasNestedEmptyStruct extends Struct {
EmptyStruct nestedEmptyStruct; //# 1106: compile-time error
+
+ Pointer notEmpty;
}
void testAllocateGeneric() {