re PR c++/67273 (Incorrect -Wshadow warning with generic lambdas)
authorNathan Sidwell <nathan@acm.org>
Tue, 31 Jan 2017 18:05:37 +0000 (18:05 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Tue, 31 Jan 2017 18:05:37 +0000 (18:05 +0000)
PR c++/67273
PR c++/79253
* pt.c: (instantiate_decl): Push to top level when current
function scope doesn't match.  Only push lmabda scope stack when
pushing to top.

PR c++/67273
PR c++/79253
* g++.dg/cpp1y/pr67273.C: New.
* g++.dg/cpp1y/pr79253.C: New.

From-SVN: r245067

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1y/pr67273.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/pr79253.C [new file with mode: 0644]

index 5df2f723c711734702c05baac4b231414dd3309d..78a5725dc6d0f6c84428f736b4dccc72f35b23d7 100644 (file)
@@ -1,5 +1,11 @@
 2017-01-31  Nathan Sidwell  <nathan@acm.org>
 
+       PR c++/67273
+       PR c++/79253
+       * pt.c: (instantiate_decl): Push to top level when current
+       function scope doesn't match.  Only push lmabda scope stack when
+       pushing to top.
+
        * cp-tree.h (instantiate_decl): Make defer_ok bool.
        * pt.c: Fix instantiate_decl calls to pass true/false not 0/1
        (instantiate_decl): Simplify and reorder state saving and restoration.
index bd39ee383e1acd19b239dd6fb3f7f67b332d9a9f..c69c27063e86a62d54637ad33f4b1d7aeeb3a069 100644 (file)
@@ -22666,20 +22666,21 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
        goto out;
     }
 
-  bool nested;
+  bool push_to_top, nested;
   tree fn_context;
   fn_context = decl_function_context (d);
-  nested = (current_function_decl != NULL_TREE);
+  nested = current_function_decl != NULL_TREE;
+  push_to_top = !(nested && fn_context == current_function_decl);
+
   vec<tree> omp_privatization_save;
   if (nested)
     save_omp_privatization_clauses (omp_privatization_save);
 
-  if (!fn_context)
+  if (push_to_top)
     push_to_top_level ();
   else
     {
-      if (nested)
-       push_function_context ();
+      push_function_context ();
       cp_unevaluated_operand = 0;
       c_inhibit_evaluation_warnings = 0;
     }
@@ -22756,7 +22757,7 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
        block = push_stmt_list ();
       else
        {
-         if (LAMBDA_FUNCTION_P (d))
+         if (push_to_top && LAMBDA_FUNCTION_P (d))
            {
              /* When instantiating a lambda's templated function
                 operator, we need to push the non-lambda class scope
@@ -22849,9 +22850,9 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
   /* We're not deferring instantiation any more.  */
   TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0;
 
-  if (!fn_context)
+  if (push_to_top)
     pop_from_top_level ();
-  else if (nested)
+  else
     pop_function_context ();
 
   if (nested)
index 675c190bb1ac0a868661d4386dd5c5eb72134e7d..922fe645755a1b484e5f0bf612142a6e606e0e86 100644 (file)
@@ -1,3 +1,10 @@
+2017-01-31  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/67273
+       PR c++/79253
+       * g++.dg/cpp1y/pr67273.C: New.
+       * g++.dg/cpp1y/pr79253.C: New.
+
 2017-01-31  Nathan Sidwell  <nathan@acm.org>
 
        PR c++/79264
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr67273.C b/gcc/testsuite/g++.dg/cpp1y/pr67273.C
new file mode 100644 (file)
index 0000000..d2bc035
--- /dev/null
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++14 } }
+// { dg-additional-options "-Wshadow" }
+
+// pr67273 bogus warning about shadowing.
+
+
+template <typename T> void Foo (T &&lambda)
+{
+  int ARG = 2;
+  lambda (1);
+}
+
+void Baz ()
+{
+  Foo ([] (auto &&ARG) {});
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr79253.C b/gcc/testsuite/g++.dg/cpp1y/pr79253.C
new file mode 100644 (file)
index 0000000..b15efe8
--- /dev/null
@@ -0,0 +1,33 @@
+// { dg-do compile { target c++14 } }
+// PR 79253 ICE instantiating lambda body.
+
+template <typename> struct A;
+template <typename = A<int>> class B {};
+template <class T, class U, class V> void foo (U, V) { T (0, 0); }
+struct C {};
+template <template <bool, bool, bool> class F, class>
+void
+bar ()
+{
+  F<0, 0, 0>::baz;
+}
+struct G { int l; };
+template <int, int, int> struct E : C
+{
+  E (int, int) : e (0)
+  {
+    auto &m = this->m ();
+    auto c = [&] { m.l; };
+  }
+  G &m ();
+  int e;
+};
+struct D
+{
+  void
+  baz () { bar<F, B<>>; }
+  template <bool, bool, bool> struct F
+  {
+    static B<> baz () { foo<E<0, 0, 0>> (0, 0); }
+  };
+};