Bug 21087 - [4.0 Regression] ICE in do_nonmember_using_decl
Summary: [4.0 Regression] ICE in do_nonmember_using_decl
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: 4.0.1
Assignee: Alexandre Oliva
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2005-04-18 14:50 UTC by Stefan Straßer
Modified: 2005-04-25 20:54 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 4.1.0
Known to fail:
Last reconfirmed: 2005-04-19 05:27:57


Attachments
testcase (88.39 KB, application/octet-stream)
2005-04-18 14:51 UTC, Stefan Straßer
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Straßer 2005-04-18 14:50:02 UTC
out.cpp:17279: internal compiler error: in do_nonmember_using_decl, at
cp/name-lookup.c:2072
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.

I think the code is valid, though I'm not sure since I don't know what's the
cause for this, the line reported, 17279, definitly is valid.

attaching source.

ICE with: gcc version 4.0.0 20050418 (prerelease)
works with: gcc-Version 3.4.4 20050314 (prerelease) (Debian 3.4.3-12)
Comment 1 Stefan Straßer 2005-04-18 14:51:18 UTC
Created attachment 8676 [details]
testcase
Comment 2 Andrew Pinski 2005-04-18 19:04:17 UTC
Reduced testcase:
extern "C" signed int toupper(signed int __c) throw();
namespace std
{
  template< typename a > a toupper(a,int){}
  using ::toupper;
}


Note this has to do with builtin functions as if I cange toupper to be named something different I don't 
get an ICE.
Comment 3 Alexandre Oliva 2005-04-19 21:45:55 UTC
Subject: [PR c++/21087] don't keep builtin anticipated decl, override it with actual declaration

When push_overloaded_decl() was passed a new declaration that matches
a builtin decl, it would verify that the declarations matched and, if
so, leave the existing (built-in) declaration alone.

The intended behavior is to merge the built-in declaration with the
new declaration, into the location of the built-in declaration.

The problem is that duplicate_decl() doesn't perform such merging when
the new declaration is a template decl, and then we end up with an
overload involving the template decl and the anticipated built-in
decl.  However, overloads involving anticipated decls are something we
try to avoid, and actually check for elsewhere.

This patch fixes the code such that, if the existing decl is
anticipated and the two decls weren't merged, we discard the built-in
and use the new decl by itself.

Bootstrapped and regtested on amd64-linux-gnu.  Ok to install?

Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/21087
	* name-lookup.c (push_overloaded_decl): Do not overload with
	non-duplicate anticipated built-in.

Index: gcc/cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.113
diff -u -p -r1.113 name-lookup.c
--- gcc/cp/name-lookup.c 14 Mar 2005 14:51:14 -0000 1.113
+++ gcc/cp/name-lookup.c 19 Apr 2005 19:20:11 -0000
@@ -1883,6 +1883,13 @@ push_overloaded_decl (tree decl, int fla
 	      if (duplicate_decls (decl, fn) == fn)
 		POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fn);
 	    }
+
+	  /* We don't overload implicit built-ins.  duplicate_decls()
+	     may fail to merge the decls if the new decl is e.g. a
+	     template function.  */
+	  if (TREE_CODE (old) == FUNCTION_DECL
+	      && DECL_ANTICIPATED (old))
+	    old = NULL;
 	}
       else if (old == error_mark_node)
 	/* Ignore the undefined symbol marker.  */
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/21087
	* g++.dg/lookup/builtin2.C: New test.

Index: gcc/testsuite/g++.dg/lookup/builtin2.C
===================================================================
RCS file: gcc/testsuite/g++.dg/lookup/builtin2.C
diff -N gcc/testsuite/g++.dg/lookup/builtin2.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/lookup/builtin2.C 19 Apr 2005 19:20:27 -0000
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+/* PR c++/21087 */
+
+/* We used to overload the template function with the built-in
+   declaration, instead of replacing it as we should, and then barf at
+   the using decl because of a test that none of the overload set
+   members were anticipated built-ins.  */
+
+extern "C" signed int toupper(signed int __c) throw();
+namespace std
+{
+  template< typename a > a toupper(a,int){}
+  using ::toupper;
+}
+
+int f () {
+  std::toupper((signed int)'a');
+}

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}
Comment 4 Mark Mitchell 2005-04-22 00:58:55 UTC
Subject: Re: [PR c++/21087] don't keep builtin anticipated decl, override
 it with actual declaration

Alexandre Oliva wrote:
> When push_overloaded_decl() was passed a new declaration that matches
> a builtin decl, it would verify that the declarations matched and, if
> so, leave the existing (built-in) declaration alone.
> 
> The intended behavior is to merge the built-in declaration with the
> new declaration, into the location of the built-in declaration.
> 
> The problem is that duplicate_decl() doesn't perform such merging when
> the new declaration is a template decl, and then we end up with an
> overload involving the template decl and the anticipated built-in
> decl.  However, overloads involving anticipated decls are something we
> try to avoid, and actually check for elsewhere.
> 
> This patch fixes the code such that, if the existing decl is
> anticipated and the two decls weren't merged, we discard the built-in
> and use the new decl by itself.
> 
> Bootstrapped and regtested on amd64-linux-gnu.  Ok to install?

OK.

Yet another reason we should generate builtins lazily, as needed...

Comment 5 GCC Commits 2005-04-22 16:57:47 UTC
Subject: Bug 21087

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	aoliva@gcc.gnu.org	2005-04-22 16:57:24

Modified files:
	gcc/cp         : ChangeLog name-lookup.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/lookup: builtin2.C 

Log message:
	gcc/cp/ChangeLog:
	PR c++/21087
	* name-lookup.c (push_overloaded_decl): Do not overload with
	non-duplicate anticipated built-in.
	gcc/testsuite/ChangeLog:
	PR c++/21087
	* g++.dg/lookup/builtin2.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4716&r2=1.4717
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/name-lookup.c.diff?cvsroot=gcc&r1=1.114&r2=1.115
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5381&r2=1.5382
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/lookup/builtin2.C.diff?cvsroot=gcc&r1=1.1&r2=1.2

Comment 6 Alexandre Oliva 2005-04-23 02:47:05 UTC
Subject: Re: [PR c++/21087] don't keep builtin anticipated decl, override it with actual declaration

On Apr 21, 2005, Mark Mitchell <mark@codesourcery.com> wrote:

> Alexandre Oliva wrote:
>> When push_overloaded_decl() was passed a new declaration that matches
>> a builtin decl, it would verify that the declarations matched and, if
>> so, leave the existing (built-in) declaration alone.
>> The intended behavior is to merge the built-in declaration with the
>> new declaration, into the location of the built-in declaration.
>> The problem is that duplicate_decl() doesn't perform such merging
>> when
>> the new declaration is a template decl, and then we end up with an
>> overload involving the template decl and the anticipated built-in
>> decl.  However, overloads involving anticipated decls are something we
>> try to avoid, and actually check for elsewhere.
>> This patch fixes the code such that, if the existing decl is
>> anticipated and the two decls weren't merged, we discard the built-in
>> and use the new decl by itself.
>> Bootstrapped and regtested on amd64-linux-gnu.  Ok to install?

> OK.

Ok for 4.0 branch as well?  The same patch applies cleanly there, and
it's just completed bootstrap and regtesting on amd64-linux-gnu in the
branch as well.

Comment 7 Mark Mitchell 2005-04-24 17:05:39 UTC
Subject: Re: [PR c++/21087] don't keep builtin anticipated decl, override
 it with actual declaration

Alexandre Oliva wrote:

> 
> Ok for 4.0 branch as well?  The same patch applies cleanly there, and
> it's just completed bootstrap and regtesting on amd64-linux-gnu in the
> branch as well.

OK.

Though it's very polite of you to ask, you don't really need my 
persmission: fixes for regressions that have been accepted for mainline 
are automatically OK for 4.0 if properly tested.

Thanks,

Comment 8 GCC Commits 2005-04-25 20:54:49 UTC
Subject: Bug 21087

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-4_0-branch
Changes by:	aoliva@gcc.gnu.org	2005-04-25 20:54:27

Modified files:
	gcc/cp         : ChangeLog name-lookup.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/lookup: builtin2.C 

Log message:
	gcc/cp/ChangeLog:
	PR c++/21087
	* name-lookup.c (push_overloaded_decl): Do not overload with
	non-duplicate anticipated built-in.
	gcc/testsuite/ChangeLog:
	PR c++/21087
	* g++.dg/lookup/builtin2.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.4648.2.35&r2=1.4648.2.36
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/name-lookup.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.109.4.1&r2=1.109.4.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.5084.2.138&r2=1.5084.2.139
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/lookup/builtin2.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.2.2.1

Comment 9 Alexandre Oliva 2005-04-25 20:54:57 UTC
Fixed