mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-21 19:35:36 -05:00
Look through DECL_ANON_UNION_VAR_P during reflection-name parsing.
This commit is contained in:
committed by
Marek Polacek
parent
5bc0ec8129
commit
95f5ec013f
@@ -4183,7 +4183,10 @@ write_reflection (tree refl)
|
|||||||
write_type (arg);
|
write_type (arg);
|
||||||
else if (strcmp (prefix, "dm") == 0)
|
else if (strcmp (prefix, "dm") == 0)
|
||||||
{
|
{
|
||||||
write_prefix (decl_mangling_context (arg));
|
tree ctx = decl_mangling_context (arg);
|
||||||
|
while (ctx && ANON_UNION_TYPE_P (ctx))
|
||||||
|
ctx = decl_mangling_context (TYPE_NAME (ctx));
|
||||||
|
write_prefix (ctx);
|
||||||
write_unqualified_name (arg);
|
write_unqualified_name (arg);
|
||||||
}
|
}
|
||||||
else if (strcmp (prefix, "un") == 0)
|
else if (strcmp (prefix, "un") == 0)
|
||||||
|
|||||||
@@ -10052,6 +10052,15 @@ cp_parser_reflection_name (cp_parser *parser)
|
|||||||
if (name != error_mark_node && decl == error_mark_node)
|
if (name != error_mark_node && decl == error_mark_node)
|
||||||
cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, loc);
|
cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, loc);
|
||||||
|
|
||||||
|
/* If lookup finds a class member of an anonymous union, R represents
|
||||||
|
that class member. */
|
||||||
|
if (VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl))
|
||||||
|
{
|
||||||
|
tree v = DECL_VALUE_EXPR (decl);
|
||||||
|
if (v != error_mark_node && TREE_CODE (v) == COMPONENT_REF)
|
||||||
|
decl = TREE_OPERAND (v, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return decl;
|
return decl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1077,8 +1077,6 @@ eval_is_variable (const_tree r, reflect_kind kind)
|
|||||||
if ((TREE_CODE (r) == PARM_DECL && kind != REFLECT_PARM)
|
if ((TREE_CODE (r) == PARM_DECL && kind != REFLECT_PARM)
|
||||||
|| (VAR_P (r)
|
|| (VAR_P (r)
|
||||||
&& kind == REFLECT_UNDEF
|
&& kind == REFLECT_UNDEF
|
||||||
/* The definition of a variable excludes non-static data members. */
|
|
||||||
&& !DECL_ANON_UNION_VAR_P (r)
|
|
||||||
/* A structured binding is not a variable. */
|
/* A structured binding is not a variable. */
|
||||||
&& !(DECL_DECOMPOSITION_P (r) && !DECL_DECOMP_IS_BASE (r)))
|
&& !(DECL_DECOMPOSITION_P (r) && !DECL_DECOMP_IS_BASE (r)))
|
||||||
|| (VAR_P (r)
|
|| (VAR_P (r)
|
||||||
@@ -1299,8 +1297,6 @@ eval_is_class_member (tree r)
|
|||||||
}
|
}
|
||||||
else if (TYPE_P (r) && typedef_variant_p (r))
|
else if (TYPE_P (r) && typedef_variant_p (r))
|
||||||
r = TYPE_NAME (r);
|
r = TYPE_NAME (r);
|
||||||
else if (VAR_P (r) && DECL_ANON_UNION_VAR_P (r))
|
|
||||||
return boolean_true_node;
|
|
||||||
if (DECL_P (r) && DECL_CLASS_SCOPE_P (r))
|
if (DECL_P (r) && DECL_CLASS_SCOPE_P (r))
|
||||||
return boolean_true_node;
|
return boolean_true_node;
|
||||||
else if (TYPE_P (r) && TYPE_CLASS_SCOPE_P (r))
|
else if (TYPE_P (r) && TYPE_CLASS_SCOPE_P (r))
|
||||||
@@ -1508,8 +1504,6 @@ eval_is_namespace_member (tree r)
|
|||||||
}
|
}
|
||||||
else if (TYPE_P (r) && typedef_variant_p (r))
|
else if (TYPE_P (r) && typedef_variant_p (r))
|
||||||
r = TYPE_NAME (r);
|
r = TYPE_NAME (r);
|
||||||
else if (VAR_P (r) && DECL_ANON_UNION_VAR_P (r))
|
|
||||||
return boolean_false_node;
|
|
||||||
if (r == global_namespace || r == unknown_type_node)
|
if (r == global_namespace || r == unknown_type_node)
|
||||||
return boolean_false_node;
|
return boolean_false_node;
|
||||||
if (DECL_P (r) && DECL_NAMESPACE_SCOPE_P (r))
|
if (DECL_P (r) && DECL_NAMESPACE_SCOPE_P (r))
|
||||||
@@ -1527,8 +1521,6 @@ eval_is_namespace_member (tree r)
|
|||||||
static tree
|
static tree
|
||||||
eval_is_nonstatic_data_member (const_tree r)
|
eval_is_nonstatic_data_member (const_tree r)
|
||||||
{
|
{
|
||||||
if (VAR_P (r) && DECL_ANON_UNION_VAR_P (r))
|
|
||||||
return boolean_true_node;
|
|
||||||
if (TREE_CODE (r) == FIELD_DECL && !DECL_UNNAMED_BIT_FIELD (r))
|
if (TREE_CODE (r) == FIELD_DECL && !DECL_UNNAMED_BIT_FIELD (r))
|
||||||
return boolean_true_node;
|
return boolean_true_node;
|
||||||
else
|
else
|
||||||
@@ -1635,12 +1627,6 @@ eval_has_automatic_storage_duration (const_tree r, reflect_kind kind)
|
|||||||
static tree
|
static tree
|
||||||
eval_is_mutable_member (tree r)
|
eval_is_mutable_member (tree r)
|
||||||
{
|
{
|
||||||
if (VAR_P (r) && DECL_ANON_UNION_VAR_P (r))
|
|
||||||
{
|
|
||||||
tree v = DECL_VALUE_EXPR (r);
|
|
||||||
if (v != error_mark_node && TREE_CODE (v) == COMPONENT_REF)
|
|
||||||
r = TREE_OPERAND (v, 1);
|
|
||||||
}
|
|
||||||
if (TREE_CODE (r) == FIELD_DECL
|
if (TREE_CODE (r) == FIELD_DECL
|
||||||
&& !DECL_UNNAMED_BIT_FIELD (r)
|
&& !DECL_UNNAMED_BIT_FIELD (r)
|
||||||
&& DECL_MUTABLE_P (r))
|
&& DECL_MUTABLE_P (r))
|
||||||
@@ -2952,14 +2938,6 @@ eval_parent_of (location_t loc, const constexpr_ctx *ctx, tree r,
|
|||||||
else
|
else
|
||||||
c = CP_TYPE_CONTEXT (r);
|
c = CP_TYPE_CONTEXT (r);
|
||||||
}
|
}
|
||||||
else if (VAR_P (r) && DECL_ANON_UNION_VAR_P (r))
|
|
||||||
{
|
|
||||||
tree v = DECL_VALUE_EXPR (r);
|
|
||||||
if (v != error_mark_node && TREE_CODE (v) == COMPONENT_REF)
|
|
||||||
c = CP_DECL_CONTEXT (TREE_OPERAND (v, 1));
|
|
||||||
else
|
|
||||||
c = CP_DECL_CONTEXT (r);
|
|
||||||
}
|
|
||||||
else if (kind == REFLECT_BASE)
|
else if (kind == REFLECT_BASE)
|
||||||
c = direct_base_parent (r);
|
c = direct_base_parent (r);
|
||||||
else
|
else
|
||||||
@@ -6367,14 +6345,6 @@ eval_is_accessible (location_t loc, const constexpr_ctx *ctx, tree r,
|
|||||||
else
|
else
|
||||||
c = CP_TYPE_CONTEXT (c);
|
c = CP_TYPE_CONTEXT (c);
|
||||||
}
|
}
|
||||||
else if (VAR_P (r) && DECL_ANON_UNION_VAR_P (r))
|
|
||||||
{
|
|
||||||
tree v = DECL_VALUE_EXPR (r);
|
|
||||||
if (v != error_mark_node && TREE_CODE (v) == COMPONENT_REF)
|
|
||||||
c = CP_DECL_CONTEXT (TREE_OPERAND (v, 1));
|
|
||||||
else
|
|
||||||
c = CP_DECL_CONTEXT (r);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
c = CP_DECL_CONTEXT (r);
|
c = CP_DECL_CONTEXT (r);
|
||||||
}
|
}
|
||||||
@@ -7225,8 +7195,15 @@ can_extract_member_or_function_p (tree T, tree r, reflect_kind kind)
|
|||||||
if (eval_is_bit_field (r, kind) == boolean_true_node)
|
if (eval_is_bit_field (r, kind) == boolean_true_node)
|
||||||
return false;
|
return false;
|
||||||
/* static union { int m; }; extract<int>(^^m); is invalid. */
|
/* static union { int m; }; extract<int>(^^m); is invalid. */
|
||||||
if (VAR_P (r) && DECL_ANON_UNION_VAR_P (r))
|
if (TREE_CODE (r) == FIELD_DECL
|
||||||
return false;
|
&& ANON_UNION_TYPE_P (DECL_CONTEXT (r)))
|
||||||
|
{
|
||||||
|
tree c = CP_TYPE_CONTEXT (DECL_CONTEXT (r));
|
||||||
|
while (ANON_UNION_TYPE_P (c))
|
||||||
|
c = CP_TYPE_CONTEXT (c);
|
||||||
|
if (!TYPE_P (c))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/* Create the X C::* type. */
|
/* Create the X C::* type. */
|
||||||
tree type = build_offset_type (CP_DECL_CONTEXT (r), TREE_TYPE (r));
|
tree type = build_offset_type (CP_DECL_CONTEXT (r), TREE_TYPE (r));
|
||||||
if (similar_type_p (type, T) && is_convertible (type, T))
|
if (similar_type_p (type, T) && is_convertible (type, T))
|
||||||
@@ -8396,8 +8373,8 @@ check_splice_expr (location_t loc, location_t start_loc, tree t,
|
|||||||
foo.[: ^^S::bar :]. */
|
foo.[: ^^S::bar :]. */
|
||||||
if (!address_p
|
if (!address_p
|
||||||
&& !member_access_p
|
&& !member_access_p
|
||||||
&& ((DECL_P (t) && DECL_NONSTATIC_MEMBER_P (t))
|
&& DECL_P (t)
|
||||||
|| (VAR_P (t) && DECL_ANON_UNION_VAR_P (t))))
|
&& DECL_NONSTATIC_MEMBER_P (t))
|
||||||
{
|
{
|
||||||
if (complain_p)
|
if (complain_p)
|
||||||
error_at (loc, "cannot implicitly reference a class member %qD "
|
error_at (loc, "cannot implicitly reference a class member %qD "
|
||||||
@@ -8408,12 +8385,20 @@ check_splice_expr (location_t loc, location_t start_loc, tree t,
|
|||||||
splice-expression designating a non-static member m, other than an
|
splice-expression designating a non-static member m, other than an
|
||||||
explicit object member function, m shall be a direct member of some
|
explicit object member function, m shall be a direct member of some
|
||||||
class C that is not an anonymous union." */
|
class C that is not an anonymous union." */
|
||||||
if (address_p && VAR_P (t) && DECL_ANON_UNION_VAR_P (t))
|
if (address_p
|
||||||
|
&& TREE_CODE (t) == FIELD_DECL
|
||||||
|
&& ANON_UNION_TYPE_P (DECL_CONTEXT (t)))
|
||||||
{
|
{
|
||||||
if (complain_p)
|
tree c = CP_TYPE_CONTEXT (DECL_CONTEXT (t));
|
||||||
error_at (loc, "unary %<&%> applied to an anonymous union member %qD "
|
while (ANON_UNION_TYPE_P (c))
|
||||||
"that is not a direct member of a named class", t);
|
c = CP_TYPE_CONTEXT (c);
|
||||||
return false;
|
if (!TYPE_P (c))
|
||||||
|
{
|
||||||
|
if (complain_p)
|
||||||
|
error_at (loc, "unary %<&%> applied to an anonymous union member "
|
||||||
|
"%qD that is not a direct member of a named class", t);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [expr.prim.splice]/2: "The expression is ill-formed if S [the construct
|
/* [expr.prim.splice]/2: "The expression is ill-formed if S [the construct
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
static union { int m; };
|
static union { int m; };
|
||||||
constexpr auto r = ^^m;
|
constexpr auto r = ^^m;
|
||||||
auto p = [:r:]; // { dg-error "cannot implicitly reference a class member .m. through a splice" }
|
auto p = [:r:]; // { dg-error "cannot implicitly reference a class member .<unnamed union>::m. through a splice" }
|
||||||
|
|
||||||
namespace N {
|
namespace N {
|
||||||
static union { int mn; };
|
static union { int mn; };
|
||||||
constexpr auto rn = ^^mn;
|
constexpr auto rn = ^^mn;
|
||||||
auto pn = [:rn:]; // { dg-error "cannot implicitly reference a class member .mn. through a splice" }
|
auto pn = [:rn:]; // { dg-error "cannot implicitly reference a class member .N::<unnamed union>::mn. through a splice" }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct S {
|
struct S {
|
||||||
@@ -25,14 +25,14 @@ f ()
|
|||||||
static union {
|
static union {
|
||||||
int x;
|
int x;
|
||||||
};
|
};
|
||||||
auto rx = [: ^^x :]; // { dg-error "cannot implicitly reference a class member .x. through a splice" }
|
auto rx = [: ^^x :]; // { dg-error "cannot implicitly reference a class member .f\\\(\\\)::<unnamed union>::x. through a splice" }
|
||||||
|
|
||||||
union {
|
union {
|
||||||
union {
|
union {
|
||||||
int u;
|
int u;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
auto ru = [: ^^u :]; // { dg-error "cannot implicitly reference a class member .u. through a splice" }
|
auto ru = [: ^^u :]; // { dg-error "cannot implicitly reference a class member .f\\\(\\\)::<unnamed union>::<unnamed union>::u. through a splice" }
|
||||||
|
|
||||||
struct L {
|
struct L {
|
||||||
union {
|
union {
|
||||||
|
|||||||
@@ -219,9 +219,9 @@ baz (int x)
|
|||||||
// { dg-final { scan-assembler "_Z3barILi216ELDmtyN3NS24TClsILi42EEEEEvv" } }
|
// { dg-final { scan-assembler "_Z3barILi216ELDmtyN3NS24TClsILi42EEEEEvv" } }
|
||||||
// { dg-final { scan-assembler "_Z3barILi220ELDmdm1S3memEEvv" } }
|
// { dg-final { scan-assembler "_Z3barILi220ELDmdm1S3memEEvv" } }
|
||||||
// { dg-final { scan-assembler "_Z3barILi221ELDmdm3NS21S3memEEvv" } }
|
// { dg-final { scan-assembler "_Z3barILi221ELDmdm3NS21S3memEEvv" } }
|
||||||
// { dg-final { scan-assembler "_Z3barILi222ELDmdm2auEEvv" } }
|
// { dg-final { scan-assembler "_Z3barILi222ELDmdm3NS22auEEvv" } }
|
||||||
// { dg-final { scan-assembler "_Z3barILi223ELDmdm3NS21XUt_1aEEvv" } }
|
// { dg-final { scan-assembler "_Z3barILi223ELDmdm3NS21X1aEEvv" } }
|
||||||
// { dg-final { scan-assembler "_Z3barILi224ELDmdm3NS21YIiEUt_1aEEvv" } }
|
// { dg-final { scan-assembler "_Z3barILi224ELDmdm3NS21YIiE1aEEvv" } }
|
||||||
// { dg-final { scan-assembler "_Z3barILi230ELDmun1S_EEvv" } }
|
// { dg-final { scan-assembler "_Z3barILi230ELDmun1S_EEvv" } }
|
||||||
// { dg-final { scan-assembler "_Z3barILi231ELDmun3NS21S_EEvv" } }
|
// { dg-final { scan-assembler "_Z3barILi231ELDmun3NS21S_EEvv" } }
|
||||||
// { dg-final { scan-assembler "_Z3barILi232ELDmun3NS21S0_EEvv" } }
|
// { dg-final { scan-assembler "_Z3barILi232ELDmun3NS21S0_EEvv" } }
|
||||||
|
|||||||
Reference in New Issue
Block a user