This patch makes the class member ordering well defined, in the face of
decls with identical locations.
We spuriously generate duplicate TYPE_DECLS, which we shouldn't do. But
we can also reach this via (at least) template parameter pack expansions.
Fixed by using DECL_UID as a more complete ordering than
DECL_SOURCE_LOCATION.
nathan
--
Nathan Sidwell
2017-09-20 Nathan Sidwell <nat...@acm.org>
* name-lookup.c (member_name_cmp): Use DECL_UID for final
ordering.
Index: name-lookup.c
===================================================================
--- name-lookup.c (revision 252918)
+++ name-lookup.c (working copy)
@@ -1434,29 +1434,38 @@ member_name_cmp (const void *a_p, const
b = OVL_FUNCTION (b);
/* We're in STAT_HACK or USING_DECL territory (or possibly error-land). */
- if (TREE_CODE (a) == TREE_CODE (b))
- /* We can get two TYPE_DECLs or two USING_DECLs. Place in source
- order. */
- return DECL_SOURCE_LOCATION (a) < DECL_SOURCE_LOCATION (b) ? -1 : +1;
-
- /* If one of them is a TYPE_DECL, it loses. */
- if (TREE_CODE (a) == TYPE_DECL)
- return +1;
- else if (TREE_CODE (b) == TYPE_DECL)
- return -1;
-
- /* If one of them is a USING_DECL, it loses. */
- if (TREE_CODE (a) == USING_DECL)
- return +1;
- else if (TREE_CODE (b) == USING_DECL)
- return -1;
-
- /* There are no other cases, as duplicate detection should have
- kicked in earlier. However, some erroneous cases get though.
- Order by source location. We should really prevent this
- happening. */
- gcc_assert (errorcount);
- return DECL_SOURCE_LOCATION (a) < DECL_SOURCE_LOCATION (b) ? -1 : +1;
+ if (TREE_CODE (a) != TREE_CODE (b))
+ {
+ /* If one of them is a TYPE_DECL, it loses. */
+ if (TREE_CODE (a) == TYPE_DECL)
+ return +1;
+ else if (TREE_CODE (b) == TYPE_DECL)
+ return -1;
+
+ /* If one of them is a USING_DECL, it loses. */
+ if (TREE_CODE (a) == USING_DECL)
+ return +1;
+ else if (TREE_CODE (b) == USING_DECL)
+ return -1;
+
+ /* There are no other cases with different kinds of decls, as
+ duplicate detection should have kicked in earlier. However,
+ some erroneous cases get though. */
+ gcc_assert (errorcount);
+ }
+
+ /* Using source location would be the best thing here, but we can
+ get identically-located decls in the following circumstances:
+
+ 1) duplicate artificial type-decls for the same type.
+
+ 2) pack expansions of using-decls.
+
+ We should not be doing #1, but in either case it doesn't matter
+ how we order these. Use UID as a proxy for source ordering, so
+ that identically-located decls still have a well-defined stable
+ ordering. */
+ return DECL_UID (a) < DECL_UID (b) ? -1 : +1;
}
static struct {