<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/83400>83400</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
clang-format: Wrong spacing in macro with C-style cast and address-of operator
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
akien-mga
</td>
</tr>
</table>
<pre>
We noticed a regression in clang-format when moving from clang-format 16 to 17 in godotengine/godot: https://github.com/godotengine/godot/pull/88959
The following test case reproduces the issue with the default clang-format config:
```cpp
#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
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](https://github.com/llvm/llvm-project/files/14446204/clang_format_operator_spacing.zip)
---
Real life examples found in Godot:
```diff
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 https://github.com/godotengine/godot/pull/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".
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWc1u4zgSfhrmUrAhUbItHXxwHLvXwGy64fTMYE8CJZVs7kikIFJxZ59-QerHku0knZ3twRwaEBL-VJHFqvo-UWWmFD8IxCWZ3ZPZwx2r9VFWS_YHRzEpDuwulunL8ncEITVPMAUGFR4qVIpLAVxAkjNxmGSyKpiG0xEFFPKZiwNklSzGs-4ctAR3YdQOMpUaxYELJHRre8RbwVHrUhFvRejWDHN9rONpIotO5kKDbss6zwndBkE4C4nzQJxV8_frESGTeS5PxhaNSkPCFEKFZSXTOkEF-ojAlaoRTlwfbTfFjNW5HpudSJHxgzGqWX_uNE9Slu0I9bhI8jpFIN46UTrlQhNv8-qsPE92IilmXCB82e8ev0arh4f95umJ0KCIBCuQ0BDKigudERoQSgmdpWS2Fra5BkKDmgs99yNNaEjovNcabvIseQpZLRLXLhICWdyTxcPFJL0x2fzlQkPBuBgI2PErm9s9QuJ1EjdF6FikQl1XApx-6Lx95_BxfLkCrqCJkTaJafvxy2XOGQ_FtYaqFsLkwnh6AQcUWDHdJsQ5Z1KeZddBt6N2yLRgMjlwDYzQrXHNNClLiAedznMpfoPEo7NswabTwGVzj4bgOs7c9xuRyWQyWqXLi_vmubEo8R3iOzBxCV0vgND7tmGHW6e-nZi3puVgtjHsR-emOd__cQcgdA4Xe7RHgTcRAG9D4FYO7jQoxEIZVtMVMg1GgM7J3DHZyCDm-sQVgixNhskKuFAaWQoyA5amhkUnMuunp8PF_4EVErpQlnAbztKGcstK_hsT3XEWV2dyM95gwlB0Q1kGHMakssJJIouCa2OZlgYKEEt9vKJno93wswGjmsK_ZA0JE6BQA9dQl3bfa1g03ZKX9ogsz2GwaTPX9zuRq3Fj1oS94XAyu7cWR43FUee4SJUs4eIw_Q8vyeyB0OCN90ieP3f_Jq0zCd1mPEdF6Nb1fX9OHZ_Q7ftbjQl2MpkMu3tkOeQ8Q8BvrChzNGRVi9R491P7vhsd7l2KSaRJiS1-0yjM69ecLO17ERcaq4wl2NPQRxSGVOUk4TzxqBss2Gw2nWbhnAXBwktYlt6mrY9vNKa2_0G_oz_fnfUM2LebSaWZ5kkD7OFymHITySPmZZRLlkbfijwy15Wo1lkQJUdWKUKDRAoDrCOrgNBVGaVMswGnUA9FyrOu2_PIFW_uN592T183-2j3-HWz367Wm2j76-N6xG-fHjb92b0V8VYVHrjSWJ3PHhlu0tY5AaFep2sJcKC-6-S3rfgXXTXMO3QBod5gjVtc_Lew2rL5u3aP-H0orVDX5dmWq5sLccLXj3lAHdlbZvSMVZOU5_vKbWQ-s4ozoc-tZm_B8ulxmOdvyQ1x6C5cZ-G7QZDNaTidLsIY0zBGz1s4b-Lw_fVvwu871FrUBa7Tga5vdpir6kTDb80Cu1Z_lSSolKyIt46lzIm3GUahz7nfVvvdytwA1uvN09PnffT46z_vN3ubc_qltDlHZutz9DQWZc60vb_YRYeT75rSLtoYc9adECe06pY9ou3n_XoT7R5_2T1uImh04IC6Z4h2A0MSz21-dbfZoeWEri5MaTBj8sxcy2jw3GSY4ZKzNSZMP8QeM3_pnLcsGjv3VYMsCJU1Z2zIurO1jJ5ZXmNn2vf5BYj30Gte-sgatHg4f018DKQK9QH15VvzLbkhSGdOEiauEwaLmGbTKXVC341D389iL_sYSC_X_06QXqm1IPU9j9C1ifN932ymusC0_8_-NrSa9on0pCsuDo-sQMPDZVRgEWNlv6ekzM1YZQLCUxOfRmXEre1zFSn7FFFTemhyQtSFjeq1HM9M1tq4T4i3MVY2CRy0WWESY3SQ3ePXPrcuMN08oi5sOlk0DKwYgfQT9vlo3kXeuvvG8DZnf5XmLRV06Tw6QY_bd_ccAvHP7jp2O-YK4eMO3P7yefVDXJjKOs7xL_bgxza94cCRF2BoEqErKWNrVcZyha-tZCUtUl6R7SEbznrIds2fkP0J2Z-Q_ftB9laB4r7W8NKWTFiuJChEW005IigDyi_7P1fiBn1kGqQ-YmVLPgpOR6xwUHiKuIpulZ5ORizj3zC9rJFOYUfoogAhNai6QmNtV3sSL4BMvcCJvdhq0qhgpCX8IeQJTkeeHIGrpmHIhmegJOygFilWSjORmiHd1mwN7_AUK_trAqH0ZL6tFtpYRyid3qVLLw29kN3h0l04IXVcZ-bfHZdzhunMicOEpUGWzV0_ZmnmJ8EscUPf8ed3fEkd6juUhq7j-K43jZ0wmXmp4zEXfTf2iO9gwXg-zfPnYiqrw539AWAZeL7j3OUsxlx1v4RUS1siiuuDIr6Tc6XVWU1zneNy6A3ireD3SooDtBUiE_eCJZVsSnXridIvOZqo6aZKd10AvKurfPnh0pU9gjIZYk7x3wAAAP__zkO6oQ">