<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/144328>144328</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Bug Report: clang-format incorrectly reorders const and static for std::size_t
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang-format
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
AnonimiAngels
</td>
</tr>
</table>
<pre>
### Bug Report: clang-format incorrectly reorders `const` and `static` for `std::size_t` in C++11
**Description**
When using `clang-format` (version 19.1.7) with a C++11 style, qualifiers like `const` and `static` are incorrectly reordered when they appear after a namespaced type (e.g., `std::size_t const`). Specifically, `std::size_t const` is transformed into `std::const size_t`, and `std::size_t static` is transformed into `std::static size_t`. This reordering results in a compilation error, as `std::const` and `std::static` are not valid types or constructs within the `std` namespace. This issue occurs when the qualifier immediately follows the namespaced type.
---
**clang-format Version**
Debian clang-format version 19.1.7 (3)
---
**.clang-format Configuration**
```yaml
Language: Cpp
BasedOnStyle: LLVM
Standard: c++11
# Indentation
UseTab: Always
TabWidth: 4
IndentWidth: 4
ContinuationIndentWidth: 4
ConstructorInitializerIndentWidth: 4
# Braces
BreakBeforeBraces: Allman
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
# Spacing
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesInParentheses: false
SpacesInAngles: false
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeRangeBasedForLoopColon: true
BitFieldColonSpacing: After
# Line breaks
ColumnLimit: 190
MaxEmptyLinesToKeep: 1
SpacesBeforeTrailingComments: 4
KeepEmptyLinesAtTheStartOfBlocks: true
# Alignment
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: Consecutive
AlignConsecutiveBitFields: Consecutive
AlignConsecutiveDeclarations: None
AlignOperands: Align
AlignTrailingComments: true
# Pointers and references
PointerAlignment: Right
ReferenceAlignment: Right
# Qualifiers
QualifierAlignment: Custom
QualifierOrder: ['inline', 'static', 'friend', 'constexpr', 'const', 'volatile', 'restrict', 'type']
# Include sorting
SortIncludes: true
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<.*\\.h>'
Priority: 1
- Regex: '^<.*>'
Priority: 2
- Regex: '.*'
Priority: 3
# Function formatting
AlwaysBreakAfterReturnType: None
AllowAllParametersOfDeclarationOnNextLine: true
BinPackParameters: false
BinPackArguments: false
# Misc
FixNamespaceComments: true
CompactNamespaces: false
NamespaceIndentation: All
# C++11 specific
Cpp11BracedListStyle: true
# Access modifiers
AccessModifierOffset: -4
# Case labels
IndentCaseLabels: false
# Comments
ReflowComments: true
# Penalty settings for better formatting
PenaltyBreakBeforeFirstCallParameter: 100
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
# Break before operators
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeTernaryOperators: true
# Constructor initializers
BreakConstructorInitializers: BeforeColon
ConstructorInitializerAllOnOneLineOrOnePerLine: true
# Disable some auto-formatting that might conflict with style
DerivePointerAlignment: true
DisableFormat: false
# Empty line handling
SeparateDefinitionBlocks: Always
```
---
**Reproduction Steps**
1. Create a file (`test.cpp`) with the following code:
```cpp
template <typename T> auto replace_next(const T& p_value) -> void
{
std::size_t const placeholder_pos = m_format_string.find("{}", m_current_pos); // Issue with 'const'
// std::size_t static placeholder_pos; // This would also exhibit the error
if (placeholder_pos != std::string::npos)
{
std::string const replacement = type_converter<T>::to_string(p_value);
m_format_string.replace(placeholder_pos, 2, replacement);
m_current_pos = placeholder_pos + replacement.length();
}
}
```
2. Save the `.clang-format` configuration (shown above) in the same directory.
3. Run `clang-format -i test.cpp`
---
**Expected Behavior**
The `std::size_t const` (or `std::size_t static`) declaration should remain unchanged, or at most, be formatted to `const std::size_t` (or `static std::size_t`). The `QualifierOrder` specifies these qualifiers before 'type', so placing them before `std::size_t` is acceptable.
---
**Actual Behavior**
After formatting, `std::size_t const` becomes `std::const size_t`, and `std::size_t static` becomes `std::static size_t`. Both are syntactically incorrect in C++ and result in compilation errors.
---
**After-format Code (for `const` issue)**
```cpp
template <typename T> auto replace_next(const T& p_value) -> void
{
std::const size_t placeholder_pos = m_format_string.find("{}", m_current_pos);
if (placeholder_pos != std::string::npos)
{
const std::string replacement = type_converter<T>::to_string(p_value);
m_format_string.replace(placeholder_pos, 2, replacement);
m_current_pos = placeholder_pos + replacement.length();
}
}
```
---
**Notes**
This appears to be a bug in qualifier reordering logic when applied to namespaced types. The formatter should detect namespace-prefixed types and avoid injecting qualifiers inside the namespace scope.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzcWUtv4zgS_jXMhYghy4kdH3yQlQ4QbLrdm2RnjgFNlSRuKFJLUk48v35RpJ62u3sG2N3DAp6HyGKx-NW7wqwVhQLYkNstub2_Yo0rtdkkSitRiUQVIO3VXmfHDYkX4Ue3TUGfodbGkUVCuWSquM61qZijQnFtDHAnj9SANhkYS8ky4lpZR5YRZSrDb-uYExwXcm3CQkYWCVkkVvwBb55UKJqSeEvi7XxOogR_Mf7uwXIjaie0CgskSn4vQdHGClX420YiIScS3x3AWKEVna9n89mKxGv6IVxJ2XAFte4ogcQp_VfDpMgFii7FO_xcfmbg0qshox8okyvhSFldAzOU5Q4MZVSxCmzNOGTUHWtA8WBWzPDqcyRodzWJ1zP6UgMXueBMyuMv6Kmw1BmmLOIAGRXK6Qm9J6Q93siuf92U5fDaX_EMlAPTGX0the1AQfUYsI10FrXLKNdVLSRDVVIwRhsvhD0XcwL95K5OB0o7emBSBEwt1SYgYRrurFe28NroWCyjQQ-tlMLaBqjmvDG2195gDVRUFWSCOZBHmmsp9Yf1FCf6nAVjvb6-HlvtxE1-C9bYm-897AVTU1eaWiwayYLE64u8Z5ODqVa5KBrDJh6Cv2UUfkdWSRIlT0wVDSsAvTitaxIlW2Yh26kX7wmLhD49_faVRMmLYypjJvPufuqSC_qoMlAuXBcl_7DwyvZImsgPdrQkSl7Z_neRuRIXb0iUhAOTpVQrJ1TjmVzeDqrU5lEJJ5gUf4C5QNiKtDWMA169NcDet5BrA-2aF0xWDGVNUIkvpTbuMX9xzEEFytmdSl6EKiQ8CeVh-AYHMBPyJ63rc7qcSQsTuodGcXzSOe2jkkLBTsnj5MBWav7-ZyRImYUntgf5YzFaLF5qxoUqUI9opAGM78yA8mAg8kbL4fkd4aP6UtXu6CldCTZg1zH3JPZR_WI7QcHOdxIMham3s5RZd7YfhEx8ckKhdjUY5rTxnJxpTgifmSrAG--DNqibVEutRrRb4R4EyMyvd4CgJaAcA1SIIN2jyVhvdLKp1JOohBdwvo5IlHxlnx4WJLWv-m8Atd_s3xwkejVMSKGKVFcB1NY-kX44n7jXEl4cM26XB82PZG5lSmSLgVe_KJSXeVeDQoN-BxcsWhSqI0BnAd44cRgh2Om627lA3IH0J0jvgUsWIoyn_qZVT-Z1pTJ7JtclTKZv_a6Fcph3MdYbyMGACn7c7gxgLBL6LIoSUXnuCC_utqz_3id1EiX9x-RE2linq_H2DrMWbmF1FK-E91kSr3zqjVdtBuq_cyNAZcO3T0DwWZuTpeHzoDH7yRFPA9YZwUc0mFPw6_Z-HHK5bDKgVhvX-jYGsbA6BrZdGozrGQqjm3rYSpmDQhvhj5EoofQaieDTvxvv_UIW6QyzyG1KbtNZSRZfcB1JKf1uhDbCHTsn-MnxHx2LcW16ytNfJF4MIHTBlYbE1wIRso6P-95TnsE1Rr0iiGNDlfojkfI7M6wCNLldPrLpnfoGn66Lp30MUd8Zfx-OjKNWu5mYoult-yQOfxWWkyh5EJ_fuoLhgiekuqoZdz3JhFO_Ok65IaEN94wq2rZaRLZ1PZ_7DJg9Cev6DH8SazgHa2mls95VwtLXdmWX5zZEnOtRtsVcRKVPRn12H_LTBSj6d3vnlfrjJyEBFJPuSC14BVvfMOzBYSk90XtLOEr4D8JYl7KRlr2RRtEJdXu5t66zTc_kCazFf_z5-JTkxZk2ncyj8fkvnwhdWjLD-HB5NKEZrHOnHp3dfajO6pbRuJwB9k73_lVU97lwWt4Ixcxxkii_aTUkgCn1K5gz8inwo5KLiqHm6m-9XJJ5RuGKkIN_VLslUu7UTvmiZWd2Cr6DOXG4VpB7YdleYqyrgLLG6etB79SVzNEKQz2W-7kU3IXOLnRzWFobcYBL6aO9pWX_ELrFc1v12Zpi4KclU5lswy3UGCvgHnIPjlZDiO3r3r7gvli1P0NtdNaEEPbioLbjYn0-o6kB5oAymgvpu0SyjBxYN-N1HRrC8FTsQUI_gohwnUGI5GMJuK_vHVS1RJ5kkWJawc6FvpLFF48rNVBLxuFNwacj8V1oEF9JvKT124HJBvDKayQ_aJEh-9W2DdEXu1Dq2ZVaZmDeam0pWdzT6i2o7816t5nlAlPmHYlj5La6x_-JU1q98cZgaYkHsfFZbCmJH0j8QB99n-afPs6oQZCW5nILeyrQiKnvAD90IzPKpNUUPkuxF86DG1rTKGmvEDkq4-xt8RyfN2pP26hAFolq39CK2KM2Rc4faJFrVYG26lFDbb1xrQ5gfChJUWvhnNMtlChUryey8Jecot3yPZcfMffAj24esxlpwwt0_vzt-OhMgipc6RXbMfFP90VM-PfUO-IZfWEH6Hr02ekQh4_bWlSALfWHomyvD94u2_beoklnwgDGmyP24osZfW7U6VyIXgs6dqZLHvrlswbuIKNbKNlBaNM76OswSLg4eyHx3cW51jBKQZGzoeKgtvS2Z6BiQtFG8RJ7mgw1og3FIKfRzFO6hy7vQUbD-KWd5JyP0EZihLnMGYmfKrWvOSl7l1FXQICfc1gYT8baZDSqT-OUWu3tIgRmqHqiy_M9SxnnUDsMv5eHJgl3DZPn8PvCbpz-fzEK2wPXFVyYK_3F8dclPucjr612pZ9J2aNyjLswrhumhKPJZtvo2Eb61bN5mP0BLvj-Yd6T-ezQTlJH8z8bIsGlEdD_LB-MYf4P54P_Sjg-9SXXTi3__8LxT2Lxibl90w7sKPah5_qRtsUAtMcSZd8UaMDDsHQ08pW6EDwMVFldSxHi1snU1IYw1IU20wXEDBy6TE99XRvIxWd3yjsQQ_OjQv0TuC8KR2FKKCsymI5pqeU6jGmvss0iWy_W7Ao289VtFC3X65v1VbmZR-wuWu5Xq9ucZevlzX6-X--XWc6yaH6zzFdXYhNH8W20nC_n0SKO17O7Nayyfbzi6xuIFvyO3EQYyuVMykM106a48v64md_cLOK7q9At-b-6xPEk1cUxub2_Mhs8d71vCktuIimsswMnJ5yEzV_9M0ywbMSrDVkYME5i3VVj5KZ0rvbDAF8ZFcKVzX7GdUXiBxSh_c91bTQCTuIH_zJL4of2cYdN_O8AAAD___0xmAU">