aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-06-20 22:24:09 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-06-20 22:24:09 -0400
commit344bf2e1a23979f149b9489155dfe2ee74e38273 (patch)
tree14b2e8dd4ee3c89d225f748b1742d9e16a52cabe
parent7bd161189862841d30c84c4d6bb5c251869adeef (diff)
downloadgcc-344bf2e1a23979f149b9489155dfe2ee74e38273.zip
gcc-344bf2e1a23979f149b9489155dfe2ee74e38273.tar.gz
gcc-344bf2e1a23979f149b9489155dfe2ee74e38273.tar.bz2
re PR c++/48138 (__attribute__((aligned)) should give an error when applied to a typedef or template parameter, at least in C++0x mode.)
PR c++/48138 * pt.c (canonicalize_type_argument): New. (convert_template_argument, unify): Use it. From-SVN: r175236
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/pt.c31
-rw-r--r--gcc/testsuite/g++.dg/ext/attr-aligned01.C15
3 files changed, 41 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index eff4c8ee..6b84111 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6f15101..4d2caa8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
diff --git a/gcc/testsuite/g++.dg/ext/attr-aligned01.C b/gcc/testsuite/g++.dg/ext/attr-aligned01.C
index a051c6e..c8ec07d 100644
--- a/gcc/testsuite/g++.dg/ext/attr-aligned01.C
+++ b/gcc/testsuite/g++.dg/ext/attr-aligned01.C
@@ -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 *-*-* } }
}