Add a compile-time check that the condition of a CHECK is not constant. (#4628)

Inspired by #4624.
This commit is contained in:
Richard Smith
2024-12-04 22:29:35 +00:00
committed by GitHub
parent 65166dc27b
commit a45cb86bf7
5 changed files with 77 additions and 22 deletions
+32 -10
View File
@@ -9,15 +9,22 @@
namespace Carbon {
namespace {
TEST(CheckTest, CheckTrue) { CARBON_CHECK(true); }
// Non-constexpr functions that always return true and false, to bypass constant
// condition checking.
auto AlwaysTrue() -> bool { return true; }
auto AlwaysFalse() -> bool { return false; }
TEST(CheckTest, CheckTrue) { CARBON_CHECK(AlwaysTrue()); }
TEST(CheckTest, CheckFalse) {
ASSERT_DEATH({ CARBON_CHECK(false); },
"\nCHECK failure at common/check_test.cpp:\\d+: false\n");
ASSERT_DEATH({ CARBON_CHECK(AlwaysFalse()); },
R"(
CHECK failure at common/check_test.cpp:\d+: AlwaysFalse\(\)
)");
}
TEST(CheckTest, CheckFalseHasStackDump) {
ASSERT_DEATH({ CARBON_CHECK(false); }, "\nStack dump:\n");
ASSERT_DEATH({ CARBON_CHECK(AlwaysFalse()); }, "\nStack dump:\n");
}
TEST(CheckTest, CheckTrueCallbackNotUsed) {
@@ -26,13 +33,15 @@ TEST(CheckTest, CheckTrueCallbackNotUsed) {
called = true;
return "called";
};
CARBON_CHECK(true, "{0}", callback());
CARBON_CHECK(AlwaysTrue(), "{0}", callback());
EXPECT_FALSE(called);
}
TEST(CheckTest, CheckFalseMessage) {
ASSERT_DEATH({ CARBON_CHECK(false, "msg"); },
"\nCHECK failure at common/check_test.cpp:.+: false: msg\n");
ASSERT_DEATH({ CARBON_CHECK(AlwaysFalse(), "msg"); },
R"(
CHECK failure at common/check_test.cpp:.+: AlwaysFalse\(\): msg
)");
}
TEST(CheckTest, CheckFalseFormattedMessage) {
@@ -40,15 +49,17 @@ TEST(CheckTest, CheckFalseFormattedMessage) {
std::string str = "str";
int i = 1;
ASSERT_DEATH(
{ CARBON_CHECK(false, "{0} {1} {2} {3}", msg, str, i, 0); },
"\nCHECK failure at common/check_test.cpp:.+: false: msg str 1 0\n");
{ CARBON_CHECK(AlwaysFalse(), "{0} {1} {2} {3}", msg, str, i, 0); },
R"(
CHECK failure at common/check_test.cpp:.+: AlwaysFalse\(\): msg str 1 0
)");
}
TEST(CheckTest, CheckOutputForms) {
const char msg[] = "msg";
std::string str = "str";
int i = 1;
CARBON_CHECK(true, "{0} {1} {2} {3}", msg, str, i, 0);
CARBON_CHECK(AlwaysTrue(), "{0} {1} {2} {3}", msg, str, i, 0);
}
TEST(CheckTest, Fatal) {
@@ -67,5 +78,16 @@ TEST(ErrorTest, FatalNoReturnRequired) {
"\nFATAL failure at common/check_test.cpp:.+: msg\n");
}
// Detects whether `CARBON_CHECK(F())` compiles.
template <auto F>
concept CheckCompilesWithCondition = requires { CARBON_CHECK(F()); };
TEST(CheckTest, CheckConstantCondition) {
EXPECT_TRUE(CheckCompilesWithCondition<[] { return AlwaysTrue(); }>);
EXPECT_TRUE(CheckCompilesWithCondition<[] { return AlwaysFalse(); }>);
EXPECT_FALSE(CheckCompilesWithCondition<[] { return true; }>);
EXPECT_FALSE(CheckCompilesWithCondition<[] { return false; }>);
}
} // namespace
} // namespace Carbon