Revert:PR c++/50800
authorJason Merrill <jason@gcc.gnu.org>
Thu, 23 Apr 2015 19:40:16 +0000 (15:40 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 23 Apr 2015 19:40:16 +0000 (15:40 -0400)
Revert:PR c++/50800
       * tree.c (strip_typedefs): Add remove_attributes parm.
       (strip_typedefs_expr): Likewise.
       (apply_identity_attributes): New subroutine of strip_typedefs.
       * pt.c (canonicalize_type_argument): Let strip_typedefs handle attrs.
       (convert_nontype_argument, unify): Likewise.
       * cp-tree.h: Adjust.

From-SVN: r222384

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/tree.c
gcc/testsuite/g++.dg/abi/mangle40.C
gcc/testsuite/g++.dg/ext/alias-canon2.C
gcc/testsuite/g++.dg/ext/alias-mangle.C
gcc/testsuite/g++.dg/ext/attrib50.C [deleted file]

index 717aaa6..a463f66 100644 (file)
@@ -1,13 +1,5 @@
 2015-04-23  Jason Merrill  <jason@redhat.com>
 
-       PR c++/50800
-       * tree.c (strip_typedefs): Add remove_attributes parm.
-       (strip_typedefs_expr): Likewise.
-       (apply_identity_attributes): New subroutine of strip_typedefs.
-       * pt.c (canonicalize_type_argument): Let strip_typedefs handle attrs.
-       (convert_nontype_argument, unify): Likewise.
-       * cp-tree.h: Adjust.
-
        PR c++/65646
        * pt.c (check_explicit_specialization): Don't
        SET_DECL_TEMPLATE_SPECIALIZATION for a variable with no template
index df03d1a..2a904a5 100644 (file)
@@ -6066,8 +6066,8 @@ extern bool class_tmpl_impl_spec_p                (const_tree);
 extern int zero_init_p                         (const_tree);
 extern bool check_abi_tag_redeclaration                (const_tree, const_tree, const_tree);
 extern bool check_abi_tag_args                 (tree, tree);
-extern tree strip_typedefs                     (tree, bool * = NULL);
-extern tree strip_typedefs_expr                        (tree, bool * = NULL);
+extern tree strip_typedefs                     (tree);
+extern tree strip_typedefs_expr                        (tree);
 extern tree copy_binfo                         (tree, tree, tree,
                                                 tree *, int);
 extern int member_p                            (const_tree);
index ea0d3bc..f9a5c3b 100644 (file)
@@ -6493,14 +6493,20 @@ template_template_parm_bindings_ok_p (tree tparms, tree targs)
 static tree
 canonicalize_type_argument (tree arg, tsubst_flags_t complain)
 {
+  tree mv;
   if (!arg || arg == error_mark_node || arg == TYPE_CANONICAL (arg))
     return arg;
-  bool removed_attributes = false;
-  tree canon = strip_typedefs (arg, &removed_attributes);
-  if (removed_attributes
-      && (complain & tf_warning))
-    warning (0, "ignoring attributes on template argument %qT", arg);
-  return canon;
+  mv = TYPE_MAIN_VARIANT (arg);
+  arg = strip_typedefs (arg);
+  if (TYPE_ALIGN (arg) != TYPE_ALIGN (mv)
+      || TYPE_ATTRIBUTES (arg) != TYPE_ATTRIBUTES (mv))
+    {
+      if (complain & tf_warning)
+       warning (0, "ignoring attributes on template argument %qT", arg);
+      arg = build_aligned_type (arg, TYPE_ALIGN (mv));
+      arg = cp_build_type_attribute_variant (arg, TYPE_ATTRIBUTES (mv));
+    }
+  return arg;
 }
 
 /* Convert the indicated template ARG as necessary to match the
@@ -6737,10 +6743,7 @@ convert_template_argument (tree parm,
           argument specification is valid.  */
        val = convert_nontype_argument (t, orig_arg, complain);
       else
-       {
-         bool removed_attr = false;
-         val = strip_typedefs_expr (orig_arg, &removed_attr);
-       }
+       val = strip_typedefs_expr (orig_arg);
 
       if (val == NULL_TREE)
        val = error_mark_node;
@@ -18199,10 +18202,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
          && !TEMPLATE_PARM_PARAMETER_PACK (parm))
        return unify_parameter_pack_mismatch (explain_p, parm, arg);
 
-      {
-       bool removed_attr = false;
-       arg = strip_typedefs_expr (arg, &removed_attr);
-      }
+      arg = strip_typedefs_expr (arg);
       TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
       return unify_success (explain_p);
 
index 1c4cc57..9a4779f 100644 (file)
@@ -55,7 +55,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "gimplify.h"
 #include "wide-int.h"
-#include "attribs.h"
 
 static tree bot_manip (tree *, int *, void *);
 static tree bot_replace (tree *, int *, void *);
@@ -1176,52 +1175,6 @@ cv_unqualified (tree type)
   return cp_build_qualified_type (type, quals);
 }
 
-/* Subroutine of strip_typedefs.  We want to apply to RESULT the attributes
-   from ATTRIBS that affect type identity, and no others.  If any are not
-   applied, set *remove_attributes to true.  */
-
-static tree
-apply_identity_attributes (tree result, tree attribs, bool *remove_attributes)
-{
-  tree first_ident = NULL_TREE;
-  tree new_attribs = NULL_TREE;
-  tree *p = &new_attribs;
-
-  for (tree a = TYPE_ATTRIBUTES (result); a; a = TREE_CHAIN (a))
-    {
-      const attribute_spec *as
-       = lookup_attribute_spec (get_attribute_name (a));
-      if (as && as->affects_type_identity)
-       {
-         if (!first_ident)
-           first_ident = a;
-         else if (first_ident == error_mark_node)
-           {
-             *p = tree_cons (TREE_PURPOSE (a), TREE_VALUE (a), NULL_TREE);
-             p = &TREE_CHAIN (*p);
-           }
-       }
-      else if (first_ident)
-       {
-         for (tree a2 = first_ident; a2; a2 = TREE_CHAIN (a2))
-           {
-             *p = tree_cons (TREE_PURPOSE (a2), TREE_VALUE (a2), NULL_TREE);
-             p = &TREE_CHAIN (*p);
-           }
-         first_ident = error_mark_node;
-       }
-    }
-  if (first_ident != error_mark_node)
-    new_attribs = first_ident;
-
-  if (first_ident == attribs)
-    /* All attributes affected type identity.  */;
-  else
-    *remove_attributes = true;
-
-  return cp_build_type_attribute_variant (result, new_attribs);
-}
-
 /* Builds a qualified variant of T that is not a typedef variant.
    E.g. consider the following declarations:
      typedef const int ConstInt;
@@ -1240,14 +1193,10 @@ apply_identity_attributes (tree result, tree attribs, bool *remove_attributes)
     * If T is a type that needs structural equality
       its TYPE_CANONICAL (T) will be NULL.
     * TYPE_CANONICAL (T) desn't carry type attributes
-      and loses template parameter names.
-
-   If REMOVE_ATTRIBUTES is non-null, also strip attributes that don't
-   affect type identity, and set the referent to true if any were
-   stripped.  */
+      and loses template parameter names.   */
 
 tree
