Bug 41786 - [4.4/4.5 regression] misparsing an object declaration - parameter may not have variably modified type
Summary: [4.4/4.5 regression] misparsing an object declaration - parameter may not hav...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.2
: P2 normal
Target Milestone: 4.4.4
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2009-10-21 19:42 UTC by jarausch
Modified: 2010-03-30 21:22 UTC (History)
1 user (show)

See Also:
Host: x86-64
Target: x86-64
Build: x86-64
Known to work: 4.3.4
Known to fail: 4.4.3
Last reconfirmed: 2010-03-09 22:33:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description jarausch 2009-10-21 19:42:24 UTC
The declaration 
form proj (space(V[i]), V_new_i, "mass");
of an object 'proj' of class 'form' is not recognized,
see below

#include <vector>
using std::vector;
#include <string>

struct space_component;
struct const_space_component;

template <class T>
class smart_pointer {
public:

// allocators:

	smart_pointer (T* p = 0);
	smart_pointer (const smart_pointer&);
	~smart_pointer ();
	smart_pointer& operator= (const smart_pointer&);

// accessors:

	const T* pointer    () const;
	const T& data       () const;
	const T* operator-> () const;
	const T& operator*  () const;

// modifiers:

	T* pointer ();
	T* operator-> ();
	T& data ();
	T& operator* ();

// implementation:

};

typedef int basis;

class spacerep {
public:
  typedef std::vector<basis>::size_type  size_type;
  spacerep();
};


class space : public smart_pointer<spacerep> {
public:
// typdefs:

    typedef spacerep::size_type size_type;
 
// allocator/deallocator:

    space ();
    space(const const_space_component&);

    space_component operator [] (size_type i_comp);
    const_space_component operator [] (size_type i_comp) const;
};

struct space_component {
    typedef space::size_type size_type;
    space_component();
    space_component(space& V, size_type i);
};
struct const_space_component {
    typedef space::size_type size_type;
    const_space_component();
    const_space_component(const space_component&);
};

class form {
public :
    form ();
    form (const space& X, const space& Y, const std::string& op_name, 
    	bool locked_boundaries=false);

};

int main() {
    	    space V, V_new_i;
            int i=1;
    	    form proj (space(V[i]), V_new_i, "mass");
/* error: parameter may not have variably modified type 
  'space [(((long unsigned int)(((long int)i) + -0x00000000000000001)) + 1)]'
*/

}
Comment 1 Andrew Pinski 2009-10-21 19:49:27 UTC
I don't think this is misparsing this at all.  This is one place in the C++ standard that says it should be parsed as a function declaration rather than a variable declaration to resolve an ambiguous between those two.
Comment 2 jarausch 2009-10-22 10:35:33 UTC
(In reply to comment #1)
> I don't think this is misparsing this at all.  This is one place in the C++
> standard that says it should be parsed as a function declaration rather than a
> variable declaration to resolve an ambiguous between those two.
> 


There are different opinions about that.
The current Comeau compiler does accept the code.

Here an answer James Kanze on the news group comp.lang.c++

First, there is absolutely no way that proj can be interpreted
as a function declaration; the string literal prevents that,
regardless of anything else.  Second, if "space" is the
name of a type (as it is in your code), »space(V[i])« is a
function declaration in any context that allows function
declarations.  The only contexts which allow declarations
other than at the statement level, however, is as part of other
declarations; the only context in which a function declaration
can be followed by a comma is as a parameter in another function
declaration.  Since in this case, the string literal means that
this statement cannot be a function declaration, »space(V[i])«
cannot be a parameter declaration, and thus, cannot be a
function declaration.  There's no ambiguity.  (This is a
difficult parse, however, since the interpretation here depends
on context.  In something like:
    form proj( space(V[i]) );
»space(V[i])« is a function declaration, and the entire
statement is a function declaration, because there is nothing
which makes it illegal as a function declaration.)

I do remember earlier versions of g++ (2.95.2?) having problems
with this; they didn't consider context to the right of the
expression when making the decision, so something like:
    form proj( space(V[i]), "abc" );
would fail to compile, treating »space(V[i])« as a function
declaration, whereas:
    form proj( "abc", space(V[i]) );
worked, since the preceding string literal had removed the
ambiguity of the context.  Later versions of g++ fixed this.  It
sounds to me like they've reintroduced the bug, and that someone
has decided (on what grounds, I don't know), that it's not a
bug, but a feature.

This is probably a shorter test case:

struct A { A(int, char const*); };
int main() {
  int i = 0, *b = &i;
  A a(int(b[i]), "hello");
}

Comment 3 Jason Merrill 2010-03-09 22:32:49 UTC
I agree with James Kanze's analysis.
Comment 4 Jason Merrill 2010-03-30 21:19:47 UTC
Subject: Bug 41786

Author: jason
Date: Tue Mar 30 21:19:23 2010
New Revision: 157838

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=157838
Log:
	PR c++/41185
	PR c++/41786
	* parser.c (cp_parser_direct_declarator): Don't allow VLAs in
	function parameter context.  Don't print an error if parsing
	tentatively.

Added:
    trunk/gcc/testsuite/g++.dg/parse/ambig5.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/parse/varmod1.C

Comment 5 Jason Merrill 2010-03-30 21:21:18 UTC
Subject: Bug 41786

Author: jason
Date: Tue Mar 30 21:20:58 2010
New Revision: 157839

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=157839
Log:
	PR c++/41185
	PR c++/41786
	* parser.c (cp_parser_direct_declarator): Don't allow VLAs in
	function parameter context.  Don't print an error if parsing
	tentatively.

Added:
    branches/gcc-4_4-branch/gcc/testsuite/g++.dg/parse/ambig5.C
Modified:
    branches/gcc-4_4-branch/gcc/cp/ChangeLog
    branches/gcc-4_4-branch/gcc/cp/parser.c
    branches/gcc-4_4-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_4-branch/gcc/testsuite/g++.dg/parse/varmod1.C

Comment 6 Jason Merrill 2010-03-30 21:22:55 UTC
Fixed for 4.4.4 and 4.5.0.