[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