re PR c++/50800 (Internal compiler error in finish_member_declarations, possibly related to may_alias attribute)
PR c++/50800 * tree.c (strip_typedefs): Add remove_attributes parm. (strip_typedefs_expr): Likewise. (apply_identity_attributes): New subroutine of strip_typedefs. * pt.c (canonicalize_type_argument): Let strip_typedefs handle attrs. (convert_nontype_argument, unify): Likewise. * cp-tree.h: Adjust. From-SVN: r222377
This commit is contained in:
parent
6c28362134
commit
b88fa2656b
|
@ -1,5 +1,13 @@
|
||||||
2015-04-23 Jason Merrill <jason@redhat.com>
|
2015-04-23 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
PR c++/50800
|
||||||
|
* tree.c (strip_typedefs): Add remove_attributes parm.
|
||||||
|
(strip_typedefs_expr): Likewise.
|
||||||
|
(apply_identity_attributes): New subroutine of strip_typedefs.
|
||||||
|
* pt.c (canonicalize_type_argument): Let strip_typedefs handle attrs.
|
||||||
|
(convert_nontype_argument, unify): Likewise.
|
||||||
|
* cp-tree.h: Adjust.
|
||||||
|
|
||||||
PR c++/65646
|
PR c++/65646
|
||||||
* pt.c (check_explicit_specialization): Don't
|
* pt.c (check_explicit_specialization): Don't
|
||||||
SET_DECL_TEMPLATE_SPECIALIZATION for a variable with no template
|
SET_DECL_TEMPLATE_SPECIALIZATION for a variable with no template
|
||||||
|
|
|
@ -6066,8 +6066,8 @@ extern bool class_tmpl_impl_spec_p (const_tree);
|
||||||
extern int zero_init_p (const_tree);
|
extern int zero_init_p (const_tree);
|
||||||
extern bool check_abi_tag_redeclaration (const_tree, const_tree, const_tree);
|
extern bool check_abi_tag_redeclaration (const_tree, const_tree, const_tree);
|
||||||
extern bool check_abi_tag_args (tree, tree);
|
extern bool check_abi_tag_args (tree, tree);
|
||||||
extern tree strip_typedefs (tree);
|
extern tree strip_typedefs (tree, bool * = NULL);
|
||||||
extern tree strip_typedefs_expr (tree);
|
extern tree strip_typedefs_expr (tree, bool * = NULL);
|
||||||
extern tree copy_binfo (tree, tree, tree,
|
extern tree copy_binfo (tree, tree, tree,
|
||||||
tree *, int);
|
tree *, int);
|
||||||
extern int member_p (const_tree);
|
extern int member_p (const_tree);
|
||||||
|
|
26
gcc/cp/pt.c
26
gcc/cp/pt.c
|
@ -6493,20 +6493,14 @@ template_template_parm_bindings_ok_p (tree tparms, tree targs)
|
||||||
static tree
|
static tree
|
||||||
canonicalize_type_argument (tree arg, tsubst_flags_t complain)
|
canonicalize_type_argument (tree arg, tsubst_flags_t complain)
|
||||||
{
|
{
|
||||||
tree mv;
|
|
||||||
if (!arg || arg == error_mark_node || arg == TYPE_CANONICAL (arg))
|
if (!arg || arg == error_mark_node || arg == TYPE_CANONICAL (arg))
|
||||||
return arg;
|
return arg;
|
||||||
mv = TYPE_MAIN_VARIANT (arg);
|
bool removed_attributes = false;
|
||||||
arg = strip_typedefs (arg);
|
tree canon = strip_typedefs (arg, &removed_attributes);
|
||||||
if (TYPE_ALIGN (arg) != TYPE_ALIGN (mv)
|
if (removed_attributes
|
||||||
|| TYPE_ATTRIBUTES (arg) != TYPE_ATTRIBUTES (mv))
|
&& (complain & tf_warning))
|
||||||
{
|
|
||||||
if (complain & tf_warning)
|
|
||||||
warning (0, "ignoring attributes on template argument %qT", arg);
|
warning (0, "ignoring attributes on template argument %qT", arg);
|
||||||
arg = build_aligned_type (arg, TYPE_ALIGN (mv));
|
return canon;
|
||||||
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
|
||||||
|
@ -6743,7 +6737,10 @@ convert_template_argument (tree parm,
|
||||||
argument specification is valid. */
|
argument specification is valid. */
|
||||||
val = convert_nontype_argument (t, orig_arg, complain);
|
val = convert_nontype_argument (t, orig_arg, complain);
|
||||||
else
|
else
|
||||||
val = strip_typedefs_expr (orig_arg);
|
{
|
||||||
|
bool removed_attr = false;
|
||||||
|
val = strip_typedefs_expr (orig_arg, &removed_attr);
|
||||||
|
}
|
||||||
|
|
||||||
if (val == NULL_TREE)
|
if (val == NULL_TREE)
|
||||||
val = error_mark_node;
|
val = error_mark_node;
|
||||||
|
@ -18202,7 +18199,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
|
||||||
&& !TEMPLATE_PARM_PARAMETER_PACK (parm))
|
&& !TEMPLATE_PARM_PARAMETER_PACK (parm))
|
||||||
return unify_parameter_pack_mismatch (explain_p, parm, arg);
|
return unify_parameter_pack_mismatch (explain_p, parm, arg);
|
||||||
|
|
||||||
arg = strip_typedefs_expr (arg);
|
{
|
||||||
|
bool removed_attr = false;
|
||||||
|
arg = strip_typedefs_expr (arg, &removed_attr);
|
||||||
|
}
|
||||||
TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
|
TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
|
||||||
return unify_success (explain_p);
|
return unify_success (explain_p);
|
||||||
|
|
||||||
|
|
121
gcc/cp/tree.c
121
gcc/cp/tree.c
|
@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "gimple-expr.h"
|
#include "gimple-expr.h"
|
||||||
#include "gimplify.h"
|
#include "gimplify.h"
|
||||||
#include "wide-int.h"
|
#include "wide-int.h"
|
||||||
|
#include "attribs.h"
|
||||||
|
|
||||||
static tree bot_manip (tree *, int *, void *);
|
static tree bot_manip (tree *, int *, void *);
|
||||||
static tree bot_replace (tree *, int *, void *);
|
static tree bot_replace (tree *, int *, void *);
|
||||||
|
@ -1175,6 +1176,52 @@ cv_unqualified (tree type)
|
||||||
return cp_build_qualified_type (type, quals);
|
return cp_build_qualified_type (type, quals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Subroutine of strip_typedefs. We want to apply to RESULT the attributes
|
||||||
|
from ATTRIBS that affect type identity, and no others. If any are not
|
||||||
|
applied, set *remove_attributes to true. */
|
||||||
|
|
||||||
|
static tree
|
||||||
|
apply_identity_attributes (tree result, tree attribs, bool *remove_attributes)
|
||||||
|
{
|
||||||
|
tree first_ident = NULL_TREE;
|
||||||
|
tree new_attribs = NULL_TREE;
|
||||||
|
tree *p = &new_attribs;
|
||||||
|
|
||||||
|
for (tree a = TYPE_ATTRIBUTES (result); a; a = TREE_CHAIN (a))
|
||||||
|
{
|
||||||
|
const attribute_spec *as
|
||||||
|
= lookup_attribute_spec (get_attribute_name (a));
|
||||||
|
if (as && as->affects_type_identity)
|
||||||
|
{
|
||||||
|
if (!first_ident)
|
||||||
|
first_ident = a;
|
||||||
|
else if (first_ident == error_mark_node)
|
||||||
|
{
|
||||||
|
*p = tree_cons (TREE_PURPOSE (a), TREE_VALUE (a), NULL_TREE);
|
||||||
|
p = &TREE_CHAIN (*p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (first_ident)
|
||||||
|
{
|
||||||
|
for (tree a2 = first_ident; a2; a2 = TREE_CHAIN (a2))
|
||||||
|
{
|
||||||
|
*p = tree_cons (TREE_PURPOSE (a2), TREE_VALUE (a2), NULL_TREE);
|
||||||
|
p = &TREE_CHAIN (*p);
|
||||||
|
}
|
||||||
|
first_ident = error_mark_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (first_ident != error_mark_node)
|
||||||
|
new_attribs = first_ident;
|
||||||
|
|
||||||
|
if (first_ident == attribs)
|
||||||
|
/* All attributes affected type identity. */;
|
||||||
|
else
|
||||||
|
*remove_attributes = true;
|
||||||
|
|
||||||
|
return cp_build_type_attribute_variant (result, new_attribs);
|
||||||
|
}
|
||||||
|
|
||||||
/* Builds a qualified variant of T that is not a typedef variant.
|
/* Builds a qualified variant of T that is not a typedef variant.
|
||||||
E.g. consider the following declarations:
|
E.g. consider the following declarations:
|
||||||
typedef const int ConstInt;
|
typedef const int ConstInt;
|
||||||
|
@ -1193,10 +1240,14 @@ cv_unqualified (tree type)
|
||||||
* If T is a type that needs structural equality
|
* If T is a type that needs structural equality
|
||||||
its TYPE_CANONICAL (T) will be NULL.
|
its TYPE_CANONICAL (T) will be NULL.
|
||||||
* TYPE_CANONICAL (T) desn't carry type attributes
|
* TYPE_CANONICAL (T) desn't carry type attributes
|
||||||
and loses template parameter names. */
|
and loses template parameter names.
|
||||||
|
|
||||||
|
If REMOVE_ATTRIBUTES is non-null, also strip attributes that don't
|
||||||
|
affect type identity, and set the referent to true if any were
|
||||||
|
stripped. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
strip_typedefs (tree t)
|
strip_typedefs (tree t, bool *remove_attributes)
|
||||||
{
|
{
|
||||||
tree result = NULL, type = NULL, t0 = NULL;
|
tree result = NULL, type = NULL, t0 = NULL;
|
||||||
|
|
||||||
|
@ -1210,7 +1261,7 @@ strip_typedefs (tree t)
|
||||||
for (; t; t = TREE_CHAIN (t))
|
for (; t; t = TREE_CHAIN (t))
|
||||||
{
|
{
|
||||||
gcc_assert (!TREE_PURPOSE (t));
|
gcc_assert (!TREE_PURPOSE (t));
|
||||||
tree elt = strip_typedefs (TREE_VALUE (t));
|
tree elt = strip_typedefs (TREE_VALUE (t), remove_attributes);
|
||||||
if (elt != TREE_VALUE (t))
|
if (elt != TREE_VALUE (t))
|
||||||
changed = true;
|
changed = true;
|
||||||
vec_safe_push (vec, elt);
|
vec_safe_push (vec, elt);
|
||||||
|
@ -1235,28 +1286,28 @@ strip_typedefs (tree t)
|
||||||
switch (TREE_CODE (t))
|
switch (TREE_CODE (t))
|
||||||
{
|
{
|
||||||
case POINTER_TYPE:
|
case POINTER_TYPE:
|
||||||
type = strip_typedefs (TREE_TYPE (t));
|
type = strip_typedefs (TREE_TYPE (t), remove_attributes);
|
||||||
result = build_pointer_type (type);
|
result = build_pointer_type (type);
|
||||||
break;
|
break;
|
||||||
case REFERENCE_TYPE:
|
case REFERENCE_TYPE:
|
||||||
type = strip_typedefs (TREE_TYPE (t));
|
type = strip_typedefs (TREE_TYPE (t), remove_attributes);
|
||||||
result = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
|
result = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
|
||||||
break;
|
break;
|
||||||
case OFFSET_TYPE:
|
case OFFSET_TYPE:
|
||||||
t0 = strip_typedefs (TYPE_OFFSET_BASETYPE (t));
|
t0 = strip_typedefs (TYPE_OFFSET_BASETYPE (t), remove_attributes);
|
||||||
type = strip_typedefs (TREE_TYPE (t));
|
type = strip_typedefs (TREE_TYPE (t), remove_attributes);
|
||||||
result = build_offset_type (t0, type);
|
result = build_offset_type (t0, type);
|
||||||
break;
|
break;
|
||||||
case RECORD_TYPE:
|
case RECORD_TYPE:
|
||||||
if (TYPE_PTRMEMFUNC_P (t))
|
if (TYPE_PTRMEMFUNC_P (t))
|
||||||
{
|
{
|
||||||
t0 = strip_typedefs (TYPE_PTRMEMFUNC_FN_TYPE (t));
|
t0 = strip_typedefs (TYPE_PTRMEMFUNC_FN_TYPE (t), remove_attributes);
|
||||||
result = build_ptrmemfunc_type (t0);
|
result = build_ptrmemfunc_type (t0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARRAY_TYPE:
|
case ARRAY_TYPE:
|
||||||
type = strip_typedefs (TREE_TYPE (t));
|
type = strip_typedefs (TREE_TYPE (t), remove_attributes);
|
||||||
t0 = strip_typedefs (TYPE_DOMAIN (t));;
|
t0 = strip_typedefs (TYPE_DOMAIN (t), remove_attributes);
|
||||||
result = build_cplus_array_type (type, t0);
|
result = build_cplus_array_type (type, t0);
|
||||||
break;
|
break;
|
||||||
case FUNCTION_TYPE:
|
case FUNCTION_TYPE:
|
||||||
|
@ -1269,7 +1320,8 @@ strip_typedefs (tree t)
|
||||||
{
|
{
|
||||||
if (arg_node == void_list_node)
|
if (arg_node == void_list_node)
|
||||||
break;
|
break;
|
||||||
arg_type = strip_typedefs (TREE_VALUE (arg_node));
|
arg_type = strip_typedefs (TREE_VALUE (arg_node),
|
||||||
|
remove_attributes);
|
||||||
gcc_assert (arg_type);
|
gcc_assert (arg_type);
|
||||||
|
|
||||||
arg_types =
|
arg_types =
|
||||||
|
@ -1284,7 +1336,7 @@ strip_typedefs (tree t)
|
||||||
if (arg_node)
|
if (arg_node)
|
||||||
arg_types = chainon (arg_types, void_list_node);
|
arg_types = chainon (arg_types, void_list_node);
|
||||||
|
|
||||||
type = strip_typedefs (TREE_TYPE (t));
|
type = strip_typedefs (TREE_TYPE (t), remove_attributes);
|
||||||
if (TREE_CODE (t) == METHOD_TYPE)
|
if (TREE_CODE (t) == METHOD_TYPE)
|
||||||
{
|
{
|
||||||
tree class_type = TREE_TYPE (TREE_VALUE (arg_types));
|
tree class_type = TREE_TYPE (TREE_VALUE (arg_types));
|
||||||
|
@ -1325,9 +1377,9 @@ strip_typedefs (tree t)
|
||||||
tree arg = TREE_VEC_ELT (args, i);
|
tree arg = TREE_VEC_ELT (args, i);
|
||||||
tree strip_arg;
|
tree strip_arg;
|
||||||
if (TYPE_P (arg))
|
if (TYPE_P (arg))
|
||||||
strip_arg = strip_typedefs (arg);
|
strip_arg = strip_typedefs (arg, remove_attributes);
|
||||||
else
|
else
|
||||||
strip_arg = strip_typedefs_expr (arg);
|
strip_arg = strip_typedefs_expr (arg, remove_attributes);
|
||||||
TREE_VEC_ELT (new_args, i) = strip_arg;
|
TREE_VEC_ELT (new_args, i) = strip_arg;
|
||||||
if (strip_arg != arg)
|
if (strip_arg != arg)
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -1343,12 +1395,14 @@ strip_typedefs (tree t)
|
||||||
else
|
else
|
||||||
ggc_free (new_args);
|
ggc_free (new_args);
|
||||||
}
|
}
|
||||||
result = make_typename_type (strip_typedefs (TYPE_CONTEXT (t)),
|
result = make_typename_type (strip_typedefs (TYPE_CONTEXT (t),
|
||||||
|
remove_attributes),
|
||||||
fullname, typename_type, tf_none);
|
fullname, typename_type, tf_none);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DECLTYPE_TYPE:
|
case DECLTYPE_TYPE:
|
||||||
result = strip_typedefs_expr (DECLTYPE_TYPE_EXPR (t));
|
result = strip_typedefs_expr (DECLTYPE_TYPE_EXPR (t),
|
||||||
|
remove_attributes);
|
||||||
if (result == DECLTYPE_TYPE_EXPR (t))
|
if (result == DECLTYPE_TYPE_EXPR (t))
|
||||||
return t;
|
return t;
|
||||||
else
|
else
|
||||||
|
@ -1367,14 +1421,25 @@ strip_typedefs (tree t)
|
||||||
|| TYPE_ALIGN (t) != TYPE_ALIGN (result))
|
|| TYPE_ALIGN (t) != TYPE_ALIGN (result))
|
||||||
{
|
{
|
||||||
gcc_assert (TYPE_USER_ALIGN (t));
|
gcc_assert (TYPE_USER_ALIGN (t));
|
||||||
|
if (remove_attributes)
|
||||||
|
*remove_attributes = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
if (TYPE_ALIGN (t) == TYPE_ALIGN (result))
|
if (TYPE_ALIGN (t) == TYPE_ALIGN (result))
|
||||||
result = build_variant_type_copy (result);
|
result = build_variant_type_copy (result);
|
||||||
else
|
else
|
||||||
result = build_aligned_type (result, TYPE_ALIGN (t));
|
result = build_aligned_type (result, TYPE_ALIGN (t));
|
||||||
TYPE_USER_ALIGN (result) = true;
|
TYPE_USER_ALIGN (result) = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (TYPE_ATTRIBUTES (t))
|
if (TYPE_ATTRIBUTES (t))
|
||||||
|
{
|
||||||
|
if (remove_attributes)
|
||||||
|
result = apply_identity_attributes (result, TYPE_ATTRIBUTES (t),
|
||||||
|
remove_attributes);
|
||||||
|
else
|
||||||
result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t));
|
result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t));
|
||||||
|
}
|
||||||
return cp_build_qualified_type (result, cp_type_quals (t));
|
return cp_build_qualified_type (result, cp_type_quals (t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1389,7 +1454,7 @@ strip_typedefs (tree t)
|
||||||
sizeof(TT) is replaced by sizeof(T). */
|
sizeof(TT) is replaced by sizeof(T). */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
strip_typedefs_expr (tree t)
|
strip_typedefs_expr (tree t, bool *remove_attributes)
|
||||||
{
|
{
|
||||||
unsigned i,n;
|
unsigned i,n;
|
||||||
tree r, type, *ops;
|
tree r, type, *ops;
|
||||||
|
@ -1404,7 +1469,7 @@ strip_typedefs_expr (tree t)
|
||||||
/* Some expressions have type operands, so let's handle types here rather
|
/* Some expressions have type operands, so let's handle types here rather
|
||||||
than check TYPE_P in multiple places below. */
|
than check TYPE_P in multiple places below. */
|
||||||
if (TYPE_P (t))
|
if (TYPE_P (t))
|
||||||
return strip_typedefs (t);
|
return strip_typedefs (t, remove_attributes);
|
||||||
|
|
||||||
code = TREE_CODE (t);
|
code = TREE_CODE (t);
|
||||||
switch (code)
|
switch (code)
|
||||||
|
@ -1418,8 +1483,8 @@ strip_typedefs_expr (tree t)
|
||||||
|
|
||||||
case TRAIT_EXPR:
|
case TRAIT_EXPR:
|
||||||
{
|
{
|
||||||
tree type1 = strip_typedefs (TRAIT_EXPR_TYPE1 (t));
|
tree type1 = strip_typedefs (TRAIT_EXPR_TYPE1 (t), remove_attributes);
|
||||||
tree type2 = strip_typedefs (TRAIT_EXPR_TYPE2 (t));
|
tree type2 = strip_typedefs (TRAIT_EXPR_TYPE2 (t), remove_attributes);
|
||||||
if (type1 == TRAIT_EXPR_TYPE1 (t)
|
if (type1 == TRAIT_EXPR_TYPE1 (t)
|
||||||
&& type2 == TRAIT_EXPR_TYPE2 (t))
|
&& type2 == TRAIT_EXPR_TYPE2 (t))
|
||||||
return t;
|
return t;
|
||||||
|
@ -1436,7 +1501,7 @@ strip_typedefs_expr (tree t)
|
||||||
tree it;
|
tree it;
|
||||||
for (it = t; it; it = TREE_CHAIN (it))
|
for (it = t; it; it = TREE_CHAIN (it))
|
||||||
{
|
{
|
||||||
tree val = strip_typedefs_expr (TREE_VALUE (t));
|
tree val = strip_typedefs_expr (TREE_VALUE (t), remove_attributes);
|
||||||
vec_safe_push (vec, val);
|
vec_safe_push (vec, val);
|
||||||
if (val != TREE_VALUE (t))
|
if (val != TREE_VALUE (t))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -1462,7 +1527,8 @@ strip_typedefs_expr (tree t)
|
||||||
vec_safe_reserve (vec, n);
|
vec_safe_reserve (vec, n);
|
||||||
for (i = 0; i < n; ++i)
|
for (i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
tree op = strip_typedefs_expr (TREE_VEC_ELT (t, i));
|
tree op = strip_typedefs_expr (TREE_VEC_ELT (t, i),
|
||||||
|
remove_attributes);
|
||||||
vec->quick_push (op);
|
vec->quick_push (op);
|
||||||
if (op != TREE_VEC_ELT (t, i))
|
if (op != TREE_VEC_ELT (t, i))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -1487,17 +1553,18 @@ strip_typedefs_expr (tree t)
|
||||||
vec<constructor_elt, va_gc> *vec
|
vec<constructor_elt, va_gc> *vec
|
||||||
= vec_safe_copy (CONSTRUCTOR_ELTS (t));
|
= vec_safe_copy (CONSTRUCTOR_ELTS (t));
|
||||||
n = CONSTRUCTOR_NELTS (t);
|
n = CONSTRUCTOR_NELTS (t);
|
||||||
type = strip_typedefs (TREE_TYPE (t));
|
type = strip_typedefs (TREE_TYPE (t), remove_attributes);
|
||||||
for (i = 0; i < n; ++i)
|
for (i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
constructor_elt *e = &(*vec)[i];
|
constructor_elt *e = &(*vec)[i];
|
||||||
tree op = strip_typedefs_expr (e->value);
|
tree op = strip_typedefs_expr (e->value, remove_attributes);
|
||||||
if (op != e->value)
|
if (op != e->value)
|
||||||
{
|
{
|
||||||
changed = true;
|
changed = true;
|
||||||
e->value = op;
|
e->value = op;
|
||||||
}
|
}
|
||||||
gcc_checking_assert (e->index == strip_typedefs_expr (e->index));
|
gcc_checking_assert
|
||||||
|
(e->index == strip_typedefs_expr (e->index, remove_attributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!changed && type == TREE_TYPE (t))
|
if (!changed && type == TREE_TYPE (t))
|
||||||
|
@ -1538,12 +1605,12 @@ strip_typedefs_expr (tree t)
|
||||||
case REINTERPRET_CAST_EXPR:
|
case REINTERPRET_CAST_EXPR:
|
||||||
case CAST_EXPR:
|
case CAST_EXPR:
|
||||||
case NEW_EXPR:
|
case NEW_EXPR:
|
||||||
type = strip_typedefs (type);
|
type = strip_typedefs (type, remove_attributes);
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
for (i = 0; i < n; ++i)
|
for (i = 0; i < n; ++i)
|
||||||
ops[i] = strip_typedefs_expr (TREE_OPERAND (t, i));
|
ops[i] = strip_typedefs_expr (TREE_OPERAND (t, i), remove_attributes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,5 +24,5 @@ void f (T t) { } // { dg-warning "mangled name" }
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
f (A<__m128>::t);
|
f (A<__v4sf>::t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,3 @@ out_long (ui64 longVal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void f(ui32 *) { }
|
|
||||||
void f(ui32a *) { }
|
|
||||||
|
|
|
@ -8,4 +8,4 @@ template<typename> struct A
|
||||||
A();
|
A();
|
||||||
};
|
};
|
||||||
|
|
||||||
A<X> a;
|
A<X> a; // { dg-warning "ignoring attributes on template argument" }
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
// PR c++/50800
|
||||||
|
|
||||||
|
template <typename T> struct B;
|
||||||
|
template <typename T> struct B<T &> {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
struct A {
|
||||||
|
typedef int TA __attribute__((__may_alias__));
|
||||||
|
};
|
||||||
|
void d() { B<int &> b; }
|
||||||
|
int main() { B<A::TA &> b; } // { dg-warning "attributes" }
|
Loading…
Reference in New Issue