This revision was automatically updated to reflect the committed changes.
Closed by commit rG82afc9b169a6: Fix -Wbitfield-constant-conversion on 1-bit 
signed bitfield (authored by ShawnZhong, committed by aaron.ballman).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131255/new/

https://reviews.llvm.org/D131255

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CXX/class/class.bit/p1.cpp
  clang/test/CXX/drs/dr6xx.cpp
  clang/test/CodeGen/bitfield.c
  clang/test/CodeGenCXX/bitfield-layout.cpp
  clang/test/Rewriter/rewrite-modern-struct-ivar-1.mm
  clang/test/Rewriter/rewrite-modern-struct-ivar.mm
  clang/test/Sema/constant-conversion.c
  clang/test/SemaCXX/constant-expression-cxx11.cpp
  clang/test/SemaCXX/cxx1z-decomposition.cpp
  clang/test/SemaCXX/decomposition-blocks.cpp

Index: clang/test/SemaCXX/decomposition-blocks.cpp
===================================================================
--- clang/test/SemaCXX/decomposition-blocks.cpp
+++ clang/test/SemaCXX/decomposition-blocks.cpp
@@ -7,7 +7,7 @@
 
 void run(void (^)());
 void test() {
-  auto [i, j] = S{1, 42}; // expected-note {{'i' declared here}}
+  auto [i, j] = S{-1, 42}; // expected-note {{'i' declared here}}
   run(^{
     (void)i; // expected-error {{reference to local binding 'i' declared in enclosing function 'test'}}
   });
Index: clang/test/SemaCXX/cxx1z-decomposition.cpp
===================================================================
--- clang/test/SemaCXX/cxx1z-decomposition.cpp
+++ clang/test/SemaCXX/cxx1z-decomposition.cpp
@@ -84,7 +84,7 @@
 
   (void)[outerbit1]{}; // expected-error {{'outerbit1' cannot be captured because it does not have automatic storage duration}}
 
-  auto [bit, var] = S2{1, 1}; // expected-note 2{{'bit' declared here}}
+  auto [bit, var] = S2{-1, 1}; // expected-note 2{{'bit' declared here}}
 
   (void)[&bit] { // expected-error {{non-const reference cannot bind to bit-field 'a'}} \
                     // expected-warning {{C++20}}
Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===================================================================
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2035,6 +2035,7 @@
       }
     };
     static_assert(X::f(3) == -1, "3 should truncate to -1");
+    static_assert(X::f(1) == -1, "1 should truncate to -1");
   }
 
   struct HasUnnamedBitfield {
Index: clang/test/Sema/constant-conversion.c
===================================================================
--- clang/test/Sema/constant-conversion.c
+++ clang/test/Sema/constant-conversion.c
@@ -15,8 +15,16 @@
 }
 
 void test(void) {
-  struct { int bit : 1; } a;
-  a.bit = 1; // shouldn't warn
+  struct S {
+    int b : 1;  // The only valid values are 0 and -1.
+  } s;
+
+  s.b = -3; // expected-warning {{implicit truncation from 'int' to bit-field changes value from -3 to -1}}
+  s.b = -2; // expected-warning {{implicit truncation from 'int' to bit-field changes value from -2 to 0}}
+  s.b = -1; // no-warning
+  s.b = 0;  // no-warning
+  s.b = 1;  // expected-warning {{implicit truncation from 'int' to bit-field changes value from 1 to -1}}
+  s.b = 2;  // expected-warning {{implicit truncation from 'int' to bit-field changes value from 2 to 0}}
 }
 
 enum Test2 { K_zero, K_one };
Index: clang/test/Rewriter/rewrite-modern-struct-ivar.mm
===================================================================
--- clang/test/Rewriter/rewrite-modern-struct-ivar.mm
+++ clang/test/Rewriter/rewrite-modern-struct-ivar.mm
@@ -41,10 +41,10 @@
 @implementation Foo
 - (void)x {
   bar.x = 0;
-  bar.y = 1;
+  bar.y = -1;
 
   s.x = 0;
-  s.y = 1;
+  s.y = -1;
 }
 @end
 
Index: clang/test/Rewriter/rewrite-modern-struct-ivar-1.mm
===================================================================
--- clang/test/Rewriter/rewrite-modern-struct-ivar-1.mm
+++ clang/test/Rewriter/rewrite-modern-struct-ivar-1.mm
@@ -34,7 +34,7 @@
 @implementation Foo
 - (void)x:(Foo *)other {
   bar.x = 0;
-  bar.y = 1;
+  bar.y = -1;
   self->_internal._singleRange._range = (( other ->bar.x) ? &( other ->_internal._singleRange._range) : ((NSRange *)(&(((_NSRangeInfo *)( other ->_internal._multipleRanges._data))->_ranges))))[0];
 }
 @end
