Skip to content

Commit

Permalink
[clang-repl] Add host exception support check utility flag.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sunho committed Jul 28, 2022
1 parent 72ea1a7 commit 3cc3be8
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 3 deletions.
14 changes: 14 additions & 0 deletions clang/test/Interpreter/simple-exception.cpp
Original file line number Diff line number Diff line change
@@ -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
9 changes: 6 additions & 3 deletions clang/test/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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')
Expand Down
46 changes: 46 additions & 0 deletions clang/tools/clang-repl/ClangRepl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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]"));

Expand Down Expand Up @@ -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: ");
Expand All @@ -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));
Expand Down

0 comments on commit 3cc3be8

Please sign in to comment.