[clang] 3cc3be8 - [clang-repl] Add host exception support check utility flag.

Sunho Kim via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 28 05:16:42 PDT 2022


Author: Sunho Kim
Date: 2022-07-28T21:14:58+09:00
New Revision: 3cc3be8fa471c69ac7cf9c071554a14020226158

URL: https://github.com/llvm/llvm-project/commit/3cc3be8fa471c69ac7cf9c071554a14020226158
DIFF: https://github.com/llvm/llvm-project/commit/3cc3be8fa471c69ac7cf9c071554a14020226158.diff

LOG: [clang-repl] Add host exception support check utility flag.

Add host exception support check utility flag. This is needed to not run tests that require exception support in few buildbots that lacks related symbols for some reason.

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D129242

Added: 
    clang/test/Interpreter/simple-exception.cpp

Modified: 
    clang/test/lit.cfg.py
    clang/tools/clang-repl/ClangRepl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/test/Interpreter/simple-exception.cpp b/clang/test/Interpreter/simple-exception.cpp
new file mode 100644
index 0000000000000..c56fbbb417f08
--- /dev/null
+++ b/clang/test/Interpreter/simple-exception.cpp
@@ -0,0 +1,14 @@
+// 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
+extern "C" int printf(const char *, ...);
+
+int f() { throw "Simple exception"; return 0; }
+int checkException() { try { printf("Running f()\n"); f(); } catch (const char *e) { printf("%s\n", e); } return 0; }
+auto r1 = checkException();
+// CHECK: Running f()
+// CHECK-NEXT: Simple exception
+
+%quit
\ No newline at end of file

diff  --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py
index d95ea5d2da198..01da76de86a15 100644
--- a/clang/test/lit.cfg.py
+++ b/clang/test/lit.cfg.py
@@ -70,7 +70,7 @@
 if config.clang_examples:
     config.available_features.add('examples')
 
-def have_host_jit_support():
+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:
@@ -79,7 +79,7 @@ def have_host_jit_support():
 
     try:
         clang_repl_cmd = subprocess.Popen(
-            [clang_repl_exe, '--host-supports-jit'], stdout=subprocess.PIPE)
+            [clang_repl_exe, '--host-supports-' + feature_name], stdout=subprocess.PIPE)
     except OSError:
         print('could not exec clang-repl')
         return False
@@ -89,9 +89,12 @@ def have_host_jit_support():
 
     return 'true' in clang_repl_out
 
-if have_host_jit_support():
+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/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp
index 4f673bdcb7cc5..490e2feed50e1 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -28,6 +28,8 @@ 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]"));
 
@@ -65,6 +67,42 @@ 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: ");
@@ -87,6 +125,14 @@ 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));


        


More information about the cfe-commits mailing list