[libcxx-commits] [libcxx] DRAFT [libc++][hardening] In production hardening modes, trap rather than abort (PR #78561)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jan 18 13:05:53 PST 2024
================
@@ -27,37 +28,70 @@
#include "test_allocator.h"
#if TEST_STD_VER < 11
-# error "C++11 or greater is required to use this header"
+# error "C++11 or greater is required to use this header"
#endif
struct AssertionInfoMatcher {
- static const int any_line = -1;
+ // When printing the assertion message to `stderr`, delimit it with a marker to make it easier to match the message
+ // later.
+ static constexpr const char* Marker = "###";
+
+ static const int any_line = -1;
static constexpr const char* any_file = "*";
- static constexpr const char* any_msg = "*";
+ static constexpr const char* any_msg = "*";
- constexpr AssertionInfoMatcher() : is_empty_(true), msg_(any_msg, __builtin_strlen(any_msg)), file_(any_file, __builtin_strlen(any_file)), line_(any_line) { }
+ constexpr AssertionInfoMatcher()
+ : msg_(any_msg, __builtin_strlen(any_msg)), file_(any_file, __builtin_strlen(any_file)), line_(any_line) {}
constexpr AssertionInfoMatcher(const char* msg, const char* file = any_file, int line = any_line)
- : is_empty_(false), msg_(msg, __builtin_strlen(msg)), file_(file, __builtin_strlen(file)), line_(line) {}
+ : is_empty_(false), msg_(msg, __builtin_strlen(msg)), file_(file, __builtin_strlen(file)), line_(line) {}
+
+ bool CheckMatchInOutput(const std::string& output, std::string& error) const {
+ // Extract information from the error message. This has to stay synchronized with how we format assertions in the
+ // library.
+ std::regex message_format(".*###\\n(.*):(\\d+): assertion (.*) failed: (.*)\\n###");
+
+ std::smatch match_result;
+ bool has_match = std::regex_match(output, match_result, message_format);
+ assert(has_match);
+ assert(match_result.size() == 5);
+
+ const std::string& file = match_result[1];
+ int line = std::stoi(match_result[2]);
+ // Omitting `expression` in `match_result[3]`
+ const std::string& failure_reason = match_result[4];
+
+ bool result = Matches(file, line, failure_reason);
+ if (!result) {
+ error = FormatMatchingError(file, line, failure_reason);
+ }
+ return result;
+ }
- bool Matches(char const* file, int line, char const* message) const {
- assert(!empty() && "empty matcher");
+ bool Matches(const std::string& file, int line, const std::string& message) const {
+ assert(!empty() && "Empty matcher");
+ return CheckLineMatches(line) && CheckFileMatches(file) && CheckMessageMatches(message);
+ }
- if (CheckLineMatches(line) && CheckFileMatches(file) && CheckMessageMatches(message))
- return true;
- // Write to stdout because that's the file descriptor captured by the parent
- // process.
- std::printf("Failed to match assertion info!\n%s\nVS\n%s:%d (%s)\n", ToString().data(), file, line, message);
- return false;
+ std::string FormatMatchingError(const std::string& file, int line, const std::string& message) const {
+ std::stringstream output;
+ output //
+ << "Expected message: '" << msg_.data() << "'\n" //
+ << "Actual message: '" << message.c_str() << "'\n" //
+ << "Expected location: " << FormatLocation(file_, line_) << "\n" //
+ << "Actual location: " << FormatLocation(file, line) << "\n";
+ return output.str();
}
- std::string ToString() const {
- std::string result = "msg = \""; result += msg_; result += "\"\n";
- result += "line = " + (line_ == any_line ? "'*'" : std::to_string(line_)) + "\n";
- result += "file = " + (file_ == any_file ? "'*'" : std::string(file_));
+ static std::string FormatLocation(std::string_view file, int line) {
+ std::string result;
+ result += (file == any_file ? "*" : std::string(file)) + ":";
+ result += (line == any_line ? "*" : std::to_string(line));
return result;
}
bool empty() const { return is_empty_; }
+ bool IsAnyMatcher() const { return msg_ == any_msg && file_ == any_file && line_ == any_line; }
----------------
ldionne wrote:
I think this is unused now.
https://github.com/llvm/llvm-project/pull/78561
More information about the libcxx-commits
mailing list