summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-11-24 20:49:32 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2020-12-03 13:51:32 +0100
commitdf8fbcf382b086e96082a8eb3622c60273e94c4d (patch)
treeb76364fc052a0bd1535e995ba07496934fc8a359 /src/tools
parent9a161b6700f39756bda0089e639cb92f39b70402 (diff)
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>
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/moc/preprocessor.cpp10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp
index a99b8cc80c..c6e84c0913 100644
--- a/src/tools/moc/preprocessor.cpp
+++ b/src/tools/moc/preprocessor.cpp
@@ -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();