| Summary: | typename in a using declaration not supported | ||
|---|---|---|---|
| Product: | gcc | Reporter: | Jim Apple <japple> |
| Component: | c++ | Assignee: | fabien |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | CC: | akim.demaille, fang, gcc-bugs, gcc, ian, igodard, ilpoilves, jbeulich, joao.eiras, jwakely.gcc, l.jirkovsky, pinskia, pipping, reichelt, rleigh, smelkov, starlight |
| Priority: | P2 | Keywords: | monitored, rejects-valid |
| Version: | 3.3.1 | ||
| Target Milestone: | 4.7.0 | ||
| Host: | i686-pc-linux-gnu | Target: | i686-pc-linux-gnu |
| Build: | i686-pc-linux-gnu | Known to work: | |
| Known to fail: | 2.95.3, 3.0.4, 3.2.3, 3.3.3, 3.4.0, 4.0.0 | Last reconfirmed: | 2010-06-07 12:43:20 |
| Bug Depends on: | |||
| Bug Blocks: | 23211 | ||
Yes. I flag this as a regression since the valid code used to be accepted thanks to the implicit typename extension. Ehm, sorry, this is obviously a regression only for 3.4 and mainline. The problem is that our USING_DECL doesn't record the "typename", that is the fact that it is a type which is imported through it. This used to work thanks to the implicit type name extension, I believe. This is expected behavior, given that G++ does not implement the new using-declaration semantics, but rather the old ARM-style access-declaration semantics. This bug will not be fixed in GCC 3.4.x, so I have changed the target milestone to 3.5.0. It's not a regression. The code never compiled - in some versions we only get a warning in addition to the error. I therefore removed the target milestone. *** Bug 14778 has been marked as a duplicate of this bug. *** *** Bug 18541 has been marked as a duplicate of this bug. *** *** Bug 21484 has been marked as a duplicate of this bug. *** *** Bug 15260 has been marked as a duplicate of this bug. *** Also fails with GCC 4.1.3. Also fails with GCC 4.2.3. *** Bug 37141 has been marked as a duplicate of this bug. *** *** Bug 46690 has been marked as a duplicate of this bug. *** *** Bug 46748 has been marked as a duplicate of this bug. *** Author: fabien Date: Tue Dec 13 18:46:58 2011 New Revision: 182292 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182292 Log: gcc/testsuite/ChangeLog 2011-12-11 Fabien Chene <fabien@gcc.gnu.org> PR c++/14258 * g++.dg/template/using16.C: New. * g++.dg/template/using17.C: New. gcc/cp/ChangeLog 2011-12-11 Fabien Chene <fabien@gcc.gnu.org> PR c++/14258 * cp-tree.h (USING_DECL_TYPENAME_P): New macro. * parser.c (cp_parser_nonclass_name): Handle using declarations that refer to a dependent type. (cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if the using declaration refers to a dependent type. Added: trunk/gcc/testsuite/g++.dg/template/using16.C trunk/gcc/testsuite/g++.dg/template/using17.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-tree.h trunk/gcc/cp/parser.c trunk/gcc/testsuite/ChangeLog Fixed. *** Bug 52620 has been marked as a duplicate of this bug. *** I'm a bit confused here. Please consider the following piece of code:
<<SNIP
template <typename T> struct A {
typedef int type;
};
template <typename T> struct B : public A<T> {
using typename A<T>::type;
static const int block_size = type::block_size;
};
<<SNAP
Compiling it with gcc 4.8.2 yields
foo.hh:9:33: error: ‘type’ is not a class, namespace, or enumeration
whereas clang 3.4 will happily accept it(*).
At a first glance, this bug appears to address issues such as this, so that gcc 4.8.2 should be fine. This does not seem to be the case, however -- the test case provided by Jim Apple compiles but the one above does not; I'll have to assume the bug was only partly fixed?
(*) I orginally thought this was not valid and filed a clang bug: http://llvm.org/bugs/show_bug.cgi?id=18574
That example's a bit misleading, because 'int' really isn't a class, namespace or enumeration, but the error's wrong because there could be a specialization of A<>, and the same error is produced even if A<T>::type is a class type. Fabien, the fix doesn't seem to work with nested-name-specifiers, do you remember if there's another bug report about that case? (In reply to Jonathan Wakely from comment #19) > Fabien, the fix doesn't seem to work with nested-name-specifiers, do you > remember if there's another bug report about that case? Yes, it's probably PR58047. (In reply to Jonathan Wakely from comment #19) > That example's a bit misleading, because 'int' really isn't a class, > namespace or enumeration, but the error's wrong because there could be a > specialization of A<>, and the same error is produced even if A<T>::type is > a class type. You're right. This will reproduce the problem, too: <<SNIP struct C; template <typename T> struct A { typedef C type; }; template <typename T> struct B : public A<T> { using typename A<T>::type; static const int block_size = type::block_size; }; <<SNAP I guess my test case is a reduction/duplicate of PR37140. |
The following code: template<typename T> struct A { typedef A type; }; template<typename T> struct B : A<T> { using typename A<T>::type; type f(type); }; Give a "syntax error before typename." Without typename in the using declaration, however, type in B<T> is not a typename, so f's declaration is not well formed. Because the "typename" is necessary, this is not the same as bug 3033.