https://github.com/mechakotik updated https://github.com/llvm/llvm-project/pull/195793
>From 0083046de6e7e741d228d7576846d0343ebff683 Mon Sep 17 00:00:00 2001 From: Andrei Sabalenka <[email protected]> Date: Tue, 5 May 2026 01:45:22 +0300 Subject: [PATCH] [clang][AST] Treat unsigned _BitInt(1) as boolean-valued Update Expr::isKnownToHaveBooleanValue to recognize unsigned _BitInt(1) when semantic boolean-ness is not required. --- clang/lib/AST/Expr.cpp | 5 ++++ clang/unittests/AST/ASTExprTest.cpp | 46 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 64d61dbc3d128..a542f2492c63f 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -142,6 +142,11 @@ bool Expr::isKnownToHaveBooleanValue(bool Semantic) const { // If this is a non-scalar-integer type, we don't care enough to try. if (!E->getType()->isIntegralOrEnumerationType()) return false; + if (!Semantic) + if (const auto *BIT = E->getType()->getAs<BitIntType>()) + if (BIT->isUnsigned() && BIT->getNumBits() == 1) + return true; + if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { switch (UO->getOpcode()) { case UO_Plus: diff --git a/clang/unittests/AST/ASTExprTest.cpp b/clang/unittests/AST/ASTExprTest.cpp index adaceb76de8b4..6e5683c68eb4d 100644 --- a/clang/unittests/AST/ASTExprTest.cpp +++ b/clang/unittests/AST/ASTExprTest.cpp @@ -108,3 +108,49 @@ TEST(ASTExpr, InitListIsConstantInitialized) { (void)FooInit->updateInit(Ctx, 2, Ref); EXPECT_FALSE(FooInit->isConstantInitializer(Ctx, false)); } + +TEST(ASTExpr, IsKnownToHaveBooleanValue) { + auto AST = tooling::buildASTFromCodeWithArgs( + R"c( + struct S { + int signed_bf1 : 1; + unsigned unsigned_bf1 : 1; + unsigned unsigned_bf2 : 2; + }; + + _Bool bool_value; + int int_value; + unsigned _BitInt(1) unsigned_bitint1; + unsigned _BitInt(2) unsigned_bitint2; + struct S s; + + void f(void) { + int from_bool = bool_value; + int from_int = int_value; + int from_signed_bitfield1 = s.signed_bf1; + int from_bitfield1 = s.unsigned_bf1; + int from_bitfield2 = s.unsigned_bf2; + int from_bitint1 = unsigned_bitint1; + int from_bitint2 = unsigned_bitint2; + } + )c", + {"-std=c23"}, "input.c"); + ASSERT_TRUE(AST); + + auto ExpectKnown = [&](const char *Name, bool Semantic, bool NonSemantic) { + const VarDecl *VD = getVariableNode(AST.get(), Name); + ASSERT_NE(VD, nullptr); + ASSERT_TRUE(VD->hasInit()); + const Expr *Init = VD->getInit(); + EXPECT_EQ(Semantic, Init->isKnownToHaveBooleanValue(true)) << Name; + EXPECT_EQ(NonSemantic, Init->isKnownToHaveBooleanValue(false)) << Name; + }; + + ExpectKnown("from_bool", true, true); + ExpectKnown("from_int", false, false); + ExpectKnown("from_signed_bitfield1", false, false); + ExpectKnown("from_bitfield1", false, true); + ExpectKnown("from_bitfield2", false, false); + ExpectKnown("from_bitint1", false, true); + ExpectKnown("from_bitint2", false, false); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