Index: clang/test/CodeGenCXX/bitfield-layout.cpp
===================================================================
--- clang/test/CodeGenCXX/bitfield-layout.cpp
+++ clang/test/CodeGenCXX/bitfield-layout.cpp
@@ -105,6 +105,15 @@
 // CHECK: define{{.*}} i32 @test_trunc_three_bits()
 // CHECK: ret i32 -1
 
+int test_trunc_one_bit() {
+  union {
+    int i : 1; // truncated to 0b1 == -1
+  } const U = {1};  // 0b00000001
+  return U.i;
+}
+// CHECK: define{{.*}} i32 @test_trunc_one_bit()
+// CHECK: ret i32 -1
+
 int test_trunc_1() {
   union {
     int i : 1; // truncated to 0b1 == -1
Index: clang/test/CodeGen/bitfield.c
===================================================================
--- clang/test/CodeGen/bitfield.c
+++ clang/test/CodeGen/bitfield.c
@@ -87,3 +87,19 @@
 // PATH: ret i32 1
   return f3(20) + 130725747;
 }
+
+static int f4(void) {
+  struct s5 {
+    int b:1;
+  } x;
+  x.b = 1;
+  return x.b;
+}
+
+int g4(void) {
+// CHECK-LABEL: @g4()
+// CHECK: ret i32 1
+// PATH-LABEL: @g4()
+// PATH: ret i32 1
+  return f4() + 2;
+}
Index: clang/test/CXX/drs/dr6xx.cpp
===================================================================
--- clang/test/CXX/drs/dr6xx.cpp
+++ clang/test/CXX/drs/dr6xx.cpp
@@ -911,9 +911,9 @@
 namespace dr675 { // dr675: dup 739
   template<typename T> struct A { T n : 1; };
 #if __cplusplus >= 201103L
-  static_assert(A<char>{1}.n < 0, "");
-  static_assert(A<int>{1}.n < 0, "");
-  static_assert(A<long long>{1}.n < 0, "");
+  static_assert(A<char>{1}.n < 0, ""); // expected-warning {{implicit truncation from 'int' to bit-field changes value from 1 to -1}}
+  static_assert(A<int>{1}.n < 0, ""); // expected-warning {{implicit truncation from 'int' to bit-field changes value from 1 to -1}}
+  static_assert(A<long long>{1}.n < 0, ""); // expected-warning {{implicit truncation from 'int' to bit-field changes value from 1 to -1}}
 #endif
 }
 
Index: clang/test/CXX/class/class.bit/p1.cpp
===================================================================
--- clang/test/CXX/class/class.bit/p1.cpp
+++ clang/test/CXX/class/class.bit/p1.cpp
@@ -9,11 +9,11 @@
   int [[]] c : 1; // OK, attribute applies to the type.
   int : 2 = 1; // expected-error {{anonymous bit-field cannot have a default member initializer}}
   int : 0 { 1 }; // expected-error {{anonymous bit-field cannot have a default member initializer}}
-  int : 0, d : 1 = 1;
+  unsigned int : 0, d : 1 = 1;
   int : 1 = 12, e : 1; // expected-error {{anonymous bit-field cannot have a default member initializer}}
-  int : 0, f : 1 = 1;
-  int g [[]] : 1 = 1;
-  int h [[]] : 1 {1};
-  int i : foo() = foo();
+  unsigned int : 0, f : 1 = 1;
+  unsigned int g [[]] : 1 = 1;
+  unsigned int h [[]] : 1 {1};
+  unsigned int i : foo() = foo();
   int j, [[]] k; // expected-error {{an attribute list cannot appear here}}
 };
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -13064,11 +13064,6 @@
   if (llvm::APSInt::isSameValue(Value, TruncatedValue))
     return false;
 
-  // Special-case bitfields of width 1: booleans are naturally 0/1, and
-  // therefore don't strictly fit into a signed bitfield of width 1.
-  if (FieldWidth == 1 && Value == 1)
-    return false;
-
   std::string PrettyValue = toString(Value, 10);
   std::string PrettyTrunc = toString(TruncatedValue, 10);
 
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -82,6 +82,9 @@
 - ``-Wformat`` now recognizes ``%b`` for the ``printf``/``scanf`` family of
   functions and ``%B`` for the ``printf`` family of functions. Fixes
   `Issue 56885: <https://github.com/llvm/llvm-project/issues/56885>`_.
+- ``-Wbitfield-constant-conversion`` now diagnoses implicit truncation when 1 is
+  assigned to a 1-bit signed integer bitfield. This fixes
+  `Issue 53253 <https://github.com/llvm/llvm-project/issues/53253>`_.
 
 Non-comprehensive list of changes in this release
 -------------------------------------------------
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to