https://gcc.gnu.org/g:f60cc4641662724afd0b2dce1339a08be7af7dde

commit r16-8442-gf60cc4641662724afd0b2dce1339a08be7af7dde
Author: Jakub Jelinek <[email protected]>
Date:   Fri Apr 3 10:29:51 2026 +0200

    c++: Implement LWG4517 - data_member_spec should throw for cv-qualified 
unnamed bit-fields
    
    As written in https://wg21.link/lwg4517 , unnamed bit-fields shall not
    be declared with cv-qualified types, so the following patch rejects it
    when trying to create that in data_member_spec.
    
    2026-04-03  Jakub Jelinek  <[email protected]>
    
            * reflect.cc (eval_data_member_spec): Implement C++26 LWG4517
            - data_member_spec should throw for cv-qualified unnamed bit-fields.
    
            * g++.dg/reflect/data_member_spec2.C: Add tests for unnamed 
bit-fields
            with const and/or volatile types.
    
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/cp/reflect.cc                                | 11 +++++++++++
 gcc/testsuite/g++.dg/reflect/data_member_spec2.C |  6 ++++++
 2 files changed, 17 insertions(+)

diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index 670d84afb67a..e4cef5228e3e 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -5910,6 +5910,17 @@ eval_data_member_spec (location_t loc, const 
constexpr_ctx *ctx,
       if (tree_int_cst_sgn (args[m_bit_width]) < 0)
        return throw_exception (loc, ctx, "bit_width is negative",
                                fun, non_constant_p, jump_target);
+      if (args[m_name] == NULL_TREE)
+       {
+         if (eval_is_const (type, REFLECT_UNDEF) == boolean_true_node)
+           return throw_exception (loc, ctx,
+                                   "name unspecified and type is const",
+                                   fun, non_constant_p, jump_target);
+         if (eval_is_volatile (type, REFLECT_UNDEF) == boolean_true_node)
+           return throw_exception (loc, ctx,
+                                   "name unspecified and type is volatile",
+                                   fun, non_constant_p, jump_target);
+       }
     }
   if (args[m_alignment])
     {
diff --git a/gcc/testsuite/g++.dg/reflect/data_member_spec2.C 
b/gcc/testsuite/g++.dg/reflect/data_member_spec2.C
index 3c0043fe3145..40914609b3ff 100644
--- a/gcc/testsuite/g++.dg/reflect/data_member_spec2.C
+++ b/gcc/testsuite/g++.dg/reflect/data_member_spec2.C
@@ -86,6 +86,12 @@ static_assert (!valid_data_member_spec (^^Enum_class::A, { 
.name = "dms" }));
 static_assert (!valid_data_member_spec (^^decomp, { .name = "dms" }));
 static_assert (!valid_data_member_spec (^^decomp_ref, { .name = "dms" }));
 static_assert (!valid_data_member_spec (^^arr, { .name = "dms" }));
+// LWG4517 - data_member_spec should throw for cv-qualified unnamed bit-fields
+static_assert (!valid_data_member_spec (^^const int, { .bit_width = 3 }));
+static_assert (!valid_data_member_spec (^^volatile short, { .bit_width = 7 }));
+static_assert (!valid_data_member_spec (^^const int, { .bit_width = 0 }));
+static_assert (!valid_data_member_spec (^^volatile short, { .bit_width = 0 }));
+static_assert (!valid_data_member_spec (^^const volatile char, { .bit_width = 
2 }));
 
 constexpr auto dms = data_member_spec (^^int, { .name = "dms" });
 static_assert (!valid_data_member_spec (dms, { .name = "dms" }));

Reply via email to