c++: cp_tree_equal tweaks
authorNathan Sidwell <nathan@acm.org>
Fri, 11 Dec 2020 16:22:57 +0000 (08:22 -0800)
committerNathan Sidwell <nathan@acm.org>
Fri, 11 Dec 2020 16:28:19 +0000 (08:28 -0800)
When comparing streamed trees we can encounter NON_LVALUE_EXPR and
VIEW_CONVERT_EXPRs with null types.  Also, when checking a potential
duplicate we don't want to reject PARM_DECLs with different contexts,
if those two contexts are the two decls of interest.

gcc/cp/
* cp-tree.h (map_context_from, map_context_to): Declare.
* module.cc (map_context_from, map_context_to): Define.
* tree.c (cp_tree_equal): Check map_context_{from,to} for parm
context difference.  Allow NON_LVALUE_EXPR and VIEW_CONVERT_EXPR
with null types.

gcc/cp/cp-tree.h
gcc/cp/module.cc
gcc/cp/tree.c

index 63170fc013d5624bfdc74abbcf2671b218318284..f2a01d25d0c4773d3507c53c298c06a5005b9b32 100644 (file)
@@ -5454,6 +5454,10 @@ extern int function_depth;
    in structrual_comptypes.  */
 extern int comparing_specializations;
 
+/* When comparing specializations permit context _FROM to match _TO.  */
+extern tree map_context_from;
+extern tree map_context_to;
+
 /* In parser.c.  */
 
 /* Nonzero if we are parsing an unevaluated operand: an operand to
index 02b5af811896c411c5d6a4a75605207f0fcf7cc1..2417d67ee410e10dfb82952b4d77548dce1f4d16 100644 (file)
@@ -65,6 +65,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "langhooks.h"
 
+/* During duplicate detection we need to tell some comparators that
+   these are equivalent.  */
+tree map_context_from;
+tree map_context_to;
+
 /* Id for dumping module information.  */
 int module_dump_id;
 
index d9fa505041f5495cd59e28458bb64b16b17bc16c..0584a7b725e49e25097bf2b60706667011789884 100644 (file)
@@ -3837,7 +3837,12 @@ cp_tree_equal (tree t1, tree t2)
         template.  */
 
       if (comparing_specializations
-         && DECL_CONTEXT (t1) != DECL_CONTEXT (t2))
+         && DECL_CONTEXT (t1) != DECL_CONTEXT (t2)
+         /* Module duplicate checking can have t1 = new, t2 =
+            existing, and they should be considered matching at this
+            point.  */
+         && (DECL_CONTEXT (t1) != map_context_from
+             && DECL_CONTEXT (t2) != map_context_to))
        /* When comparing hash table entries, only an exact match is
           good enough; we don't want to replace 'this' with the
           version from another function.  But be more flexible
@@ -3974,6 +3979,17 @@ cp_tree_equal (tree t1, tree t2)
       return same_type_p (TRAIT_EXPR_TYPE1 (t1), TRAIT_EXPR_TYPE1 (t2))
        && cp_tree_equal (TRAIT_EXPR_TYPE2 (t1), TRAIT_EXPR_TYPE2 (t2));
 
+    case NON_LVALUE_EXPR:
+    case VIEW_CONVERT_EXPR:
+      /* Used for location wrappers with possibly NULL types.  */
+      if (!TREE_TYPE (t1) || !TREE_TYPE (t2))
+       {
+         if (TREE_TYPE (t1) || TREE_TYPE (t2))
+           return false;
+         break;
+       }
+      /* FALLTHROUGH  */
+
     case CAST_EXPR:
     case STATIC_CAST_EXPR:
     case REINTERPRET_CAST_EXPR:
@@ -3981,10 +3997,8 @@ cp_tree_equal (tree t1, tree t2)
     case DYNAMIC_CAST_EXPR:
     case IMPLICIT_CONV_EXPR:
     case NEW_EXPR:
-    CASE_CONVERT:
-    case NON_LVALUE_EXPR:
-    case VIEW_CONVERT_EXPR:
     case BIT_CAST_EXPR:
+    CASE_CONVERT:
       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
        return false;
       /* Now compare operands as usual.  */