[clang] 6d0fab4 - [Clang] Fix defaulted equality operator so that it does not attempt to compare unnamed bit-fields
Shafik Yaghmour via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 14 15:01:07 PDT 2023
Author: Shafik Yaghmour
Date: 2023-04-14T15:01:00-07:00
New Revision: 6d0fab467efbc7ce92bd890d9618259c4995ddcc
URL: https://github.com/llvm/llvm-project/commit/6d0fab467efbc7ce92bd890d9618259c4995ddcc
DIFF: https://github.com/llvm/llvm-project/commit/6d0fab467efbc7ce92bd890d9618259c4995ddcc.diff
LOG: [Clang] Fix defaulted equality operator so that it does not attempt to compare unnamed bit-fields
If we look at class.bit p2 it tells us that that unnamed bit-fields are not
members and class.compare.default p5 tells us that we should only compare
non-static data members of the class.
This fixes: https://github.com/llvm/llvm-project/issues/61335 and https://github.com/llvm/llvm-project/issues/61417
Differential Revision: https://reviews.llvm.org/D146329
Added:
clang/test/CodeGenCXX/defaulted_equality_ignore_unnamed_bitfields.cpp
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d854590363a54..1f66a877c50b4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -303,6 +303,10 @@ Bug Fixes in This Version
- Fix a failed assertion due to an invalid source location when trying to form
a coverage report for an unresolved constructor expression.
(`#62105 <https://github.com/llvm/llvm-project/issues/62105>`_)
+- Fix defaulted equality operator so that it does not attempt to compare unnamed
+ bit-fields. This fixes:
+ (`#61355 <https://github.com/llvm/llvm-project/issues/61335>`_) and
+ (`#61417 <https://github.com/llvm/llvm-project/issues/61417>`_)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 7fd12319e4d61..26476f793a461 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7758,6 +7758,10 @@ class DefaultedComparisonVisitor {
// 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(),
diff --git a/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp b/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
index f07b19fefbe74..eadb5718780a3 100644
--- a/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
+++ b/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
@@ -226,3 +226,26 @@ void f2() {
(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
+}
+}
diff --git a/clang/test/CodeGenCXX/defaulted_equality_ignore_unnamed_bitfields.cpp b/clang/test/CodeGenCXX/defaulted_equality_ignore_unnamed_bitfields.cpp
new file mode 100644
index 0000000000000..0eb1493a3eb6f
--- /dev/null
+++ b/clang/test/CodeGenCXX/defaulted_equality_ignore_unnamed_bitfields.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux -emit-llvm -o - | FileCheck %s
+
+// GH61417
+// 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;
+// CHECK: define{{.*}} @_Zeq1AS_
+// CHECK: %[[LHS:.+]] = alloca %struct.A, align 4
+// CHECK: %[[RHS:.+]] = alloca %struct.A, align 4
+// CHECK: %[[LHS_LOAD:.+]] = load i8, ptr %[[LHS]], align 4
+// CHECK: %[[LHS_CLEAR:.+]] = and i8 %[[LHS_LOAD]], 1
+// CHECK: %[[LHS_CAST:.+]] = zext i8 %[[LHS_CLEAR]] to i32
+
+// CHECK: %[[RHS_LOAD:.+]] = load i8, ptr %[[RHS]]
+// CHECK: %[[RHS_CLEAR:.+]] = and i8 %[[RHS_LOAD]], 1
+// CHECK: %[[RHS_CAST:.+]] = zext i8 %[[RHS_CLEAR]] to i32
+// CHECK: %[[CMP:.*]] = icmp eq i32 %[[LHS_CAST]], %[[RHS_CAST]]
+// CHECK: ret i1 %[[CMP]]
+
+bool operator==(B, B) = default;
+// CHECK: define{{.*}} @_Zeq1BS_
+// CHECK: %[[LHS_B:.+]] = alloca %struct.B, align 4
+// CHECK: %[[RHS_B:.+]] = alloca %struct.B, align 4
+// CHECK: %[[LHS_LOAD_B:.+]] = load i32, ptr %[[LHS_B]], align 4
+// CHECK: %[[LHS_CLEAR_B:.+]] = and i32 %[[LHS_LOAD_B]], 1
+
+// CHECK: %[[RHS_LOAD_B:.+]] = load i32, ptr %[[RHS_B]]
+// CHECK: %[[RHS_CLEAR_B:.+]] = and i32 %[[RHS_LOAD_B]], 1
+// CHECK: %[[CMP_B:.*]] = icmp eq i32 %[[LHS_CLEAR_B]], %[[RHS_CLEAR_B]]
+// CHECK: ret i1 %[[CMP_B]]
More information about the cfe-commits
mailing list