diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart index 9f915eb4d21..ace44263e58 100644 --- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart +++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart @@ -4643,6 +4643,15 @@ Message _withArgumentsFfiCompoundImplementsFinalizable( arguments: {'string': string, 'name': name}); } +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code codeFfiCreateOfStructOrUnion = messageFfiCreateOfStructOrUnion; + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const MessageCode messageFfiCreateOfStructOrUnion = const MessageCode( + "FfiCreateOfStructOrUnion", + problemMessage: + r"""Subclasses of 'Struct' and 'Union' are backed by native memory, and can't be instantiated by a generative constructor. Try allocating it via allocation, or load from a 'Pointer'."""); + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Template< Message Function( diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart index 97357b37043..bafc97a2d09 100644 --- a/pkg/front_end/lib/src/api_unstable/vm.dart +++ b/pkg/front_end/lib/src/api_unstable/vm.dart @@ -59,6 +59,7 @@ export '../fasta/fasta_codes.dart' LocatedMessage, messageFfiAbiSpecificIntegerInvalid, messageFfiAbiSpecificIntegerMappingInvalid, + messageFfiCreateOfStructOrUnion, messageFfiExceptionalReturnNull, messageFfiExpectedConstant, messageFfiLeafCallMustNotReturnHandle, diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status index 70f91be11bc..14483ee6480 100644 --- a/pkg/front_end/messages.status +++ b/pkg/front_end/messages.status @@ -377,6 +377,7 @@ FastaUsageShort/analyzerCode: Fail FastaUsageShort/example: Fail FfiAbiSpecificIntegerInvalid/analyzerCode: Fail FfiAbiSpecificIntegerMappingInvalid/analyzerCode: Fail +FfiCreateOfStructOrUnion/analyzerCode: Fail FfiCompoundImplementsFinalizable/analyzerCode: Fail FfiDartTypeMismatch/analyzerCode: Fail FfiEmptyStruct/analyzerCode: Fail diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index 9f673dd4fee..5ba305dc440 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -4918,6 +4918,11 @@ FfiAbiSpecificIntegerMappingInvalid: problemMessage: "Classes extending 'AbiSpecificInteger' must have exactly one 'AbiSpecificIntegerMapping' annotation specifying the mapping from ABI to a NativeType integer with a fixed size." external: test/ffi_test.dart +FfiCreateOfStructOrUnion: + # Used by dart:ffi + problemMessage: "Subclasses of 'Struct' and 'Union' are backed by native memory, and can't be instantiated by a generative constructor. Try allocating it via allocation, or load from a 'Pointer'." + external: test/ffi_test.dart + FfiTypeMismatch: # Used by dart:ffi problemMessage: "Expected type '#type' to be '#type2', which is the Dart type corresponding to '#type3'." diff --git a/pkg/front_end/test/spell_checking_list_messages.txt b/pkg/front_end/test/spell_checking_list_messages.txt index d46c665b2a7..02e8ab0c525 100644 --- a/pkg/front_end/test/spell_checking_list_messages.txt +++ b/pkg/front_end/test/spell_checking_list_messages.txt @@ -22,6 +22,7 @@ augmentation augmentations augmented b +backed c cast collide diff --git a/pkg/vm/lib/transformations/ffi/use_sites.dart b/pkg/vm/lib/transformations/ffi/use_sites.dart index f531770b686..7328a50799e 100644 --- a/pkg/vm/lib/transformations/ffi/use_sites.dart +++ b/pkg/vm/lib/transformations/ffi/use_sites.dart @@ -4,6 +4,7 @@ import 'package:front_end/src/api_unstable/vm.dart' show + messageFfiCreateOfStructOrUnion, messageFfiExceptionalReturnNull, messageFfiExpectedConstant, templateFfiDartTypeMismatch, @@ -13,6 +14,7 @@ import 'package:front_end/src/api_unstable/vm.dart' templateFfiExtendsOrImplementsSealedClass, templateFfiNotStatic; +import 'package:front_end/src/api_prototype/lowering_predicates.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; import 'package:kernel/core_types.dart'; @@ -116,17 +118,34 @@ mixin _FfiUseSiteTransformer on FfiTransformer { } } + @override + visitConstructorInvocation(ConstructorInvocation node) { + if (_inFfiTearoff) { + return node; + } + final target = node.target; + if (hierarchy.isSubclassOf(target.enclosingClass, compoundClass) && + target.name != Name("#fromTypedDataBase")) { + diagnosticReporter.report(messageFfiCreateOfStructOrUnion, + node.fileOffset, 1, node.location?.file); + } + return super.visitConstructorInvocation(node); + } + @override visitProcedure(Procedure node) { assert(_inFfiTearoff == false); - _inFfiTearoff = (isFfiLibrary && - node.isExtensionMember && - (node == allocationTearoff || - node == asFunctionTearoff || - node == lookupFunctionTearoff || - node == abiSpecificIntegerPointerElementAtTearoff || - node == structPointerElementAtTearoff || - node == unionPointerElementAtTearoff)); + _inFfiTearoff = ((isFfiLibrary && + node.isExtensionMember && + (node == allocationTearoff || + node == asFunctionTearoff || + node == lookupFunctionTearoff || + node == abiSpecificIntegerPointerElementAtTearoff || + node == structPointerElementAtTearoff || + node == unionPointerElementAtTearoff))) || + // Dart2wasm uses enabledConstructorTearOffLowerings but these are not + // users trying to call constructors. + isConstructorTearOffLowering(node); final result = super.visitProcedure(node); _inFfiTearoff = false; return result;