From: Sunho Kim Date: Sat, 30 Jul 2022 20:42:16 +0000 (+0900) Subject: [clang-repl] Disable building when LLVM_STATIC_LINK_CXX_STDLIB is ON. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a8f2e24e48fddb3707301c9d24cc50ab778d4fda;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 480f13e..82207fa 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -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) diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index 5b604b2..a05c372 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -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 diff --git a/clang/test/Interpreter/code-undo.cpp b/clang/test/Interpreter/code-undo.cpp index 9a908d6..c963e45 100644 --- a/clang/test/Interpreter/code-undo.cpp +++ b/clang/test/Interpreter/code-undo.cpp @@ -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 diff --git a/clang/test/Interpreter/execute-weak.cpp b/clang/test/Interpreter/execute-weak.cpp index 7d0b706..5b34351 100644 --- a/clang/test/Interpreter/execute-weak.cpp +++ b/clang/test/Interpreter/execute-weak.cpp @@ -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 diff --git a/clang/test/Interpreter/execute.cpp b/clang/test/Interpreter/execute.cpp index 124f649..ce2a5c7 100644 --- a/clang/test/Interpreter/execute.cpp +++ b/clang/test/Interpreter/execute.cpp @@ -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 diff --git a/clang/test/Interpreter/global-dtor-win.cpp b/clang/test/Interpreter/global-dtor-win.cpp deleted file mode 100644 index 4e03298..0000000 --- a/clang/test/Interpreter/global-dtor-win.cpp +++ /dev/null @@ -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(m)); }} d; -// CHECK: D[f=1.000000, m=0x0] - -%quit \ No newline at end of file diff --git a/clang/test/Interpreter/global-dtor.cpp b/clang/test/Interpreter/global-dtor.cpp index 7367fe4..1f241d9 100644 --- a/clang/test/Interpreter/global-dtor.cpp +++ b/clang/test/Interpreter/global-dtor.cpp @@ -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. diff --git a/clang/test/Interpreter/lit.local.cfg b/clang/test/Interpreter/lit.local.cfg new file mode 100644 index 0000000..b1ca766 --- /dev/null +++ b/clang/test/Interpreter/lit.local.cfg @@ -0,0 +1,2 @@ +if 'host-supports-jit' not in config.available_features: + config.unsupported = True \ No newline at end of file diff --git a/clang/test/Interpreter/plugins.cpp b/clang/test/Interpreter/plugins.cpp index 9faa7e9..59e4f2f 100644 --- a/clang/test/Interpreter/plugins.cpp +++ b/clang/test/Interpreter/plugins.cpp @@ -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*,...); diff --git a/clang/test/Interpreter/simple-exception.cpp b/clang/test/Interpreter/simple-exception.cpp index c56fbbb..dc13402 100644 --- a/clang/test/Interpreter/simple-exception.cpp +++ b/clang/test/Interpreter/simple-exception.cpp @@ -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 diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py index 01da76d..fd2c4fe 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -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') diff --git a/clang/tools/CMakeLists.txt b/clang/tools/CMakeLists.txt index 90ef041..1628109 100644 --- a/clang/tools/CMakeLists.txt +++ b/clang/tools/CMakeLists.txt @@ -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) diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index afd604d..d325373 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -28,8 +28,6 @@ static llvm::cl::list llvm::cl::CommaSeparated); static llvm::cl::opt OptHostSupportsJit("host-supports-jit", llvm::cl::Hidden); -static llvm::cl::opt OptHostSupportsException("host-supports-exception", - llvm::cl::Hidden); static llvm::cl::list 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 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)); diff --git a/clang/unittests/CMakeLists.txt b/clang/unittests/CMakeLists.txt index 51fe5de..3183619 100644 --- a/clang/unittests/CMakeLists.txt +++ b/clang/unittests/CMakeLists.txt @@ -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) diff --git a/clang/unittests/Interpreter/ExceptionTests/InterpreterExceptionTest.cpp b/clang/unittests/Interpreter/ExceptionTests/InterpreterExceptionTest.cpp index d827c91..f54c655 100644 --- a/clang/unittests/Interpreter/ExceptionTests/InterpreterExceptionTest.cpp +++ b/clang/unittests/Interpreter/ExceptionTests/InterpreterExceptionTest.cpp @@ -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 =