1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
#include "ast/passes/return_path_analyser.h"
#include "ast/passes/parser.h"
#include "ast/passes/semantic_analyser.h"
#include "ast/passes/type_system.h"
#include "mocks.h"
#include "gtest/gtest.h"
namespace bpftrace::test::return_path_analyser {
using ::testing::_;
void test(BPFtrace &bpftrace, const std::string &input, int expected_result = 0)
{
ast::ASTContext ast("stdin", input);
std::stringstream out;
std::stringstream msg;
msg << "\nInput:\n" << input << "\n\nOutput:\n";
ast::TypeMetadata no_types; // No external types defined.
auto ok = ast::PassManager()
.put(ast)
.put(bpftrace)
.put(no_types)
.add(ast::AllParsePasses())
.add(ast::CreateSemanticPass())
.add(ast::CreateReturnPathPass())
.run();
ast.diagnostics().emit(out);
EXPECT_EQ(int(!ast.diagnostics().ok()), expected_result)
<< msg.str() << out.str();
}
void test(const std::string &input, int expected_result = 0)
{
auto bpftrace = get_mock_bpftrace();
test(*bpftrace, input, expected_result);
}
TEST(return_path_analyser, simple_return)
{
test("fn test(): int64 { $x = 0; return 0; }", 0);
}
TEST(return_path_analyser, simple_no_return)
{
test("fn test(): int64 { $x = 0; }", 1);
}
TEST(return_path_analyser, if_else)
{
test("fn test($x: int64): int64 {"
" if ($x > 0) { return 0; } else { return 1; }"
"}",
0);
}
TEST(return_path_analyser, if_else_no_return)
{
test("fn test($x: int64): int64 {"
" if ($x > 0) { return 0; } else { $x = 0; }"
"}",
1);
}
TEST(return_path_analyser, if_without_else)
{
test("fn test($x: int64): int64 { if ($x > 0) { return 0; } }", 1);
}
TEST(return_path_analyser, while_loop)
{
test("fn test($x: int64): int64 { while ($x) { return 0; } }", 1);
}
TEST(return_path_analyser, if_branches)
{
test("fn test($x: int64): int64 {"
" if ($x > 0) {"
" if ($x > 0) { return 1; } else { return 0; }"
" } else {"
" if ($x > 0) { return 1; } else { return 0; }"
" }"
"}",
0);
}
TEST(return_path_analyser, if_branches_fail)
{
test("fn test($x: int64): int64 {"
" if ($x > 0) {"
" if ($x > 0) { return 1; } else { return 0; }"
" } else {"
" if ($x > 0) { return 1; } else { $x = 1; }"
" }"
"}",
1);
}
TEST(return_path_analyser, void_return_type)
{
test("fn test() : void {}", 0);
}
} // namespace bpftrace::test::return_path_analyser
|