https://github.com/mechakotik updated 
https://github.com/llvm/llvm-project/pull/195793

>From 3816db232598ed1aa352ad18ecac21490a116b73 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..af3b57f29bff5 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>();
+        BIT && 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

Reply via email to