mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 01:58:44 +08:00
[clang-repl] Disable building when LLVM_STATIC_LINK_CXX_STDLIB is ON.
We have seen random symbol not found "__cxa_throw" error in fuschia build bots and out-of-tree users. The understanding have been that they are built without exception support, but it turned out that these platforms have LLVM_STATIC_LINK_CXX_STDLIB ON so that they link libstdc++ to llvm statically. The reason why this is problematic for clang-repl is that by default clang-repl tries to find symbols from symbol table of executable and dynamic libraries loaded by current process. It needs to load another libstdc++, but the platform that had LLVM_STATIC_LINK_CXX_STDLIB turned on is usally those with missing or obsolate shared libstdc++ in the first place -- trying to load it again would be destined to fail eventually with a risk to introuduce mixed libstdc++ versions. A proper solution that doesn't take a workaround is statically link the same libstdc++ by clang-repl side, but this is not possible with old JIT linker runtimedyld. New just-in-time linker JITLink handles this relatively well, but it's not availalbe in majority of platforms. For now, this patch just disables the building of clang-repl when LLVM_STATIC_LINK_CXX_STDLIB is ON and removes the "__cxa_throw" check in exception unittest as well as reverting previous exception check flag patch. Reviewed By: v.g.vassilev Differential Revision: https://reviews.llvm.org/D130788
This commit is contained in:
@@ -504,6 +504,13 @@ CMAKE_DEPENDENT_OPTION(CLANG_PLUGIN_SUPPORT
|
||||
"Build clang with plugin support" ON
|
||||
"HAVE_CLANG_PLUGIN_SUPPORT" OFF)
|
||||
|
||||
# If libstdc++ is statically linked, clang-repl needs to statically link libstdc++
|
||||
# itself, which is not possible in many platforms because of current limitations in
|
||||
# JIT stack. (more platforms need to be supported by JITLink)
|
||||
if(NOT LLVM_STATIC_LINK_CXX_STDLIB)
|
||||
set(HAVE_CLANG_REPL_SUPPORT ON)
|
||||
endif()
|
||||
|
||||
option(CLANG_ENABLE_ARCMT "Build ARCMT." ON)
|
||||
option(CLANG_ENABLE_STATIC_ANALYZER
|
||||
"Include static analyzer in clang binary." ON)
|
||||
|
||||
@@ -66,7 +66,6 @@ list(APPEND CLANG_TEST_DEPS
|
||||
clang-import-test
|
||||
clang-rename
|
||||
clang-refactor
|
||||
clang-repl
|
||||
clang-diff
|
||||
clang-scan-deps
|
||||
diagtool
|
||||
@@ -147,6 +146,12 @@ if(CLANG_ENABLE_STATIC_ANALYZER)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (HAVE_CLANG_REPL_SUPPORT)
|
||||
list(APPEND CLANG_TEST_DEPS
|
||||
clang-repl
|
||||
)
|
||||
endif()
|
||||
|
||||
# Copy gen_ast_dump_json_test.py to the clang build dir. This allows invoking
|
||||
# it without having to pass the --clang= argument
|
||||
configure_file(AST/gen_ast_dump_json_test.py
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \
|
||||
// RUN: 'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s
|
||||
// REQUIRES: host-supports-jit
|
||||
// UNSUPPORTED: system-aix
|
||||
// CHECK-DRIVER: i = 10
|
||||
// RUN: cat %s | clang-repl | FileCheck %s
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// RUN: clang-repl "int x = 10;" "int y=7; err;" "int y = 10;"
|
||||
// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \
|
||||
// RUN: 'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s
|
||||
// REQUIRES: host-supports-jit
|
||||
// CHECK-DRIVER: i = 10
|
||||
// UNSUPPORTED: system-aix, system-windows
|
||||
// RUN: cat %s | clang-repl | FileCheck %s
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// RUN: clang-repl "int x = 10;" "int y=7; err;" "int y = 10;"
|
||||
// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \
|
||||
// RUN: 'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s
|
||||
// REQUIRES: host-supports-jit
|
||||
// UNSUPPORTED: system-aix
|
||||
// CHECK-DRIVER: i = 10
|
||||
// RUN: cat %s | clang-repl | FileCheck %s
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
// clang-format off
|
||||
// FIXME: Merge into global-dtor.cpp when exception support arrives on windows-msvc
|
||||
// REQUIRES: host-supports-jit && windows-msvc
|
||||
//
|
||||
// Tests that a global destructor is ran in windows-msvc platform.
|
||||
//
|
||||
// RUN: cat %s | clang-repl | FileCheck %s
|
||||
|
||||
extern "C" int printf(const char *, ... );
|
||||
|
||||
struct D { float f = 1.0; D *m = nullptr; D(){} ~D() { printf("D[f=%f, m=0x%llx]\n", f, reinterpret_cast<unsigned long long>(m)); }} d;
|
||||
// CHECK: D[f=1.000000, m=0x0]
|
||||
|
||||
%quit
|
||||
@@ -1,5 +1,4 @@
|
||||
// clang-format off
|
||||
// REQUIRES: host-supports-jit, host-supports-exception
|
||||
// UNSUPPORTED: system-aix
|
||||
//
|
||||
// Tests that a global destructor is ran on platforms with gnu exception support.
|
||||
|
||||
2
clang/test/Interpreter/lit.local.cfg
Normal file
2
clang/test/Interpreter/lit.local.cfg
Normal file
@@ -0,0 +1,2 @@
|
||||
if 'host-supports-jit' not in config.available_features:
|
||||
config.unsupported = True
|
||||
@@ -1,7 +1,7 @@
|
||||
// RUN: cat %s | clang-repl -Xcc -Xclang -Xcc -load -Xcc -Xclang \
|
||||
// RUN: -Xcc %llvmshlibdir/PrintFunctionNames%pluginext -Xcc -Xclang\
|
||||
// RUN: -Xcc -add-plugin -Xcc -Xclang -Xcc print-fns 2>&1 | FileCheck %s
|
||||
// REQUIRES: host-supports-jit, plugins, examples
|
||||
// REQUIRES: plugins, examples
|
||||
|
||||
int i = 10;
|
||||
extern "C" int printf(const char*,...);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// clang-format off
|
||||
// REQUIRES: host-supports-jit, host-supports-exception
|
||||
// UNSUPPORTED: system-aix
|
||||
// XFAIL: arm, arm64-apple, windows-msvc, windows-gnu
|
||||
// RUN: cat %s | clang-repl | FileCheck %s
|
||||
|
||||
@@ -74,7 +74,6 @@ def have_host_jit_feature_support(feature_name):
|
||||
clang_repl_exe = lit.util.which('clang-repl', config.clang_tools_dir)
|
||||
|
||||
if not clang_repl_exe:
|
||||
print('clang-repl not found')
|
||||
return False
|
||||
|
||||
try:
|
||||
@@ -92,9 +91,6 @@ def have_host_jit_feature_support(feature_name):
|
||||
if have_host_jit_feature_support('jit'):
|
||||
config.available_features.add('host-supports-jit')
|
||||
|
||||
if have_host_jit_feature_support('exception'):
|
||||
config.available_features.add('host-supports-exception')
|
||||
|
||||
if config.clang_staticanalyzer:
|
||||
config.available_features.add('staticanalyzer')
|
||||
tools.append('clang-check')
|
||||
|
||||
@@ -14,7 +14,9 @@ add_clang_subdirectory(clang-offload-packager)
|
||||
add_clang_subdirectory(clang-offload-bundler)
|
||||
add_clang_subdirectory(clang-offload-wrapper)
|
||||
add_clang_subdirectory(clang-scan-deps)
|
||||
add_clang_subdirectory(clang-repl)
|
||||
if(HAVE_CLANG_REPL_SUPPORT)
|
||||
add_clang_subdirectory(clang-repl)
|
||||
endif()
|
||||
|
||||
add_clang_subdirectory(c-index-test)
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@ static llvm::cl::list<std::string>
|
||||
llvm::cl::CommaSeparated);
|
||||
static llvm::cl::opt<bool> OptHostSupportsJit("host-supports-jit",
|
||||
llvm::cl::Hidden);
|
||||
static llvm::cl::opt<bool> OptHostSupportsException("host-supports-exception",
|
||||
llvm::cl::Hidden);
|
||||
static llvm::cl::list<std::string> OptInputs(llvm::cl::Positional,
|
||||
llvm::cl::desc("[code to run]"));
|
||||
|
||||
@@ -67,42 +65,6 @@ static int checkDiagErrors(const clang::CompilerInstance *CI) {
|
||||
return Errs ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Check if the host environment supports c++ exception handling
|
||||
// by querying the existence of symbol __cxa_throw.
|
||||
static bool checkExceptionSupport() {
|
||||
auto J = llvm::orc::LLJITBuilder().create();
|
||||
if (!J) {
|
||||
llvm::consumeError(J.takeError());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<const char *> Dummy;
|
||||
auto CI = clang::IncrementalCompilerBuilder::create(Dummy);
|
||||
if (!CI) {
|
||||
llvm::consumeError(CI.takeError());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto Interp = clang::Interpreter::create(std::move(*CI));
|
||||
if (!Interp) {
|
||||
llvm::consumeError(Interp.takeError());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto Err = (*Interp)->ParseAndExecute("")) {
|
||||
llvm::consumeError(std::move(Err));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto Sym = (*Interp)->getSymbolAddress("__cxa_throw");
|
||||
if (!Sym) {
|
||||
llvm::consumeError(Sym.takeError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
llvm::ExitOnError ExitOnErr;
|
||||
int main(int argc, const char **argv) {
|
||||
ExitOnErr.setBanner("clang-repl: ");
|
||||
@@ -127,14 +89,6 @@ int main(int argc, const char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (OptHostSupportsException) {
|
||||
if (checkExceptionSupport())
|
||||
llvm::outs() << "true\n";
|
||||
else
|
||||
llvm::outs() << "false\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: Investigate if we could use runToolOnCodeWithArgs from tooling. It
|
||||
// can replace the boilerplate code for creation of the compiler instance.
|
||||
auto CI = ExitOnErr(clang::IncrementalCompilerBuilder::create(ClangArgv));
|
||||
|
||||
@@ -35,7 +35,9 @@ add_subdirectory(Frontend)
|
||||
add_subdirectory(Rewrite)
|
||||
add_subdirectory(Sema)
|
||||
add_subdirectory(CodeGen)
|
||||
add_subdirectory(Interpreter)
|
||||
if(HAVE_CLANG_REPL_SUPPORT)
|
||||
add_subdirectory(Interpreter)
|
||||
endif()
|
||||
# FIXME: libclang unit tests are disabled on Windows due
|
||||
# to failures, mostly in libclang.VirtualFileOverlay_*.
|
||||
if(NOT WIN32 AND CLANG_TOOL_LIBCLANG_BUILD)
|
||||
|
||||
@@ -113,17 +113,6 @@ extern "C" int throw_exception() {
|
||||
Triple.getArch() == llvm::Triple::aarch64_32))
|
||||
return;
|
||||
|
||||
// Check if platform does not support exceptions.
|
||||
{
|
||||
// Force the creation of an incremental executor to call getSymbolAddress.
|
||||
llvm::cantFail(Interp->ParseAndExecute(""));
|
||||
auto Sym = Interp->getSymbolAddress("__cxa_throw");
|
||||
if (!Sym) {
|
||||
LLVMConsumeError(llvm::wrap(Sym.takeError()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
llvm::cantFail(Interp->ParseAndExecute(ExceptionCode));
|
||||
testing::internal::CaptureStdout();
|
||||
auto ThrowException =
|
||||
|
||||
Reference in New Issue
Block a user