aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-04-06 14:09:53 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-04-06 14:09:53 -0400
commit96975b1159808defb222a57b369db02a0eab5fee (patch)
tree09a519ef6a26c4fc39366f1fd44d9701a19e00ba /gcc
parente1c7971b81abab836f2fc4f0b8d0f7964f8a6e13 (diff)
downloadgcc-96975b1159808defb222a57b369db02a0eab5fee.zip
gcc-96975b1159808defb222a57b369db02a0eab5fee.tar.gz
gcc-96975b1159808defb222a57b369db02a0eab5fee.tar.bz2
PR c++/85214 - ICE with alias, generic lambda, constexpr if.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/constexpr-if20.C17
3 files changed, 27 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e71b4fb..ba323bf 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 450ffae..db3d7e3 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
index 0000000..24343ad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if20.C
@@ -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());
+}