Merge bitcoin-core/gui#949: Fix -Wsfinae-incomplete warnings when building with GCC 16.x

51d36dfd07 qt: Fix `-Wsfinae-incomplete` warnings when building with GCC 16.x (Hennadii Stepanov)

Pull request description:

  According to the CMake documentation for [`AUTOMOC`](https://cmake.org/cmake/help/latest/prop_tgt/AUTOMOC.html), all `moc` output files that are not included in a source file are aggregated into the CMake-generated `<AUTOGEN_BUILD_DIR>/mocs_compilation.cpp`, which is added to the target's sources.

  Within that single translation unit, `moc`-generated code checks the completeness of a signal or slot parameter type while it is still only forward-declared, and the type is completed later, when a subsequently included `moc_*.cpp` file pulls in the header that defines it. GCC 16.x diagnoses this pattern with the `-Wsfinae-incomplete` warning, which is enabled by default.

  Including the `moc` output files at the end of the corresponding source files excludes them from `mocs_compilation.cpp`, so each one is compiled in a translation unit where the relevant types are complete.

  FWIW, Qt itself uses the same approach throughout its own codebase. Also see https://www.youtube.com/watch?v=Cx_m-qVnEjo.

  ---

  Steps to reproduce on the master branch @ 18c05d9301  on Fedora 44 (GCC 16.1.1):
  ```console
  $ cmake --preset dev-mode
  $ cmake --build build_dev_mode -t bitcoind
  $ cmake --build build_dev_mode -t bitcoin-qt
  [166/172] Building CXX object src/qt/CMakeFiles/bitcoinqt.dir/bitcoinqt_autogen/mocs_compilation.cpp.o
  In file included from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/EWIEGA46WW/moc_bitcoingui.cpp:9,
                   from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/mocs_compilation.cpp:9:
  /home/hebasto/dev/bitcoin-gui/src/qt/bitcoingui.h:67:7: warning: defining ‘BitcoinGUI’, which previously failed to be complete in a SFINAE context [-Wsfinae-incomplete=]
     67 | class BitcoinGUI : public QMainWindow
        |       ^~~~~~~~~~
  In file included from /usr/include/qt6/QtCore/qobject.h:19,
                   from /usr/include/qt6/QtWidgets/qwidget.h:10,
                   from /usr/include/qt6/QtWidgets/qdialog.h:9,
                   from /usr/include/qt6/QtWidgets/QDialog:1,
                   from /home/hebasto/dev/bitcoin-gui/src/qt/addressbookpage.h:8,
                   from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/EWIEGA46WW/moc_addressbookpage.cpp:9,
                   from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/mocs_compilation.cpp:2:
  /usr/include/qt6/QtCore/qmetatype.h:344:64: note: here.  Use ‘-Wsfinae-incomplete=2’ for a diagnostic at that point
    344 |         static auto check(U *) -> std::integral_constant<bool, sizeof(U) != 0>;
        |                                                                ^~~~~~~~~
  In file included from /home/hebasto/dev/bitcoin-gui/src/qt/paymentserver.h:35,
                   from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/EWIEGA46WW/moc_paymentserver.cpp:9,
                   from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/mocs_compilation.cpp:27:
  /home/hebasto/dev/bitcoin-gui/src/qt/sendcoinsrecipient.h:15:7: warning: defining ‘SendCoinsRecipient’, which previously failed to be complete in a SFINAE context [-Wsfinae-incomplete=]
     15 | class SendCoinsRecipient
        |       ^~~~~~~~~~~~~~~~~~
  /usr/include/qt6/QtCore/qmetatype.h:344:64: note: here.  Use ‘-Wsfinae-incomplete=2’ for a diagnostic at that point
    344 |         static auto check(U *) -> std::integral_constant<bool, sizeof(U) != 0>;
        |                                                                ^~~~~~~~~
  In file included from /home/hebasto/dev/bitcoin-gui/src/qt/psbtoperationsdialog.h:13,
                   from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/EWIEGA46WW/moc_psbtoperationsdialog.cpp:9,
                   from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/mocs_compilation.cpp:30:
  /home/hebasto/dev/bitcoin-gui/src/qt/walletmodel.h:48:7: warning: defining ‘WalletModel’, which previously failed to be complete in a SFINAE context [-Wsfinae-incomplete=]
     48 | class WalletModel : public QObject
        |       ^~~~~~~~~~~
  /usr/include/qt6/QtCore/qmetatype.h:344:64: note: here.  Use ‘-Wsfinae-incomplete=2’ for a diagnostic at that point
    344 |         static auto check(U *) -> std::integral_constant<bool, sizeof(U) != 0>;
        |                                                                ^~~~~~~~~
  In file included from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/EWIEGA46WW/moc_qvalidatedlineedit.cpp:9,
                   from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/mocs_compilation.cpp:32:
  /home/hebasto/dev/bitcoin-gui/src/qt/qvalidatedlineedit.h:13:7: warning: defining ‘QValidatedLineEdit’, which previously failed to be complete in a SFINAE context [-Wsfinae-incomplete=]
     13 | class QValidatedLineEdit : public QLineEdit
        |       ^~~~~~~~~~~~~~~~~~
  /usr/include/qt6/QtCore/qmetatype.h:344:64: note: here.  Use ‘-Wsfinae-incomplete=2’ for a diagnostic at that point
    344 |         static auto check(U *) -> std::integral_constant<bool, sizeof(U) != 0>;
        |                                                                ^~~~~~~~~
  In file included from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/EWIEGA46WW/moc_rpcconsole.cpp:9,
                   from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/mocs_compilation.cpp:37:
  /home/hebasto/dev/bitcoin-gui/src/qt/rpcconsole.h:43:7: warning: defining ‘RPCConsole’, which previously failed to be complete in a SFINAE context [-Wsfinae-incomplete=]
     43 | class RPCConsole: public QWidget
        |       ^~~~~~~~~~
  /usr/include/qt6/QtCore/qmetatype.h:344:64: note: here.  Use ‘-Wsfinae-incomplete=2’ for a diagnostic at that point
    344 |         static auto check(U *) -> std::integral_constant<bool, sizeof(U) != 0>;
        |                                                                ^~~~~~~~~
  In file included from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/EWIEGA46WW/moc_sendcoinsentry.cpp:9,
                   from /home/hebasto/dev/bitcoin-gui/build_dev_mode/src/qt/bitcoinqt_autogen/mocs_compilation.cpp:39:
  /home/hebasto/dev/bitcoin-gui/src/qt/sendcoinsentry.h:26:7: warning: defining ‘SendCoinsEntry’, which previously failed to be complete in a SFINAE context [-Wsfinae-incomplete=]
     26 | class SendCoinsEntry : public QWidget
        |       ^~~~~~~~~~~~~~
  /usr/include/qt6/QtCore/qmetatype.h:344:64: note: here.  Use ‘-Wsfinae-incomplete=2’ for a diagnostic at that point
    344 |         static auto check(U *) -> std::integral_constant<bool, sizeof(U) != 0>;
        |                                                                ^~~~~~~~~
  [172/172] Linking CXX executable bin/bitcoin-qt
  ```

ACKs for top commit:
  maflcko:
    review ACK 51d36dfd07 🦅

Tree-SHA512: fe48e4925aaccb833bc065aa7f988f22482ef83d3d555e601d3955109f840b221be971c560668eac79506f567999d4e1b2a464ec3717b5cecb9a3eaaa1dbc01b
This commit is contained in:
Hennadii Stepanov
2026-07-22 10:11:49 +01:00
5 changed files with 17 additions and 3 deletions

View File

@@ -1721,3 +1721,5 @@ void UnitDisplayStatusBarControl::onMenuSelection(QAction* action)
optionsModel->setDisplayUnit(action->data());
}
}
#include <moc_bitcoingui.cpp>

