Avoid signed overflow in moc

moc's preprocessor needs to implement certain math operation to
correctly handle #if conditions. Unfortunately, its implementation is
not overflow safe. However, those are rare enough in practice that we
in general do not need to care about them.
This patch adds a workaround for one case where UBSAN run into an
overflow related issue.
A complete fix would require to make moc spec compliant (do math with
std::max_(u)int_t operands; always wrap on overflow) in all operations.

Pick-to: 6.0 5.15
Fixes: QTBUG-88825
Change-Id: Ic4d2cb097db2fa2f9d4681bbaab3068eaa2745aa
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Fabian Kosmale 2020-11-24 20:49:32 +01:00
parent 9a161b6700
commit df8fbcf382

View File

@ -886,7 +886,15 @@ int PP_Expression::multiplicative_expression()
int value = unary_expression();
switch (next()) {
case PP_STAR:
return value * multiplicative_expression();
{
// get well behaved overflow behavior by converting to long
// and then back to int
// NOTE: A conformant preprocessor would need to work intmax_t/
// uintmax_t according to [cpp.cond], 19.1 §10
// But we're not compliant anyway
qint64 result = qint64(value) * qint64(multiplicative_expression());
return int(result);
}
case PP_PERCENT:
{
int remainder = multiplicative_expression();