Commit 344bf2e1 by Jason Merrill Committed by Jason Merrill

re PR c++/48138 (__attribute__((aligned)) should give an error when applied to a…

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
parent 7bd16118
2011-06-20 Jason Merrill <jason@redhat.com> 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 PR c++/47080
* call.c (rejection_reason_code): Add rr_explicit_conversion. * call.c (rejection_reason_code): Add rr_explicit_conversion.
(print_z_candidate): Handle it. (print_z_candidate): Handle it.
......
...@@ -5916,6 +5916,28 @@ template_template_parm_bindings_ok_p (tree tparms, tree targs) ...@@ -5916,6 +5916,28 @@ template_template_parm_bindings_ok_p (tree tparms, tree targs)
return ret; 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 /* Convert the indicated template ARG as necessary to match the
indicated template PARM. Returns the converted ARG, or indicated template PARM. Returns the converted ARG, or
error_mark_node if the conversion was unsuccessful. Error and error_mark_node if the conversion was unsuccessful. Error and
...@@ -6092,7 +6114,7 @@ convert_template_argument (tree parm, ...@@ -6092,7 +6114,7 @@ convert_template_argument (tree parm,
the typedef, which is confusing if those future uses do not the typedef, which is confusing if those future uses do not
themselves also use the typedef. */ themselves also use the typedef. */
if (TYPE_P (val)) if (TYPE_P (val))
val = strip_typedefs (val); val = canonicalize_type_argument (val, complain);
} }
else else
{ {
...@@ -6136,8 +6158,9 @@ convert_template_argument (tree parm, ...@@ -6136,8 +6158,9 @@ convert_template_argument (tree parm,
if (TREE_CODE (val) == SCOPE_REF) if (TREE_CODE (val) == SCOPE_REF)
{ {
/* Strip typedefs from the SCOPE_REF. */ /* Strip typedefs from the SCOPE_REF. */
tree type = strip_typedefs (TREE_TYPE (val)); tree type = canonicalize_type_argument (TREE_TYPE (val), complain);
tree scope = strip_typedefs (TREE_OPERAND (val, 0)); tree scope = canonicalize_type_argument (TREE_OPERAND (val, 0),
complain);
val = build_qualified_name (type, scope, TREE_OPERAND (val, 1), val = build_qualified_name (type, scope, TREE_OPERAND (val, 1),
QUALIFIED_NAME_IS_TEMPLATE (val)); QUALIFIED_NAME_IS_TEMPLATE (val));
} }
...@@ -15479,7 +15502,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15479,7 +15502,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
return 1; return 1;
/* Strip typedefs as in convert_template_argument. */ /* 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 /* If ARG is a parameter pack or an expansion, we cannot unify
......
// PR c++/48138 // PR c++/48138
// { dg-options -std=c++0x }
#define ALIGNED(x) __attribute__((aligned(x))) #define ALIGNED(x) __attribute__((aligned(x)))
#define SA(X) static_assert ((X),#X) #define SA(X) int ar[(X)?1:-1];
template<typename T> template<typename T>
void type_alignment(const T&) { void type_alignment(const T&) {
struct { char c; T t; } s; 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() { int main() {
typedef char unaligned[15]; typedef char unaligned[15];
typedef char aligned[15] ALIGNED(8); typedef char aligned[15] ALIGNED(8);
A<aligned> a; // { dg-warning "ignoring attributes" }
SA((char*)&a.t - (char*)&a.c == 1);
aligned z; aligned z;
type_alignment(z); type_alignment(z); // { dg-warning "ignoring attributes" "" { xfail *-*-* } }
type_alignment<unaligned ALIGNED(8)>(z); type_alignment<unaligned ALIGNED(8)>(z); // { dg-warning "ignoring attributes" "" { xfail *-*-* } }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment