Blob Blame History Raw
diff --git a/src/common/dout.h b/src/common/dout.h
index 4cd60efff8fef..db68a042a7f1b 100644
--- a/src/common/dout.h
+++ b/src/common/dout.h
@@ -144,17 +144,24 @@ struct is_dynamic<dynamic_marker_t<T>> : public std::true_type {};
 #else
 #define dout_impl(cct, sub, v)						\
   do {									\
-  const bool should_gather = [&](const auto cctX) {			\
-    if constexpr (ceph::dout::is_dynamic<decltype(sub)>::value ||	\
-		  ceph::dout::is_dynamic<decltype(v)>::value) {		\
+  const bool should_gather = [&](const auto cctX, auto sub_, auto v_) {	\
+    /* The check is performed on `sub_` and `v_` to leverage the C++'s 	\
+     * guarantee on _discarding_ one of blocks of `if constexpr`, which	\
+     * includes also the checks for ill-formed code (`should_gather<>`	\
+     * must not be feed with non-const expresions), BUT ONLY within	\
+     * a template (thus the generic lambda) and under the restriction	\
+     * it's dependant on a parameter of this template).			\
+     * GCC prior to v14 was not enforcing these restrictions. */	\
+    if constexpr (ceph::dout::is_dynamic<decltype(sub_)>::value ||	\
+		  ceph::dout::is_dynamic<decltype(v_)>::value) {	\
       return cctX->_conf->subsys.should_gather(sub, v);			\
     } else {								\
-      /* The parentheses are **essential** because commas in angle	\
-       * brackets are NOT ignored on macro expansion! A language's	\
-       * limitation, sorry. */						\
-      return (cctX->_conf->subsys.template should_gather<sub, v>());	\
+      constexpr auto sub_helper = static_cast<decltype(sub_)>(sub);	\
+      constexpr auto v_helper = static_cast<decltype(v_)>(v);		\
+      return cctX->_conf->subsys.template should_gather<sub_helper,	\
+							v_helper>();	\
     }									\
-  }(cct);								\
+  }(cct, sub, v);							\
 									\
   if (should_gather) {							\
     ceph::logging::MutableEntry _dout_e(v, sub);                        \