Bug 13549

Summary: [4.2/4.3/4.4 regression] Problem compiling Boost.Python test
Product: gcc Reporter: Ralf W. Grosse-Kunstleve <RWGrosse-Kunstleve>
Component: c++Assignee: Jason Merrill <jason>
Status: RESOLVED FIXED    
Severity: normal CC: dave, debian-gcc, gcc-bugs, jason
Priority: P2 Keywords: rejects-valid
Version: 3.4.0   
Target Milestone: 4.4.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2009-03-05 00:44:57
Bug Depends on:    
Bug Blocks: 12944    
Attachments: Preprocessed source, gzipped
g++ error message
g++ error message, reformatted using stlfilt

Description Ralf W. Grosse-Kunstleve 2004-01-02 18:48:17 UTC
gcc snapshot from 2003/12/30, ca. 7:40am PST
Configured with: ../gcc/configure --prefix=/usr/local_cci/gcc_cvs_2003_12_30 --
enable-languages=c,c++
Redhat Linux 8.0

One of our regression test for Boost.Python does not compile with g++
(GCC) 3.4.0 20031230 (experimental). We are puzzled by the error
message. David Abrahams, principle author of the Boost.Python library,
writes:

>I don't have a clue.  It seems to be failing to find the overload of
>the get function in make_constructor.hpp.
>
><shrug>

The same code works with many other compilers incl. earlier gcc's. I
will attach a preprocessed file that can be used to reproduce the
problem:

% g++ -fPIC -ftemplate-depth-120 -w -DNDEBUG -O3 -DBOOST_PYTHON_MAX_BASES=2 -
I/net/worm/scratch1/rwgk/rc1310/boost -I/usr/include/python2.2 -
E /net/worm/scratch1/rwgk/rc1310/boost/libs/python/test/injected.cpp > 
injected_pp.cpp

% g++ -fPIC -ftemplate-depth-120 -w -O3 injected_pp.cpp >& injected_pp_error

% g++ -fPIC -ftemplate-depth-120 -w -O3 injected_pp.cpp |& perl 
~/stlfilt/gSTLFilt.pl > injected_pp_error_stlfilt

The files are also available here:

http://cci.lbl.gov/~rwgk/bugs/gcc340/injected_pp.cpp
http://cci.lbl.gov/~rwgk/bugs/gcc340/injected_pp_error
http://cci.lbl.gov/~rwgk/bugs/gcc340/injected_pp_error_stlfilt

The full source code (complete boost tree, release candidate branch for
version 1.31.0) is also available:

http://cci.lbl.gov/~rwgk/bugs/gcc340/boost_rc1310_2004_01_02_1016.tar.gz

Remark: the release candidate is patched already to work around
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13530
Comment 1 Ralf W. Grosse-Kunstleve 2004-01-02 18:49:33 UTC
Created attachment 5401 [details]
Preprocessed source, gzipped
Comment 2 Ralf W. Grosse-Kunstleve 2004-01-02 18:50:30 UTC
Created attachment 5402 [details]
g++ error message
Comment 3 Ralf W. Grosse-Kunstleve 2004-01-02 18:51:08 UTC
Created attachment 5403 [details]
g++ error message, reformatted using stlfilt
Comment 4 Ralf W. Grosse-Kunstleve 2004-01-02 19:05:13 UTC
Another remark: we had to apply two trivial patches to the original
Boost.Python code in order to make gcc 3.4.0 work for all other
regression tests:

http://cvs.sourceforge.net/viewcvs.py/boost/boost/boost/python/long.hpp?
r1=1.11&r2=1.12
http://cvs.sourceforge.net/viewcvs.py/boost/boost/libs/python/src/module.cpp?
r1=1.21&r2=1.22

Could there be a general problem with the gcc 3.4.0 parser?
Could bug 13549 be just another manifestation of the same problem?
Comment 5 Andrew Pinski 2004-01-02 21:15:59 UTC
Could you make the next release candidate not have the work around for PR 13530 aka bug 12573  
as it will be fixed before the release of 3.4?

But aways the problem looks like is that PyObject* get(offset_args<BaseArgs,Offset> const& args_ ) 
is not defined until after 47482 (line numbers do not match but that does not matter) (this is where 
the invalid initialization of reference error is) until line 61811.

I do not know if this should work like this or if this is really a problem in GCC.
Comment 6 Andrew Pinski 2004-01-02 22:24:55 UTC
I found a simple testcase which shows this:

template <typename T> int g(int);
class h{};
template <typename T> int l(){h j; return g<T>(j);}
template <typename T> int g(const h&);
class j{};
int jj(){return l<j>();}

