re PR c++/62207 (ICE: tree check: expected tree that contains 'decl minimal' structur...
authorPaolo Carlini <paolo.carlini@oracle.com>
Mon, 1 Apr 2019 17:09:47 +0000 (17:09 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 1 Apr 2019 17:09:47 +0000 (17:09 +0000)
/cp
2019-04-01  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/62207
* pt.c (tsubst_copy): Deal with lookup_name not returing a variable.

/testsuite
2019-04-01  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/62207
* g++.dg/template/crash130.C: New.
* g++.dg/template/crash131.C: Likewise.

From-SVN: r270064

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/crash130.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/crash131.C [new file with mode: 0644]

index 8c6e9931db161361e59663ad7a348e9bbfbb8246..3501f6b8cf3b6bd8d28356225da2e3dfe5f70b3a 100644 (file)
@@ -1,3 +1,8 @@
+2019-04-01  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/62207
+       * pt.c (tsubst_copy): Deal with lookup_name not returing a variable.
+
 2019-03-31  Marek Polacek  <polacek@redhat.com>
 
        PR c++/89852 - ICE with C++11 functional cast with { }.
index f3faa89f671018c99e3734076e0ca1a276d0cb94..d5249a095c6f8e3e7844c6a0440672aec10043f0 100644 (file)
@@ -15591,12 +15591,23 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            {
              /* First try name lookup to find the instantiation.  */
              r = lookup_name (DECL_NAME (t));
-             if (r && !is_capture_proxy (r))
+             if (r)
                {
-                 /* Make sure that the one we found is the one we want.  */
-                 tree ctx = enclosing_instantiation_of (DECL_CONTEXT (t));
-                 if (ctx != DECL_CONTEXT (r))
-                   r = NULL_TREE;
+                 if (!VAR_P (r))
+                   {
+                     /* During error-recovery we may find a non-variable,
+                        even an OVERLOAD: just bail out and avoid ICEs and
+                        duplicate diagnostics (c++/62207).  */
+                     gcc_assert (seen_error ());
+                     return error_mark_node;
+                   }
+                 if (!is_capture_proxy (r))
+                   {
+                     /* Make sure the one we found is the one we want.  */
+                     tree ctx = enclosing_instantiation_of (DECL_CONTEXT (t));
+                     if (ctx != DECL_CONTEXT (r))
+                       r = NULL_TREE;
+                   }
                }
 
              if (r)
@@ -15632,7 +15643,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                    }
                  gcc_assert (cp_unevaluated_operand || TREE_STATIC (r)
                              || decl_constant_var_p (r)
-                             || errorcount || sorrycount);
+                             || seen_error ());
                  if (!processing_template_decl
                      && !TREE_STATIC (r))
                    r = process_outer_var_ref (r, complain);
index 1c516a95185edc3d7a786c6aba91d886e1b31f69..244ae87b49510df9f47e5f6586e5ae386468f434 100644 (file)
@@ -1,3 +1,9 @@
+2019-04-01  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/62207
+       * g++.dg/template/crash130.C: New.
+       * g++.dg/template/crash131.C: Likewise.
+
 2019-04-01  Martin Sebor  <msebor@redhat.com>
 
        PR c/89685
diff --git a/gcc/testsuite/g++.dg/template/crash130.C b/gcc/testsuite/g++.dg/template/crash130.C
new file mode 100644 (file)
index 0000000..c3e154f
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/62207
+
+template<typename T> void foo(T)
+{
+  X;  // { dg-error "not declared" }
+  X;
+}
+
+void X();
+void X(int);
+
+void bar()
+{
+  foo(0);
+}
diff --git a/gcc/testsuite/g++.dg/template/crash131.C b/gcc/testsuite/g++.dg/template/crash131.C
new file mode 100644 (file)
index 0000000..7b3a47d
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/62207
+
+template<class F>
+class X {
+public:
+  template<F f> class Y {};
+  template<F f> void y() {}
+  X(F f)
+  {
+    Y<f> y;  // { dg-error "not a constant" }
+
+    y.value();
+  }
+};
+
+int main() { X<int> x(1); }