Bug 6709 - [DR743] decltype cannot be used with the :: operator
Summary: [DR743] decltype cannot be used with the :: operator
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.1
: P3 normal
Target Milestone: 4.7.0
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
: 10767 12379 20551 30837 43285 43780 (view as bug list)
Depends on:
Blocks:
 
Reported: 2002-05-17 15:46 UTC by marco
Modified: 2011-07-22 21:24 UTC (History)
13 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-04-19 09:38:32


Attachments
a.cc (104 bytes, text/plain)
2003-05-21 15:16 UTC, marco
Details

Note You need to log in before you can comment on or make changes to this bug.
Description marco 2002-05-17 15:46:01 UTC
Using typeof() together with the :: operator results in a parsing error, though typeof() returns a type-expression where :: is applyable (class type etc.). 

The message is 'parse error before ";" token'

Release:
gcc-3.1

Environment:
$ uname -a
CYGWIN_NT-5.0 OBLOMOW 1.3.10(0.51/3/2) 2002-02-25 11:14 i686 unknown

Administrator@OBLOMOW ~
$ gcc -v
Reading specs from /usr/lib/gcc-lib/i686-pc-cygwin/3.1/specs
Configured with: ../gcc-3.1/configure --program-suffix=-3.1 --enable-shared --enable-threads=win32 --enable-languages=c,
c++,objc,f77 --enable-win32-registry : (reconfigured) ../gcc-3.1/configure --prefix=/usr --program-suffix=-3.1 --enable-
shared --enable-threads=win32 --enable-languages=c,c++,objc,f77 --enable-win32-registry
Thread model: win32
gcc version 3.1

How-To-Repeat:
The file attachment 'a.cc' produces the message for line 10.
Comment 1 Kriang Lerdsuwanakij 2002-05-22 07:21:39 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirmed.
Comment 2 Wolfgang Bangerth 2003-05-01 15:58:43 UTC
From: Wolfgang Bangerth <bangerth@ices.utexas.edu>
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: Re: c++/6709
Date: Thu, 1 May 2003 15:58:43 -0500 (CDT)

 A slight variant ICEs with present 3.4 mainline. I opened PR 10586 for 
 this.
 
 W.
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth              email:            bangerth@ices.utexas.edu
                                www: http://www.ices.utexas.edu/~bangerth/
Comment 3 Andrew Pinski 2003-09-23 19:35:58 UTC
*** Bug 12379 has been marked as a duplicate of this bug. ***
Comment 4 hakonrk 2003-11-24 23:05:29 UTC
Just noticed this bug myself.  You can work around it by creating
a temporary typedef.  E.g.,

  typedef typeof(obj) T;
  T::size_type s;

