[CI] Test ctest for LLVM 10-19
Fixes: https://github.com/lfortran/lfortran/issues/4980
This works on my machine, I need to check why it is failing here.
This is not related to LLVM 17. It fails for LLVM 12 as well.
It seg faults for testing the failures:
CHECK_THROWS_AS(e.add_module(R"""(
define i64 @f3()
{
; FAIL: @count is not defined
%1 = load i64, i64* @count
ret i64 %1
}
)"""), LCompilers::LCompilersException);
I got the following information from lldb in GitHub Actions:
* thread #1, name = 'test_lfortran', stop reason = signal SIGSEGV: address not mapped to object (fault address: 0x7ffff7fb5000)
* frame #0: 0x00007ffff7ebf9ee libgcc_s.so.1`___lldb_unnamed_symbol296 + 14
frame #1: 0x00007ffff7ec064a libgcc_s.so.1`___lldb_unnamed_symbol301 + 794
frame #2: 0x00007ffff7ec0f86 libgcc_s.so.1`_Unwind_Find_FDE + 678
frame #3: 0x00007ffff7ebd453 libgcc_s.so.1`___lldb_unnamed_symbol283 + 99
frame #4: 0x00007ffff7ebe6f0 libgcc_s.so.1`___lldb_unnamed_symbol286 + 80
frame #5: 0x00007ffff7ebec79 libgcc_s.so.1`_Unwind_RaiseException + 73
frame #6: 0x00007ffff7cae4cb libstdc++.so.6`__cxa_throw + 59
frame #7: 0x000055555638077c test_lfortran`LCompilers::LFortran::Tokenizer::lex(this=0x00007fffffffc210, al=0x00007fffffffced8, yylval=0x00007fffffffbf38, loc=0x00007fffffffbf58, diagnostics=0x00007fffffffc680) at tokenizer.re:263:17
frame #8: 0x000055555677e75d test_lfortran`yylex(yylval=0x00007fffffffbf38, yyloc=0x00007fffffffbf58, p=0x00007fffffffc1e0) at parser.yy:42:33
frame #9: 0x000055555677ea22 test_lfortran`yygetToken(yycharp=0x00007fffffffbf34, yystackp=0x00007fffffffbe50, p=0x00007fffffffc1e0) at parser.tab.cc:15886:24
frame #10: 0x00005555567b90f7 test_lfortran`yyparse(p=0x00007fffffffc1e0) at parser.tab.cc:23042:45
frame #11: 0x00005555563a9889 test_lfortran`LCompilers::LFortran::Parser::parse(this=0x00007fffffffc1e0, input="$") at parser.cpp:168:20
frame #12: 0x00005555563a9482 test_lfortran`LCompilers::LFortran::parse(al=0x00007fffffffced8, s="$", diagnostics=0x00007fffffffc680, co=0x00007fffffffcca0) at parser.cpp:124:21
frame #13: 0x00005555565c878a test_lfortran`LCompilers::FortranEvaluator::get_ast2(this=0x00007fffffffcca0, code_orig="$", lm=0x00007fffffffc6a0, diagnostics=0x00007fffffffc680) at fortran_evaluator.cpp:218:71
frame #14: 0x00005555565c7730 test_lfortran`LCompilers::FortranEvaluator::evaluate(this=0x00007fffffffcca0, code_orig="$", verbose=false, lm=0x00007fffffffc6a0, pass_manager=0x00007fffffffc6d0, diagnostics=0x00007fffffffc680) at fortran_evaluator.cpp:87:35
frame #15: 0x000055555635a5d8 test_lfortran`::DOCTEST_ANON_FUNC_32() at test_llvm.cpp:574:52
frame #16: 0x0000555556c1a84d test_lfortran`doctest::Context::run(this=0x00007fffffffd3c0) at doctest.h:6727:30
frame #17: 0x0000555556c1b2ac test_lfortran`main(argc=1, argv=0x00007fffffffd4f8) at doctest.h:6805:74
frame #18: 0x00007ffff7829d90 libc.so.6`___lldb_unnamed_symbol3139 + 128
frame #19: 0x00007ffff7829e40 libc.so.6`__libc_start_main + 128
frame #20: 0x00005555562ba235 test_lfortran`_start + 37
tokenizer.re, line 263 is the end of:
* { token_loc(loc);
std::string t = token();
throw parser_local::TokenizerError(diag::Diagnostic(
"Token '" + t + "' is not recognized",
diag::Level::Error, diag::Stage::Tokenizer, {
diag::Label("token not recognized", {loc})
})
);
}
so it is probably getting some token that it can't tokenize and raising an exception that somehow fails? It seems to fail at this test in test_llvm.cpp:
LCompilers::Result<FortranEvaluator::EvalResult>
r = e.evaluate("$", false, lm, lpm, diagnostics);
CHECK(!r.ok);
This test is checking that we give the correct error when the token ($ in this case) is not recognized by the lexer. It seems the lexer correctly not recognized it, and is throwing TokenizerError exception. However, somehow we get a segfault later. It's possible the exception is not caught, or there is some dangling pointer somewhere in the exception. Try to modify this to be just simple exception like std::runtime_error and catch it, or something like that.
It looks like we are not catching this exception here:
bool Parser::parse(const std::string &input)
{
inp = input;
if (inp.size() > 0) {
if (inp[inp.size()-1] != '\n') inp.append("\n");
} else {
inp.append("\n");
}
if (!fixed_form) {
m_tokenizer.set_string(inp);
if (yyparse(*this) == 0) {
if (diag.has_error())
return false;
return true;
}
Which might be the issue. We do catch it in the other parser function:
Result<AST::TranslationUnit_t*> parse(Allocator &al, const std::string &s,
diag::Diagnostics &diagnostics, const CompilerOptions &co)
{
Parser p(al, diagnostics, co.fixed_form);
try {
if (!p.parse(s)) {
return Error();
};
} catch (const parser_local::TokenizerError &e) {
Error error;
diagnostics.diagnostics.push_back(e.d);
return error;
So I think the bug is that the exception is never caught. But how is it that the test sometimes passes? And how is it that it works for LLVM < 17? It seems this has nothing to do with LLVM.
Yes, it seems the issue is not related to LLVM.
It fails on multiple tests in test_llvm, as well as test_parse and test_pickle.
In test_llvm, FortranEvaluator 6, 9, and llvm ir 1 fail.
In test_parse, LFortran::Allocator, LFortran::Allocator 2 and Tokenizer fail.
I used, std::runtime_error, it still seg faults. The issue can be related to CHECK_THROWS_AS
The ctest is already being tested by the CI, so closing this. See, https://github.com/lfortran/lfortran/blob/7345b2e537c335b81655b66e68dbdb21f473fed1/.github/workflows/CI.yml#L974