c++: Stat-hack for members [PR 98530]
authorNathan Sidwell <nathan@acm.org>
Thu, 21 Jan 2021 12:48:39 +0000 (04:48 -0800)
committerNathan Sidwell <nathan@acm.org>
Thu, 21 Jan 2021 12:54:43 +0000 (04:54 -0800)
This was a header file that deployed the stat-hack inside a class
(both a member-class and a [non-static data] member had the same
name).  Due to the way that's represented in name lookup we missed the
class.  Sadly just changing the representation globally has
detrimental effects elsewhere, and this is a rare case, so just
creating a new overload on the fly shouldn't be a problem.

PR c++/98530
gcc/cp/
* name-lookup.c (lookup_class_binding): Rearrange a stat-hack.
gcc/testsuite/
* g++.dg/modules/stat-mem-1.h: New.
* g++.dg/modules/stat-mem-1_a.H: New.
* g++.dg/modules/stat-mem-1_b.C: New.

gcc/cp/name-lookup.c
gcc/testsuite/g++.dg/modules/stat-mem-1.h [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/stat-mem-1_a.H [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/stat-mem-1_b.C [new file with mode: 0644]

index 843e5f305c0ef13c16a1a479fdc02c51c252c2f3..0fb0036c4f38bb7c9a4fcf5ae482feaf38f36514 100644 (file)
@@ -3926,11 +3926,16 @@ lookup_class_binding (tree klass, tree name)
       vec<tree, va_gc> *member_vec = CLASSTYPE_MEMBER_VEC (klass);
 
       found = member_vec_binary_search (member_vec, name);
-      if (IDENTIFIER_CONV_OP_P (name))
+      if (!found)
+       ;
+      else if (STAT_HACK_P (found))
+       /* Rearrange the stat hack so that we don't need to expose that
+          internal detail.  */
+       found = ovl_make (STAT_TYPE (found), STAT_DECL (found));
+      else if (IDENTIFIER_CONV_OP_P (name))
        {
          gcc_checking_assert (name == conv_op_identifier);
-         if (found)
-           found = OVL_CHAIN (found);
+         found = OVL_CHAIN (found);
        }
     }
   else
diff --git a/gcc/testsuite/g++.dg/modules/stat-mem-1.h b/gcc/testsuite/g++.dg/modules/stat-mem-1.h
new file mode 100644 (file)
index 0000000..b5703ea
--- /dev/null
@@ -0,0 +1,6 @@
+
+struct fpu {
+  struct NAME {
+    int state;
+  } NAME;
+};
diff --git a/gcc/testsuite/g++.dg/modules/stat-mem-1_a.H b/gcc/testsuite/g++.dg/modules/stat-mem-1_a.H
new file mode 100644 (file)
index 0000000..6daa137
--- /dev/null
@@ -0,0 +1,5 @@
+// { dg-additional-options -fmodule-header }
+// PR c++ 98530  stat-hack inside a structure
+// { dg-module-cmi {} }
+
+#include "stat-mem-1.h"
diff --git a/gcc/testsuite/g++.dg/modules/stat-mem-1_b.C b/gcc/testsuite/g++.dg/modules/stat-mem-1_b.C
new file mode 100644 (file)
index 0000000..9b83d4e
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-additional-options "-fmodules-ts -fno-module-lazy" }
+
+#include "stat-mem-1.h"
+import "stat-mem-1_a.H";