diff mbox

fix PR45049, DECL_CHAIN error

Message ID 20100818132959.GP25394@codesourcery.com
State New
Headers show

Commit Message

Nathan Froyd Aug. 18, 2010, 1:29 p.m. UTC
The patch below fixes PR45049 by changing offending DECL_CHAINs back to
TREE_CHAINs.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

gcc/cp/
	PR c++/45049
	* name-lookup.c (push_overloaded_decl): Change DECL_CHAIN to
	TREE_CHAIN.

gcc/testsuite/
	PR c++/45049
	* g++.dg/pr45049-1.C: New test.
	* g++.dg/pr45049-2.C: New test.

Comments

Jakub Jelinek Aug. 18, 2010, 1:36 p.m. UTC | #1
On Wed, Aug 18, 2010 at 06:29:59AM -0700, Nathan Froyd wrote:
> The patch below fixes PR45049 by changing offending DECL_CHAINs back to
> TREE_CHAINs.
> 
> Tested on x86_64-unknown-linux-gnu.  OK to commit?

PR45062 needs similar treatment.

	Jakub
Nathan Froyd Aug. 18, 2010, 1:43 p.m. UTC | #2
On Wed, Aug 18, 2010 at 03:36:22PM +0200, Jakub Jelinek wrote:
> On Wed, Aug 18, 2010 at 06:29:59AM -0700, Nathan Froyd wrote:
> > The patch below fixes PR45049 by changing offending DECL_CHAINs back to
> > TREE_CHAINs.
> 
> PR45062 needs similar treatment.

Yes, I know.  But for PR45062, I don't think the right fix is to
s/DECL_CHAIN/TREE_CHAIN/.  The error stems from a dodgy bit of code in
grokparms:

  else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE)
    {
      if (!funcdef_flag)
      pedwarn (input_location, 0, "parameter names (without types) in function declaration");

      arg_info->parms = arg_info->types;
      arg_info->types = 0;
      return 0;
    }

What in the world are we doing assigning a TREE_LIST (arg_info->types)
to a field that's supposed to be a chain of DECLs?  Later on,
arg_info->parms is iterated through with DECL_CHAIN and things blow up.

I *think* the right fix here is to simply NULL_TREE out arg_info->parms
if !funcdef_flag, but I have not yet constructed enough test cases to
convince myself that would not regress things.

-Nathan
Mark Mitchell Aug. 18, 2010, 3:32 p.m. UTC | #3
Nathan Froyd wrote:

> gcc/cp/
> 	PR c++/45049
> 	* name-lookup.c (push_overloaded_decl): Change DECL_CHAIN to
> 	TREE_CHAIN.
> 
> gcc/testsuite/
> 	PR c++/45049
> 	* g++.dg/pr45049-1.C: New test.
> 	* g++.dg/pr45049-2.C: New test.

OK.
diff mbox

Patch

diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 01f29e4..800e340 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2157,7 +2157,7 @@  push_overloaded_decl (tree decl, int flags, bool is_friend)
 
 	  for (d = &IDENTIFIER_BINDING (name)->scope->names;
 	       *d;
-	       d = &DECL_CHAIN (*d))
+	       d = &TREE_CHAIN (*d))
 	    if (*d == old
 		|| (TREE_CODE (*d) == TREE_LIST
 		    && TREE_VALUE (*d) == old))
@@ -2168,7 +2168,7 @@  push_overloaded_decl (tree decl, int flags, bool is_friend)
 		else
 		  /* Build a TREE_LIST to wrap the OVERLOAD.  */
 		  *d = tree_cons (NULL_TREE, new_binding,
-				  DECL_CHAIN (*d));
+				  TREE_CHAIN (*d));
 
 		/* And update the cxx_binding node.  */
 		IDENTIFIER_BINDING (name)->value = new_binding;
diff --git a/gcc/testsuite/g++.dg/pr45049-1.C b/gcc/testsuite/g++.dg/pr45049-1.C
new file mode 100644
index 0000000..7863a6b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr45049-1.C
@@ -0,0 +1,15 @@ 
+namespace n1 {
+  void modf ();
+}
+
+namespace n2 {
+  void trunc ();
+  void modf ();
+}
+    
+void max ()
+{
+  using n1::modf;
+  using n2::trunc;
+  using n2::modf;
+}
diff --git a/gcc/testsuite/g++.dg/pr45049-2.C b/gcc/testsuite/g++.dg/pr45049-2.C
new file mode 100644
index 0000000..ea1f6d6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr45049-2.C
@@ -0,0 +1,7 @@ 
+void foo()
+{
+  void bar(int);
+  void baz(int);
+  void baz(void);
+  void bar(void);
+}