Bug 12579 – DMD rejects valid function literal

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-04-14T17:28:00Z
Last change time
2014-09-24T12:03:49Z
Keywords
accepts-invalid, pull, spec
Assigned to
nobody
Creator
briancschott
Blocks
10233

Comments

Comment #0 by briancschott — 2014-04-14T17:28:14Z
From the grammar documentation: Decl: StorageClasses(opt) BasicType Declarator FunctionBody DMD rejects the following code: void function() foo {}; and accepts the following: void function() foo = {}; According to the grammar spec, the latter should be parsed as a variable declaration whose type is "void function()", with a name of "foo" and an empty struct initializer. (By the way, the grammar does not allow empty struct initializers). This should not pass semantic analysis because a struct literal is not of type void function().
Comment #1 by k.hara.pg — 2014-04-15T10:37:06Z
(In reply to brian-schott from comment #0) > void function() foo = {}; > > According to the grammar spec, the latter should be parsed as a variable > declaration whose type is "void function()", with a name of "foo" and an > empty struct initializer. (By the way, the grammar does not allow empty > struct initializers). This should not pass semantic analysis because a > struct literal is not of type void function(). StructInitializer is defined as follows: StructInitializer: { StructMemberInitializers_opt } Between braces StructMemberInitializers is optional, so {} is properly accepted. And, If a delegate variable is initialized by empty StructInitializer, it is treated as a function literal in semantic phase. https://github.com/D-Programming-Language/dmd/blob/d4f778f96a85de9605a035864d3480e40097df28/src/init.c#L287
Comment #2 by briancschott — 2014-04-15T16:54:11Z
The compiler still rejects this: void function() bar { writeln("test"); } The grammar specification says this is valid. It does not require the '=' token. If the compiler's behavior is correct, the specification needs to be changed. Please do not close bugs while the specification is not consistent with the compiler just because the compiler's behavior is correct.
Comment #3 by briancschott — 2014-04-15T17:27:01Z
The grammar also states that function literals can have contracts by using the FunctionBody rule, but the compiler rejects this: void function() f = in { assert(true); } body { writeln("hello world"); }
Comment #4 by k.hara.pg — 2014-04-15T23:52:38Z
(In reply to brian-schott from comment #2) > The compiler still rejects this: > > void function() bar { writeln("test"); } > > The grammar specification says this is valid. It does not require the '=' > token. If the compiler's behavior is correct, the specification needs to be > changed. Even if grammar accept the token list, it could be rejected in some reason. In this case, it cannot be treated as a function definition, because of the lack of parameter list. More simple case is: auto auto x = 1; This is allowed in grammar, but will be rejected with the error "redundant storage class 'auto'".
Comment #5 by k.hara.pg — 2014-09-23T13:46:24Z
OK, the definition of more strict grammar for function declarations was not so difficult. https://github.com/D-Programming-Language/dlang.org/pull/660
Comment #6 by github-bugzilla — 2014-09-24T12:03:46Z
Commit pushed to master at https://github.com/D-Programming-Language/dlang.org https://github.com/D-Programming-Language/dlang.org/commit/7fbb9cac0718f36e27c19905ec037f9bf692e774 fix Issue 12579 - DMD rejects valid function literal Remove FuncDeclaratorSuffixes to disallow zero, two or more parameter lists And disallow mixing C-style suffix in function declaration, as follows: void foo[](int a);