View File

@@ -114,7 +114,9 @@ protected:
private:
interfaces::Node& m_node;
#ifdef ENABLE_WALLET
WalletController* m_wallet_controller{nullptr};
#endif // ENABLE_WALLET
std::unique_ptr<interfaces::Handler> m_handler_message_box;
std::unique_ptr<interfaces::Handler> m_handler_question;
ClientModel* clientModel = nullptr;
@@ -158,15 +160,17 @@ private:
QAction* m_restore_wallet_action{nullptr};
QAction* m_close_wallet_action{nullptr};
QAction* m_close_all_wallets_action{nullptr};
#ifdef ENABLE_WALLET
QAction* m_wallet_selector_label_action = nullptr;
QAction* m_wallet_selector_action = nullptr;
#endif // ENABLE_WALLET
QAction* m_mask_values_action{nullptr};
QAction* m_migrate_wallet_action{nullptr};
QMenu* m_migrate_wallet_menu{nullptr};
#ifdef ENABLE_WALLET
QLabel *m_wallet_selector_label = nullptr;
QComboBox* m_wallet_selector = nullptr;
#endif // ENABLE_WALLET
QSystemTrayIcon* trayIcon = nullptr;
const std::unique_ptr<QMenu> trayIconMenu;
Notificator* notificator = nullptr;

View File

@@ -126,3 +126,5 @@ bool QValidatedLineEdit::isValid()
return valid;
}
#include <moc_qvalidatedlineedit.cpp>

View File

@@ -238,3 +238,5 @@ bool SendCoinsEntry::updateLabel(const QString &address)
return false;
}
#include <moc_sendcoinsentry.cpp>

View File

@@ -70,7 +70,11 @@ def find_included_cpps():
if e.returncode > 1:
raise e
return included_cpps
# Exception: `#include <moc_*.cpp>` statements in src/qt source files are permitted.
# See:
# - https://doc.qt.io/qt-6/moc.html
# - https://cmake.org/cmake/help/latest/prop_tgt/AUTOMOC.html
return [i for i in included_cpps if not re.match(r"src/qt/[^:]+\.cpp:#include <moc_[^<>:]+\.cpp>$", i)]
def find_extra_boosts():