shafik updated this revision to Diff 512983.
shafik added a comment.

- Added codegen test


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

https://reviews.llvm.org/D146329

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
  clang/test/CodeGenCXX/defaulted_equality_ignore_unnamed_bitfields.cpp


Index: clang/test/CodeGenCXX/defaulted_equality_ignore_unnamed_bitfields.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/defaulted_equality_ignore_unnamed_bitfields.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - | FileCheck %s
+
+// Check that we don't attempt to compare the unnamed bitfields
+struct A {
+  unsigned x : 1;
+  unsigned   : 1;
+
+  friend bool operator==(A, A);
+};
+
+
+struct B {
+  unsigned x : 1;
+  unsigned   : 31;
+
+  friend bool operator==(B, B);
+};
+
+bool operator==(A, A) = default;
+bool operator==(B, B) = default;
+
+
+// If it compares the unnamed bitfields it will first compare the named 
bit-field
+// and then branch based on the result of that comparison.
+// We also won't see a lshr in order to clear the named bitfield.
+// CHECK-NOT: br
+// CHECK-NOT: lshr
Index: clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
+++ clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
@@ -226,3 +226,26 @@
   (void)(b == 0);
 }
 } // namespace p2085_2
+
+namespace GH61417 {
+struct A {
+  unsigned x : 1;
+  unsigned   : 0;
+  unsigned y : 1;
+
+  constexpr A() : x(0), y(0) {}
+  bool operator==(const A& rhs) const noexcept = default;
+};
+
+void f1() {
+  constexpr A a, b;
+  constexpr bool c = (a == b); // no diagnostic, we should not be comparing the
+                               // unnamed bit-field which is indeterminate
+}
+
+void f2() {
+    A a, b;
+    bool c = (a == b); // no diagnostic nor crash during codegen attempting to
+                       // access info for unnamed bit-field
+}
+}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -7755,6 +7755,10 @@
 
     //   followed by the non-static data members of C
     for (FieldDecl *Field : Record->fields()) {
+      // C++23 [class.bit]p2:
+      //   Unnamed bit-fields are not members ...
+      if (Field->isUnnamedBitfield())
+        continue;
       // Recursively expand anonymous structs.
       if (Field->isAnonymousStructOrUnion()) {
         if (visitSubobjects(Results, Field->getType()->getAsCXXRecordDecl(),


Index: clang/test/CodeGenCXX/defaulted_equality_ignore_unnamed_bitfields.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/defaulted_equality_ignore_unnamed_bitfields.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - | FileCheck %s
+
+// Check that we don't attempt to compare the unnamed bitfields
+struct A {
+  unsigned x : 1;
+  unsigned   : 1;
+
+  friend bool operator==(A, A);
+};
+
+
+struct B {
+  unsigned x : 1;
+  unsigned   : 31;
+
+  friend bool operator==(B, B);
+};
+
+bool operator==(A, A) = default;
+bool operator==(B, B) = default;
+
+
+// If it compares the unnamed bitfields it will first compare the named bit-field
+// and then branch based on the result of that comparison.
+// We also won't see a lshr in order to clear the named bitfield.
+// CHECK-NOT: br
+// CHECK-NOT: lshr
Index: clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
+++ clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
@@ -226,3 +226,26 @@
   (void)(b == 0);
 }
 } // namespace p2085_2
+
+namespace GH61417 {
+struct A {
+  unsigned x : 1;
+  unsigned   : 0;
+  unsigned y : 1;
+
+  constexpr A() : x(0), y(0) {}
+  bool operator==(const A& rhs) const noexcept = default;
+};
+
+void f1() {
+  constexpr A a, b;
+  constexpr bool c = (a == b); // no diagnostic, we should not be comparing the
+                               // unnamed bit-field which is indeterminate
+}
+
+void f2() {
+    A a, b;
+    bool c = (a == b); // no diagnostic nor crash during codegen attempting to
+                       // access info for unnamed bit-field
+}
+}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -7755,6 +7755,10 @@
 
     //   followed by the non-static data members of C
     for (FieldDecl *Field : Record->fields()) {
+      // C++23 [class.bit]p2:
+      //   Unnamed bit-fields are not members ...
+      if (Field->isUnnamedBitfield())
+        continue;
       // Recursively expand anonymous structs.
       if (Field->isAnonymousStructOrUnion()) {
         if (visitSubobjects(Results, Field->getType()->getAsCXXRecordDecl(),
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to