Patchwork C++ PATCH for c++/39055 (accepts-valid with 'this' in default argument)

login
register
mail settings
Submitter Jason Merrill
Date Feb. 14, 2012, 8:39 a.m.
Message ID <4F3A1DCD.7070405@redhat.com>
Download mbox | patch
Permalink /patch/141070/
State New
Headers show

Comments

Jason Merrill - Feb. 14, 2012, 8:39 a.m.
This is a regression since 3.3; discussion at the C++ meeting last week 
concluded both that yes, this is ill-formed, and we think it should be 
ill-formed.

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

Patch

commit 399365c251914176b5b34076e5a7b4658c06e917
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Feb 10 22:57:05 2012 -1000

    	PR c++/39055
    	* decl.c (local_variable_p_walkfn): Don't check DECL_ARTIFICIAL.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 8fcfbd5..f0ba181 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10509,7 +10509,9 @@  static tree
 local_variable_p_walkfn (tree *tp, int *walk_subtrees,
 			 void *data ATTRIBUTE_UNUSED)
 {
-  if (local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
+  /* Check DECL_NAME to avoid including temporaries.  We don't check
+     DECL_ARTIFICIAL because we do want to complain about 'this'.  */
+  if (local_variable_p (*tp) && DECL_NAME (*tp))
     return *tp;
   else if (TYPE_P (*tp))
     *walk_subtrees = 0;
@@ -10517,7 +10519,6 @@  local_variable_p_walkfn (tree *tp, int *walk_subtrees,
   return NULL_TREE;
 }
 
-
 /* Check that ARG, which is a default-argument expression for a
    parameter DECL, is valid.  Returns ARG, or ERROR_MARK_NODE, if
    something goes wrong.  DECL may also be a _TYPE node, rather than a
@@ -10578,7 +10579,10 @@  check_default_argument (tree decl, tree arg)
   var = cp_walk_tree_without_duplicates (&arg, local_variable_p_walkfn, NULL);
   if (var)
     {
-      error ("default argument %qE uses local variable %qD", arg, var);
+      if (DECL_NAME (var) == this_identifier)
+	permerror (input_location, "default argument %qE uses %qD", arg, var);
+      else
+	error ("default argument %qE uses local variable %qD", arg, var);
       return error_mark_node;
     }
 
diff --git a/gcc/testsuite/g++.dg/overload/defarg5.C b/gcc/testsuite/g++.dg/overload/defarg5.C
new file mode 100644
index 0000000..06ea6bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/defarg5.C
@@ -0,0 +1,7 @@ 
+// PR c++/39055
+
+struct A
+{
+  int i;
+  A() { void foo(int=i); }	// { dg-error "this" }
+};