Skip to content

Fall-through in the last case of a switch statement #7537

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
DartBot opened this issue Dec 20, 2012 · 10 comments
Closed

Fall-through in the last case of a switch statement #7537

DartBot opened this issue Dec 20, 2012 · 10 comments
Labels
area-specification (deprecated) Deprecated: use area-language and a language- label.

Comments

@DartBot
Copy link

DartBot commented Dec 20, 2012

This issue was originally filed by [email protected]


Spec "13.9 Switch" has follwing two assertions:

The last case in a switch (default or otherwise) can ‘fall-through’ to the end of the statement.
...
It is a static warning if the last statement of the statement sequence sk is not a
break, continue, return or throw statement.

To comply with the first assertion, the second assertion should be adjusted so that it does not apply to the last case in a switch.

Currently analyzer warns of "fall through" from the last case, which has no sense.

@anders-sandholm
Copy link
Contributor

Please file an editor issue (or change Area) once this is fixed in the spec.


Added Area-Language, Triaged labels.

@DartBot
Copy link
Author

DartBot commented Feb 6, 2013

This comment was originally written by [email protected]


Spec 0.20 changed this to a runtime error instead of a static warning, but
analyzer still reports one regardless of whether or not it's the last case

@DartBot
Copy link
Author

DartBot commented Feb 6, 2013

This comment was originally written by [email protected]


see co19 test Language/12_Statements/14_Continue_A02_t13

@kevmoo
Copy link
Member

kevmoo commented Apr 4, 2014

Not sure if this overlaps:

switch(truth) {
  case true:
    if(foo.contains(baz)) {
      return 0;
    } else {
      return 1;
    }
  default:
    throw 'silly, I know';
}

The last statement of the 'true' case is not a return, but the effect is to always return.

Could this be valid?

@bwilkerson
Copy link
Member

The specification currently states:

It is a static warning if the last statement of the statement sequence sk is not a break, continue, return or throw statement.

This has a couple of problems (including the fact that 'throw' is an expression, not a statement, and that 'rethrow' isn't included in the list), not the least of which is that it disallows code patterns like the one Kevin included. Unfortunately, changing it to allow such code patterns would require specifying when statements and expressions are considered to terminate. I'm guessing that isn't likely to happen, but Gilad would know better than I.


Set owner to @gbracha.

@DartBot DartBot added Type-Defect area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). labels Apr 5, 2014
@kevmoo kevmoo added P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) and removed triaged labels Feb 29, 2016
@eernstg
Copy link
Member

eernstg commented Oct 24, 2016

What we need in order to handle this correctly is a little bit of control flow analysis. I think we have a compositional way to specify this which would probably map rather directly to an implementation, and that would be useful because it would be much more lightweight than an explicit control flow analysis in the spec.

In short, every statement and expression should have a boolean compile-time property which says whether it is definitely not going to complete normally -- which would be because a statement continues, breaks, returns, or throws, and for the expression because it throws. Composite statements/expressions would compute this based on their embedded statements/expressions; e.g., e1 ? e2 : e3 would definitely not complete normally if the same is true for e1, or if it is true for both e2 and e3.

(Note overlapping issues: #27650, #21822).

@bwilkerson
Copy link
Member

We also have a similar need for the changes I proposed to type promotion. I wrote up a potential description in the doc I sent out a couple of weeks ago.

@munificent
Copy link
Member

The original focus of this issue is that the spec is internally inconsistent. In one place, it says you can fall-through from the last case. In another, it says you can't. More specifically:

The last case in a switch (default or otherwise) can ‘fall-through’ to the end of the statement.

This is non-normative text and is restating the runtime semantics. It's stating the difference between these two cases:

switch (n) {
  case 1:
    print("inside 1");
    // <-- runtime error here.
  case 2:
    print("inside 2");
    // <-- no runtime error here.
}

If you call the above code with n equal to 1, you get a runtime exception after "inside 1" is printed.

It is a static warning if the last statement of the statement sequence sk is not a break, continue, return or throw statement.

This is describing the static warnings shown. This does not make any exception for the last case. So, as the language is currently specified:

switch (n) {
  case 1:
    print("body");
}

This code should run correctly, but also have a static warning because the last case does not exit. I don't think that static warning is useful, and it's not what the analyzer implements, so I think we should fix the spec to say:

It is a static warning if k != n and the last statement of the statement sequence sk is not a break, continue, return or throw statement.

@munificent munificent added area-specification (deprecated) Deprecated: use area-language and a language- label. and removed area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) labels Dec 14, 2016
@eernstg
Copy link
Member

eernstg commented Feb 6, 2018

No milestone now: This will not block Dart 2.

It will be reconsidered later.

@srawlins
Copy link
Member

The text for switch statements has changed to use flow analysis introduced in the null safety language feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-specification (deprecated) Deprecated: use area-language and a language- label.
Projects
None yet
Development

No branches or pull requests

8 participants