mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-02 22:02:51 +01:00
Add a compile-time check that the condition of a CHECK is not constant. (#4628)
Inspired by #4624.
This commit is contained in:
+32
-10
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user