Skip to content

Commit 63178e8

Browse files
committed
AST: Improve robustness with invalid nesting of extensions in generic context
Extensions cannot capture generic parameters from outer contexts. Their generic parameter list does not point to the outer parameter list, the signature does not contain outer parameters and they do not appear in the extension's generic environment. Furthermore, the depth/index of the extension's parameters may clash with outer parameters, which would break all kinds of invariants. This patch changes these DeclContext methods to return false or nullptr even if an extension is contained in a generic context: - isGenericContext() - getGenericParamsOfContext() - getGenericSignatureOfContext() - getGenericEnvironmentOfContext()
1 parent 81fad09 commit 63178e8

4 files changed

+13
-13
lines changed

lib/AST/DeclContext.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,8 @@ GenericParamList *DeclContext::getGenericParamsOfContext() const {
206206
continue;
207207

208208
case DeclContextKind::ExtensionDecl:
209-
if (auto GP = cast<ExtensionDecl>(dc)->getGenericParams())
210-
return GP;
211-
continue;
209+
// Extensions do not capture outer generic parameters.
210+
return cast<ExtensionDecl>(dc)->getGenericParams();
212211
}
213212
llvm_unreachable("bad DeclContextKind");
214213
}
@@ -247,9 +246,8 @@ GenericSignature *DeclContext::getGenericSignatureOfContext() const {
247246

248247
case DeclContextKind::ExtensionDecl: {
249248
auto ED = cast<ExtensionDecl>(dc);
250-
if (auto genericSig = ED->getGenericSignature())
251-
return genericSig;
252-
continue;
249+
// Extensions do not capture outer generic parameters.
250+
return ED->getGenericSignature();
253251
}
254252
}
255253
llvm_unreachable("bad DeclContextKind");
@@ -288,9 +286,8 @@ GenericEnvironment *DeclContext::getGenericEnvironmentOfContext() const {
288286

289287
case DeclContextKind::ExtensionDecl: {
290288
auto ED = cast<ExtensionDecl>(dc);
291-
if (auto genericCtx = ED->getGenericEnvironment())
292-
return genericCtx;
293-
continue;
289+
// Extensions do not capture outer generic parameters.
290+
return ED->getGenericEnvironment();
294291
}
295292
}
296293
llvm_unreachable("bad DeclContextKind");
@@ -468,17 +465,20 @@ bool DeclContext::isGenericContext() const {
468465
case DeclContextKind::AbstractFunctionDecl:
469466
if (cast<AbstractFunctionDecl>(dc)->getGenericParams())
470467
return true;
468+
// Check parent context.
471469
continue;
472470

473471
case DeclContextKind::GenericTypeDecl:
474472
if (cast<GenericTypeDecl>(dc)->getGenericParams())
475473
return true;
474+
// Check parent context.
476475
continue;
477476

478477
case DeclContextKind::ExtensionDecl:
479478
if (cast<ExtensionDecl>(dc)->getGenericParams())
480479
return true;
481-
continue;
480+
// Extensions do not capture outer generic parameters.
481+
return false;
482482
}
483483
llvm_unreachable("bad decl context kind");
484484
}

validation-test/compiler_crashers/28212-swift-typechecker-resolvetypeincontext.swift renamed to validation-test/compiler_crashers_fixed/28212-swift-typechecker-resolvetypeincontext.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// See https://swift.org/LICENSE.txt for license information
66
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
77

8-
// RUN: not --crash %target-swift-frontend %s -typecheck
8+
// RUN: not %target-swift-frontend %s -typecheck
99
// REQUIRES: asserts
1010
struct B{let f= <a
1111
extension{

validation-test/compiler_crashers/28332-swift-archetypebuilder-getgenericsignature.swift renamed to validation-test/compiler_crashers_fixed/28332-swift-archetypebuilder-getgenericsignature.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// See https://swift.org/LICENSE.txt for license information
66
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
77

8-
// RUN: not --crash %target-swift-frontend %s -typecheck
8+
// RUN: not %target-swift-frontend %s -typecheck
99
// REQUIRES: asserts
1010
class A{var b=a
1111
struct Q<h{
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// See https://swift.org/LICENSE.txt for license information
66
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
77

8-
// RUN: not --crash %target-swift-frontend %s -emit-ir
8+
// RUN: not %target-swift-frontend %s -emit-ir
99
// REQUIRES: asserts
1010
class A{let f= <c
1111
protocol A{

0 commit comments

Comments
 (0)