diff mbox

C++ PATCH for c++/60185 (ICE with invalid default arg in template)

Message ID 5307CADD.903@redhat.com
State New
Headers show

Commit Message

Jason Merrill Feb. 21, 2014, 9:53 p.m. UTC
To avoid problems trying to resolve an invalid use of 'this' before 
diagnosing it later, let's do the same thing we do in 
tsubst_default_argument, namely clear current_class_{ptr,ref}.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox

Patch

commit f1051ca23020746350bacff3c499b2a9d1ec0dff
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Feb 21 15:08:28 2014 -0500

    	PR c++/60185
    	* parser.c (cp_parser_default_argument): Clear
    	current_class_ptr/current_class_ref like tsubst_default_argument.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7bbdf90..47a67c4 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -18633,8 +18633,24 @@  cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
   /* Parse the assignment-expression.  */
   if (template_parm_p)
     push_deferring_access_checks (dk_no_deferred);
+  tree saved_class_ptr = NULL_TREE;
+  tree saved_class_ref = NULL_TREE;
+  /* The "this" pointer is not valid in a default argument.  */
+  if (cfun)
+    {
+      saved_class_ptr = current_class_ptr;
+      cp_function_chain->x_current_class_ptr = NULL_TREE;
+      saved_class_ref = current_class_ref;
+      cp_function_chain->x_current_class_ref = NULL_TREE;
+    }
   default_argument
     = cp_parser_initializer (parser, &is_direct_init, &non_constant_p);
+  /* Restore the "this" pointer.  */
+  if (cfun)
+    {
+      cp_function_chain->x_current_class_ptr = saved_class_ptr;
+      cp_function_chain->x_current_class_ref = saved_class_ref;
+    }
   if (BRACE_ENCLOSED_INITIALIZER_P (default_argument))
     maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
   if (template_parm_p)
diff --git a/gcc/testsuite/g++.dg/overload/defarg5.C b/gcc/testsuite/g++.dg/overload/defarg5.C
index 06ea6bf..d022b0c 100644
--- a/gcc/testsuite/g++.dg/overload/defarg5.C
+++ b/gcc/testsuite/g++.dg/overload/defarg5.C
@@ -2,6 +2,6 @@ 
 
 struct A
 {
-  int i;
-  A() { void foo(int=i); }	// { dg-error "this" }
+  int i;			// { dg-message "" }
+  A() { void foo(int=i); }	// { dg-error "" }
 };
diff --git a/gcc/testsuite/g++.dg/template/defarg17.C b/gcc/testsuite/g++.dg/template/defarg17.C
new file mode 100644
index 0000000..38d68d4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/defarg17.C
@@ -0,0 +1,9 @@ 
+// PR c++/60185
+
+template<int> struct A
+{
+  int i;			// { dg-message "" }
+  A() { void foo(int=i); }	// { dg-error "" }
+};
+
+A<0> a;