llvm / llvm/llvm-project

[clang-format] A standalone comment between ternary branches corrupts operand alignment

Open
#203,044 1 comment 0 reactions 0 assignees View on GitHub
clang-format
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

## Summary

In an operand-aligned ternary chain (`?`/`:` lined up one branch per line), inserting a
single standalone (own-line) comment between two branches breaks the alignment of every
branch after the comment. The operand on the line immediately after the comment is indented
by an extra `ContinuationIndentWidth`, and the operator columns of the remaining branches
shift, so the `?`/`:` operators that were aligned in the comment-free chain are no longer
aligned.

The corruption is caused by the mere presence of the wedged comment; it is not a
comment-placement issue.
## Environment

Reproduced on the following:

- clang-format version: Ubuntu clang-format version 22.1.3
- clang-format version 23.0.0git, built from `main` at commit
`3443243ded167229ddc37e64b7e754854ae1ba2c`.

## Config (`.clang-format`)

```yaml
BasedOnStyle: LLVM
ColumnLimit: 80
BreakBeforeTernaryOperators: false
AlignTrailingComments:
Kind: Leave
```
- Also reproduces on `BasedOnStyle: Google`
- The `AlignTrailingComments: Kind: Leave` is only to prevent a separate bug on `Never` and `Always` (#203050), and is not required to reproduce this bug.

## Reproduction

Baseline: without the wedged comment, the chain is aligned (the `?`/`:` line up and the
conditions are padded to a common width):

```cpp
void g(int a) {
int x = (a == 0x01) ? MODEL_5 :
(a == 0x02) ? MODEL_34 :
(a == 0x03) ? MODEL_12 :
(a == 10) ? MODEL_5 :
(a == 11) ? MODEL_34 :
MODEL_2;
}
```

Inserting one standalone comment between two branches:

```cpp
void g(int a) {
int x = (a == 0x01) ? MODEL_5 :
(a == 0x02) ? MODEL_34 :
(a == 0x03) ? MODEL_12 :
// comment
(a == 10) ? MODEL_5 :
(a == 11) ? MODEL_34 :
MODEL_12;
}
```

clang-format produces (the alignment of operands after the comment are corrupted):

```cpp
void g(int a) {
int x = (a == 0x01) ? MODEL_5 :
(a == 0x02) ? MODEL_34 :
(a == 0x03) ? MODEL_12 :
// comment
(a == 10) ? MODEL_5 :
(a == 11) ? MODEL_34 :
MODEL_12;
}
```

The branch after the comment (`(a == 10)`) is indented by an extra
`ContinuationIndentWidth`, and the operator column of the trailing branches shifts, so the
`?`/`:` no longer align with the lines above.

## Expected behavior

Inserting the standalone comment should not change the alignment of the surrounding ternary
branches. The `?`/`:` should stay aligned exactly as in the comment-free chain, with the
comment simply occupying its own line.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.