===================================================================
@@ -0,0 +1,30 @@
+// PR c++/58930
+// { dg-do compile { target c++11 } }
+
+struct SampleModule
+{
+ explicit SampleModule (int);
+};
+
+template < typename >
+struct BaseHandler
+{
+ SampleModule module_ { 0 };
+};
+
+BaseHandler<int> a;
+// PR c++/58930
+// { dg-do compile { target c++11 } }
+
+struct SampleModule
+{
+ explicit SampleModule (int);
+};
+
+template < typename >
+struct BaseHandler
+{
+ SampleModule module_ { 0 };
+};
+
+BaseHandler<int> a;
===================================================================
@@ -0,0 +1,22 @@
+// PR c++/58704
+// { dg-do compile { target c++11 } }
+
+struct A {};
+
+template<typename> struct B
+{
+ A a[1] = { };
+};
+
+B<int> b;
+// PR c++/58704
+// { dg-do compile { target c++11 } }
+
+struct A {};
+
+template<typename> struct B
+{
+ A a[1] = { };
+};
+
+B<int> b;
===================================================================
@@ -0,0 +1,34 @@
+// PR c++/58753
+// { dg-do compile { target c++11 } }
+
+#include <initializer_list>
+
+template <class T>
+struct X {X(std::initializer_list<int>) {}};
+
+template <class zomg>
+class T {
+ X<T> x{1};
+};
+
+int main()
+{
+ T<int> t;
+}
+// PR c++/58753
+// { dg-do compile { target c++11 } }
+
+#include <initializer_list>
+
+template <class T>
+struct X {X(std::initializer_list<int>) {}};
+
+template <class zomg>
+class T {
+ X<T> x{1};
+};
+
+int main()
+{
+ T<int> t;
+}
===================================================================
@@ -522,6 +522,49 @@
}
}
+/* Return the non-static data initializer for FIELD_DECL MEMBER. */
+
+tree
+get_nsdmi (tree member, bool in_ctor)
+{
+ tree init;
+ tree save_ccp = current_class_ptr;
+ tree save_ccr = current_class_ref;
+ if (!in_ctor)
+ inject_this_parameter (DECL_CONTEXT (member), TYPE_UNQUALIFIED);
+ if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member))
+ {
+ /* Do deferred instantiation of the NSDMI. */
+ init = (tsubst_copy_and_build
+ (DECL_INITIAL (DECL_TI_TEMPLATE (member)),
+ DECL_TI_ARGS (member),
+ tf_warning_or_error, member, /*function_p=*/false,
+ /*integral_constant_expression_p=*/false));
+
+ init = digest_nsdmi_init (member, init);
+ }
+ else
+ {
+ init = DECL_INITIAL (member);
+ if (init && TREE_CODE (init) == DEFAULT_ARG)
+ {
+ error ("constructor required before non-static data member "
+ "for %qD has been parsed", member);
+ DECL_INITIAL (member) = error_mark_node;
+ init = NULL_TREE;
+ }
+ /* Strip redundant TARGET_EXPR so we don't need to remap it, and
+ so the aggregate init code below will see a CONSTRUCTOR. */
+ if (init && TREE_CODE (init) == TARGET_EXPR
+ && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (init))))
+ init = TARGET_EXPR_INITIAL (init);
+ init = break_out_target_exprs (init);
+ }
+ current_class_ptr = save_ccp;
+ current_class_ref = save_ccr;
+ return init;
+}
+
/* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
arguments. If TREE_LIST is void_type_node, an empty initializer
list was given; if NULL_TREE no initializer was given. */
@@ -535,31 +578,7 @@
/* Use the non-static data member initializer if there was no
mem-initializer for this field. */
if (init == NULL_TREE)
- {
- if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member))
- /* Do deferred instantiation of the NSDMI. */
- init = (tsubst_copy_and_build
- (DECL_INITIAL (DECL_TI_TEMPLATE (member)),
- DECL_TI_ARGS (member),
- tf_warning_or_error, member, /*function_p=*/false,
- /*integral_constant_expression_p=*/false));
- else
- {
- init = DECL_INITIAL (member);
- if (init && TREE_CODE (init) == DEFAULT_ARG)
- {
- error ("constructor required before non-static data member "
- "for %qD has been parsed", member);
- init = NULL_TREE;
- }
- /* Strip redundant TARGET_EXPR so we don't need to remap it, and
- so the aggregate init code below will see a CONSTRUCTOR. */
- if (init && TREE_CODE (init) == TARGET_EXPR
- && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (init))))
- init = TARGET_EXPR_INITIAL (init);
- init = break_out_target_exprs (init);
- }
- }
+ init = get_nsdmi (member, /*ctor*/true);
if (init == error_mark_node)
return;
===================================================================
@@ -1097,6 +1097,22 @@
{
return digest_init_r (type, init, false, flags, tf_warning_or_error);
}
+
+/* Process the initializer INIT for an NSDMI DECL (a FIELD_DECL). */
+tree
+digest_nsdmi_init (tree decl, tree init)
+{
+ gcc_assert (TREE_CODE (decl) == FIELD_DECL);
+
+ int flags = LOOKUP_IMPLICIT;
+ if (DIRECT_LIST_INIT_P (init))
+ flags = LOOKUP_NORMAL;
+ init = digest_init_flags (TREE_TYPE (decl), init, flags);
+ if (TREE_CODE (init) == TARGET_EXPR)
+ /* This represents the whole initialization. */
+ TARGET_EXPR_DIRECT_INIT_P (init) = true;
+ return init;
+}
/* Set of flags used within process_init_constructor to describe the
initializers. */
===================================================================
@@ -17852,7 +17852,7 @@
/* Used by handling of trailing-return-types and NSDMI, in which 'this'
is in scope even though it isn't real. */
-static void
+void
inject_this_parameter (tree ctype, cp_cv_quals quals)
{
tree this_parm;
@@ -23686,16 +23686,7 @@
parsed_arg = check_default_argument (parmtype, parsed_arg,
tf_warning_or_error);
else
- {
- int flags = LOOKUP_IMPLICIT;
- if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg)
- && CONSTRUCTOR_IS_DIRECT_INIT (parsed_arg))
- flags = LOOKUP_NORMAL;
- parsed_arg = digest_init_flags (TREE_TYPE (decl), parsed_arg, flags);
- if (TREE_CODE (parsed_arg) == TARGET_EXPR)
- /* This represents the whole initialization. */
- TARGET_EXPR_DIRECT_INIT_P (parsed_arg) = true;
- }
+ parsed_arg = digest_nsdmi_init (decl, parsed_arg);
}
/* If the token stream has not been completely used up, then
===================================================================
@@ -3436,6 +3436,9 @@
B b{1,2}, not B b({1,2}) or B b = {1,2}. */
#define CONSTRUCTOR_IS_DIRECT_INIT(NODE) (TREE_LANG_FLAG_0 (CONSTRUCTOR_CHECK (NODE)))
+#define DIRECT_LIST_INIT_P(NODE) \
+ (BRACE_ENCLOSED_INITIALIZER_P (NODE) && CONSTRUCTOR_IS_DIRECT_INIT (NODE))
+
/* True if NODE represents a conversion for direct-initialization in a
template. Set by perform_implicit_conversion_flags. */
#define IMPLICIT_CONV_EXPR_DIRECT_INIT(NODE) \
@@ -4353,6 +4356,11 @@
PARM_DECLs in cp_tree_equal. */
extern int comparing_specializations;
+/* A type-qualifier, or bitmask therefore, using the TYPE_QUAL
+ constants. */
+
+typedef int cp_cv_quals;
+
/* In parser.c. */
/* Nonzero if we are parsing an unevaluated operand: an operand to
@@ -4362,6 +4370,7 @@
extern int cp_unevaluated_operand;
extern tree cp_convert_range_for (tree, tree, tree, bool);
extern bool parsing_nsdmi (void);
+extern void inject_this_parameter (tree, cp_cv_quals);
/* in pt.c */
@@ -4741,11 +4750,6 @@
extern GTY(()) operator_name_info_t assignment_operator_name_info
[(int) MAX_TREE_CODES];
-/* A type-qualifier, or bitmask therefore, using the TYPE_QUAL
- constants. */
-
-typedef int cp_cv_quals;
-
/* Non-static member functions have an optional virt-specifier-seq.
There is a VIRT_SPEC value for each virt-specifier.
They can be combined by bitwise-or to form the complete set of
@@ -5421,6 +5425,7 @@
extern tree build_zero_init (tree, tree, bool);
extern tree build_value_init (tree, tsubst_flags_t);
extern tree build_value_init_noctor (tree, tsubst_flags_t);
+extern tree get_nsdmi (tree, bool);
extern tree build_offset_ref (tree, tree, bool,
tsubst_flags_t);
extern tree throw_bad_array_new_length (void);
@@ -6157,6 +6162,7 @@
extern void check_narrowing (tree, tree);
extern tree digest_init (tree, tree, tsubst_flags_t);
extern tree digest_init_flags (tree, tree, int);
+extern tree digest_nsdmi_init (tree, tree);
extern tree build_scoped_ref (tree, tree, tree *);
extern tree build_x_arrow (location_t, tree,
tsubst_flags_t);