PR c++/85214 - ICE with alias, generic lambda, constexpr if.
authorJason Merrill <jason@redhat.com>
Fri, 6 Apr 2018 18:09:53 +0000 (14:09 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 6 Apr 2018 18:09:53 +0000 (14:09 -0400)
Here, since the condition for the constexpr if depends on the type of 'j',
it's still dependent when we are partially instantiating the inner lambda,
so we need to defer instantiating the constexpr if.  When we instantiated
the inner lambda, we tried to substitute into the typename, which failed
because we didn't have a declaration of 'i' available.

Fixed by teaching extract_locals_r to capture local typedefs such as 'ar';
if we have the typedef handy, we don't need to substitute into its
definition.

* pt.c (extract_locals_r): Remember local typedefs.

From-SVN: r259185

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

index e71b4fbe9d82bc1d30e628bf185eab50287c85f5..ba323bf7c20e9e4179489d817840cc5b9b994418 100644 (file)
@@ -1,3 +1,8 @@
+2018-04-06  Jason Merrill  <jason@redhat.com>
+
+       PR c++/85214 - ICE with alias, generic lambda, constexpr if.
+       * pt.c (extract_locals_r): Remember local typedefs.
+
 2018-04-06  David Malcolm  <dmalcolm@redhat.com>
 
        PR c++/84269
index 450ffaec9bec2cd2453532b49cd950b33528a85b..db3d7e38d85329b58fc125d957e288e0eeeca426 100644 (file)
@@ -11610,6 +11610,11 @@ extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data_)
   el_data &data = *reinterpret_cast<el_data*>(data_);
   tree *extra = &data.extra;
   tsubst_flags_t complain = data.complain;
+
+  if (TYPE_P (*tp) && typedef_variant_p (*tp))
+    /* Remember local typedefs (85214).  */
+    tp = &TYPE_NAME (*tp);
+
   if (TREE_CODE (*tp) == DECL_EXPR)
     data.internal.add (DECL_EXPR_DECL (*tp));
   else if (tree spec = retrieve_local_specialization (*tp))
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if20.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if20.C
new file mode 100644 (file)
index 0000000..24343ad
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/85214
+// { dg-additional-options -std=c++17 }
+
+struct g {
+  constexpr operator int() { return true; }
+};
+template <typename T, typename U> constexpr bool m = true;
+template <long L> struct C { typedef double q; };
+void ao() {
+  [](auto i) {
+      using ar = typename C<i>::q;
+      [](auto j) {
+       using as = typename C<j>::q;
+       if constexpr (m<ar, as>) {}
+      }(g());
+  }(g());
+}