diff options
author | Jason Merrill <jason@redhat.com> | 2011-06-20 22:24:09 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-06-20 22:24:09 -0400 |
commit | 344bf2e1a23979f149b9489155dfe2ee74e38273 (patch) | |
tree | 14b2e8dd4ee3c89d225f748b1742d9e16a52cabe | |
parent | 7bd161189862841d30c84c4d6bb5c251869adeef (diff) | |
download | gcc-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/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/attr-aligned01.C | 15 |
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 *-*-* } } } |