Skip to content

Commit 6892ab5

Browse files
committed
ClangImporter: Take ownership of clang::TargetOptions used for code
generation Since llvm/llvm-project#106271, `clang::TargetInfo` does not co-own target options, so there is no longer anything to keep them alive after we discard the throwaway Clang invocation they originate from. Make the importer take ownership of a copy of code generation target options to avoid a use after free.
1 parent 59891c4 commit 6892ab5

File tree

2 files changed

+46
-30
lines changed

2 files changed

+46
-30
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,22 +1427,12 @@ ClangImporter::create(ASTContext &ctx,
14271427
importer.get(), importerOpts, VFS, *swiftTargetClangArgs);
14281428
if (!swiftTargetClangInvocation)
14291429
return nullptr;
1430-
auto targetInfo = clang::TargetInfo::CreateTargetInfo(
1431-
clangDiags, swiftTargetClangInvocation->getTargetOpts());
1432-
// Ensure the target info has configured target-specific defines
1433-
std::string defineBuffer;
1434-
llvm::raw_string_ostream predefines(defineBuffer);
1435-
clang::MacroBuilder builder(predefines);
1436-
targetInfo->getTargetDefines(instance.getLangOpts(), builder);
1437-
importer->Impl.setSwiftTargetInfo(targetInfo);
1438-
importer->Impl.setSwiftCodeGenOptions(new clang::CodeGenOptions(
1439-
swiftTargetClangInvocation->getCodeGenOpts()));
1430+
1431+
importer->Impl.configureOptionsForCodeGen(clangDiags,
1432+
swiftTargetClangInvocation.get());
14401433
} else {
1441-
// Just use the existing Invocation's directly
1442-
importer->Impl.setSwiftTargetInfo(clang::TargetInfo::CreateTargetInfo(
1443-
clangDiags, importer->Impl.Invocation->getTargetOpts()));
1444-
importer->Impl.setSwiftCodeGenOptions(
1445-
new clang::CodeGenOptions(importer->Impl.Invocation->getCodeGenOpts()));
1434+
// Set using the existing invocation.
1435+
importer->Impl.configureOptionsForCodeGen(clangDiags);
14461436
}
14471437

14481438
// Create the associated action.
@@ -4132,7 +4122,7 @@ clang::TargetInfo &ClangImporter::getModuleAvailabilityTarget() const {
41324122
}
41334123

41344124
clang::TargetInfo &ClangImporter::getTargetInfo() const {
4135-
return *Impl.getSwiftTargetInfo();
4125+
return Impl.getCodeGenTargetInfo();
41364126
}
41374127

41384128
clang::ASTContext &ClangImporter::getClangASTContext() const {
@@ -4165,7 +4155,7 @@ clang::Sema &ClangImporter::getClangSema() const {
41654155
}
41664156

41674157
clang::CodeGenOptions &ClangImporter::getCodeGenOpts() const {
4168-
return *Impl.getSwiftCodeGenOptions();
4158+
return Impl.getCodeGenOptions();
41694159
}
41704160

41714161
std::string ClangImporter::getClangModuleHash() const {
@@ -4612,6 +4602,36 @@ void ClangImporter::Implementation::getMangledName(
46124602
}
46134603
}
46144604

4605+
void ClangImporter::Implementation::configureOptionsForCodeGen(
4606+
clang::DiagnosticsEngine &Diags, clang::CompilerInvocation *CI) {
4607+
clang::TargetInfo *targetInfo = nullptr;
4608+
if (CI) {
4609+
TargetOpts.reset(new clang::TargetOptions(CI->getTargetOpts()));
4610+
CodeGenOpts.reset(new clang::CodeGenOptions(CI->getCodeGenOpts()));
4611+
targetInfo = clang::TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
4612+
4613+
// Ensure the target info has configured target-specific defines
4614+
std::string defineBuffer;
4615+
llvm::raw_string_ostream predefines(defineBuffer);
4616+
clang::MacroBuilder builder(predefines);
4617+
targetInfo->getTargetDefines(Instance->getLangOpts(), builder);
4618+
} else {
4619+
targetInfo =
4620+
clang::TargetInfo::CreateTargetInfo(Diags, Invocation->getTargetOpts());
4621+
}
4622+
4623+
CodeGenTargetInfo.reset(targetInfo);
4624+
}
4625+
4626+
clang::CodeGenOptions &
4627+
ClangImporter::Implementation::getCodeGenOptions() const {
4628+
if (CodeGenOpts) {
4629+
return *CodeGenOpts.get();
4630+
}
4631+
4632+
return Invocation->getCodeGenOpts();
4633+
}
4634+
46154635
// ---------------------------------------------------------------------------
46164636
// Swift lookup tables
46174637
// ---------------------------------------------------------------------------

lib/ClangImporter/ImporterImpl.h

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -634,22 +634,18 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
634634
/// corresponding to the instantiating Swift compilation's triple. These are
635635
/// to be used by all IRGen/CodeGen clients of `ClangImporter`.
636636
std::unique_ptr<clang::TargetInfo> CodeGenTargetInfo;
637+
std::unique_ptr<clang::TargetOptions> TargetOpts;
637638
std::unique_ptr<clang::CodeGenOptions> CodeGenOpts;
638639

639-
public:
640-
void setSwiftTargetInfo(clang::TargetInfo *SwiftTargetInfo) {
641-
CodeGenTargetInfo.reset(SwiftTargetInfo);
642-
}
643-
clang::TargetInfo *getSwiftTargetInfo() const {
644-
return CodeGenTargetInfo.get();
645-
}
640+
/// Sets the target & code generation options for use by IRGen/CodeGen
641+
/// clients of `ClangImporter`. If `CI` is null, the data is drawn from the
642+
/// importer's invocation.
643+
void configureOptionsForCodeGen(clang::DiagnosticsEngine &Diags,
644+
clang::CompilerInvocation *CI = nullptr);
646645

647-
void setSwiftCodeGenOptions(clang::CodeGenOptions *SwiftCodeGenOpts) {
648-
CodeGenOpts.reset(SwiftCodeGenOpts);
649-
}
650-
clang::CodeGenOptions *getSwiftCodeGenOptions() const {
651-
return CodeGenOpts.get();
652-
}
646+
clang::TargetInfo &getCodeGenTargetInfo() const { return *CodeGenTargetInfo; }
647+
648+
clang::CodeGenOptions &getCodeGenOptions() const;
653649

654650
private:
655651
/// Generation number that is used for crude versioning.

0 commit comments

Comments
 (0)