Issue |
91671
|
Summary |
[clang-format] Formatting overflows column limit with `BreakBeforeTernaryOperators: true` and `AlignAfterOpenBracket: AlwaysBreak`
|
Labels |
clang-format
|
Assignees |
|
Reporter |
JamieStM
|
## Summary
Long brace-initialized values in the true statement of ternary operators results in incorrect formatting, including arbitrarily overflowing the column limit, when:
```yaml
BreakBeforeTernaryOperators: true
```
and
```yaml
AlignAfterOpenBracket: AlwaysBreak
```
## Versions affected
Affects clang-format versions >= 10, but not <= 9. Tested each of 7, 8, 9, 10, 11, 14 and 18 on windows. Tested clang-format-18 on ubuntu.
## Repro case
Invoke `clang-format --style=file` on a folder with the following code (as shown after formatting on clang-format-18):
`.clang-format`:
```yaml
Language: Cpp
BasedOnStyle: LLVM
BreakBeforeTernaryOperators: true
AlignAfterOpenBracket: AlwaysBreak
ColumnLimit: 80
```
`main.cpp`:
```cpp
#include <string>
#include <vector>
int main() {
auto my_vect =
true
? std::vector<
std::
string>{std::string{"long string for demonstration"}, std::string{"long string for demonstration"}, std::string{"long string for demonstration"}}
: std::vector<std::string>{
std::string{"long string for demonstration"},
std::string{"long string for demonstration"},
std::string{"long string for demonstration"}};
}
```
Expected result:
```cpp
auto my_vect =
true
? std::vector<std::string>{
std::string{"long string for demonstration"},
std::string{"long string for demonstration"},
std::string{"long string for demonstration"}}
: std::vector<std::string>{
std::string{"long string for demonstration"},
std::string{"long string for demonstration"},
std::string{"long string for demonstration"}};
// or similar, e.g.
auto my_vect = true ? std::vector<std::string>{
std::string{"long string for demonstration"},
std::string{"long string for demonstration"},
std::string{"long string for demonstration"}}
: std::vector<std::string>{
std::string{"long string for demonstration"},
std::string{"long string for demonstration"},
std::string{"long string for demonstration"}};
```
Result prior to clang-format 10 (acceptable, but still not quite what is expected):
```cpp
auto my_vect =
true ? std::vector<std::string>{std::string{
"long string for demonstration"},
std::string{
"long string for demonstration"},
std::string{
"long string for demonstration"}}
: std::vector<std::string>{
std::string{"long string for demonstration"},
std::string{"long string for demonstration"},
std::string{"long string for demonstration"}};
```
## Further information
What does affect it:
- If the vector's brace initializer is changed to use a parentheses initializer (including when passing an initializer list as a single parameter), this formats correctly.
- The length of each element of the initializer list. It formats lists of short elements correctly, e.g. `std::vector<int>{1, 2, 3, ...}`. I don't know where the boundary is, but it at least occurs when two elements are too long to fit on a single line (i.e. where, in the false case of the ternary _expression_, the same _expression_ breaks each element onto their own line).
- BOTH `BreakBeforeTernaryOperators: true` and `AlignAfterOpenBracket: AlwaysBreak` must be set
- `BreakBeforeTernaryOperators: false` and `AlignAfterOpenBracket: AlwaysBreak` formats this correctly (albeit slightly differently)
- `BreakBeforeTernaryOperators: true` and `AlignAfterOpenBracket: Align` formats this correctly (albeit slightly differently)
- `BreakBeforeTernaryOperators: false` and `AlignAfterOpenBracket: Align` formats this correctly (albeit slightly differently)
What doesn't affect it:
- The actual type used within the vector or how each is defined (e.g. whether the constructors use parentheses or braces, whether there is a type specified at all, whether there are string literals, etc.), provided that each element of the initializer list is sufficiently long.
- Indentation level
- `Standard`, `IndentWidth`, or `ContinuationIndentWidth`
- Whether the template parameter is there or not (i.e. `std::vector{...}` has the same result as `std::vector<std::string>{...}`)
- Length of predicate _expression_
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs