public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* c++/10394: type inference gets confused during template instantiation
@ 2003-04-13 21:36 colby
0 siblings, 0 replies; 3+ messages in thread
From: colby @ 2003-04-13 21:36 UTC (permalink / raw)
To: gcc-gnats
>Number: 10394
>Category: c++
>Synopsis: type inference gets confused during template instantiation
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: rejects-legal
>Submitter-Id: net
>Arrival-Date: Sun Apr 13 21:36:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Christopher Colby
>Release: 3.2.2
>Organization:
>Environment:
Windows XP
>Description:
Enclosed is a small test program with class A templated by <class T> and class C templated by <class V>. C expects V to define a type V::X and instantiates A with that type. In C's constructor, there are two occurrences of A<typename V::X>. The first occurrence correctly instantiates A with V::X, but the second occurrence erroneously instantiates A with V, thus causing the compiler to reject the program.
Tweaking the enclosed demonstration program in almost any way makes this error disappear. For instance, line #1 compiles, but line #2 generates the type error:
#1 C<E> c(A<int>());
#2 A<int> a; C<E> c(a);
Also, removing the unused template argument from A's templated subclass B also eliminates the type error.
>How-To-Repeat:
Read the comments in main() before compiling the program.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="test.cpp"
Content-Disposition: inline; filename="test.cpp"
template <class T> class A {
public:
template <class U> class B {};
void f(B<int>) {}
};
template <class V> class C {
public:
C(A<typename V::X> a) { a.f(A<typename V::X>::B<int>()); }
};
template <class V> class D {
public:
D(A<typename V::X>* a) { a->f(A<typename V::X>::B<int>()); }
};
class E {
public:
typedef int X;
};
int main() {
A<int> a;
// When you uncomment one of the following four lines...
// C<E> c(A<int>()); // okay; see [1] below.
// C<E> c(a); // compile error; see [2] below.
// D<E> d(new A<int>()); // compile error; see [3] below.
// D<E> d(&a); // compile error; see [4] below.
}
/*
c:\cygwin\home\Christopher Colby\df>g++ -v
g++ -v
Reading specs from /usr/lib/gcc-lib/i686-pc-cygwin/3.2.2/specs
Configured with: ../src/configure --enable-languages=c,c++,f77,java --enable-libgcj --enable-threads=posix --with-system-zlib --enable-nls --without-included-gettext --enable-interpreter --disable-sjlj-exceptions --disable-version-specific-runtime-libs --enable-shared --enable-haifa --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --includedir=/nonexistent/include --libexecdir=/usr/sbin
Thread model: posix
gcc version 3.2.2
[1]
c:\cygwin\home\Christopher Colby\df>g++ test.cpp
g++ test.cpp
[2]
c:\cygwin\home\Christopher Colby\df>g++ test.cpp
g++ test.cpp
test.cpp: In constructor `C<V>::C(A<V::X>) [with V = E]':
test.cpp:28: instantiated from here
test.cpp:9: no matching function for call to `A<int>::f(A<E>::B<int>)'
test.cpp:4: candidates are: void A<T>::f(A<T>::B<int>) [with T = int]
[3]
c:\cygwin\home\Christopher Colby\df>g++ test.cpp
g++ test.cpp
test.cpp: In constructor `D<V>::D(A<V::X>*) [with V = E]':
test.cpp:29: instantiated from here
test.cpp:14: no matching function for call to `A<int>::f(A<E>::B<int>)'
test.cpp:4: candidates are: void A<T>::f(A<T>::B<int>) [with T = int]
[4]
c:\cygwin\home\Christopher Colby\df>g++ test.cpp
g++ test.cpp
test.cpp: In constructor `D<V>::D(A<V::X>*) [with V = E]':
test.cpp:30: instantiated from here
test.cpp:14: no matching function for call to `A<int>::f(A<E>::B<int>)'
test.cpp:4: candidates are: void A<T>::f(A<T>::B<int>) [with T = int]
*/
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: c++/10394: type inference gets confused during template instantiation
@ 2003-04-14 1:26 Giovanni Bajo
0 siblings, 0 replies; 3+ messages in thread
From: Giovanni Bajo @ 2003-04-14 1:26 UTC (permalink / raw)
To: nobody; +Cc: gcc-prs
The following reply was made to PR c++/10394; it has been noted by GNATS.
From: "Giovanni Bajo" <giovannibajo@libero.it>
To: <colby@alum.mit.edu>,
<gcc-gnats@gcc.gnu.org>,
<gcc-bugs@gcc.gnu.org>,
<nobody@gcc.gnu.org>,
<gcc-prs@gcc.gnu.org>
Cc: "Wolfgang Bangerth" <bangerth@ices.utexas.edu>
Subject: Re: c++/10394: type inference gets confused during template instantiation
Date: Mon, 14 Apr 2003 03:24:12 +0200
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&p
r=10394
Your code is ill-formed, and correctly rejected by any GCC version I have
(even if the error message could use a lifting).
To invoke correctly the function, you have to use this syntax:
a.f(typename A<typename V::X>::template B<int>());
Because:
- B<> is a nested template within A<>. A<> is dependent on C's template
parameter, so the keyword 'template' is needed in front of it to
disambiguate the parser.
- The whole expression A<typename V::X>::template B<int> refers to a type
name, which is dependent on C's template paremter, so the keyword 'typename'
is needed in front of it to disambiguate the parser.
Your line marked as [1] compiles because it is a function declaration, not
an object instantiation. Specifically, you're declaring a function called
"c" which returns an object of type C<E>, and accepts as parameter a pointer
to a function which gets no parameters and returns a A<int>.
Nonetheless, I found a regression on the mainline while playing with this:
-------------------------------------------------------
template <class T>
struct A
{
template <class U>
class B {};
};
template <class V>
struct C
{
C()
{
A<typename V::X>::template B<int> k;
}
};
struct E
{
typedef int X;
};
template struct C<E>;
int main()
{}
-------------------------------------------------------
pr10394.cpp: In constructor `C<V>::C()':
pr10394.cpp:13: error: expected `;'
pr10394.cpp: In constructor `C<V>::C() [with V = E]':
pr10394.cpp:22: instantiated from here
pr10394.cpp:13: internal compiler error: in resolve_offset_ref, at
cp/init.c:
1841
Please submit a full bug report,
on 3.4 20030413. Since the code is ill-formed (missing 'typename' keyword at
the start of the definition of k), this is a 3.4 regression,
ice-on-illegal-code. Previous versions (2.95 -> 3.3) reports some kind of
(unreadable) error message at least.
Giovanni Bajo
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: c++/10394: type inference gets confused during template instantiation
@ 2003-04-14 12:00 ehrhardt
0 siblings, 0 replies; 3+ messages in thread
From: ehrhardt @ 2003-04-14 12:00 UTC (permalink / raw)
To: colby, gcc-bugs, gcc-prs, nobody
Synopsis: type inference gets confused during template instantiation
State-Changed-From-To: open->closed
State-Changed-By: cae
State-Changed-When: Mon Apr 14 12:00:29 2003
State-Changed-Why:
Not a bug. The remaining ICE found by Giovanni is now PR 10398.
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=10394
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-04-14 12:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-13 21:36 c++/10394: type inference gets confused during template instantiation colby
2003-04-14 1:26 Giovanni Bajo
2003-04-14 12:00 ehrhardt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).