-strip_typedefs (tree t, bool *remove_attributes)
+strip_typedefs (tree t)
 {
   tree result = NULL, type = NULL, t0 = NULL;
 
@@ -1261,7 +1210,7 @@ strip_typedefs (tree t, bool *remove_attributes)
       for (; t; t = TREE_CHAIN (t))
        {
          gcc_assert (!TREE_PURPOSE (t));
-         tree elt = strip_typedefs (TREE_VALUE (t), remove_attributes);
+         tree elt = strip_typedefs (TREE_VALUE (t));
          if (elt != TREE_VALUE (t))
            changed = true;
          vec_safe_push (vec, elt);
@@ -1286,28 +1235,28 @@ strip_typedefs (tree t, bool *remove_attributes)
   switch (TREE_CODE (t))
     {
     case POINTER_TYPE:
-      type = strip_typedefs (TREE_TYPE (t), remove_attributes);
+      type = strip_typedefs (TREE_TYPE (t));
       result = build_pointer_type (type);
       break;
     case REFERENCE_TYPE:
-      type = strip_typedefs (TREE_TYPE (t), remove_attributes);
+      type = strip_typedefs (TREE_TYPE (t));
       result = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
       break;
     case OFFSET_TYPE:
-      t0 = strip_typedefs (TYPE_OFFSET_BASETYPE (t), remove_attributes);
-      type = strip_typedefs (TREE_TYPE (t), remove_attributes);
+      t0 = strip_typedefs (TYPE_OFFSET_BASETYPE (t));
+      type = strip_typedefs (TREE_TYPE (t));
       result = build_offset_type (t0, type);
       break;
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (t))
        {
-         t0 = strip_typedefs (TYPE_PTRMEMFUNC_FN_TYPE (t), remove_attributes);
+         t0 = strip_typedefs (TYPE_PTRMEMFUNC_FN_TYPE (t));
          result = build_ptrmemfunc_type (t0);
        }
       break;
     case ARRAY_TYPE:
-      type = strip_typedefs (TREE_TYPE (t), remove_attributes);
-      t0  = strip_typedefs (TYPE_DOMAIN (t), remove_attributes);
+      type = strip_typedefs (TREE_TYPE (t));
+      t0  = strip_typedefs (TYPE_DOMAIN (t));;
       result = build_cplus_array_type (type, t0);
       break;
     case FUNCTION_TYPE:
@@ -1320,8 +1269,7 @@ strip_typedefs (tree t, bool *remove_attributes)
          {
            if (arg_node == void_list_node)
              break;
-           arg_type = strip_typedefs (TREE_VALUE (arg_node),
-                                      remove_attributes);
+           arg_type = strip_typedefs (TREE_VALUE (arg_node));
            gcc_assert (arg_type);
 
            arg_types =
@@ -1336,7 +1284,7 @@ strip_typedefs (tree t, bool *remove_attributes)
        if (arg_node)
          arg_types = chainon (arg_types, void_list_node);
 
-       type = strip_typedefs (TREE_TYPE (t), remove_attributes);
+       type = strip_typedefs (TREE_TYPE (t));
        if (TREE_CODE (t) == METHOD_TYPE)
          {
            tree class_type = TREE_TYPE (TREE_VALUE (arg_types));
@@ -1377,9 +1325,9 @@ strip_typedefs (tree t, bool *remove_attributes)
                tree arg = TREE_VEC_ELT (args, i);
                tree strip_arg;
                if (TYPE_P (arg))
-                 strip_arg = strip_typedefs (arg, remove_attributes);
+                 strip_arg = strip_typedefs (arg);
                else
-                 strip_arg = strip_typedefs_expr (arg, remove_attributes);
+                 strip_arg = strip_typedefs_expr (arg);
                TREE_VEC_ELT (new_args, i) = strip_arg;
                if (strip_arg != arg)
                  changed = true;
@@ -1395,14 +1343,12 @@ strip_typedefs (tree t, bool *remove_attributes)
            else
              ggc_free (new_args);
          }
-       result = make_typename_type (strip_typedefs (TYPE_CONTEXT (t),
-                                                    remove_attributes),
+       result = make_typename_type (strip_typedefs (TYPE_CONTEXT (t)),
                                     fullname, typename_type, tf_none);
       }
       break;
     case DECLTYPE_TYPE:
-      result = strip_typedefs_expr (DECLTYPE_TYPE_EXPR (t),
-                                   remove_attributes);
+      result = strip_typedefs_expr (DECLTYPE_TYPE_EXPR (t));
       if (result == DECLTYPE_TYPE_EXPR (t))
        return t;
       else
@@ -1421,25 +1367,14 @@ strip_typedefs (tree t, bool *remove_attributes)
       || TYPE_ALIGN (t) != TYPE_ALIGN (result))
     {
       gcc_assert (TYPE_USER_ALIGN (t));
-      if (remove_attributes)
-       *remove_attributes = true;
+      if (TYPE_ALIGN (t) == TYPE_ALIGN (result))
+       result = build_variant_type_copy (result);
       else
-       {
-         if (TYPE_ALIGN (t) == TYPE_ALIGN (result))
-           result = build_variant_type_copy (result);
-         else
-           result = build_aligned_type (result, TYPE_ALIGN (t));
-         TYPE_USER_ALIGN (result) = true;
-       }
+       result = build_aligned_type (result, TYPE_ALIGN (t));
+      TYPE_USER_ALIGN (result) = true;
     }
   if (TYPE_ATTRIBUTES (t))
-    {
-      if (remove_attributes)
-       result = apply_identity_attributes (result, TYPE_ATTRIBUTES (t),
-                                           remove_attributes);
-      else
-       result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t));
-    }
+    result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t));
   return cp_build_qualified_type (result, cp_type_quals (t));
 }
 
@@ -1454,7 +1389,7 @@ strip_typedefs (tree t, bool *remove_attributes)
    sizeof(TT) is replaced by sizeof(T).  */
 
 tree
-strip_typedefs_expr (tree t, bool *remove_attributes)
+strip_typedefs_expr (tree t)
 {
   unsigned i,n;
   tree r, type, *ops;
@@ -1469,7 +1404,7 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
   /* Some expressions have type operands, so let's handle types here rather
      than check TYPE_P in multiple places below.  */
   if (TYPE_P (t))
-    return strip_typedefs (t, remove_attributes);
+    return strip_typedefs (t);
 
   code = TREE_CODE (t);
   switch (code)
@@ -1483,8 +1418,8 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
 
     case TRAIT_EXPR:
       {
-       tree type1 = strip_typedefs (TRAIT_EXPR_TYPE1 (t), remove_attributes);
-       tree type2 = strip_typedefs (TRAIT_EXPR_TYPE2 (t), remove_attributes);
+       tree type1 = strip_typedefs (TRAIT_EXPR_TYPE1 (t));
+       tree type2 = strip_typedefs (TRAIT_EXPR_TYPE2 (t));
        if (type1 == TRAIT_EXPR_TYPE1 (t)
            && type2 == TRAIT_EXPR_TYPE2 (t))
          return t;
@@ -1501,7 +1436,7 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
        tree it;
        for (it = t; it; it = TREE_CHAIN (it))
          {
-           tree val = strip_typedefs_expr (TREE_VALUE (t), remove_attributes);
+           tree val = strip_typedefs_expr (TREE_VALUE (t));
            vec_safe_push (vec, val);
            if (val != TREE_VALUE (t))
              changed = true;
@@ -1527,8 +1462,7 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
        vec_safe_reserve (vec, n);
        for (i = 0; i < n; ++i)
          {
-           tree op = strip_typedefs_expr (TREE_VEC_ELT (t, i),
-                                          remove_attributes);
+           tree op = strip_typedefs_expr (TREE_VEC_ELT (t, i));
            vec->quick_push (op);
            if (op != TREE_VEC_ELT (t, i))
              changed = true;
@@ -1553,18 +1487,17 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
        vec<constructor_elt, va_gc> *vec
          = vec_safe_copy (CONSTRUCTOR_ELTS (t));
        n = CONSTRUCTOR_NELTS (t);
-       type = strip_typedefs (TREE_TYPE (t), remove_attributes);
+       type = strip_typedefs (TREE_TYPE (t));
        for (i = 0; i < n; ++i)
          {
            constructor_elt *e = &(*vec)[i];
-           tree op = strip_typedefs_expr (e->value, remove_attributes);
+           tree op = strip_typedefs_expr (e->value);
            if (op != e->value)
              {
                changed = true;
                e->value = op;
              }
-           gcc_checking_assert
-             (e->index == strip_typedefs_expr (e->index, remove_attributes));
+           gcc_checking_assert (e->index == strip_typedefs_expr (e->index));
          }
 
        if (!changed && type == TREE_TYPE (t))
@@ -1605,12 +1538,12 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
     case REINTERPRET_CAST_EXPR:
     case CAST_EXPR:
     case NEW_EXPR:
-      type = strip_typedefs (type, remove_attributes);
+      type = strip_typedefs (type);
       /* fallthrough */
 
     default:
       for (i = 0; i < n; ++i)
-       ops[i] = strip_typedefs_expr (TREE_OPERAND (t, i), remove_attributes);
+       ops[i] = strip_typedefs_expr (TREE_OPERAND (t, i));
       break;
     }
 
index a7032a0..2b8300b 100644 (file)
@@ -24,5 +24,5 @@ void f (T t) { }              // { dg-warning "mangled name" }
 
 int main()
 {
-  f (A<__v4sf>::t);
+  f (A<__m128>::t);
 }
index 3806cb4..4833db8 100644 (file)
@@ -31,3 +31,6 @@ out_long (ui64 longVal)
         }
     }
 }
+
+void f(ui32 *) { }
+void f(ui32a *) { }
index d804c1a..a7706e9 100644 (file)
@@ -8,4 +8,4 @@ template<typename> struct A
   A();
 };
 
-A<X> a;               // { dg-warning "ignoring attributes on template argument" }
+A<X> a;
diff --git a/gcc/testsuite/g++.dg/ext/attrib50.C b/gcc/testsuite/g++.dg/ext/attrib50.C
deleted file mode 100644 (file)
index 9ff9918..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// PR c++/50800
-
-template <typename T> struct B;
-template <typename T> struct B<T &> {
-  typedef T type;
-};
-struct A {
-  typedef int TA __attribute__((__may_alias__));
-};
-void d() { B<int &> b; }
-int main() { B<A::TA &> b; }   // { dg-warning "attributes" }