Sema: Fix crash with invalid @_opaqueReturnTypeOf attribute

If we demangle the name but we can't resolve the opaque return
declaration, we would dereference a null pointer and crash.

Speculative fix for rdar://161067984.
This commit is contained in:
Slava Pestov
2025-09-22 18:47:21 -04:00
parent 8ad16fbc80
commit ffc501cbd3
3 changed files with 31 additions and 25 deletions

View File

@@ -4039,13 +4039,12 @@ TypeResolver::resolveOpaqueReturnType(TypeRepr *repr, StringRef mangledName,
builder.getNodeFactory().createNode(Node::Kind::OpaqueReturnTypeOf);
opaqueNode->addChild(definingDeclNode, builder.getNodeFactory());
auto *opaqueDecl = builder.resolveOpaqueTypeDecl(opaqueNode);
auto *ownerDecl = opaqueDecl->getNamingDecl();
if (!ownerDecl) {
if (!opaqueDecl) {
diagnose(repr->getLoc(), diag::no_opaque_return_type_of);
return ErrorType::get(getASTContext());
}
auto *ownerDecl = opaqueDecl->getNamingDecl();
auto genericSig = ownerDecl->getInnermostDeclContext()
->getGenericSignatureOfContext();

View File

@@ -1,22 +0,0 @@
// Test that we emit a diagnostic (and don't crash) when we cannot resolve
// an opaque result type reference.
//
// First, emit an empty module interface:
//
// RUN: %empty-directory(%t)
// RUN: echo "" | %target-swift-frontend -typecheck -emit-module-interface-path %t/InvalidOpaqueResultType.swiftinterface -enable-library-evolution -swift-version 5 -module-name InvalidOpaqueResultType -
//
// Then, blit some invalid opaque result types into the interface
//
// Test that we reject broken type parameters
// RUN: echo "public typealias SomeGenericBalderdash = @_opaqueReturnTypeOf(\"$somesuchnonsense\", 0) __<InvalidParameter>" >> %t/InvalidOpaqueResultType.swiftinterface
// Test that we reject types we cannot demangle
// RUN: echo "public typealias SomesuchNonsense = @_opaqueReturnTypeOf(\"$somesuchnonsense\", 0) __" >> %t/InvalidOpaqueResultType.swiftinterface
//
// The stage is set:
//
// RUN: not %target-swift-frontend -typecheck %s -I %t 2>&1 | %FileCheck %s
// CHECK: unable to resolve type for _opaqueReturnTypeOf attribute
// CHECK: failed to build module 'InvalidOpaqueResultType' for importation
import InvalidOpaqueResultType

View File

@@ -0,0 +1,29 @@
// Test that we emit a diagnostic (and don't crash) when we cannot resolve
// an opaque result type reference.
//
// RUN: %target-typecheck-verify-swift -module-name OpaqueTypes
//
public struct G<T> {
public func f() -> some Any
}
// Type doesn't demangle
public typealias Bad1 = @_opaqueReturnTypeOf("nonsense", 0) __
// expected-error@-1 {{unable to resolve type for _opaqueReturnTypeOf attribute}}
// Type demangles but doesn't name an opaque return type
public typealias Bad2 = @_opaqueReturnTypeOf("$sSi", 0) __
// expected-error@-1 {{unable to resolve type for _opaqueReturnTypeOf attribute}}
// Bad index
public typealias Bad3 = @_opaqueReturnTypeOf("$s11OpaqueTypes1GV1fQryF", 5) __<Int>
// expected-error@-1 {{unable to resolve type for _opaqueReturnTypeOf attribute}}
// Bad generic argument
public typealias Bad4 = @_opaqueReturnTypeOf("$s11OpaqueTypes1GV1fQryF", 0) __<InvalidType>
// expected-error@-1 {{cannot find type 'InvalidType' in scope}}
// Missing generic argument
public typealias Bad5 = @_opaqueReturnTypeOf("$s11OpaqueTypes1GV1fQryF", 0) __
// expected-error@-1 {{unable to resolve type for _opaqueReturnTypeOf attribute}}