Skip to content

[clang-format] Penalty overflow picks a worse layout for long braced lists #235788

Description

@chfast
gen() { python3 -c "
print('int t[] = {')
for i in range($1): print('    0x%0100x,' % i)
print('};')"; }
gen 80 | clang-format --style=LLVM | head -2
gen 81 | clang-format --style=LLVM | head -3

With 80 elements:

int t[] = {
    0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,

With 81 elements the brace moves to its own line and every element is indented 4 more:

int t[] =
    {
        0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,

Every element line is over the column limit, and with PenaltyExcessCharacter: 1000000 the penalty of the statement reaches 2^32: -debug-only=format-formatter reports Penalty for line: 4240003369 for 80 elements and 646036309 for 81. OptimizingLineFormatter::analyzeSolutionSpace() sums the penalty in an unsigned, so it wraps and the worse layout wins. With that sum and OrderedPenalty changed to 64 bits locally, the layout stays int t[] = { (checked up to 1000 elements).

Same in clang-format 21, 23 and trunk. Found in intx (multi-precision integers), where a division test table of 100-digit literals was reformatted this way after adding rows.

Activity

  1. llvmorg-github-actions commented on Oct 26, 2026

    @llvmorg-github-actions

    @llvm/issue-subscribers-clang-format

    Author: Paweł Bylica (chfast)

    Details ```sh gen() { python3 -c " print('int t[] = {') for i in range($1): print(' 0x%0100x,' % i) print('};')"; } gen 80 | clang-format --style=LLVM | head -2 gen 81 | clang-format --style=LLVM | head -3 ```

    With 80 elements:

    int t[] = {
        0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,

    With 81 elements the brace moves to its own line and every element is indented 4 more:

    int t[] =
        {
            0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,

    Every element line is over the column limit, and with PenaltyExcessCharacter: 1000000 the penalty of the statement reaches 2^32: -debug-only=format-formatter reports Penalty for line: 4240003369 for 80 elements and 646036309 for 81. OptimizingLineFormatter::analyzeSolutionSpace() sums the penalty in an unsigned, so it wraps and the worse layout wins. With that sum and OrderedPenalty changed to 64 bits locally, the layout stays int t[] = { (checked up to 1000 elements).

    Same in clang-format 21, 23 and trunk. Found in intx (multi-precision integers), where a division test table of 100-digit literals was reformatted this way after adding rows.

  2. yashaggarwal85d commented on Oct 27, 2026

    @yashaggarwal85d
    Contributor

    Hi, I started working on this one, have a PR ready, thanks

  3. HazardyKnusperkeks commented on Oct 30, 2026

    @HazardyKnusperkeks
    Contributor

    While it's likely that the PR will be merged, which will postpone that problem. I think it's also a good idea to either disable clang-format on such code, or provide a bigger column limit. There will always be the chance of an overflow.

  4. added a commit that references this issue on Nov 2, 2026
    e98939a
  5. added a commit that references this issue on Nov 3, 2026
    629f056
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions