clc: Rework logging a bit
First, separate out the LLVM context logging to make it take a clc_logger instead of passing in a string stream. Currently, the LLVM context may outlive the string stream which we assign which may lead to use-after-free errors. Second, use a separate string stream for clang diagnosticl logging which we intentionally declare before the compiler so the compiler can't outlive it. Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Reviewed-by: Icecream95 <ixn@disroot.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15937>
This commit is contained in:

committed by
Marge Bot

parent
6e3b9b1b1d
commit
6099e6ce9a
@@ -73,9 +73,14 @@ using ::llvm::raw_string_ostream;
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
llvm_log_handler(const ::llvm::DiagnosticInfo &di, void *data) {
|
llvm_log_handler(const ::llvm::DiagnosticInfo &di, void *data) {
|
||||||
raw_string_ostream os { *reinterpret_cast<std::string *>(data) };
|
const clc_logger *logger = static_cast<clc_logger *>(data);
|
||||||
|
|
||||||
|
std::string log;
|
||||||
|
raw_string_ostream os { log };
|
||||||
::llvm::DiagnosticPrinterRawOStream printer { os };
|
::llvm::DiagnosticPrinterRawOStream printer { os };
|
||||||
di.print(printer);
|
di.print(printer);
|
||||||
|
|
||||||
|
clc_error(logger, "%s", log.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
class SPIRVKernelArg {
|
class SPIRVKernelArg {
|
||||||
@@ -748,15 +753,21 @@ clc_compile_to_llvm_module(const struct clc_compile_args *args,
|
|||||||
{
|
{
|
||||||
clc_initialize_llvm();
|
clc_initialize_llvm();
|
||||||
|
|
||||||
std::string log;
|
|
||||||
std::unique_ptr<LLVMContext> llvm_ctx { new LLVMContext };
|
std::unique_ptr<LLVMContext> llvm_ctx { new LLVMContext };
|
||||||
llvm_ctx->setDiagnosticHandlerCallBack(llvm_log_handler, &log);
|
llvm_ctx->setDiagnosticHandlerCallBack(llvm_log_handler,
|
||||||
|
const_cast<clc_logger *>(logger));
|
||||||
|
|
||||||
|
std::string diag_log_str;
|
||||||
|
raw_string_ostream diag_log_stream { diag_log_str };
|
||||||
|
|
||||||
std::unique_ptr<clang::CompilerInstance> c { new clang::CompilerInstance };
|
std::unique_ptr<clang::CompilerInstance> c { new clang::CompilerInstance };
|
||||||
clang::DiagnosticsEngine diag { new clang::DiagnosticIDs,
|
|
||||||
|
clang::DiagnosticsEngine diag {
|
||||||
|
new clang::DiagnosticIDs,
|
||||||
new clang::DiagnosticOptions,
|
new clang::DiagnosticOptions,
|
||||||
new clang::TextDiagnosticPrinter(*new raw_string_ostream(log),
|
new clang::TextDiagnosticPrinter(diag_log_stream,
|
||||||
&c->getDiagnosticOpts(), true)};
|
&c->getDiagnosticOpts())
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<const char *> clang_opts = {
|
std::vector<const char *> clang_opts = {
|
||||||
args->source.name,
|
args->source.name,
|
||||||
@@ -786,13 +797,13 @@ clc_compile_to_llvm_module(const struct clc_compile_args *args,
|
|||||||
clang_opts.data() + clang_opts.size(),
|
clang_opts.data() + clang_opts.size(),
|
||||||
#endif
|
#endif
|
||||||
diag)) {
|
diag)) {
|
||||||
clc_error(logger, "%sCouldn't create Clang invocation.\n", log.c_str());
|
clc_error(logger, "Couldn't create Clang invocation.\n");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diag.hasErrorOccurred()) {
|
if (diag.hasErrorOccurred()) {
|
||||||
clc_error(logger, "%sErrors occurred during Clang invocation.\n",
|
clc_error(logger, "%sErrors occurred during Clang invocation.\n",
|
||||||
log.c_str());
|
diag_log_str.c_str());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -802,8 +813,8 @@ clc_compile_to_llvm_module(const struct clc_compile_args *args,
|
|||||||
c->getDiagnosticOpts().ShowCarets = false;
|
c->getDiagnosticOpts().ShowCarets = false;
|
||||||
|
|
||||||
c->createDiagnostics(new clang::TextDiagnosticPrinter(
|
c->createDiagnostics(new clang::TextDiagnosticPrinter(
|
||||||
*new raw_string_ostream(log),
|
diag_log_stream,
|
||||||
&c->getDiagnosticOpts(), true));
|
&c->getDiagnosticOpts()));
|
||||||
|
|
||||||
c->setTarget(clang::TargetInfo::CreateTargetInfo(
|
c->setTarget(clang::TargetInfo::CreateTargetInfo(
|
||||||
c->getDiagnostics(), c->getInvocation().TargetOpts));
|
c->getDiagnostics(), c->getInvocation().TargetOpts));
|
||||||
@@ -870,7 +881,7 @@ clc_compile_to_llvm_module(const struct clc_compile_args *args,
|
|||||||
clang::EmitLLVMOnlyAction act(llvm_ctx.get());
|
clang::EmitLLVMOnlyAction act(llvm_ctx.get());
|
||||||
if (!c->ExecuteAction(act)) {
|
if (!c->ExecuteAction(act)) {
|
||||||
clc_error(logger, "%sError executing LLVM compilation action.\n",
|
clc_error(logger, "%sError executing LLVM compilation action.\n",
|
||||||
log.c_str());
|
diag_log_str.c_str());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user