forked from simdjson/simdjson
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathondemand_assert_out_of_order_values.cpp
80 lines (69 loc) · 2.07 KB
/
ondemand_assert_out_of_order_values.cpp
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
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include "simdjson.h"
// We get spurious "maybe used uninitialized" warnings under GCC 12.
using namespace simdjson;
#if defined(__GNUC__) && !defined(__clang__)
#if __GNUC__ >= 12
SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
#endif
#endif
// This ensures the compiler can't rearrange them into the proper order (which causes it to work!)
simdjson_never_inline bool check_point(simdjson_result<ondemand::value> xval, simdjson_result<ondemand::value> yval) {
// Verify the expected release behavior
uint64_t x, y;
if (!xval.get(x)) { return false; }
if (!yval.get(y)) { return false; }
std::cout << x << "," << y << std::endl;
return true;
}
bool test_check_point() {
auto json = R"(
{
"x": 1,
"y": 2 3
)"_padded;
ondemand::parser parser;
auto doc = parser.iterate(json);
return check_point(doc["x"], doc["y"]);
}
// Run a test function in a fork and check whether it exited with an assert signal
template<typename F>
bool assert_test(const F& f) {
pid_t pid = fork();
if (pid == -1) {
std::cerr << "fork failed" << std::endl;
exit(1);
}
if (!pid) {
//
// This code runs in the fork (so we run the test function)
//
bool succeeded = f();
exit(succeeded ? 0 : 1);
}
//
// This code runs in the original executable (so we wait for the fork and check the exit code)
//
int exit_code = 0;
if (waitpid(pid, &exit_code, 0) == pid_t(-1)) {
std::cerr << "waitpid failed: " << std::string_view(strerror(errno)) << std::endl;
exit(1);
}
// Test passes if the child exited with an assert signal
return WIFSIGNALED(exit_code);
}
int main(void) {
// To verify that the program asserts (which sends a signal), we fork a new process and use wait()
// to check the resulting error code. If it's a signal error code, we consider the
// test to have passed.
// From https://stackoverflow.com/a/33694733
bool succeeded = true;
#ifndef NDEBUG
succeeded |= assert_test(test_check_point);
#endif
return succeeded ? 0 : 1;
}