mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Fixes crash while instrumenting generic func body embedded in another func.
The crash was caused by attempting to add logging expressions that capture generic variables while using the outer func decl context that was not the generic decl context of the inner (generic) func. The fix "pushes" the current func decl context while instrumenting the body. Rather than always using the top-level func decl context for all nested func bodies.
This commit is contained in:
@@ -339,7 +339,12 @@ public:
|
||||
if (auto *FD = dyn_cast<FuncDecl>(D)) {
|
||||
if (BraceStmt *B = FD->getTypecheckedBody()) {
|
||||
const ParameterList *PL = FD->getParameters();
|
||||
|
||||
// Use FD's DeclContext as TypeCheckDC for transforms in func body
|
||||
// then swap back TypeCheckDC at end of scope.
|
||||
llvm::SaveAndRestore<DeclContext *> localDC(TypeCheckDC, FD);
|
||||
BraceStmt *NB = transformBraceStmt(B, PL);
|
||||
|
||||
// Since it would look strange going straight to the first line in a
|
||||
// function body, we throw in a before/after pointing at the function
|
||||
// decl at the start of the transformed body
|
||||
|
||||
@@ -312,6 +312,11 @@ public:
|
||||
if (BraceStmt *B = FD->getTypecheckedBody()) {
|
||||
const ParameterList *PL = FD->getParameters();
|
||||
TargetKindSetter TKS(BracePairs, BracePair::TargetKinds::Return);
|
||||
|
||||
// Use FD's DeclContext as TypeCheckDC for transforms in func body
|
||||
// then swap back TypeCheckDC at end of scope.
|
||||
llvm::SaveAndRestore<DeclContext *> localDC(TypeCheckDC, FD);
|
||||
|
||||
BraceStmt *NB = transformBraceStmt(B, PL);
|
||||
if (NB != B) {
|
||||
FD->setBody(NB, AbstractFunctionDecl::BodyKind::TypeChecked);
|
||||
|
||||
33
test/PlaygroundTransform/generic_func_in_local_scope.swift
Normal file
33
test/PlaygroundTransform/generic_func_in_local_scope.swift
Normal file
@@ -0,0 +1,33 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// Build PlaygroundSupport module
|
||||
// RUN: %target-build-swift -whole-module-optimization -module-name PlaygroundSupport -emit-module-path %t/PlaygroundSupport.swiftmodule -parse-as-library -c -o %t/PlaygroundSupport.o %S/Inputs/SilentPCMacroRuntime.swift %S/Inputs/PlaygroundsRuntime.swift
|
||||
|
||||
// RUN: %target-build-swift -swift-version 5 -emit-module -Xfrontend -playground -I=%t %s
|
||||
// RUN: %target-build-swift -swift-version 6 -emit-module -Xfrontend -playground -I=%t %s
|
||||
|
||||
// RUN: %target-build-swift -swift-version 5 -emit-module -Xfrontend -playground -Xfrontend -pc-macro -I=%t %s
|
||||
// RUN: %target-build-swift -swift-version 6 -emit-module -Xfrontend -playground -Xfrontend -pc-macro -I=%t %s
|
||||
|
||||
// REQUIRES: executable_test
|
||||
|
||||
import PlaygroundSupport
|
||||
|
||||
func test1() {
|
||||
func buildBlock<Content>(content: Content) {
|
||||
content
|
||||
}
|
||||
}
|
||||
|
||||
func test2() {
|
||||
func buildBlock<Content>(content: Content) -> Content {
|
||||
content
|
||||
return content
|
||||
}
|
||||
}
|
||||
|
||||
func test3<Content>(_ content: Content) {
|
||||
func buildBlock<Content2>(_ content2: Content2) -> Content2 {
|
||||
return content2
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user