Fix single argument QT_OVERLOADED_MACRO with pedantic warnings enabled

The use of QT_OVERLOADED_MACRO combined with pedantic warnings would
result in

  warning: must specify at least one argument for '...' parameter of
  variadic macro [-Wgnu-zero-variadic-macro-arguments]

when used with a single argument, as the QT_VA_ARGS_COUNT macro would
end up not passing anything to the last ... argument of the helper macro
QT_VA_ARGS_CHOOSE.

To work around this we extend the arguments passed to QT_VA_ARGS_CHOOSE
by one, adding a zero-count, so that the variadic parameter always has
at least one argument.

Unfortunately this doesn't give us a count of 0 if a overloaded Qt macro
is used without arguments, due to __VA_ARGS__ always being treated as an
argument to QT_VA_ARGS_CHOOSE, even when empty, due to the comma after it.
The result is that we end up calling the 1-argument macro for this case
as well.

Getting a correct zero-count, for both MSVC and GCC/Clang, without using
GCC extensions, is quite involved, so we're opting to live with this
limitation. See https://stackoverflow.com/a/62183700 for details.

Fixes: QTBUG-93750
Change-Id: Ib7b26216f36a639642a70387e0d73223633ba6b6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 0855f6279182af9cb54ac5113ba5c99db8ecb819)
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Tor Arne Vestbø 2021-05-18 17:35:40 +02:00
parent 959ff6ae8e
commit 115016c172

View File

@ -1289,7 +1289,7 @@ inline int qIntCast(float f) { return int(f); }
#define QT_VA_ARGS_CHOOSE(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
#define QT_VA_ARGS_EXPAND(...) __VA_ARGS__ // Needed for MSVC
#define QT_VA_ARGS_COUNT(...) QT_VA_ARGS_EXPAND(QT_VA_ARGS_CHOOSE(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1))
#define QT_VA_ARGS_COUNT(...) QT_VA_ARGS_EXPAND(QT_VA_ARGS_CHOOSE(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
#define QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) MACRO##ARGC
#define QT_OVERLOADED_MACRO_IMP(MACRO, ARGC) QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC)
#define QT_OVERLOADED_MACRO(MACRO, ...) QT_VA_ARGS_EXPAND(QT_OVERLOADED_MACRO_IMP(MACRO, QT_VA_ARGS_COUNT(__VA_ARGS__))(__VA_ARGS__))