c++: spec_hasher::equal and PARM_DECLs [PR94632]
[gcc.git] / gcc / cp / tree.c
index 72b3a720ee8ce549890ee308e9b3382b243ac7b1..dc4f1f48d3c5cd6eae4f9bc5207d72286c517ab4 100644 (file)
@@ -669,6 +669,9 @@ build_aggr_init_expr (tree type, tree init)
   else
     rval = init;
 
+  if (location_t loc = EXPR_LOCATION (init))
+    SET_EXPR_LOCATION (rval, loc);
+
   return rval;
 }
 
@@ -2464,6 +2467,8 @@ is_overloaded_fn (tree x)
 tree
 dependent_name (tree x)
 {
+  /* FIXME a dependent name must be unqualified, but this function doesn't
+     distinguish between qualified and unqualified identifiers.  */
   if (identifier_p (x))
     return x;
   if (TREE_CODE (x) == TEMPLATE_ID_EXPR)
@@ -2778,9 +2783,10 @@ verify_stmt_tree (tree t)
   cp_walk_tree (&t, verify_stmt_tree_r, &statements, NULL);
 }
 
-/* Check if the type T depends on a type with no linkage and if so, return
-   it.  If RELAXED_P then do not consider a class type declared within
-   a vague-linkage function to have no linkage.  */
+/* Check if the type T depends on a type with no linkage and if so,
+   return it.  If RELAXED_P then do not consider a class type declared
+   within a vague-linkage function to have no linkage.  Remember:
+   no-linkage is not the same as internal-linkage*/
 
 tree
 no_linkage_check (tree t, bool relaxed_p)
@@ -2794,9 +2800,12 @@ no_linkage_check (tree t, bool relaxed_p)
      fix it up later if not.  We need to check this even in templates so
      that we properly handle a lambda-expression in the signature.  */
   if (LAMBDA_TYPE_P (t)
-      && CLASSTYPE_LAMBDA_EXPR (t) != error_mark_node
-      && LAMBDA_TYPE_EXTRA_SCOPE (t) == NULL_TREE)
-    return t;
+      && CLASSTYPE_LAMBDA_EXPR (t) != error_mark_node)
+    {
+      tree extra = LAMBDA_TYPE_EXTRA_SCOPE (t);
+      if (!extra)
+       return t;
+    }
 
   /* Otherwise there's no point in checking linkage on template functions; we
      can't know their complete types.  */
@@ -3223,7 +3232,7 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
    a PLACEHOLDER_EXPR has been encountered.  */
 
 tree
-replace_placeholders (tree exp, tree obj, bool *seen_p)
+replace_placeholders (tree exp, tree obj, bool *seen_p /*= NULL*/)
 {
   /* This is only relevant for C++14.  */
   if (cxx_dialect < cxx14)
@@ -3231,7 +3240,7 @@ replace_placeholders (tree exp, tree obj, bool *seen_p)
 
   /* If the object isn't a (member of a) class, do nothing.  */
   tree op0 = obj;
-  while (TREE_CODE (op0) == COMPONENT_REF)
+  while (handled_component_p (op0))
     op0 = TREE_OPERAND (op0, 0);
   if (!CLASS_TYPE_P (strip_array_types (TREE_TYPE (op0))))
     return exp;
@@ -3567,6 +3576,15 @@ called_fns_equal (tree t1, tree t2)
       if (name1 != name2)
        return false;
 
+      /* FIXME dependent_name currently returns an unqualified name regardless
+        of whether the function was named with a qualified- or unqualified-id.
+        Until that's fixed, check that we aren't looking at overload sets from
+        different scopes.  */
+      if (is_overloaded_fn (t1) && is_overloaded_fn (t2)
+         && (DECL_CONTEXT (get_first_fn (t1))
+             != DECL_CONTEXT (get_first_fn (t2))))
+       return false;
+
       if (TREE_CODE (t1) == TEMPLATE_ID_EXPR)
        targs1 = TREE_OPERAND (t1, 1);
       if (TREE_CODE (t2) == TEMPLATE_ID_EXPR)
@@ -3663,7 +3681,8 @@ cp_tree_equal (tree t1, tree t2)
       {
        tree arg1, arg2;
        call_expr_arg_iterator iter1, iter2;
-       if (!called_fns_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
+       if (KOENIG_LOOKUP_P (t1) != KOENIG_LOOKUP_P (t2)
+           || !called_fns_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
          return false;
        for (arg1 = first_call_expr_arg (t1, &iter1),
               arg2 = first_call_expr_arg (t2, &iter2);
@@ -3704,11 +3723,12 @@ cp_tree_equal (tree t1, tree t2)
         up for expressions that involve 'this' in a member function
         template.  */
 
-      if (comparing_specializations && !CONSTRAINT_VAR_P (t1))
+      if (comparing_specializations
+         && DECL_CONTEXT (t1) != DECL_CONTEXT (t2))
        /* 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
-          with local parameters in a requires-expression.  */
+          with parameters with identical contexts.  */
        return false;
 
       if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
@@ -3788,9 +3808,13 @@ cp_tree_equal (tree t1, tree t2)
            if (SIZEOF_EXPR_TYPE_P (t2))
              o2 = TREE_TYPE (o2);
          }
+
        if (TREE_CODE (o1) != TREE_CODE (o2))
          return false;
-       if (TYPE_P (o1))
+
+       if (ARGUMENT_PACK_P (o1))
+         return template_args_equal (o1, o2);
+       else if (TYPE_P (o1))
          return same_type_p (o1, o2);
        else
          return cp_tree_equal (o1, o2);
@@ -3857,12 +3881,27 @@ cp_tree_equal (tree t1, tree t2)
                             DEFERRED_NOEXCEPT_PATTERN (t2))
              && comp_template_args (DEFERRED_NOEXCEPT_ARGS (t1),
                                     DEFERRED_NOEXCEPT_ARGS (t2)));
-      break;
 
     case LAMBDA_EXPR:
       /* Two lambda-expressions are never considered equivalent.  */
       return false;
 
+    case TYPE_ARGUMENT_PACK:
+    case NONTYPE_ARGUMENT_PACK:
+      {
+       tree p1 = ARGUMENT_PACK_ARGS (t1);
+       tree p2 = ARGUMENT_PACK_ARGS (t2);
+       int len = TREE_VEC_LENGTH (p1);
+       if (TREE_VEC_LENGTH (p2) != len)
+         return false;
+
+       for (int ix = 0; ix != len; ix++)
+         if (!template_args_equal (TREE_VEC_ELT (p1, ix),
+                                   TREE_VEC_ELT (p2, ix)))
+           return false;
+       return true;
+      }
+
     default:
       break;
     }
@@ -5712,7 +5751,15 @@ type_initializer_zero_p (tree type, tree init)
     return TREE_CODE (init) != STRING_CST && initializer_zerop (init);
 
   if (TREE_CODE (init) != CONSTRUCTOR)
-    return initializer_zerop (init);
+    {
+      /* A class can only be initialized by a non-class type if it has
+        a ctor that converts from that type.  Such classes are excluded
+        since their semantics are unknown.  */
+      if (RECORD_OR_UNION_TYPE_P (type)
+         && !RECORD_OR_UNION_TYPE_P (TREE_TYPE (init)))
+       return false;
+      return initializer_zerop (init);
+    }
 
   if (TREE_CODE (type) == ARRAY_TYPE)
     {