-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Description
- Reproducible in 17.0.0 to 17.0.6
- Not reproducible in 16.0.6 and earlier
- 18+ not tested yet, will do when it lands in Fedora 39 or the pre-commit mirror
We noticed a regression in clang-format when moving from clang-format 16 to 17 in godotengine/godot: godotengine/godot#88959
The following test case reproduces the issue with the default clang-format config:
#include <cstdint>
#include <cstdio>
#define PRINT_ADDRESS(m_name) printf("%d\n", (uint64_t)&m_name)
void func1() {}
void func2() {}
int main() {
PRINT_ADDRESS(func1);
PRINT_ADDRESS(func2);
return 0;
}
This is formatted as is by clang-format 16, but running clang-format 17 generates the following diff:
diff --git a/main.cpp b/main.cpp
index c325f7a..81a6329 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,7 +1,7 @@
#include <cstdint>
#include <cstdio>
-#define PRINT_ADDRESS(m_name) printf("%d\n", (uint64_t)&m_name)
+#define PRINT_ADDRESS(m_name) printf("%d\n", (uint64_t) & m_name)
void func1() {}
void func2() {}
It seems to treat &
as a bitwise operator instead of address-of operator.
Here's a reproduction project with this test case, and a config for pre-commit
to run both clang-format 16 and 17 in turns. You can set it up with:
pip install pre-commit
pre-commit install
pre-commit run -a
clang_format_operator_spacing.zip
Real life examples found in Godot:
diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp
index 0c96c32187a55..f96a8873cafd9 100644
--- a/core/extension/gdextension_interface.cpp
+++ b/core/extension/gdextension_interface.cpp
@@ -1415,7 +1415,7 @@ static void gdextension_editor_help_load_xml_from_utf8_chars(const char *p_data)
#endif
}
-#define REGISTER_INTERFACE_FUNC(m_name) GDExtension::register_interface_function(#m_name, (GDExtensionInterfaceFunctionPtr)&gdextension_##m_name)
+#define REGISTER_INTERFACE_FUNC(m_name) GDExtension::register_interface_function(#m_name, (GDExtensionInterfaceFunctionPtr) & gdextension_##m_name)
void gdextension_setup_interface() {
REGISTER_INTERFACE_FUNC(get_godot_version);
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 171074188f629..79bed9be33709 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -810,7 +810,7 @@ struct VariantInternalAccessor<bool> {
#define VARIANT_ACCESSOR_NUMBER(m_type) \
template <> \
struct VariantInternalAccessor<m_type> { \
- static _FORCE_INLINE_ m_type get(const Variant *v) { return (m_type)*VariantInternal::get_int(v); } \
+ static _FORCE_INLINE_ m_type get(const Variant *v) { return (m_type) * VariantInternal::get_int(v); } \
static _FORCE_INLINE_ void set(Variant *v, m_type p_value) { *VariantInternal::get_int(v) = p_value; } \
};
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index 50c9c10987b2f..20941b944fb3f 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -433,9 +433,9 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
} \
m_assign_type num; \
if (value->get_type() == Variant::INT) { \
- num = (m_assign_type)*VariantGetInternalPtr<int64_t>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<int64_t>::get_ptr(value); \
} else if (value->get_type() == Variant::FLOAT) { \
- num = (m_assign_type)*VariantGetInternalPtr<double>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<double>::get_ptr(value); \
} else { \
*oob = false; \
*valid = false; \
@@ -495,9 +495,9 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
} \
m_assign_type num; \
if (value->get_type() == Variant::INT) { \
- num = (m_assign_type)*VariantGetInternalPtr<int64_t>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<int64_t>::get_ptr(value); \
} else if (value->get_type() == Variant::FLOAT) { \
- num = (m_assign_type)*VariantGetInternalPtr<double>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<double>::get_ptr(value); \
} else { \
*oob = false; \
*valid = false; \
But you can also see in the same PR godotengine/godot#88959 that other cases where &
is a bitwise operator were fixed by clang-format. I'm not sure there's any easy way for clang-format to know which is which, if so I understand if this is considered a "won't fix".