I can confirm this on the mainline.
From Phil's regression hunter: Search converges between 2002-12-27-trunk (#177) and 
2002-12-28-trunk (#178).  That is when the new parser went in.
Comment 7 Dave Abrahams 2004-01-02 22:40:56 UTC
I think the main question here is: must a function invoked with explicitly-
specified template arguments be found in phase 1 in order to be considered as 
candidates?

I think this program captures the question:

template <int n>
int f(char*);

template <class T>
int g(T x)
{
   return f<1>(x);
}


I'm not sure how to interpret 14.6.4.2, but I believe it is relevant.
Comment 8 Andrew Pinski 2004-01-03 01:49:05 UTC
I let someone else really decide but with my reading of 3.4.1 which 14.6.4.2 says apply, 
the code is invalid.
Most likely:
In all the cases listed in 3.4.1, the scopes are searched for a declaration in the order 
listed in each of the respective categories; name lookup ends as soon as a declaration is 
found for the name. If no declaration is found, the program is ill-formed. 
The scopes are before the template but then again ICC 6.0 accpets this.
Comment 9 Dave Abrahams 2004-01-03 02:55:40 UTC
It's not that simple.  There are two searches, one at the point of definition 
and another at the point of instantiation.  One way to read this is that in my 
little example, the first search finds the "f" that's defined there.  Since 
there has been no instantiation of g, the second search is never performed in 
the little example.  In the testcase, the required definition of "get" shows 
up before the point of instantiation.

Incidentally, not only ICC6 but also EDG's latest compiler accepts this code 
(http://www.comeaucomputing.com/tryitout).  EDG's Steve Adamczyk is sometimes 
known as "Mr. name lookup", so maybe you should ask him.
Comment 10 Andrew Pinski 2004-01-03 03:00:30 UTC
But that is why I said I would should let someone else to decide this for real.
Comment 11 Mark Mitchell 2004-01-04 23:02:38 UTC
The standard does not answer this question.

14.6.4.2 does not apply because that entire section applies only to a name that
"is an unqualified-id, but not a template-id".  In these test cases, the name is
a template-id, such as "g<T>".

I believe that a core issue should be opened for this case; I will send email to
the right people about that.

Until there is a resolution, I don't see a compelling reason to make a change to
G++, so I've removed the regression tags, and marked this bug as suspended.
Comment 12 Andrew Pinski 2004-02-16 05:22:05 UTC
I almost think DR 197, 213, and 225 is related.
Comment 13 Andrew Pinski 2004-02-23 01:06:50 UTC
*** Bug 14242 has been marked as a duplicate of this bug. ***
Comment 14 André Wöbbeking 2004-03-06 14:19:24 UTC
(In reply to comment #11) 
> Until there is a resolution, I don't see a compelling reason to make a 
change to 
> G++, so I've removed the regression tags, and marked this bug as suspended. 
 
I'm not sure if my BR #14242 is the same but it compiles on all other 
compilers I'm using (GCC < 3.4.0, Intel 7 and 8, MSVC 6 - 7.1), and I can't 
believe that bla(const double&) must be declared or even defined before the 
definition of foo(). 
 
 
André 
Comment 15 Giovanni Bajo 2004-03-06 19:15:05 UTC
Dave, your testcase in comment #7 is slightly different because the argument is 
dependent. In the reduced testcase proposed by Andrew in comment #6, the 
argument is not dependent. 
Comment 16 Jason Merrill 2009-03-03 20:02:52 UTC
I don't see a core issue about this question, but it seems pretty clear to me that since g<T> is dependent, and [temp.arg.explicit]/8 says that we should do arg-dependent lookup for template-ids (which we don't seem to do currently; we get that example wrong), then we should do late lookup for g<T> as well.

We ought to accept this test.  Unsuspending, re-marking as regression.
Comment 17 Jason Merrill 2009-03-05 00:44:57 UTC
That is, even though g<T>(j) does not have any dependent arguments, the call is dependent, so it should get arg-dependent lookup, which should find g(h) because it's in the associated namespace of j.
Comment 18 Jason Merrill 2009-03-05 02:49:29 UTC
Subject: Bug 13549

Author: jason
Date: Thu Mar  5 02:49:13 2009
New Revision: 144636

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=144636
Log:
        PR c++/13549
        * semantics.c (perform_koenig_lookup): Handle TEMPLATE_ID_EXPR.
        * parser.c (cp_parser_postfix_expression): Call it for
        TEMPLATE_ID_EXPR.
        * tree.c (is_overloaded_fn): Look through TEMPLATE_ID_EXPR.
        (get_first_fn): Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/template/koenig7.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
    trunk/gcc/cp/semantics.c
    trunk/gcc/cp/tree.c
    trunk/gcc/testsuite/ChangeLog

Comment 19 Jason Merrill 2009-03-05 02:51:27 UTC
Fixed for 4.4.  I'm not comfortable applying this to older release branches.