[PATCH] D71142: [Sema] Validate large bitfields
Mark de Wever via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 6 12:24:58 PST 2019
Mordante created this revision.
Mordante added reviewers: rsmith, majnemer, aaron.ballman.
Mordante added a project: clang.
Note: I'm not entirely happy with the text of the diagnostics and I'm open to suggestions.
Fixes PR23505: Large bitfield: Assertion `getActiveBits() <= 64 && "Too many bits for uint64_t"' failed
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D71142
Files:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDecl.cpp
clang/test/Sema/bitfield.c
Index: clang/test/Sema/bitfield.c
===================================================================
--- clang/test/Sema/bitfield.c
+++ clang/test/Sema/bitfield.c
@@ -28,6 +28,12 @@
_Bool : 2; // expected-error {{width of anonymous bit-field (2 bits) exceeds width of its type (1 bit)}}
_Bool h : 5; // expected-error {{width of bit-field 'h' (5 bits) exceeds width of its type (1 bit)}}
+
+ // PR23505
+ _Bool : 1 + (unsigned __int128)0xffffffffffffffff; // expected-error {{width of anonymous bit-field doesn't fit in a 64 bit unsigned integer}}
+ _Bool i : 1 + (unsigned __int128)0xffffffffffffffff; // expected-error {{width of bit-field 'i' doesn't fit in a 64 bit unsigned integer}}
+ int : 1 + (unsigned __int128)0xffffffffffffffff; // expected-error {{width of anonymous bit-field doesn't fit in a 64 bit unsigned integer}}
+ int j : 1 + (unsigned __int128)0xffffffffffffffff; // expected-error {{width of bit-field 'j' doesn't fit in a 64 bit unsigned integer}}
};
struct b {unsigned x : 2;} x;
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15842,6 +15842,17 @@
uint64_t TypeWidth = Context.getIntWidth(FieldTy);
bool BitfieldIsOverwide = Value.ugt(TypeWidth);
+ // Don't accept too wide bit-fields they will cause assertion failures
+ // when used.
+ if (BitfieldIsOverwide && Value.ugt(UINT64_MAX)) {
+ if (FieldName)
+ return Diag(FieldLoc, diag::warn_bitfield_width_exceeds_maximum_width)
+ << FieldName;
+
+ return Diag(FieldLoc,
+ diag::warn_anon_bitfield_width_exceeds_maximum_width);
+ }
+
// Over-wide bitfields are an error in C or when using the MSVC bitfield
// ABI.
bool CStdConstraintViolation =
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5183,6 +5183,10 @@
"number of elements must be either one or match the size of the vector">;
// Used by C++ which allows bit-fields that are wider than the type.
+def warn_bitfield_width_exceeds_maximum_width: Error<
+ "width of bit-field %0 doesn't fit in a 64 bit unsigned integer">;
+def warn_anon_bitfield_width_exceeds_maximum_width : Error<
+ "width of anonymous bit-field doesn't fit in a 64 bit unsigned integer">;
def warn_bitfield_width_exceeds_type_width: Warning<
"width of bit-field %0 (%1 bits) exceeds the width of its type; value will "
"be truncated to %2 bit%s2">, InGroup<BitFieldWidth>;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D71142.232629.patch
Type: text/x-patch
Size: 2715 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191206/320c388b/attachment.bin>
More information about the cfe-commits
mailing list