re PR c++/17743 (dependent expressions in attributes)
PR c++/17743 * pt.c (apply_late_template_attributes): Set processing_template_decl. (tsubst_decl) [TYPE_DECL]: Preserve naming typedef, pass ATTR_FLAG_TYPE_IN_PLACE. (tsubst): Do unqualified lookup to find typedefs from current class. [ARRAY_TYPE]: Propagate alignment info. * decl2.c (is_late_template_attribute): Only defer handling of attribute aligned if the expression is dependent. (save_template_attributes): If we're deferring any attributes, make this a naming typedef. From-SVN: r128590
This commit is contained in:
parent
80a6ca747a
commit
5044ab0e64
@ -1,3 +1,16 @@
|
||||
2007-09-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/17743
|
||||
* pt.c (apply_late_template_attributes): Set processing_template_decl.
|
||||
(tsubst_decl) [TYPE_DECL]: Preserve naming typedef, pass
|
||||
ATTR_FLAG_TYPE_IN_PLACE.
|
||||
(tsubst): Do unqualified lookup to find typedefs from current class.
|
||||
[ARRAY_TYPE]: Propagate alignment info.
|
||||
* decl2.c (is_late_template_attribute): Only defer handling of
|
||||
attribute aligned if the expression is dependent.
|
||||
(save_template_attributes): If we're deferring any attributes,
|
||||
make this a naming typedef.
|
||||
|
||||
2007-09-18 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
PR c++/33462 (again)
|
||||
@ -38,17 +51,12 @@
|
||||
|
||||
2007-09-16 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
cp/
|
||||
PR c++/32756
|
||||
* call.c (maybe_handle_implicit_object): Set this_p, clear
|
||||
rvaluedness_matches_p.
|
||||
(compare_ics): Do not compare rvaluedness matching when one of the
|
||||
operands is an implicit object.
|
||||
|
||||
testsuite/
|
||||
PR c++/32756
|
||||
* g++.dg/overload/operator3.C: New.
|
||||
|
||||
2007-09-14 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/17743, c++/19163
|
||||
|
@ -992,7 +992,10 @@ bool
|
||||
is_late_template_attribute (tree attr)
|
||||
{
|
||||
tree name = TREE_PURPOSE (attr);
|
||||
if (is_attribute_p ("aligned", name))
|
||||
tree args = TREE_VALUE (attr);
|
||||
if (is_attribute_p ("aligned", name)
|
||||
&& args
|
||||
&& value_dependent_expression_p (TREE_VALUE (args)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@ -1039,6 +1042,19 @@ save_template_attributes (tree *attr_p, tree *decl_p)
|
||||
if (!late_attrs)
|
||||
return;
|
||||
|
||||
/* Give this type a name so we know to look it up again at instantiation
|
||||
time. */
|
||||
if (TREE_CODE (*decl_p) == TYPE_DECL
|
||||
&& DECL_ORIGINAL_TYPE (*decl_p) == NULL_TREE)
|
||||
{
|
||||
tree oldt = TREE_TYPE (*decl_p);
|
||||
tree newt = build_variant_type_copy (oldt);
|
||||
DECL_ORIGINAL_TYPE (*decl_p) = oldt;
|
||||
TREE_TYPE (*decl_p) = newt;
|
||||
TYPE_NAME (newt) = *decl_p;
|
||||
TREE_USED (newt) = TREE_USED (*decl_p);
|
||||
}
|
||||
|
||||
if (DECL_P (*decl_p))
|
||||
q = &DECL_ATTRIBUTES (*decl_p);
|
||||
else
|
||||
|
63
gcc/cp/pt.c
63
gcc/cp/pt.c
@ -6493,6 +6493,10 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
|
||||
else
|
||||
TYPE_ATTRIBUTES (*decl_p) = attributes;
|
||||
|
||||
/* Set processing_template_decl so we can check for dependent
|
||||
expressions. */
|
||||
++processing_template_decl;
|
||||
|
||||
for (t = attributes; t; t = TREE_CHAIN (t))
|
||||
if (is_late_template_attribute (t))
|
||||
late_attrs = tree_cons
|
||||
@ -6501,6 +6505,8 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
|
||||
/*integral_constant_expression_p=*/false),
|
||||
late_attrs);
|
||||
|
||||
--processing_template_decl;
|
||||
|
||||
cplus_decl_attributes (decl_p, late_attrs, attr_flags);
|
||||
}
|
||||
|
||||
@ -8223,6 +8229,16 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
|
||||
}
|
||||
determine_visibility (r);
|
||||
}
|
||||
/* Preserve a typedef that names a type. */
|
||||
else if (TREE_CODE (r) == TYPE_DECL
|
||||
&& DECL_ORIGINAL_TYPE (t)
|
||||
&& type != error_mark_node)
|
||||
{
|
||||
DECL_ORIGINAL_TYPE (r) = tsubst (DECL_ORIGINAL_TYPE (t),
|
||||
args, complain, in_decl);
|
||||
TREE_TYPE (r) = type = build_variant_type_copy (type);
|
||||
TYPE_NAME (type) = r;
|
||||
}
|
||||
|
||||
if (!local_p)
|
||||
{
|
||||
@ -8241,7 +8257,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
|
||||
|
||||
TREE_CHAIN (r) = NULL_TREE;
|
||||
|
||||
apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0,
|
||||
apply_late_template_attributes (&r, DECL_ATTRIBUTES (r),
|
||||
(int) ATTR_FLAG_TYPE_IN_PLACE,
|
||||
args, complain, in_decl);
|
||||
layout_decl (r, 0);
|
||||
}
|
||||
@ -8534,6 +8551,43 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
|
||||
gcc_assert (type != unknown_type_node);
|
||||
|
||||
/* Reuse typedefs. This is a rather complicated way to check whether the
|
||||
type is a typedef from the same class template as the current scope,
|
||||
but I can't think of a better one.
|
||||
|
||||
We need to do this to handle dependent attributes, specifically
|
||||
attribute aligned. */
|
||||
if (TYPE_P (t)
|
||||
&& TYPE_NAME (t)
|
||||
&& !IS_AGGR_TYPE (t)
|
||||
&& current_class_type
|
||||
&& CLASSTYPE_TEMPLATE_INFO (current_class_type))
|
||||
{
|
||||
tree decl = TYPE_NAME (t);
|
||||
tree context = DECL_CONTEXT (decl);
|
||||
if (context
|
||||
&& CLASS_TYPE_P (context)
|
||||
&& CLASSTYPE_TEMPLATE_INFO (context)
|
||||
&& (CLASSTYPE_TI_TEMPLATE (context)
|
||||
== CLASSTYPE_TI_TEMPLATE (current_class_type))
|
||||
&& (tsubst_aggr_type (context, args, complain, in_decl,
|
||||
/*entering_scope=*/0)
|
||||
== current_class_type))
|
||||
{
|
||||
r = lookup_name (DECL_NAME (decl));
|
||||
if (r && TREE_CODE (r) == TYPE_DECL
|
||||
&& DECL_CONTEXT (r) == current_class_type)
|
||||
{
|
||||
r = TREE_TYPE (r);
|
||||
r = cp_build_qualified_type_real
|
||||
(r, cp_type_quals (t) | cp_type_quals (r),
|
||||
complain | tf_ignore_bad_quals);
|
||||
return r;
|
||||
/* Else we're instantiating the typedef, so fall through. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type
|
||||
&& TREE_CODE (t) != TYPENAME_TYPE
|
||||
&& TREE_CODE (t) != IDENTIFIER_NODE
|
||||
@ -9013,6 +9067,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
}
|
||||
|
||||
r = build_cplus_array_type (type, domain);
|
||||
|
||||
if (TYPE_USER_ALIGN (t))
|
||||
{
|
||||
TYPE_ALIGN (r) = TYPE_ALIGN (t);
|
||||
TYPE_USER_ALIGN (r) = 1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
21
gcc/testsuite/g++.dg/ext/tmplattr3.C
Normal file
21
gcc/testsuite/g++.dg/ext/tmplattr3.C
Normal file
@ -0,0 +1,21 @@
|
||||
// PR c++/17743
|
||||
|
||||
template<typename T>
|
||||
struct X {
|
||||
typedef char layout_type[sizeof(T)]
|
||||
__attribute ((aligned(__alignof(double))));
|
||||
layout_type data;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct Y {
|
||||
typedef char layout_type[sizeof(T)]
|
||||
__attribute ((aligned(__alignof(T))));
|
||||
layout_type data;
|
||||
};
|
||||
|
||||
template<bool> struct StaticAssert;
|
||||
template<> struct StaticAssert<true> {};
|
||||
|
||||
StaticAssert<__alignof(X<double>) == __alignof(double)> d1;
|
||||
StaticAssert<__alignof(Y<double>) == __alignof(double)> d2;
|
Loading…
Reference in New Issue
Block a user