On Fri, Jun 27, 2014 at 12:51 PM, Jason Merrill <ja...@redhat.com> wrote:
> On 06/27/2014 11:04 AM, Paul Pluzhnikov wrote:
>>
>> Ok to backport r210653 (fix for PR58930) to gcc-4_9-branch?
>
>
> OK, yes.

Thanks. Committed attached patch as r212207.

Tested on Linux/x86_64, no regressions.

-- 
Paul Pluzhnikov
Index: gcc/testsuite/g++.dg/cpp0x/nsdmi-template11.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/nsdmi-template11.C       (revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/nsdmi-template11.C       (revision 212207)
@@ -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;
Index: gcc/testsuite/g++.dg/cpp0x/nsdmi-template13.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/nsdmi-template13.C       (revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/nsdmi-template13.C       (revision 212207)
@@ -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;
Index: gcc/testsuite/g++.dg/cpp0x/nsdmi-template12.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/nsdmi-template12.C       (revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/nsdmi-template12.C       (revision 212207)
@@ -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;
+}
Index: gcc/cp/init.c
===================================================================
--- gcc/cp/init.c       (revision 212206)
+++ gcc/cp/init.c       (revision 212207)
@@ -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;
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c    (revision 212206)
+++ gcc/cp/typeck2.c    (revision 212207)
@@ -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.  */
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c     (revision 212206)
+++ gcc/cp/parser.c     (revision 212207)
@@ -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
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h    (revision 212206)
+++ gcc/cp/cp-tree.h    (revision 212207)
@@ -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);

Reply via email to