]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: designator for base class member [PR101405]
authorJason Merrill <jason@redhat.com>
Thu, 20 Jan 2022 14:18:45 +0000 (09:18 -0500)
committerJason Merrill <jason@redhat.com>
Thu, 20 Jan 2022 20:23:43 +0000 (15:23 -0500)
A C++20 designator must name a direct non-static member of the class; in
this case it names a member of a base class, and we should give an error
instead of crashing.

PR c++/101405

gcc/cp/ChangeLog:

* decl.cc (reshape_init_class): Reject designator for a member of
another class.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/desig20.C: New test.

gcc/cp/decl.cc
gcc/testsuite/g++.dg/cpp2a/desig20.C [new file with mode: 0644]

index 1cbe9a34be0cb1b8d719277924e01a2e796fa8a9..8e5421848d1ef0e30456aa705ab4196ebcf81c55 100644 (file)
@@ -6569,16 +6569,22 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
          tree ictx = DECL_CONTEXT (field);
          if (!same_type_ignoring_top_level_qualifiers_p (ictx, type))
            {
-             gcc_assert (ANON_AGGR_TYPE_P (ictx));
              /* Find the anon aggr that is a direct member of TYPE.  */
-             while (true)
+             while (ANON_AGGR_TYPE_P (ictx))
                {
                  tree cctx = TYPE_CONTEXT (ictx);
                  if (same_type_ignoring_top_level_qualifiers_p (cctx, type))
-                   break;
+                   goto found;
                  ictx = cctx;
                }
-             /* And then the TYPE member with that anon aggr type.  */
+
+             /* Not found, e.g. FIELD is a member of a base class.  */
+             if (complain & tf_error)
+               error ("%qD is not a direct member of %qT", field, type);
+             return error_mark_node;
+
+           found:
+             /* Now find the TYPE member with that anon aggr type.  */
              tree aafield = TYPE_FIELDS (type);
              for (; aafield; aafield = TREE_CHAIN (aafield))
                if (TREE_TYPE (aafield) == ictx)
diff --git a/gcc/testsuite/g++.dg/cpp2a/desig20.C b/gcc/testsuite/g++.dg/cpp2a/desig20.C
new file mode 100644 (file)
index 0000000..0ceda7c
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/101405
+// { dg-do compile { target c++20 } }
+
+struct A {
+  int const a = 1;
+  int const b = 2;
+};
+
+struct B : A {
+  using A::a;
+  using A::b;
+  int const c = 3;
+  int const d = 4;
+};
+
+int main()
+{
+  [[maybe_unused]] B b =
+  { .a = 10, .d = 42 };                // { dg-error "not a direct member" }
+}