llvm / llvm/llvm-project

[clang-format] clang-format is not idempotent when a struct field with an all-caps typedef name wraps due to long comment

Open
#165,185 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

### Description
clang-format produces inconsistent output between consecutive runs when a struct member uses an all-caps typedef name and the line contains a long trailing comment that exceeds the column limit.

On the first run, clang-format breaks the declaration across two lines and indents the wrapped line relative to the type name. On the second run, it removes this indent and aligns the continuation line with the type, resulting in non-idempotent output.

This may occur because clang-format fails to recognize an all-caps type name on a separate line as a typedef and instead treats it as a macro. Typedef names that use mixed upper- and lowercase letters are recognized correctly and do not trigger this behavior.

### Steps to Reproduce:
#### .clang-format
```yaml
BasedOnStyle: LLVM
ColumnLimit: 100
ReflowComments: Never
```

#### Source code
```c
typedef int Integer;
typedef int CAPITALTYPE;

typedef struct
{
int a;
Integer b;
Integer c; // A veryveryveryvery longlonglonglonglonglonglong comment that exceeds the column limit
CAPITALTYPE d;
CAPITALTYPE e; // A veryveryveryvery longlonglonglonglonglonglong comment that exceeds the column limit
} S;
```

#### First run
Breaks the declaration across two lines and indents the wrapped line.
```c
typedef int Integer;
typedef int CAPITALTYPE;

typedef struct {
int a;
Integer b;
Integer
c; // A veryveryveryvery longlonglonglonglonglonglong comment that exceeds the column limit
CAPITALTYPE d;
CAPITALTYPE
e; // A veryveryveryvery longlonglonglonglonglonglong comment that exceeds the column limit
} S;
```

#### Second run:
Removes that indent and aligns the wrapped line with the type.
```c
typedef int Integer;
typedef int CAPITALTYPE;

typedef struct {
int a;
Integer b;
Integer
c; // A veryveryveryvery longlonglonglonglonglonglong comment that exceeds the column limit
CAPITALTYPE d;
CAPITALTYPE
e; // A veryveryveryvery longlonglonglonglonglonglong comment that exceeds the column limit
} S;
```

### Environment
- clang-format version: **21.1.3**
- OS: Windows 11

Contributor guide

Open the contributing guide

Research direction

Start by running clang-format with the provided .clang-format configuration on the C reproducer, then run it again and compare the wrapped CAPITALTYPE declaration. Trace the formatting path for typedef-versus-macro recognition and add regression coverage showing that consecutive runs produce identical output.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.