@@ -7534,6 +7534,7 @@ extern int at_function_scope_p (void);
extern bool at_class_scope_p (void);
extern bool at_namespace_scope_p (void);
extern tree context_for_name_lookup (tree);
+extern tree type_context_for_name_lookup (tree);
extern tree lookup_conversions (tree);
extern tree binfo_from_vbase (tree);
extern tree binfo_for_vbase (tree, tree);
@@ -597,7 +597,7 @@ maybe_instantiate_nsdmi_init (tree member, tsubst_flags_t complain)
DECL_INSTANTIATING_NSDMI_P (member) = 1;
bool pushed = false;
- tree ctx = DECL_CONTEXT (member);
+ tree ctx = type_context_for_name_lookup (member);
processing_template_decl_sentinel ptds (/*reset*/false);
if (!currently_open_class (ctx))
@@ -26439,11 +26439,12 @@ cp_parser_class_specifier (cp_parser* parser)
/* Now parse any NSDMIs. */
FOR_EACH_VEC_SAFE_ELT (unparsed_nsdmis, ix, decl)
{
- if (class_type != DECL_CONTEXT (decl))
+ tree ctx = type_context_for_name_lookup (decl);
+ if (class_type != ctx)
{
if (pushed_scope)
pop_scope (pushed_scope);
- class_type = DECL_CONTEXT (decl);
+ class_type = ctx;
pushed_scope = push_scope (class_type);
}
inject_this_parameter (class_type, TYPE_UNQUALIFIED);
@@ -485,6 +485,25 @@ context_for_name_lookup (tree decl)
return context;
}
+/* Like the above, but always return a type, because it's simpler for member
+ handling to refer to the anonymous aggr rather than a function. */
+
+tree
+type_context_for_name_lookup (tree decl)
+{
+ tree context = DECL_P (decl) ? DECL_CONTEXT (decl) : decl;
+ gcc_checking_assert (CLASS_TYPE_P (context));
+
+ while (context && TYPE_P (context) && ANON_AGGR_TYPE_P (context))
+ {
+ tree next = TYPE_CONTEXT (context);
+ if (!TYPE_P (next))
+ break;
+ context = next;
+ }
+ return context;
+}
+
/* Returns true iff DECL is declared in TYPE. */
static bool
@@ -881,6 +900,10 @@ accessible_p (tree type, tree decl, bool consider_local_p)
else
otype = type;
+ /* Anonymous unions don't have their own access. */
+ if (ANON_AGGR_TYPE_P (type))
+ type = type_context_for_name_lookup (type);
+
/* [class.access.base]
A member m is accessible when named in class N if
new file mode 100644
@@ -0,0 +1,16 @@
+// PR c++/105452
+// { dg-do compile { target c++11 } }
+
+template <typename T>
+struct C {
+ int i = 42;
+ union {
+ T v = i;
+ static_assert(sizeof(v) == sizeof(char), "");
+ };
+};
+
+int main() {
+ C<char> x;
+ return x.v;
+}