Message ID | 20100818132959.GP25394@codesourcery.com |
---|---|
State | New |
Headers | show |
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
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
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 --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); +}