Bug 12821 – Missed redundant storage class / protection errors.

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-05-30T05:31:00Z
Last change time
2014-06-24T02:11:12Z
Keywords
accepts-invalid, spec
Assigned to
nobody
Creator
ibuclaw

Comments

Comment #0 by ibuclaw — 2014-05-30T05:31:05Z
There are cases where redundant storage classes are caught, and others where it just slides through undetected. Example: final final void foo() { } // Error, redundant 'final' final shared final void foo() { } // Error, redundant 'final' final static final void foo() { } // OK We can find the exact culprits by iterating through each storage class to find missed cases. static static void foo() { } // OK extern extern void foo() { } // OK align align void foo() { } // OK debug debug void foo() { } // OK And we can test this: shared shared void foo() { } // Error, redundant 'shared' shared static shared void foo() { } // OK shared extern shared void foo() { } // OK shared extern(D) shared void foo() { } // OK shared align shared void foo() { } // OK shared debug shared void foo() { } // OK Other cases include mixing and matching any protection/storage class together. const const void foo() { } // Error, redundant 'const' protected protected void foo() { } // Error, redundant 'protection' const protected const void foo() { } // OK protected const protected void foo() { } // OK Resulting in allowing you to even mix conflicting storage classes together. const immutable void foo() { } // Error, conflicting const package immutable void foo() { } // OK const static immutable void foo() { } // OK Penultimately, the following throw an error unless you specify void. All of which seems redundant as there's no return type. immutable foo() { } // Without 'this' cannot be immutable immutable void foo() { } // OK const foo() { } // Without 'this' cannot be const const void foo() { } // OK inout foo() { } // Without 'this' cannot be inout inout void foo() { } // OK shared foo() { } // Without 'this' cannot be shared shared void foo() { } // OK Lastly, these are considered perfectly valid, if somewhat odd. ref foo() { } // OK, inferred as 'ref void' ref void foo() { } // OK auto void foo() { } // OK auto int foo() { return 0; } // OK, redundant 'auto' auto double foo() { return 0; } // OK, redundant 'auto' All these tests are using functions declared at module scope.
Comment #1 by k.hara.pg — 2014-06-20T03:52:34Z
By recent git-head change, many cases are properly fixed. final final void foo() { } // Error, redundant 'final' final shared final void foo() { } // Error, redundant 'final' final static final void foo() { } // Error, redundant 'final' <- OK static static void foo() { } // Error, redundant 'static' <- OK extern extern void foo() { } // Error, redundant 'extern' <- OK align align void foo() { } // Error, redundant 'align' <- OK shared shared void foo() { } // Error, redundant 'shared' shared static shared void foo() { } // Error, redundant 'shared' <- OK shared extern shared void foo() { } // Error, redundant 'shared' <- OK shared extern(D) shared void foo() { } // Error, redundant 'shared' <- OK shared align shared void foo() { } // Error, redundant 'shared' <- OK const const void foo() { } // Error, redundant 'const' protected protected void foo() { } // Error, redundant 'protection' const protected const void foo() { } // Error, redundant 'const' <- OK protected const protected void foo() { } // Error, redundant 'protection' <- OK const immutable void foo() { } // Error, conflicting const package immutable void foo() { } // Error, conflicting <- OK const static immutable void foo() { } // Error, conflicting <- OK These are still OK cases: debug debug void foo() { } // OK shared debug shared void foo() { } // OK Currently it's intended. Because `debug ...` is parsed as ConditionalDeclaration, so they are equivalent with: debug { debug { void foo() { } } } shared { debug { shared { void foo() { } } } }
Comment #2 by k.hara.pg — 2014-06-24T01:13:43Z
(In reply to Iain Buclaw from comment #0) > Penultimately, the following throw an error unless you specify void. All of > which seems redundant as there's no return type. > > immutable foo() { } // Without 'this' cannot be immutable > immutable void foo() { } // OK 'immutable' does not modify return type. But in module scope, 'this' qualifier for non-member function is meaningless and "Without 'this' cannot be immutable" error occurs in first case. But second case does not raise same error, and it's inconsistent behavior. > const foo() { } // Without 'this' cannot be const > const void foo() { } // OK > inout foo() { } // Without 'this' cannot be inout > inout void foo() { } // OK > shared foo() { } // Without 'this' cannot be shared > shared void foo() { } // OK As well, same "Without 'this' cannot be xxx" error should occur in all cases. To improve compiler behavior, I opened issue 12967.
Comment #3 by k.hara.pg — 2014-06-24T02:11:12Z
Most cases are properly improved, and remained issue is separated to 12967. Therefore, I'd like to close this issue right now.