Bug 15503 - [3.4/4.0 regression] nested template problem
|
Bug#:
15503
|
Product: gcc
|
Version: 3.4.0
|
|
Host: i686-pc-gnu-linux
|
Target: i686-pc-gnu-linux
|
Build: i686-pc-gnu-linux
|
|
Status: RESOLVED
|
Severity: normal
|
Priority: P2
|
|
Resolution: FIXED
|
Assigned To: giovannibajo@libero.it
|
Reported By: mark.a.anders@intel.com
|
|
Component: c++
|
Target Milestone: 3.4.1
|
|
Summary: [3.4/4.0 regression] nested template problem
|
|
Keywords: patch, rejects-valid
|
|
Opened: 2004-05-17 20:12
|
|
Description:
|
Last confirmed: 2004-05-17 20:43
|
Opened: 2004-05-17 20:12
|
For the following code, the compilation fails at the NProperty constructor. I
have tried numerous ways of naming the inherited constructor, none of which
compile in gcc 3.4. This compiles with gcc 3.3.3 but not with gcc 3.4.
Thanks
--------------------------------
class I {
public:
class Type;
template<class T> class Object;
};
class I::Type {
public:
class Property;
};
template<class T>
class I::Object {
public:
template<class D> class Property;
};
class I::Type::Property {
};
template<class T>
template<class D>
class I::Object<T>::Property : public I::Type::Property {
public:
Property(D T::*d) : data(d) { }
private:
D T::*data;
};
class C : public I::Object<C> {
public:
template<class T> class NProperty :
public I::Object<T>::template Property<int> {
public:
NProperty(int T::*d);
};
};
template<class T>
C::NProperty<T>::NProperty(int T::*d) :
I::Object<T>::template Property<int>(d) { }
int main() {
return 0;
}
I do not know if this is valid C++ (I think it is not, ICC6.0 rejects it in
strict mode).
The way I was able to compile it with 3.4.0, is replace the construtor with:
template<class T>
C::NProperty<T>::NProperty(int T::*d) :
Property<int>(d) { }
I'm sure this is legal, and icc7.1 also accepts it. Here is something
smaller:
------------------
template <typename> struct O {
template <typename> struct I {};
};
template <typename T>
struct S : O<T>::template I<int> {
S() : O<T>::template I<int>() { } ;
};
---------------------
g/x> /home/bangerth/bin/gcc-3.3.4-pre/bin/c++ -c x.cc
g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ -c x.cc
x.cc: In constructor `S<T>::S()':
x.cc:7: error: expected class-name before "template"
x.cc:7: error: expected `(' before "template"
x.cc:7: error: expected `{' before "template"
g/x> /home/bangerth/bin/gcc-3.5-pre/bin/c++ -c x.cc
x.cc: In constructor `S<T>::S()':
x.cc:7: error: expected class-name before "template"
x.cc:7: error: expected `(' before "template"
x.cc:7: error: expected `{' before "template"
In other words, this is a regression.
W.
I need to know which way to take with this. In my reading of the standard, the
keyword 'template' to name nested dependent templates is not allowed in neither
the base-specifier nor the mem-initializer clause. The grammar explicitally
says:
base-specifier:
::opt nested-name-specifieropt class-name
virtual access-specifieropt ::opt nested-name-specifier[opt] class-name
access-specifier virtualopt ::opt nested-name-specifier[opt] class-name
mem-initializer-id:
::opt nested-name-specifier[opt] class-name
identifier
And there is no "template[opt]". After all, it makes sense as a symbol '<' in
that context can only be the start of a template argument list.
This would also match what happens with typename, which is more explicitally
disallowed in those contexts ([temp.res]/5): "The keyword typename is not
permitted in a base-specifier or in a mem-initializer; in these contexts a
qualified-name that depends on a template-parameter (14.6.2) is implicitly
assumed to be a type name."
Gaby, do you agree with my reading of the standard? If so, I can make a patch
that emits a proper diagnostic when 'template' is found in those contexts, and
fix the rejects-valid shown in this bug (if you remove 'template' from the
testcase, it still does not accept it).
The code in Comment #2 is not allowed by the standard.
This is DR 343, which comes from DR 314, which was opened by me. It looks like
the committee will eventually allow both the version with the "template"
keyword, and the version without, and that without the keyword the parser should
still assume that it is present. Right now, the standard provides no way
whatsoever to accomplish the desired functionality.
I'll look into what fixing this would require, but I'm not eager to make major
revisions in this area for 3.4.1; they'll likely be somewhat risky.
I have a patch for this. I'll make the 'template' keyword required in this
context, much like as we do for the base-specifier.
*** Bug 14566 has been marked as a duplicate of this bug. ***
Subject: Re: [3.4/3.5 regression] nested template problem
giovannibajo at libero dot it wrote:
>------- Additional Comments From giovannibajo at libero dot it 2004-06-02 11:19 -------
>Patch posted, waiting for review:
>http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00101.html
>
>
OK, thanks.
Fixed for GCC 3.4.1 and GCC 3.5.0. Thank your for your report!