youssef47048 wrote:

> I meant, in our parsing implementation, where did you find the logic that 
> caused this?

After doing investigation, The root cause was in how the `ParseCaseStatement` 
and
`ParseDefaultStatement` register themselves on the switch case list.

`ParseCaseStatement` calls `ActOnCaseStmt` (which calls `addSwitchCase`)
**before** parsing its sub-statement, while `ParseDefaultStatement`
calls `ActOnDefaultStmt` (which calls `addSwitchCase`) **after** parsing
its sub-statement.

because `addSwitchCase` is (LIFO), this produce different linked list orderings 
depending on
whether labels are separated by break(the standard switch case) or fallthrough.

consider this example:
```

void test2(int z) {
  switch(z) {
    default:   // expected-note {{previous case defined here}}
    case 1:
    case 2:
    default: break; // expected-error {{multiple default labels in one switch}}

  }
}

```
Each statement finishes completely beforethe next one starts,
so all three addSwitchCase calls happen in
top-to-bottom order, and the LIFO prepend reverses them.
 The loop in `ActOnFinishSwitchStmt` then sees the second default first and 
treats
it as `TheDefaultStmt`, emitting the error on the first one which is wrong.

Consider this example also:

```
void f3(int z) {
    switch(z) {
      default: // expected-note {{previous case defined here}}
      case 1:
      default:  // expected-error {{multiple default labels in one switch}}
        break;
    }
}

```
In this case, the parsing is recursive: the outer default's
sub-statement is the next label. `ParseCaseStatement` registers itself
before recursing, and the inner `ParseDefaultStatement` registers after
its sub-statement. The outer default registers last. This produces a
list order that happens to be correct.

The proposed solution is to split `ActOnDefaultStmt` the same way [ 
`ActOnCaseStmt` /
`ActOnCaseStmtBody`] are already split: create the `DefaultStmt` and add
it to the switch case list immediately after parsing the 'default: `
tokens, then attach the sub-statement afterward via a new
`ActOnDefaultStmtBody`. This makes the registration order consistent
with `ParseCaseStatement` and gives `addSwitchCase` a uniform prepend
order regardless of breaks or fallthroughs.

https://github.com/llvm/llvm-project/pull/180447
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to