Skip to content

Commit 59e6662

Browse files
authored
Merge pull request #1190 from ahoppen/ahoppen/fix-memory-corruption
Fix memory corruption when constructing syntax nodes from different arenas
2 parents 60e2097 + 55d4414 commit 59e6662

File tree

7 files changed

+2731
-2290
lines changed

7 files changed

+2731
-2290
lines changed

Sources/SwiftSyntax/SyntaxNodes.swift.gyb.template

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,21 @@ public struct ${node.name}: ${base_type}Protocol, SyntaxHashable {
114114
}
115115

116116
${node.generate_initializer_decl(optional_base_as_missing=False, current_indentation=" ")} {
117+
% parameters = ', '.join([child.swift_name for child in node.children])
118+
// Extend the lifetime of all parameters so their arenas don't get destroyed
119+
// before they can be added as children of the new arena.
120+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (${parameters}))) { (arena, _) in
117121
% if node.children:
118-
let layout: [RawSyntax?] = [
122+
let layout: [RawSyntax?] = [
119123
% for child in node.children:
120124
% if child.is_optional:
121-
${child.swift_name}?.raw,
125+
${child.swift_name}?.raw,
122126
% else:
123-
${child.swift_name}.raw,
127+
${child.swift_name}.raw,
124128
% end
125129
% end
126-
]
130+
]
127131
% end
128-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
129132
% if node.children:
130133
let raw = RawSyntax.makeLayout(
131134
kind: SyntaxKind.${node.swift_syntax_kind}, from: layout, arena: arena,

Sources/SwiftSyntax/gyb_generated/syntax_nodes/SyntaxDeclNodes.swift

Lines changed: 456 additions & 406 deletions
Large diffs are not rendered by default.

Sources/SwiftSyntax/gyb_generated/syntax_nodes/SyntaxExprNodes.swift

Lines changed: 503 additions & 409 deletions
Large diffs are not rendered by default.

Sources/SwiftSyntax/gyb_generated/syntax_nodes/SyntaxNodes.swift

Lines changed: 1253 additions & 1051 deletions
Large diffs are not rendered by default.

Sources/SwiftSyntax/gyb_generated/syntax_nodes/SyntaxPatternNodes.swift

Lines changed: 97 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ public struct MissingPatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
3232
}
3333

3434
public init() {
35-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
35+
// Extend the lifetime of all parameters so their arenas don't get destroyed
36+
// before they can be added as children of the new arena.
37+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), ())) { (arena, _) in
3638
let raw = RawSyntax.makeEmptyLayout(kind: SyntaxKind.missingPattern, arena: arena)
3739
return SyntaxData.forRoot(raw)
3840
}
@@ -90,18 +92,20 @@ public struct EnumCasePatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
9092
_ unexpectedAfterAssociatedTuple: UnexpectedNodesSyntax? = nil,
9193
trailingTrivia: Trivia? = nil
9294
) {
93-
let layout: [RawSyntax?] = [
94-
unexpectedBeforeType?.raw,
95-
type?.raw,
96-
unexpectedBetweenTypeAndPeriod?.raw,
97-
period.raw,
98-
unexpectedBetweenPeriodAndCaseName?.raw,
99-
caseName.raw,
100-
unexpectedBetweenCaseNameAndAssociatedTuple?.raw,
101-
associatedTuple?.raw,
102-
unexpectedAfterAssociatedTuple?.raw,
103-
]
104-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
95+
// Extend the lifetime of all parameters so their arenas don't get destroyed
96+
// before they can be added as children of the new arena.
97+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpectedBeforeType, type, unexpectedBetweenTypeAndPeriod, period, unexpectedBetweenPeriodAndCaseName, caseName, unexpectedBetweenCaseNameAndAssociatedTuple, associatedTuple, unexpectedAfterAssociatedTuple))) { (arena, _) in
98+
let layout: [RawSyntax?] = [
99+
unexpectedBeforeType?.raw,
100+
type?.raw,
101+
unexpectedBetweenTypeAndPeriod?.raw,
102+
period.raw,
103+
unexpectedBetweenPeriodAndCaseName?.raw,
104+
caseName.raw,
105+
unexpectedBetweenCaseNameAndAssociatedTuple?.raw,
106+
associatedTuple?.raw,
107+
unexpectedAfterAssociatedTuple?.raw,
108+
]
105109
let raw = RawSyntax.makeLayout(
106110
kind: SyntaxKind.enumCasePattern, from: layout, arena: arena,
107111
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia)
@@ -418,14 +422,16 @@ public struct IsTypePatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
418422
_ unexpectedAfterType: UnexpectedNodesSyntax? = nil,
419423
trailingTrivia: Trivia? = nil
420424
) {
421-
let layout: [RawSyntax?] = [
422-
unexpectedBeforeIsKeyword?.raw,
423-
isKeyword.raw,
424-
unexpectedBetweenIsKeywordAndType?.raw,
425-
type.raw,
426-
unexpectedAfterType?.raw,
427-
]
428-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
425+
// Extend the lifetime of all parameters so their arenas don't get destroyed
426+
// before they can be added as children of the new arena.
427+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpectedBeforeIsKeyword, isKeyword, unexpectedBetweenIsKeywordAndType, type, unexpectedAfterType))) { (arena, _) in
428+
let layout: [RawSyntax?] = [
429+
unexpectedBeforeIsKeyword?.raw,
430+
isKeyword.raw,
431+
unexpectedBetweenIsKeywordAndType?.raw,
432+
type.raw,
433+
unexpectedAfterType?.raw,
434+
]
429435
let raw = RawSyntax.makeLayout(
430436
kind: SyntaxKind.isTypePattern, from: layout, arena: arena,
431437
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia)
@@ -604,14 +610,16 @@ public struct OptionalPatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
604610
_ unexpectedAfterQuestionMark: UnexpectedNodesSyntax? = nil,
605611
trailingTrivia: Trivia? = nil
606612
) {
607-
let layout: [RawSyntax?] = [
608-
unexpectedBeforeSubPattern?.raw,
609-
subPattern.raw,
610-
unexpectedBetweenSubPatternAndQuestionMark?.raw,
611-
questionMark.raw,
612-
unexpectedAfterQuestionMark?.raw,
613-
]
614-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
613+
// Extend the lifetime of all parameters so their arenas don't get destroyed
614+
// before they can be added as children of the new arena.
615+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpectedBeforeSubPattern, subPattern, unexpectedBetweenSubPatternAndQuestionMark, questionMark, unexpectedAfterQuestionMark))) { (arena, _) in
616+
let layout: [RawSyntax?] = [
617+
unexpectedBeforeSubPattern?.raw,
618+
subPattern.raw,
619+
unexpectedBetweenSubPatternAndQuestionMark?.raw,
620+
questionMark.raw,
621+
unexpectedAfterQuestionMark?.raw,
622+
]
615623
let raw = RawSyntax.makeLayout(
616624
kind: SyntaxKind.optionalPattern, from: layout, arena: arena,
617625
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia)
@@ -788,12 +796,14 @@ public struct IdentifierPatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
788796
_ unexpectedAfterIdentifier: UnexpectedNodesSyntax? = nil,
789797
trailingTrivia: Trivia? = nil
790798
) {
791-
let layout: [RawSyntax?] = [
792-
unexpectedBeforeIdentifier?.raw,
793-
identifier.raw,
794-
unexpectedAfterIdentifier?.raw,
795-
]
796-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
799+
// Extend the lifetime of all parameters so their arenas don't get destroyed
800+
// before they can be added as children of the new arena.
801+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpectedBeforeIdentifier, identifier, unexpectedAfterIdentifier))) { (arena, _) in
802+
let layout: [RawSyntax?] = [
803+
unexpectedBeforeIdentifier?.raw,
804+
identifier.raw,
805+
unexpectedAfterIdentifier?.raw,
806+
]
797807
let raw = RawSyntax.makeLayout(
798808
kind: SyntaxKind.identifierPattern, from: layout, arena: arena,
799809
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia)
@@ -925,16 +935,18 @@ public struct AsTypePatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
925935
_ unexpectedAfterType: UnexpectedNodesSyntax? = nil,
926936
trailingTrivia: Trivia? = nil
927937
) {
928-
let layout: [RawSyntax?] = [
929-
unexpectedBeforePattern?.raw,
930-
pattern.raw,
931-
unexpectedBetweenPatternAndAsKeyword?.raw,
932-
asKeyword.raw,
933-
unexpectedBetweenAsKeywordAndType?.raw,
934-
type.raw,
935-
unexpectedAfterType?.raw,
936-
]
937-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
938+
// Extend the lifetime of all parameters so their arenas don't get destroyed
939+
// before they can be added as children of the new arena.
940+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpectedBeforePattern, pattern, unexpectedBetweenPatternAndAsKeyword, asKeyword, unexpectedBetweenAsKeywordAndType, type, unexpectedAfterType))) { (arena, _) in
941+
let layout: [RawSyntax?] = [
942+
unexpectedBeforePattern?.raw,
943+
pattern.raw,
944+
unexpectedBetweenPatternAndAsKeyword?.raw,
945+
asKeyword.raw,
946+
unexpectedBetweenAsKeywordAndType?.raw,
947+
type.raw,
948+
unexpectedAfterType?.raw,
949+
]
938950
let raw = RawSyntax.makeLayout(
939951
kind: SyntaxKind.asTypePattern, from: layout, arena: arena,
940952
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia)
@@ -1164,16 +1176,18 @@ public struct TuplePatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
11641176
_ unexpectedAfterRightParen: UnexpectedNodesSyntax? = nil,
11651177
trailingTrivia: Trivia? = nil
11661178
) {
1167-
let layout: [RawSyntax?] = [
1168-
unexpectedBeforeLeftParen?.raw,
1169-
leftParen.raw,
1170-
unexpectedBetweenLeftParenAndElements?.raw,
1171-
elements.raw,
1172-
unexpectedBetweenElementsAndRightParen?.raw,
1173-
rightParen.raw,
1174-
unexpectedAfterRightParen?.raw,
1175-
]
1176-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
1179+
// Extend the lifetime of all parameters so their arenas don't get destroyed
1180+
// before they can be added as children of the new arena.
1181+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpectedBeforeLeftParen, leftParen, unexpectedBetweenLeftParenAndElements, elements, unexpectedBetweenElementsAndRightParen, rightParen, unexpectedAfterRightParen))) { (arena, _) in
1182+
let layout: [RawSyntax?] = [
1183+
unexpectedBeforeLeftParen?.raw,
1184+
leftParen.raw,
1185+
unexpectedBetweenLeftParenAndElements?.raw,
1186+
elements.raw,
1187+
unexpectedBetweenElementsAndRightParen?.raw,
1188+
rightParen.raw,
1189+
unexpectedAfterRightParen?.raw,
1190+
]
11771191
let raw = RawSyntax.makeLayout(
11781192
kind: SyntaxKind.tuplePattern, from: layout, arena: arena,
11791193
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia)
@@ -1420,14 +1434,16 @@ public struct WildcardPatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
14201434
_ unexpectedAfterTypeAnnotation: UnexpectedNodesSyntax? = nil,
14211435
trailingTrivia: Trivia? = nil
14221436
) {
1423-
let layout: [RawSyntax?] = [
1424-
unexpectedBeforeWildcard?.raw,
1425-
wildcard.raw,
1426-
unexpectedBetweenWildcardAndTypeAnnotation?.raw,
1427-
typeAnnotation?.raw,
1428-
unexpectedAfterTypeAnnotation?.raw,
1429-
]
1430-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
1437+
// Extend the lifetime of all parameters so their arenas don't get destroyed
1438+
// before they can be added as children of the new arena.
1439+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpectedBeforeWildcard, wildcard, unexpectedBetweenWildcardAndTypeAnnotation, typeAnnotation, unexpectedAfterTypeAnnotation))) { (arena, _) in
1440+
let layout: [RawSyntax?] = [
1441+
unexpectedBeforeWildcard?.raw,
1442+
wildcard.raw,
1443+
unexpectedBetweenWildcardAndTypeAnnotation?.raw,
1444+
typeAnnotation?.raw,
1445+
unexpectedAfterTypeAnnotation?.raw,
1446+
]
14311447
let raw = RawSyntax.makeLayout(
14321448
kind: SyntaxKind.wildcardPattern, from: layout, arena: arena,
14331449
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia)
@@ -1605,12 +1621,14 @@ public struct ExpressionPatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
16051621
_ unexpectedAfterExpression: UnexpectedNodesSyntax? = nil,
16061622
trailingTrivia: Trivia? = nil
16071623
) {
1608-
let layout: [RawSyntax?] = [
1609-
unexpectedBeforeExpression?.raw,
1610-
expression.raw,
1611-
unexpectedAfterExpression?.raw,
1612-
]
1613-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
1624+
// Extend the lifetime of all parameters so their arenas don't get destroyed
1625+
// before they can be added as children of the new arena.
1626+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpectedBeforeExpression, expression, unexpectedAfterExpression))) { (arena, _) in
1627+
let layout: [RawSyntax?] = [
1628+
unexpectedBeforeExpression?.raw,
1629+
expression.raw,
1630+
unexpectedAfterExpression?.raw,
1631+
]
16141632
let raw = RawSyntax.makeLayout(
16151633
kind: SyntaxKind.expressionPattern, from: layout, arena: arena,
16161634
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia)
@@ -1740,14 +1758,16 @@ public struct ValueBindingPatternSyntax: PatternSyntaxProtocol, SyntaxHashable {
17401758
_ unexpectedAfterValuePattern: UnexpectedNodesSyntax? = nil,
17411759
trailingTrivia: Trivia? = nil
17421760
) {
1743-
let layout: [RawSyntax?] = [
1744-
unexpectedBeforeLetOrVarKeyword?.raw,
1745-
letOrVarKeyword.raw,
1746-
unexpectedBetweenLetOrVarKeywordAndValuePattern?.raw,
1747-
valuePattern.raw,
1748-
unexpectedAfterValuePattern?.raw,
1749-
]
1750-
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
1761+
// Extend the lifetime of all parameters so their arenas don't get destroyed
1762+
// before they can be added as children of the new arena.
1763+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpectedBeforeLetOrVarKeyword, letOrVarKeyword, unexpectedBetweenLetOrVarKeywordAndValuePattern, valuePattern, unexpectedAfterValuePattern))) { (arena, _) in
1764+
let layout: [RawSyntax?] = [
1765+
unexpectedBeforeLetOrVarKeyword?.raw,
1766+
letOrVarKeyword.raw,
1767+
unexpectedBetweenLetOrVarKeywordAndValuePattern?.raw,
1768+
valuePattern.raw,
1769+
unexpectedAfterValuePattern?.raw,
1770+
]
17511771
let raw = RawSyntax.makeLayout(
17521772
kind: SyntaxKind.valueBindingPattern, from: layout, arena: arena,
17531773
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia)

0 commit comments

Comments
 (0)