Commit 10bce48f by Richard Sandiford Committed by Richard Sandiford

[C++] Avoid exposing internal details in aka types

This patch extends r276951 to work for C++ too.

2019-10-22  Richard Sandiford  <richard.sandiford@arm.com>

gcc/cp/
	* cp-tree.h (STF_USER_VISIBLE): New constant.
	(strip_typedefs, strip_typedefs_expr): Take a flags argument.
	* tree.c (strip_typedefs, strip_typedefs_expr): Likewise,
	updating mutual calls accordingly.  When STF_USER_VISIBLE is true,
	only look through typedefs if user_facing_original_type_p.
	* error.c (dump_template_bindings, type_to_string): Pass
	STF_USER_VISIBLE to strip_typedefs.
	(dump_type): Likewise, unless pp_c_flag_gnu_v3 is set.

gcc/testsuite/
	* g++.dg/diagnostic/aka5.h: New test.
	* g++.dg/diagnostic/aka5a.C: Likewise.
	* g++.dg/diagnostic/aka5b.C: Likewise.
	* g++.target/aarch64/diag_aka_1.C: Likewise.

From-SVN: r277281
parent 24b54eb2
2019-10-22 Richard Sandiford <richard.sandiford@arm.com>
* cp-tree.h (STF_USER_VISIBLE): New constant.
(strip_typedefs, strip_typedefs_expr): Take a flags argument.
* tree.c (strip_typedefs, strip_typedefs_expr): Likewise,
updating mutual calls accordingly. When STF_USER_VISIBLE is true,
only look through typedefs if user_facing_original_type_p.
* error.c (dump_template_bindings, type_to_string): Pass
STF_USER_VISIBLE to strip_typedefs.
(dump_type): Likewise, unless pp_c_flag_gnu_v3 is set.
2019-10-21 Kamlesh Kumar <kamleshbhalui@gmail.com> 2019-10-21 Kamlesh Kumar <kamleshbhalui@gmail.com>
Jason Merrill <jason@redhat.com> Jason Merrill <jason@redhat.com>
......
...@@ -5722,6 +5722,13 @@ enum auto_deduction_context ...@@ -5722,6 +5722,13 @@ enum auto_deduction_context
#define TFF_NO_TEMPLATE_BINDINGS (1 << 13) #define TFF_NO_TEMPLATE_BINDINGS (1 << 13)
#define TFF_POINTER (1 << 14) #define TFF_POINTER (1 << 14)
/* These constants can be used as bit flags to control strip_typedefs.
STF_USER_VISIBLE: use heuristics to try to avoid stripping user-facing
aliases of internal details. This is intended for diagnostics,
where it should (for example) give more useful "aka" types. */
const unsigned int STF_USER_VISIBLE = 1U;
/* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
node. */ node. */
#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL(NODE) \ #define TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL(NODE) \
...@@ -7259,8 +7266,10 @@ extern int zero_init_p (const_tree); ...@@ -7259,8 +7266,10 @@ extern int zero_init_p (const_tree);
extern bool check_abi_tag_redeclaration (const_tree, const_tree, extern bool check_abi_tag_redeclaration (const_tree, 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, bool * = NULL); extern tree strip_typedefs (tree, bool * = NULL,
extern tree strip_typedefs_expr (tree, bool * = NULL); unsigned int = 0);
extern tree strip_typedefs_expr (tree, bool * = NULL,
unsigned int = 0);
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);
......
...@@ -410,7 +410,7 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, ...@@ -410,7 +410,7 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
pop_deferring_access_checks (); pop_deferring_access_checks ();
/* Strip typedefs. We can't just use TFF_CHASE_TYPEDEF because /* Strip typedefs. We can't just use TFF_CHASE_TYPEDEF because
pp_simple_type_specifier doesn't know about it. */ pp_simple_type_specifier doesn't know about it. */
t = strip_typedefs (t); t = strip_typedefs (t, NULL, STF_USER_VISIBLE);
dump_type (pp, t, TFF_PLAIN_IDENTIFIER); dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
} }
} }
...@@ -449,7 +449,11 @@ dump_type (cxx_pretty_printer *pp, tree t, int flags) ...@@ -449,7 +449,11 @@ dump_type (cxx_pretty_printer *pp, tree t, int flags)
|| DECL_SELF_REFERENCE_P (decl) || DECL_SELF_REFERENCE_P (decl)
|| (!flag_pretty_templates || (!flag_pretty_templates
&& DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))) && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)))
t = strip_typedefs (t); {
unsigned int stf_flags = (!(pp->flags & pp_c_flag_gnu_v3)
? STF_USER_VISIBLE : 0);
t = strip_typedefs (t, NULL, stf_flags);
}
else if (alias_template_specialization_p (t)) else if (alias_template_specialization_p (t))
{ {
dump_alias_template_specialization (pp, t, flags); dump_alias_template_specialization (pp, t, flags);
...@@ -3205,7 +3209,7 @@ type_to_string (tree typ, int verbose, bool postprocessed, bool *quote, ...@@ -3205,7 +3209,7 @@ type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
&& !uses_template_parms (typ)) && !uses_template_parms (typ))
{ {
int aka_start, aka_len; char *p; int aka_start, aka_len; char *p;
tree aka = strip_typedefs (typ); tree aka = strip_typedefs (typ, NULL, STF_USER_VISIBLE);
if (quote && *quote) if (quote && *quote)
pp_end_quote (cxx_pp, show_color); pp_end_quote (cxx_pp, show_color);
pp_string (cxx_pp, " {aka"); pp_string (cxx_pp, " {aka");
......
...@@ -1431,7 +1431,10 @@ apply_identity_attributes (tree result, tree attribs, bool *remove_attributes) ...@@ -1431,7 +1431,10 @@ apply_identity_attributes (tree result, tree attribs, bool *remove_attributes)
return cp_build_type_attribute_variant (result, new_attribs); 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 either not a typedef variant
(the default behavior) or not a typedef variant of a user-facing type
(if FLAGS contains STF_USER_FACING).
E.g. consider the following declarations: E.g. consider the following declarations:
typedef const int ConstInt; typedef const int ConstInt;
typedef ConstInt* PtrConstInt; typedef ConstInt* PtrConstInt;
...@@ -1456,7 +1459,7 @@ apply_identity_attributes (tree result, tree attribs, bool *remove_attributes) ...@@ -1456,7 +1459,7 @@ apply_identity_attributes (tree result, tree attribs, bool *remove_attributes)
stripped. */ stripped. */
tree tree
strip_typedefs (tree t, bool *remove_attributes) strip_typedefs (tree t, bool *remove_attributes, unsigned int flags)
{ {
tree result = NULL, type = NULL, t0 = NULL; tree result = NULL, type = NULL, t0 = NULL;
...@@ -1471,7 +1474,7 @@ strip_typedefs (tree t, bool *remove_attributes) ...@@ -1471,7 +1474,7 @@ strip_typedefs (tree t, bool *remove_attributes)
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), remove_attributes); tree elt = strip_typedefs (TREE_VALUE (t), remove_attributes, flags);
if (elt != TREE_VALUE (t)) if (elt != TREE_VALUE (t))
changed = true; changed = true;
vec_safe_push (vec, elt); vec_safe_push (vec, elt);
...@@ -1494,28 +1497,29 @@ strip_typedefs (tree t, bool *remove_attributes) ...@@ -1494,28 +1497,29 @@ strip_typedefs (tree t, bool *remove_attributes)
switch (TREE_CODE (t)) switch (TREE_CODE (t))
{ {
case POINTER_TYPE: case POINTER_TYPE:
type = strip_typedefs (TREE_TYPE (t), remove_attributes); type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
result = build_pointer_type (type); result = build_pointer_type (type);
break; break;
case REFERENCE_TYPE: case REFERENCE_TYPE:
type = strip_typedefs (TREE_TYPE (t), remove_attributes); type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
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), remove_attributes); t0 = strip_typedefs (TYPE_OFFSET_BASETYPE (t), remove_attributes, flags);
type = strip_typedefs (TREE_TYPE (t), remove_attributes); type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
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), remove_attributes); t0 = strip_typedefs (TYPE_PTRMEMFUNC_FN_TYPE (t),
remove_attributes, flags);
result = build_ptrmemfunc_type (t0); result = build_ptrmemfunc_type (t0);
} }
break; break;
case ARRAY_TYPE: case ARRAY_TYPE:
type = strip_typedefs (TREE_TYPE (t), remove_attributes); type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
t0 = strip_typedefs (TYPE_DOMAIN (t), remove_attributes); t0 = strip_typedefs (TYPE_DOMAIN (t), remove_attributes, flags);
result = build_cplus_array_type (type, t0); result = build_cplus_array_type (type, t0);
break; break;
case FUNCTION_TYPE: case FUNCTION_TYPE:
...@@ -1534,7 +1538,7 @@ strip_typedefs (tree t, bool *remove_attributes) ...@@ -1534,7 +1538,7 @@ strip_typedefs (tree t, bool *remove_attributes)
&& (TYPE_ATTRIBUTES (t) || TYPE_USER_ALIGN (t))) && (TYPE_ATTRIBUTES (t) || TYPE_USER_ALIGN (t)))
is_variant = true; is_variant = true;
type = strip_typedefs (TREE_TYPE (t), remove_attributes); type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
tree canon_spec = (flag_noexcept_type tree canon_spec = (flag_noexcept_type
? canonical_eh_spec (TYPE_RAISES_EXCEPTIONS (t)) ? canonical_eh_spec (TYPE_RAISES_EXCEPTIONS (t))
: NULL_TREE); : NULL_TREE);
...@@ -1548,7 +1552,7 @@ strip_typedefs (tree t, bool *remove_attributes) ...@@ -1548,7 +1552,7 @@ strip_typedefs (tree t, bool *remove_attributes)
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); remove_attributes, flags);
gcc_assert (arg_type); gcc_assert (arg_type);
if (arg_type == TREE_VALUE (arg_node) && !changed) if (arg_type == TREE_VALUE (arg_node) && !changed)
continue; continue;
...@@ -1612,9 +1616,10 @@ strip_typedefs (tree t, bool *remove_attributes) ...@@ -1612,9 +1616,10 @@ strip_typedefs (tree t, bool *remove_attributes)
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, remove_attributes); strip_arg = strip_typedefs (arg, remove_attributes, flags);
else else
strip_arg = strip_typedefs_expr (arg, remove_attributes); strip_arg = strip_typedefs_expr (arg, remove_attributes,
flags);
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;
...@@ -1630,7 +1635,7 @@ strip_typedefs (tree t, bool *remove_attributes) ...@@ -1630,7 +1635,7 @@ strip_typedefs (tree t, bool *remove_attributes)
else else
ggc_free (new_args); ggc_free (new_args);
} }
tree ctx = strip_typedefs (TYPE_CONTEXT (t), remove_attributes); tree ctx = strip_typedefs (TYPE_CONTEXT (t), remove_attributes, flags);
if (!changed && ctx == TYPE_CONTEXT (t) && !typedef_variant_p (t)) if (!changed && ctx == TYPE_CONTEXT (t) && !typedef_variant_p (t))
return t; return t;
tree name = fullname; tree name = fullname;
...@@ -1643,7 +1648,7 @@ strip_typedefs (tree t, bool *remove_attributes) ...@@ -1643,7 +1648,7 @@ strip_typedefs (tree t, bool *remove_attributes)
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); remove_attributes, flags);
if (result == DECLTYPE_TYPE_EXPR (t)) if (result == DECLTYPE_TYPE_EXPR (t))
result = NULL_TREE; result = NULL_TREE;
else else
...@@ -1653,7 +1658,8 @@ strip_typedefs (tree t, bool *remove_attributes) ...@@ -1653,7 +1658,8 @@ strip_typedefs (tree t, bool *remove_attributes)
tf_none)); tf_none));
break; break;
case UNDERLYING_TYPE: case UNDERLYING_TYPE:
type = strip_typedefs (UNDERLYING_TYPE_TYPE (t), remove_attributes); type = strip_typedefs (UNDERLYING_TYPE_TYPE (t),
remove_attributes, flags);
result = finish_underlying_type (type); result = finish_underlying_type (type);
break; break;
default: default:
...@@ -1664,15 +1670,18 @@ strip_typedefs (tree t, bool *remove_attributes) ...@@ -1664,15 +1670,18 @@ strip_typedefs (tree t, bool *remove_attributes)
{ {
if (typedef_variant_p (t)) if (typedef_variant_p (t))
{ {
/* Explicitly get the underlying type, as TYPE_MAIN_VARIANT doesn't if ((flags & STF_USER_VISIBLE)
strip typedefs with attributes. */ && !user_facing_original_type_p (t))
result = TYPE_MAIN_VARIANT (DECL_ORIGINAL_TYPE (TYPE_NAME (t))); return t;
result = strip_typedefs (result); result = strip_typedefs (DECL_ORIGINAL_TYPE (TYPE_NAME (t)),
remove_attributes, flags);
} }
else else
result = TYPE_MAIN_VARIANT (t); result = TYPE_MAIN_VARIANT (t);
} }
gcc_assert (!typedef_variant_p (result)); gcc_assert (!typedef_variant_p (result)
|| ((flags & STF_USER_VISIBLE)
&& !user_facing_original_type_p (result)));
if (COMPLETE_TYPE_P (result) && !COMPLETE_TYPE_P (t)) if (COMPLETE_TYPE_P (result) && !COMPLETE_TYPE_P (t))
/* If RESULT is complete and T isn't, it's likely the case that T /* If RESULT is complete and T isn't, it's likely the case that T
...@@ -1721,7 +1730,7 @@ strip_typedefs (tree t, bool *remove_attributes) ...@@ -1721,7 +1730,7 @@ strip_typedefs (tree t, bool *remove_attributes)
sizeof(TT) is replaced by sizeof(T). */ sizeof(TT) is replaced by sizeof(T). */
tree tree
strip_typedefs_expr (tree t, bool *remove_attributes) strip_typedefs_expr (tree t, bool *remove_attributes, unsigned int flags)
{ {
unsigned i,n; unsigned i,n;
tree r, type, *ops; tree r, type, *ops;
...@@ -1738,7 +1747,7 @@ strip_typedefs_expr (tree t, bool *remove_attributes) ...@@ -1738,7 +1747,7 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
/* 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, remove_attributes); return strip_typedefs (t, remove_attributes, flags);
code = TREE_CODE (t); code = TREE_CODE (t);
switch (code) switch (code)
...@@ -1752,8 +1761,10 @@ strip_typedefs_expr (tree t, bool *remove_attributes) ...@@ -1752,8 +1761,10 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
case TRAIT_EXPR: case TRAIT_EXPR:
{ {
tree type1 = strip_typedefs (TRAIT_EXPR_TYPE1 (t), remove_attributes); tree type1 = strip_typedefs (TRAIT_EXPR_TYPE1 (t),
tree type2 = strip_typedefs (TRAIT_EXPR_TYPE2 (t), remove_attributes); remove_attributes, flags);
tree type2 = strip_typedefs (TRAIT_EXPR_TYPE2 (t),
remove_attributes, flags);
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;
...@@ -1770,7 +1781,8 @@ strip_typedefs_expr (tree t, bool *remove_attributes) ...@@ -1770,7 +1781,8 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
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 (it), remove_attributes); tree val = strip_typedefs_expr (TREE_VALUE (it),
remove_attributes, flags);
vec_safe_push (vec, val); vec_safe_push (vec, val);
if (val != TREE_VALUE (it)) if (val != TREE_VALUE (it))
changed = true; changed = true;
...@@ -1796,7 +1808,7 @@ strip_typedefs_expr (tree t, bool *remove_attributes) ...@@ -1796,7 +1808,7 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
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); remove_attributes, flags);
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;
...@@ -1820,18 +1832,19 @@ strip_typedefs_expr (tree t, bool *remove_attributes) ...@@ -1820,18 +1832,19 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
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), remove_attributes); type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
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, remove_attributes); tree op = strip_typedefs_expr (e->value, remove_attributes, flags);
if (op != e->value) if (op != e->value)
{ {
changed = true; changed = true;
e->value = op; e->value = op;
} }
gcc_checking_assert gcc_checking_assert
(e->index == strip_typedefs_expr (e->index, remove_attributes)); (e->index == strip_typedefs_expr (e->index, remove_attributes,
flags));
} }
if (!changed && type == TREE_TYPE (t)) if (!changed && type == TREE_TYPE (t))
...@@ -1875,12 +1888,13 @@ strip_typedefs_expr (tree t, bool *remove_attributes) ...@@ -1875,12 +1888,13 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
case REINTERPRET_CAST_EXPR: case REINTERPRET_CAST_EXPR:
case CAST_EXPR: case CAST_EXPR:
case NEW_EXPR: case NEW_EXPR:
type = strip_typedefs (type, remove_attributes); type = strip_typedefs (type, remove_attributes, flags);
/* 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), remove_attributes); ops[i] = strip_typedefs_expr (TREE_OPERAND (t, i),
remove_attributes, flags);
break; break;
} }
......
2019-10-22 Richard Sandiford <richard.sandiford@arm.com>
* g++.dg/diagnostic/aka5.h: New test.
* g++.dg/diagnostic/aka5a.C: Likewise.
* g++.dg/diagnostic/aka5b.C: Likewise.
* g++.target/aarch64/diag_aka_1.C: Likewise.
2019-10-22 Iain Sandoe <iain@sandoe.co.uk> 2019-10-22 Iain Sandoe <iain@sandoe.co.uk>
* gcc.dg/Wnonnull.c: Provide prototypes for strlen and memcpy. * gcc.dg/Wnonnull.c: Provide prototypes for strlen and memcpy.
......
#ifdef IS_SYSTEM_HEADER
#pragma GCC system_header
#endif
typedef enum __internal_enum { A, B } user_enum;
typedef user_enum *user_enum_ptr;
typedef struct __internal_struct { int i; } user_struct;
typedef user_struct user_struct_copy;
typedef user_struct *user_struct_ptr;
typedef union __internal_union { int i; } user_union;
typedef user_union user_union_copy;
typedef user_union *user_union_ptr;
typedef unsigned int user_vector __attribute__((__vector_size__(16)));
typedef user_vector user_vector_copy;
typedef user_vector *user_vector_ptr;
typedef int user_int;
typedef user_int user_int_copy;
typedef user_int *user_int_ptr;
#define IS_SYSTEM_HEADER
#include "aka5.h"
typedef user_enum user_enum_copy;
struct s { int i; };
user_enum ue1;
user_enum_copy ue2;
user_enum_ptr ue_ptr1;
user_enum *ue_ptr2;
const user_enum *const_ue_ptr1;
const user_enum_copy *const_ue_ptr2;
volatile user_enum *volatile_ue_ptr1;
volatile user_enum_copy *volatile_ue_ptr2;
user_enum (*ue_array_ptr1)[10];
user_enum_copy (*ue_array_ptr2)[10];
user_enum (*ue_fn_ptr1) (void);
void (*ue_fn_ptr2) (user_enum);
void (*ue_fn_ptr3) (user_enum, ...);
user_enum_copy (*ue_fn_ptr4) (void);
void (*ue_fn_ptr5) (user_enum_copy);
void (*ue_fn_ptr6) (user_enum_copy, ...);
user_enum (*__attribute__((__transaction_unsafe__)) unsafe_ue_fn_ptr1) (void);
user_enum_copy (*__attribute__((__transaction_unsafe__)) unsafe_ue_fn_ptr2) (void);
user_struct us1;
user_struct_copy us2;
user_struct_ptr us_ptr1;
user_struct *us_ptr2;
const user_struct *const_us_ptr1;
const user_struct_copy *const_us_ptr2;
user_union uu1;
user_union_copy uu2;
user_union_ptr uu_ptr1;
user_union *uu_ptr2;
const user_union *const_uu_ptr1;
const user_union_copy *const_uu_ptr2;
user_vector uv1;
user_vector_copy uv2;
user_vector_ptr uv_ptr1;
user_vector *uv_ptr2;
const user_vector *const_uv_ptr1;
const user_vector_copy *const_uv_ptr2;
user_int ui1;
user_int_copy ui2;
user_int_ptr ui_ptr1;
user_int *ui_ptr2;
const user_int *const_ui_ptr1;
const user_int_copy *const_ui_ptr2;
volatile user_int *volatile_ui_ptr1;
volatile user_int_copy *volatile_ui_ptr2;
user_int (*ui_array_ptr1)[10];
user_int_copy (*ui_array_ptr2)[10];
user_int (*ui_fn_ptr1) (void);
void (*ui_fn_ptr2) (user_int);
void (*ui_fn_ptr3) (user_int, ...);
user_int_copy (*ui_fn_ptr4) (void);
void (*ui_fn_ptr5) (user_int_copy);
void (*ui_fn_ptr6) (user_int_copy, ...);
user_int (*__attribute__((__transaction_unsafe__)) unsafe_ui_fn_ptr1) (void);
user_int_copy (*__attribute__((__transaction_unsafe__)) unsafe_ui_fn_ptr2) (void);
void f (s s1)
{
ue1 = s1; // { dg-error {cannot convert 's' to 'user_enum' in assignment} }
ue2 = s1; // { dg-error {cannot convert 's' to 'user_enum_copy' {aka 'user_enum'} in assignment} }
ue_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum_ptr' {aka 'user_enum\*'} in assignment} }
ue_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum\*' in assignment} }
const_ue_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'const user_enum\*' in assignment} }
const_ue_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'const user_enum_copy\*' {aka 'const user_enum\*'} in assignment} }
volatile_ue_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'volatile user_enum\*' in assignment} }
volatile_ue_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'volatile user_enum_copy\*' {aka 'volatile user_enum\*'} in assignment} }
ue_array_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum \(\*\)\[10\]' in assignment} }
ue_array_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum_copy \(\*\)\[10\]' {aka 'user_enum \(\*\)\[10\]'} in assignment} }
ue_fn_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum \(\*\)\(\)' in assignment} }
ue_fn_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_enum\)' in assignment} }
ue_fn_ptr3 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_enum, \.\.\.\)' in assignment} }
ue_fn_ptr4 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum_copy \(\*\)\(\)' {aka 'user_enum \(\*\)\(\)'} in assignment} }
ue_fn_ptr5 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_enum_copy\)' {aka 'void \(\*\)\(user_enum\)'} in assignment} }
ue_fn_ptr6 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_enum_copy, \.\.\.\)' {aka 'void \(\*\)\(user_enum, \.\.\.\)'} in assignment} }
unsafe_ue_fn_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)' in assignment} }
unsafe_ue_fn_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum_copy \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)' {aka 'user_enum \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)'} in assignment} }
us1 = s1; // { dg-error {no match for 'operator=' in 'us1 = s1' \(operand types are 'user_struct' and 's'\)} }
us2 = s1; // { dg-error {no match for 'operator=' in 'us2 = s1' \(operand types are 'user_struct_copy' {aka 'user_struct'} and 's'\)} }
us_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_struct_ptr' {aka 'user_struct\*'} in assignment} }
us_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_struct\*' in assignment} }
const_us_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'const user_struct\*' in assignment} }
const_us_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'const user_struct_copy\*' {aka 'const user_struct\*'} in assignment} }
uu1 = s1; // { dg-error {no match for 'operator=' in 'uu1 = s1' \(operand types are 'user_union' and 's'\)} }
uu2 = s1; // { dg-error {no match for 'operator=' in 'uu2 = s1' \(operand types are 'user_union_copy' {aka 'user_union'} and 's'\)} }
uu_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_union_ptr' {aka 'user_union\*'} in assignment} }
uu_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_union\*' in assignment} }
const_uu_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'const user_union\*' in assignment} }
const_uu_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'const user_union_copy\*' {aka 'const user_union\*'} in assignment} }
uv1 = s1; // { dg-error {cannot convert 's' to 'user_vector' in assignment} }
uv2 = s1; // { dg-error {cannot convert 's' to 'user_vector_copy' {aka 'user_vector'} in assignment} }
uv_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_vector_ptr' {aka 'user_vector\*'} in assignment} }
uv_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_vector\*' in assignment} }
const_uv_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'const user_vector\*' in assignment} }
const_uv_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'const user_vector_copy\*' {aka 'const user_vector\*'} in assignment} }
ui1 = s1; // { dg-error {cannot convert 's' to 'user_int' {aka 'int'} in assignment} }
ui2 = s1; // { dg-error {cannot convert 's' to 'user_int_copy' {aka 'int'} in assignment} }
ui_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_int_ptr' {aka 'int\*'} in assignment} }
ui_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_int\*' {aka 'int\*'} in assignment} }
const_ui_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'const user_int\*' {aka 'const int\*'} in assignment} }
const_ui_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'const user_int_copy\*' {aka 'const int\*'} in assignment} }
volatile_ui_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'volatile user_int\*' {aka 'volatile int\*'} in assignment} }
volatile_ui_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'volatile user_int_copy\*' {aka 'volatile int\*'} in assignment} }
ui_array_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_int \(\*\)\[10\]' {aka 'int \(\*\)\[10\]'} in assignment} }
ui_array_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_int_copy \(\*\)\[10\]' {aka 'int \(\*\)\[10\]'} in assignment} }
ui_fn_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_int \(\*\)\(\)' {aka 'int \(\*\)\(\)'} in assignment} }
ui_fn_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_int\)' {aka 'void \(\*\)\(int\)'} in assignment} }
ui_fn_ptr3 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_int, \.\.\.\)' {aka 'void \(\*\)\(int, \.\.\.\)'} in assignment} }
ui_fn_ptr4 = &s1; // { dg-error {cannot convert 's\*' to 'user_int_copy \(\*\)\(\)' {aka 'int \(\*\)\(\)'} in assignment} }
ui_fn_ptr5 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_int_copy\)' {aka 'void \(\*\)\(int\)'} in assignment} }
ui_fn_ptr6 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_int_copy, \.\.\.\)' {aka 'void \(\*\)\(int, \.\.\.\)'} in assignment} }
unsafe_ui_fn_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_int \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)' {aka 'int \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)'} in assignment} }
unsafe_ui_fn_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_int_copy \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)' {aka 'int \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)'} in assignment} }
}
#include "aka5.h"
typedef user_enum user_enum_copy;
struct s { int i; };
user_enum ue1;
user_enum_copy ue2;
user_enum_ptr ue_ptr1;
user_enum *ue_ptr2;
const user_enum *const_ue_ptr1;
const user_enum_copy *const_ue_ptr2;
volatile user_enum *volatile_ue_ptr1;
volatile user_enum_copy *volatile_ue_ptr2;
user_enum (*ue_array_ptr1)[10];
user_enum_copy (*ue_array_ptr2)[10];
user_enum (*ue_fn_ptr1) (void);
void (*ue_fn_ptr2) (user_enum);
void (*ue_fn_ptr3) (user_enum, ...);
user_enum_copy (*ue_fn_ptr4) (void);
void (*ue_fn_ptr5) (user_enum_copy);
void (*ue_fn_ptr6) (user_enum_copy, ...);
user_enum (*__attribute__((__transaction_unsafe__)) unsafe_ue_fn_ptr1) (void);
user_enum_copy (*__attribute__((__transaction_unsafe__)) unsafe_ue_fn_ptr2) (void);
user_struct us1;
user_struct_copy us2;
user_struct_ptr us_ptr1;
user_struct *us_ptr2;
const user_struct *const_us_ptr1;
const user_struct_copy *const_us_ptr2;
user_union uu1;
user_union_copy uu2;
user_union_ptr uu_ptr1;
user_union *uu_ptr2;
const user_union *const_uu_ptr1;
const user_union_copy *const_uu_ptr2;
user_vector uv1;
user_vector_copy uv2;
user_vector_ptr uv_ptr1;
user_vector *uv_ptr2;
const user_vector *const_uv_ptr1;
const user_vector_copy *const_uv_ptr2;
user_int ui1;
user_int_copy ui2;
user_int_ptr ui_ptr1;
user_int *ui_ptr2;
const user_int *const_ui_ptr1;
const user_int_copy *const_ui_ptr2;
volatile user_int *volatile_ui_ptr1;
volatile user_int_copy *volatile_ui_ptr2;
user_int (*ui_array_ptr1)[10];
user_int_copy (*ui_array_ptr2)[10];
user_int (*ui_fn_ptr1) (void);
void (*ui_fn_ptr2) (user_int);
void (*ui_fn_ptr3) (user_int, ...);
user_int_copy (*ui_fn_ptr4) (void);
void (*ui_fn_ptr5) (user_int_copy);
void (*ui_fn_ptr6) (user_int_copy, ...);
user_int (*__attribute__((__transaction_unsafe__)) unsafe_ui_fn_ptr1) (void);
user_int_copy (*__attribute__((__transaction_unsafe__)) unsafe_ui_fn_ptr2) (void);
void f (s s1)
{
ue1 = s1; // { dg-error {cannot convert 's' to 'user_enum' {aka '__internal_enum'} in assignment} }
ue2 = s1; // { dg-error {cannot convert 's' to 'user_enum_copy' {aka '__internal_enum'} in assignment} }
ue_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum_ptr' {aka '__internal_enum\*'} in assignment} }
ue_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum\*' {aka '__internal_enum\*'} in assignment} }
const_ue_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'const user_enum\*' {aka 'const __internal_enum\*'} in assignment} }
const_ue_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'const user_enum_copy\*' {aka 'const __internal_enum\*'} in assignment} }
volatile_ue_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'volatile user_enum\*' {aka 'volatile __internal_enum\*'} in assignment} }
volatile_ue_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'volatile user_enum_copy\*' {aka 'volatile __internal_enum\*'} in assignment} }
ue_array_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum \(\*\)\[10\]' {aka '__internal_enum \(\*\)\[10\]'} in assignment} }
ue_array_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum_copy \(\*\)\[10\]' {aka '__internal_enum \(\*\)\[10\]'} in assignment} }
ue_fn_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum \(\*\)\(\)' {aka '__internal_enum \(\*\)\(\)'} in assignment} }
ue_fn_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_enum\)' {aka 'void \(\*\)\(__internal_enum\)'} in assignment} }
ue_fn_ptr3 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_enum, \.\.\.\)' {aka 'void \(\*\)\(__internal_enum, \.\.\.\)'} in assignment} }
ue_fn_ptr4 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum_copy \(\*\)\(\)' {aka '__internal_enum \(\*\)\(\)'} in assignment} }
ue_fn_ptr5 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_enum_copy\)' {aka 'void \(\*\)\(__internal_enum\)'} in assignment} }
ue_fn_ptr6 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_enum_copy, \.\.\.\)' {aka 'void \(\*\)\(__internal_enum, \.\.\.\)'} in assignment} }
unsafe_ue_fn_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)' {aka '__internal_enum \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)'} in assignment} }
unsafe_ue_fn_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_enum_copy \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)' {aka '__internal_enum \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)'} in assignment} }
us1 = s1; // { dg-error {no match for 'operator=' in 'us1 = s1' \(operand types are 'user_struct' {aka '__internal_struct'} and 's'\)} }
us2 = s1; // { dg-error {no match for 'operator=' in 'us2 = s1' \(operand types are 'user_struct_copy' {aka '__internal_struct'} and 's'\)} }
us_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_struct_ptr' {aka '__internal_struct\*'} in assignment} }
us_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_struct\*' {aka '__internal_struct\*'} in assignment} }
const_us_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'const user_struct\*' {aka 'const __internal_struct\*'} in assignment} }
const_us_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'const user_struct_copy\*' {aka 'const __internal_struct\*'} in assignment} }
uu1 = s1; // { dg-error {no match for 'operator=' in 'uu1 = s1' \(operand types are 'user_union' {aka '__internal_union'} and 's'\)} }
uu2 = s1; // { dg-error {no match for 'operator=' in 'uu2 = s1' \(operand types are 'user_union_copy' {aka '__internal_union'} and 's'\)} }
uu_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_union_ptr' {aka '__internal_union\*'} in assignment} }
uu_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_union\*' {aka '__internal_union\*'} in assignment} }
const_uu_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'const user_union\*' {aka 'const __internal_union\*'} in assignment} }
const_uu_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'const user_union_copy\*' {aka 'const __internal_union\*'} in assignment} }
uv1 = s1; // { dg-error {cannot convert 's' to 'user_vector' {aka '__vector\([48]\) unsigned int'} in assignment} }
uv2 = s1; // { dg-error {cannot convert 's' to 'user_vector_copy' {aka '__vector\([48]\) unsigned int'} in assignment} }
uv_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_vector_ptr' {aka '__vector\([48]\) unsigned int\*'} in assignment} }
uv_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_vector\*' {aka '__vector\([48]\) unsigned int\*'} in assignment} }
const_uv_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'const user_vector\*' {aka 'const __vector\([48]\) unsigned int\*'} in assignment} }
const_uv_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'const user_vector_copy\*' {aka 'const __vector\([48]\) unsigned int\*'} in assignment} }
ui1 = s1; // { dg-error {cannot convert 's' to 'user_int' {aka 'int'} in assignment} }
ui2 = s1; // { dg-error {cannot convert 's' to 'user_int_copy' {aka 'int'} in assignment} }
ui_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_int_ptr' {aka 'int\*'} in assignment} }
ui_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_int\*' {aka 'int\*'} in assignment} }
const_ui_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'const user_int\*' {aka 'const int\*'} in assignment} }
const_ui_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'const user_int_copy\*' {aka 'const int\*'} in assignment} }
volatile_ui_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'volatile user_int\*' {aka 'volatile int\*'} in assignment} }
volatile_ui_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'volatile user_int_copy\*' {aka 'volatile int\*'} in assignment} }
ui_array_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_int \(\*\)\[10\]' {aka 'int \(\*\)\[10\]'} in assignment} }
ui_array_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_int_copy \(\*\)\[10\]' {aka 'int \(\*\)\[10\]'} in assignment} }
ui_fn_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_int \(\*\)\(\)' {aka 'int \(\*\)\(\)'} in assignment} }
ui_fn_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_int\)' {aka 'void \(\*\)\(int\)'} in assignment} }
ui_fn_ptr3 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_int, \.\.\.\)' {aka 'void \(\*\)\(int, \.\.\.\)'} in assignment} }
ui_fn_ptr4 = &s1; // { dg-error {cannot convert 's\*' to 'user_int_copy \(\*\)\(\)' {aka 'int \(\*\)\(\)'} in assignment} }
ui_fn_ptr5 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_int_copy\)' {aka 'void \(\*\)\(int\)'} in assignment} }
ui_fn_ptr6 = &s1; // { dg-error {cannot convert 's\*' to 'void \(\*\)\(user_int_copy, \.\.\.\)' {aka 'void \(\*\)\(int, \.\.\.\)'} in assignment} }
unsafe_ui_fn_ptr1 = &s1; // { dg-error {cannot convert 's\*' to 'user_int \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)' {aka 'int \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)'} in assignment} }
unsafe_ui_fn_ptr2 = &s1; // { dg-error {cannot convert 's\*' to 'user_int_copy \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)' {aka 'int \(__attribute__\(\(transaction_unsafe\)\) \*\)\(\)'} in assignment} }
}
#include <arm_neon.h>
typedef int16x4_t myvec;
void f (float x)
{
__Int8x8_t y1 = x; // { dg-error {cannot convert 'float' to '__Int8x8_t' in initialization} }
__Int8x8_t *ptr1 = &x; // { dg-error {cannot convert 'float\*' to '__Int8x8_t\*' in initialization} }
int8x8_t y2 = x; // { dg-error {cannot convert 'float' to 'int8x8_t' in initialization} }
int8x8_t *ptr2 = &x; // { dg-error {cannot convert 'float\*' to 'int8x8_t\*' in initialization} }
myvec y3 = x; // { dg-error {cannot convert 'float' to 'myvec' {aka 'int16x4_t'} in initialization} }
myvec *ptr3 = &x; // { dg-error {cannot convert 'float\*' to 'myvec\*' {aka 'int16x4_t\*'} in initialization} }
}
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