Still annoying though.
Comment 5 Andrew Pinski 2004-02-13 05:39:30 UTC
The error message is now:
tests/pr6709.cc: In function `int main()':
tests/pr6709.cc:10: error: `X' in namespace `::' does not name a type
which shows what is happening now.
Comment 6 Andrew Pinski 2005-03-19 13:48:46 UTC
*** Bug 20551 has been marked as a duplicate of this bug. ***
Comment 7 Andrew Pinski 2007-02-17 20:02:04 UTC
*** Bug 30837 has been marked as a duplicate of this bug. ***
Comment 8 Andrew Pinski 2007-08-12 02:05:14 UTC
Hmm, I wonder what the current draft of C++0x says of decltype with this respect (right now we reject it).
Comment 9 Wolfgang Bangerth 2010-03-08 14:29:25 UTC
*** Bug 43285 has been marked as a duplicate of this bug. ***
Comment 10 Jonathan Wakely 2010-03-08 14:40:32 UTC
(In reply to comment #8)
> Hmm, I wonder what the current draft of C++0x says of decltype with this
> respect (right now we reject it).
> 

In Bug 43285 Comment 1 I said that I think decltype is invalid in this context, which would make this a documentation bug for C++.

In the C++0x grammar:

simple-type-specifier:
  ::_opt nested-name-specifier_opt type-name
  ...
  decltype ( expression )

nested-name-specifier:
  type-name ::
  namespace-name ::
  nested-name-specifier identifier ::
  nested-name-specifier template_opt simple-template-id ::

type-name:
  class-name
  enum-name
  typedef-name

So decltype(expression) cannot appear in a nested-name-specifier
Comment 11 Jonathan Wakely 2010-03-08 14:46:16 UTC
(In reply to comment #4)
> Just noticed this bug myself.  You can work around it by creating
> a temporary typedef.  E.g.,
> 
>   typedef typeof(obj) T;
>   T::size_type s;
> 
> Still annoying though.

This workaround is required for decltype, I don't see why typeof should be any different.

The reason is that decltype(obj) doesn't declare a new type-name, it is only a simple-type-specifier, which cannot appear in a nested-name-specifier.

The typedef workaround introduces a new type-name, which is allowed in a nested-name-specifier.
Comment 12 Manuel López-Ibáñez 2010-03-08 15:59:57 UTC
*** Bug 43285 has been marked as a duplicate of this bug. ***
Comment 13 Jonathan Wakely 2010-03-08 16:10:33 UTC
the decltype issue is http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#743

the proposed change is in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3031.pdf

suspending ...
Comment 14 Andrew Pinski 2010-04-18 06:48:45 UTC
*** Bug 43780 has been marked as a duplicate of this bug. ***
Comment 15 Faisal Vali 2010-04-18 12:56:04 UTC
I had (In reply to comment #14)
> *** Bug 43780 has been marked as a duplicate of this bug. ***
> 

The DR 743 has been voted into FCD (CD2) - shouldn't this be unsuspended?
thanks!
Comment 16 Jonathan Wakely 2010-04-19 09:38:31 UTC
Unsuspending, DR743 was recently resolved
Comment 17 Adam Butcher 2011-01-20 22:03:31 UTC
I have the beginnings of a fix for this (see the patch at http://gcc.gnu.org/ml/gcc-patches/2011-01/msg01392.html); currently there is a bug with my impl where any name on the right of `decltype(x)::' at the front of a nested-name-specifier is considered a non-type unless qualified with typename.

I.e. given:

   struct X { typedef int I; }
   X x;
   
instead of:

   decltype(x)::I i = 7;

the user must currently write:

   typename decltype(x)::I i = 7;

as if decltype(x) was somehow dependent on a template parameter -- which it obviously isn't as there is no template it sight.

Otherwise the patch seems close.
Comment 18 cheburnae 2011-04-06 14:23:53 UTC
A simple workaround:

template <class T>
struct TypeEcho {
	typedef T R;
};

#define TYPE_OF(expr) TypeEcho<typeof (*&expr)>::R

template <class T>
void foo() {
	typename TYPE_OF(std::vector<T>())::value_type();
}

void foo2() {
	TYPE_OF(std::vector<int>())::value_type();
	foo<int>();
}
Comment 19 Jason Merrill 2011-07-20 14:21:09 UTC
Author: jason
Date: Wed Jul 20 14:21:05 2011
New Revision: 176513

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=176513
Log:
	PR c++/6709 (DR 743)
	PR c++/42603 (DR 950)
gcc/cp/
	* parser.c (token_is_decltype, cp_lexer_next_token_is_decltype): New.
	(cp_parser_nested_name_specifier_opt): Allow decltype.
	(cp_parser_qualifying_entity): Likewise.
	(cp_parser_decltype): Replace source tokens with CPP_DECLTYPE.
	(cp_parser_simple_type_specifier): Handle decltype as scope.
	(cp_parser_base_specifier): Allow decltype.
	(cp_parser_base_clause): Don't crash on null base.
	* parser.h (CPP_KEYWORD, CPP_TEMPLATE_ID): Move to c-common.h.
	(CPP_NESTED_NAME_SPECIFIER, N_CP_TTYPES): Likewise.
gcc/c-family/
	* c-common.h (CPP_KEYWORD, CPP_TEMPLATE_ID): Move from cp/parser.h.
	(CPP_NESTED_NAME_SPECIFIER, N_CP_TTYPES): Likewise.
	(CPP_DECLTYPE): New.
	* c-common.c (c_parse_error): Handle CPP_DECLTYPE.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/decltype21.C
Modified:
    trunk/gcc/c-family/ChangeLog
    trunk/gcc/c-family/c-common.c
    trunk/gcc/c-family/c-common.h
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
    trunk/gcc/cp/parser.h
    trunk/gcc/testsuite/ChangeLog
Comment 20 Jason Merrill 2011-07-22 21:24:35 UTC
Implemented for 4.7.