فهرست منبع

Handle FunctionType and FunctionTypeWithSelfType in TypeIterator without crashing (#5480)

A fuzzer found that converting a pointer to a `FunctionTypeWithSelfType`
to `type` does an impl lookup and ends up in TypeIterator with the
`FunctionTypeWithSelfType` being iterated over in the self type, where
we crash. It's a valid type, so the iterator should be able to walk over
and return it.

We also constructed a similar example for `FunctionType`.
Dana Jansens 11 ماه پیش
والد
کامیت
8b087738b7

+ 58 - 0
toolchain/check/testdata/impl/lookup/min_prelude/fail_function_types.carbon

@@ -0,0 +1,58 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// INCLUDE-FILE: toolchain/testing/min_prelude/convert.carbon
+// EXTRA-ARGS: --no-dump-sem-ir
+//
+// AUTOUPDATE
+// TIP: To test this file alone, run:
+// TIP:   bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/lookup/min_prelude/fail_function_types.carbon
+// TIP: To dump output, run:
+// TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/lookup/min_prelude/fail_function_types.carbon
+
+// --- fail_function_type_with_self_type.carbon
+library "[[@TEST_NAME]]";
+
+interface Z {
+  fn G();
+}
+
+impl forall [T:! type] T as Z {
+  fn G() {}
+}
+
+fn F() {
+  // CHECK:STDERR: fail_function_type_with_self_type.carbon:[[@LINE+11]]:3: error: cannot take the address of non-reference expression [AddrOfNonRef]
+  // CHECK:STDERR:   &(().(Z.G)) as type;
+  // CHECK:STDERR:   ^
+  // CHECK:STDERR:
+  // CHECK:STDERR: fail_function_type_with_self_type.carbon:[[@LINE+7]]:3: error: cannot convert non-type value of type `<type of G in () as Z>*` to `type` with `as` [ConversionFailureNonTypeToFacet]
+  // CHECK:STDERR:   &(().(Z.G)) as type;
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_function_type_with_self_type.carbon:[[@LINE+4]]:3: note: type `<type of G in () as Z>*` does not implement interface `Core.As(type)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   &(().(Z.G)) as type;
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR:
+  &(().(Z.G)) as type;
+}
+
+// --- fail_function_type.carbon
+library "[[@TEST_NAME]]";
+
+fn F() {
+  // This does an impl lookup for `As` with `FunctionType` in the self type.
+  //
+  // CHECK:STDERR: fail_function_type.carbon:[[@LINE+11]]:3: error: cannot take the address of non-reference expression [AddrOfNonRef]
+  // CHECK:STDERR:   &F as type;
+  // CHECK:STDERR:   ^
+  // CHECK:STDERR:
+  // CHECK:STDERR: fail_function_type.carbon:[[@LINE+7]]:3: error: cannot convert non-type value of type `<type of F>*` to `type` with `as` [ConversionFailureNonTypeToFacet]
+  // CHECK:STDERR:   &F as type;
+  // CHECK:STDERR:   ^~~~~~~~~~
+  // CHECK:STDERR: fail_function_type.carbon:[[@LINE+4]]:3: note: type `<type of F>*` does not implement interface `Core.As(type)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   &F as type;
+  // CHECK:STDERR:   ^~~~~~~~~~
+  // CHECK:STDERR:
+  &F as type;
+}

+ 2 - 0
toolchain/sem_ir/type_iterator.cpp

@@ -81,6 +81,8 @@ auto TypeIterator::Next() -> Step {
       case SemIR::BoolType::Kind:
       case SemIR::FacetType::Kind:
       case SemIR::FloatType::Kind:
+      case SemIR::FunctionType::Kind:
+      case SemIR::FunctionTypeWithSelfType::Kind:
       case SemIR::GenericClassType::Kind:
       case SemIR::GenericInterfaceType::Kind:
       case SemIR::ImplWitnessAccess::Kind: