Patchwork C++ PATCH for c++/48046 (ambiguity diagnostic regression)

login
register
mail settings
Submitter Jason Merrill
Date April 27, 2011, 3:53 p.m.
Message ID <4DB83BFD.4090106@redhat.com>
Download mbox | patch
Permalink /patch/93075/
State New
Headers show

Comments

Jason Merrill - April 27, 2011, 3:53 p.m.
This regression was introduced by the fix for PR 35112, but it turns out 
that fixing it is a simple matter of moving one line up in a function so 
that we are committed to the tentative parse before we call 
cp_parser_lookup_name.

Tested x86_64-pc-linux-gnu, applying to trunk and 4.6.  Will also apply 
to 4.5 when unfrozen.
commit 7ef4903eff914d44d63762c603b82a007d38a2d1
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Apr 27 10:07:37 2011 -0400

    	PR c++/48046
    	* parser.c (cp_parser_diagnose_invalid_type_name): Commit
    	to tentative parse sooner.
commit 6a5b4a16dbb00cbeb50ec100174f310cbd6f3e32
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Apr 27 10:13:34 2011 -0400

    	* class.c (resolve_address_of_overloaded_function): Don't
    	change OVERLOAD to TREE_LIST.
    	* pt.c (print_candidates_1): Remove nonsensical assert.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index fa5e00f..9af238b 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6514,14 +6514,7 @@ resolve_address_of_overloaded_function (tree target_type,
 		 DECL_NAME (OVL_CURRENT (overload)),
 		 target_type);
 
-	  /* print_candidates expects a chain with the functions in
-	     TREE_VALUE slots, so we cons one up here (we're losing anyway,
-	     so why be clever?).  */
-	  for (; overload; overload = OVL_NEXT (overload))
-	    matches = tree_cons (NULL_TREE, OVL_CURRENT (overload),
-				 matches);
-
-	  print_candidates (matches);
+	  print_candidates (overload);
 	}
       return error_mark_node;
     }
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index de574a4..481306f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1706,7 +1706,6 @@ print_candidates_1 (tree fns, bool more, const char **str)
   for (fn = fns; fn; fn = OVL_NEXT (fn))
     if (TREE_CODE (fn) == TREE_LIST)
       {
-        gcc_assert (!OVL_NEXT (fn) && !is_overloaded_fn (fn));
         for (fn2 = fn; fn2 != NULL_TREE; fn2 = TREE_CHAIN (fn2))
           print_candidates_1 (TREE_VALUE (fn2),
                               TREE_CHAIN (fn2) || more, str);
@@ -1736,7 +1735,8 @@ print_candidates_1 (tree fns, bool more, const char **str)
     }
 }
 
-/* Print the list of candidate FNS in an error message.  */
+/* Print the list of candidate FNS in an error message.  FNS can also
+   be a TREE_LIST of non-functions in the case of an ambiguous lookup.  */
 
 void
 print_candidates (tree fns)
diff --git a/gcc/testsuite/g++.old-deja/g++.oliva/overload1.C b/gcc/testsuite/g++.old-deja/g++.oliva/overload1.C
index 91b3b02..75c8723 100644
--- a/gcc/testsuite/g++.old-deja/g++.oliva/overload1.C
+++ b/gcc/testsuite/g++.old-deja/g++.oliva/overload1.C
@@ -6,7 +6,7 @@
 // Based on bug report by JDonner <jdonner@schedsys.com>
 
 struct foo {
-  static int bar(); // { dg-error "candidate" }
+  static int bar(); // { dg-error "foo::bar" }
   void bar(int); // { dg-error "foo::bar" }
 };

Patch

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 68ce052..89100aa 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2440,6 +2440,7 @@  cp_parser_diagnose_invalid_type_name (cp_parser *parser,
 				      location_t location)
 {
   tree decl, old_scope;
+  cp_parser_commit_to_tentative_parse (parser);
   /* Try to lookup the identifier.  */
   old_scope = parser->scope;
   parser->scope = scope;
@@ -2533,7 +2534,6 @@  cp_parser_diagnose_invalid_type_name (cp_parser *parser,
       else
 	gcc_unreachable ();
     }
-  cp_parser_commit_to_tentative_parse (parser);
 }
 
 /* Check for a common situation where a type-name should be present,
diff --git a/gcc/testsuite/g++.dg/parse/ambig6.C b/gcc/testsuite/g++.dg/parse/ambig6.C
new file mode 100644
index 0000000..8f37fea
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/ambig6.C
@@ -0,0 +1,12 @@ 
+// PR c++/48046
+
+namespace N1 { typedef int   T; } // { dg-error "" }
+namespace N2 { typedef float T; } // { dg-error "" }
+
+int main()
+{
+  using namespace N1;
+  using namespace N2;
+
+  static T t;			// { dg-error "" }
+}