Skip to content

[clang-format] Regression: AlignConsecutiveDeclarations introduces invalid spacing in using declarations with overloaded operators #136541

@kust1011

Description

@kust1011

Description

In Clang-format versions 20.1.1 and 20.1.2, enabling AlignConsecutiveDeclarations causes incorrect formatting of using declarations involving overloaded operators. Specifically, an extra space is inserted between the scope resolution operator :: and the overloaded operator name, resulting in invalid C++ syntax.

Minimal Example

Input:

#include <vector>

void test1() {
  using std::operator==;
  std::vector<int> v;
}

void test2() {
  using std::operator==;

  std::vector<int> v;
}

Formatted Output with Clang-format 20.1.1 / 20.1.2:

#include <vector>

void test1() {
  using std::      operator==;
  std::vector<int> v;
}

void test2() {
  using std::operator==;

  std::vector<int> v;
}

In test1(), Clang-format inserts extra whitespace between :: and operator==, producing a non-standard formatting that may be misleading or undesirable in production code. This behavior is triggered when the using declaration is followed by another declaration that enables alignment logic (e.g., std::vector<int> v;) under the AlignConsecutiveDeclarations setting. While the resulting code is still syntactically valid, the formatting contradicts conventional C++ style and may degrade readability or tooling reliability.

Style Configuration

BasedOnStyle: LLVM
SpaceBeforeParens: Never
SpacesInAngles: Never
AlignConsecutiveDeclarations: true

Analysis

This issue appears to stem from the alignment logic introduced by AlignConsecutiveDeclarations. When multiple declarations are present, Clang-format attempts to align them, treating operator== in the using declaration as a field to align. This leads to the insertion of spaces within the using declaration, breaking the syntax.

Notably, this behavior is a regression from Clang-format 19.1.7, which correctly preserved or corrected the formatting regardless of context.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions