re PR c++/48138 (__attribute__((aligned)) should give an error when applied to a...
authorJason Merrill <jason@redhat.com>
Tue, 21 Jun 2011 02:24:09 +0000 (22:24 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 21 Jun 2011 02:24:09 +0000 (22:24 -0400)
PR c++/48138
* pt.c (canonicalize_type_argument): New.
(convert_template_argument, unify): Use it.

From-SVN: r175236

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/ext/attr-aligned01.C

index eff4c8ee81e2bdf69aa66fbab0e9cf402e723513..6b84111ae1a844bf161a7be4aaeea15a03edb7c6 100644 (file)
@@ -1,5 +1,9 @@
 2011-06-20  Jason Merrill  <jason@redhat.com>
 
+       PR c++/48138
+       * pt.c (canonicalize_type_argument): New.
+       (convert_template_argument, unify): Use it.
+
        PR c++/47080
        * call.c (rejection_reason_code): Add rr_explicit_conversion.
        (print_z_candidate): Handle it.
index 6f15101d6e921dc9029f659b3b6ec6c44454432a..4d2caa883078ba45c9486011d7e58dea18a26bb7 100644 (file)
@@ -5916,6 +5916,28 @@ template_template_parm_bindings_ok_p (tree tparms, tree targs)
   return ret;
 }
 
+/* Since type attributes aren't mangled, we need to strip them from
+   template type arguments.  */
+
+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;
+  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
    indicated template PARM.  Returns the converted ARG, or
    error_mark_node if the conversion was unsuccessful.  Error and
@@ -6092,7 +6114,7 @@ convert_template_argument (tree parm,
         the typedef, which is confusing if those future uses do not
         themselves also use the typedef.  */
       if (TYPE_P (val))
-       val = strip_typedefs (val);
+       val = canonicalize_type_argument (val, complain);
     }
   else
     {
@@ -6136,8 +6158,9 @@ convert_template_argument (tree parm,
       if (TREE_CODE (val) == SCOPE_REF)
        {
          /* Strip typedefs from the SCOPE_REF.  */
-         tree type = strip_typedefs (TREE_TYPE (val));
-         tree scope = strip_typedefs (TREE_OPERAND (val, 0));
+         tree type = canonicalize_type_argument (TREE_TYPE (val), complain);
+         tree scope = canonicalize_type_argument (TREE_OPERAND (val, 0),
+                                                  complain);
          val = build_qualified_name (type, scope, TREE_OPERAND (val, 1),
                                      QUALIFIED_NAME_IS_TEMPLATE (val));
        }
@@ -15479,7 +15502,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
            return 1;
 
          /* Strip typedefs as in convert_template_argument.  */
-         arg = strip_typedefs (arg);
+         arg = canonicalize_type_argument (arg, tf_none);
        }
 
       /* If ARG is a parameter pack or an expansion, we cannot unify
index a051c6e98d3090cbd63d13d7dc3dd7f6fc0166c6..c8ec07d5107a46be9bc61199a1b695f2731dd869 100644 (file)
@@ -1,20 +1,25 @@
 // PR c++/48138
-// { dg-options -std=c++0x }
 
 #define ALIGNED(x) __attribute__((aligned(x)))
-#define SA(X) static_assert ((X),#X)
+#define SA(X) int ar[(X)?1:-1];
 
 template<typename T>
 void type_alignment(const T&) {
   struct { char c; T t; } s;
-  SA((char*)&s.t - (char*)&s.c == 8);
+  SA((char*)&s.t - (char*)&s.c == 1);
 }
 
+template <class T> struct A { char c; T t; };
+
 int main() {
   typedef char unaligned[15];
   typedef char aligned[15] ALIGNED(8);
 
+  A<aligned> a;                        // { dg-warning "ignoring attributes" }
+
+  SA((char*)&a.t - (char*)&a.c == 1);
+
   aligned z;
-  type_alignment(z);
-  type_alignment<unaligned ALIGNED(8)>(z);
+  type_alignment(z);           // { dg-warning "ignoring attributes" "" { xfail *-*-* } }
+  type_alignment<unaligned ALIGNED(8)>(z); // { dg-warning "ignoring attributes" "" { xfail *-*-* } }
 }