Skip to content

Commit 9600b97

Browse files
authored
[SIL] Fix use-after-free in SILFunction::print. (#29949)
Fix use-after-free in helper function `printSILFunctionNameAndType`. The address of a `DenseMap` local variable is used after the function returns. Resolves SR-12239.
1 parent d082e90 commit 9600b97

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

lib/SIL/SILPrinter.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -437,14 +437,13 @@ void SILType::dump() const {
437437
}
438438

439439
/// Prints the name and type of the given SIL function with the given
440-
/// `PrintOptions`. Mutates `printOptions`, setting `GenericEnv` and
441-
/// `AlternativeTypeNames`.
442-
static void printSILFunctionNameAndType(llvm::raw_ostream &OS,
443-
const SILFunction *function,
444-
PrintOptions &printOptions) {
440+
/// `PrintOptions`. Computes mapping for sugared type names and stores the
441+
/// result in `sugaredTypeNames`.
442+
static void printSILFunctionNameAndType(
443+
llvm::raw_ostream &OS, const SILFunction *function,
444+
llvm::DenseMap<CanType, Identifier> &sugaredTypeNames) {
445445
function->printName(OS);
446446
OS << " : $";
447-
llvm::DenseMap<CanType, Identifier> aliases;
448447
auto genSig = function->getLoweredFunctionType()->getSubstGenericSignature();
449448
auto *genEnv = function->getGenericEnvironment();
450449
// If `genSig` and `genEnv` are both defined, get sugared names of generic
@@ -470,22 +469,24 @@ static void printSILFunctionNameAndType(llvm::raw_ostream &OS,
470469
continue;
471470
// Otherwise, add sugared name mapping for the type (and its archetype, if
472471
// defined).
473-
aliases[paramTy->getCanonicalType()] = name;
472+
sugaredTypeNames[paramTy->getCanonicalType()] = name;
474473
if (auto *archetypeTy =
475474
genEnv->mapTypeIntoContext(paramTy)->getAs<ArchetypeType>())
476-
aliases[archetypeTy->getCanonicalType()] = name;
475+
sugaredTypeNames[archetypeTy->getCanonicalType()] = name;
477476
}
478477
}
478+
auto printOptions = PrintOptions::printSIL();
479479
printOptions.GenericEnv = genEnv;
480-
printOptions.AlternativeTypeNames = aliases.empty() ? nullptr : &aliases;
480+
printOptions.AlternativeTypeNames =
481+
sugaredTypeNames.empty() ? nullptr : &sugaredTypeNames;
481482
function->getLoweredFunctionType()->print(OS, printOptions);
482483
}
483484

484485
/// Prints the name and type of the given SIL function.
485486
static void printSILFunctionNameAndType(llvm::raw_ostream &OS,
486487
const SILFunction *function) {
487-
auto printOptions = PrintOptions::printSIL();
488-
printSILFunctionNameAndType(OS, function, printOptions);
488+
llvm::DenseMap<CanType, Identifier> sugaredTypeNames;
489+
printSILFunctionNameAndType(OS, function, sugaredTypeNames);
489490
}
490491

491492
namespace {
@@ -2513,16 +2514,17 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
25132514
if (!isExternalDeclaration() && hasOwnership())
25142515
OS << "[ossa] ";
25152516

2516-
auto printOptions = PrintOptions::printSIL();
2517-
printSILFunctionNameAndType(OS, this, printOptions);
2517+
llvm::DenseMap<CanType, Identifier> sugaredTypeNames;
2518+
printSILFunctionNameAndType(OS, this, sugaredTypeNames);
25182519

25192520
if (!isExternalDeclaration()) {
25202521
if (auto eCount = getEntryCount()) {
25212522
OS << " !function_entry_count(" << eCount.getValue() << ")";
25222523
}
25232524
OS << " {\n";
25242525

2525-
SILPrinter(PrintCtx, printOptions.AlternativeTypeNames).print(this);
2526+
SILPrinter(PrintCtx, sugaredTypeNames.empty() ? nullptr : &sugaredTypeNames)
2527+
.print(this);
25262528
OS << "} // end sil function '" << getName() << '\'';
25272529
}
25282530

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-swift-frontend -emit-sil %s
2+
3+
// SR-12239: use-after-free in `SILFunction::print`.
4+
5+
func outer<C>(_ x: C) {
6+
func inner<C>(_ x: C) {}
7+
}

0 commit comments

Comments
 (0)