PR c++/86480 - nested variadic lambda and constexpr if.
authorJason Merrill <jason@redhat.com>
Tue, 17 Jul 2018 15:39:46 +0000 (11:39 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 17 Jul 2018 15:39:46 +0000 (11:39 -0400)
* pt.c (find_parameter_packs_r) [IF_STMT]: Don't walk into
IF_STMT_EXTRA_ARGS.
* tree.c (cp_walk_subtrees) [DECLTYPE_TYPE]: Set
cp_unevaluated_operand.
[ALIGNOF_EXPR] [SIZEOF_EXPR] [NOEXCEPT_EXPR]: Likewise.

From-SVN: r262825

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/cp/tree.c
gcc/testsuite/g++.dg/cpp1z/constexpr-if24.C [new file with mode: 0644]

index 6c1384a..f6f4398 100644 (file)
@@ -1,3 +1,12 @@
+2018-07-17  Jason Merrill  <jason@redhat.com>
+
+       PR c++/86480 - nested variadic lambda and constexpr if.
+       * pt.c (find_parameter_packs_r) [IF_STMT]: Don't walk into
+       IF_STMT_EXTRA_ARGS.
+       * tree.c (cp_walk_subtrees) [DECLTYPE_TYPE]: Set
+       cp_unevaluated_operand.
+       [ALIGNOF_EXPR] [SIZEOF_EXPR] [NOEXCEPT_EXPR]: Likewise.
+
 2018-07-16  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * class.c (resolve_address_of_overloaded_function): Don't emit an
index b49dce0..2780504 100644 (file)
@@ -3865,6 +3865,17 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
        return NULL_TREE;
       }
 
+    case IF_STMT:
+      cp_walk_tree (&IF_COND (t), &find_parameter_packs_r,
+                   ppd, ppd->visited);
+      cp_walk_tree (&THEN_CLAUSE (t), &find_parameter_packs_r,
+                   ppd, ppd->visited);
+      cp_walk_tree (&ELSE_CLAUSE (t), &find_parameter_packs_r,
+                   ppd, ppd->visited);
+      /* Don't walk into IF_STMT_EXTRA_ARGS.  */
+      *walk_subtrees = 0;
+      return NULL_TREE;
+
     default:
       return NULL_TREE;
     }
index b1333f5..7e2a77b 100644 (file)
@@ -4865,7 +4865,19 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
       break;
 
     case DECLTYPE_TYPE:
-      WALK_SUBTREE (DECLTYPE_TYPE_EXPR (*tp));
+      ++cp_unevaluated_operand;
+      /* We can't use WALK_SUBTREE here because of the goto.  */
+      result = cp_walk_tree (&DECLTYPE_TYPE_EXPR (*tp), func, data, pset);
+      --cp_unevaluated_operand;
+      *walk_subtrees_p = 0;
+      break;
+
+    case ALIGNOF_EXPR:
+    case SIZEOF_EXPR:
+    case NOEXCEPT_EXPR:
+      ++cp_unevaluated_operand;
+      result = cp_walk_tree (&TREE_OPERAND (*tp, 0), func, data, pset);
+      --cp_unevaluated_operand;
       *walk_subtrees_p = 0;
       break;
  
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if24.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if24.C
new file mode 100644 (file)
index 0000000..cbdb38d
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/86480
+// { dg-additional-options -std=c++17 }
+
+template <class...> constexpr bool val = true;
+
+template <class... T>
+void f()
+{
+  [](auto... p)
+    {
+      []{
+       if constexpr (val<T..., decltype(p)...>) { return true; }
+       return false;
+      }();
+    }(42);
+}
+
+int main()
+{
+  f<int>();
+}