summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qmake/generators/makefiledeps.cpp25
-rw-r--r--tests/auto/tools/qmake/testdata/findMocs/digitseparated.h8
-rw-r--r--tests/auto/tools/qmake/testdata/findMocs/findMocs.pro3
-rw-r--r--tests/auto/tools/qmake/testdata/findMocs/main.cpp8
4 files changed, 39 insertions, 5 deletions
diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp
index 0646d232ce..c8f4772dcb 100644
--- a/qmake/generators/makefiledeps.cpp
+++ b/qmake/generators/makefiledeps.cpp
@@ -365,13 +365,21 @@ static bool matchWhileUnsplitting(const char *buffer, int buffer_len, int start,
return true;
}
-/* Advance from an opening quote at buffer[offset] to the matching close quote. */
+/* Advance from an opening quote at buffer[offset] to the matching close quote.
+ If an apostrophe turns out to be a digit-separator in a numeric literal,
+ rather than the start of a character literal, treat it as both the open and
+ the close quote of the "string" that isn't there.
+*/
static int scanPastString(char *buffer, int buffer_len, int offset, int *lines)
{
// http://en.cppreference.com/w/cpp/language/string_literal
// It might be a C++11 raw string.
bool israw = false;
- if (buffer[offset] == '"' && offset > 0) {
+
+ Q_ASSERT(offset < buffer_len);
+ if (offset <= 0) {
+ // skip, neither of these special cases applies here
+ } else if (buffer[offset] == '"') {
int explore = offset - 1;
bool prefix = false; // One of L, U, u or u8 may appear before R
bool saw8 = false; // Partial scan of u8
@@ -415,6 +423,19 @@ static int scanPastString(char *buffer, int buffer_len, int offset, int *lines)
&& (isalnum(buffer[explore]) || buffer[explore] == '_')) {
israw = false;
}
+
+ } else {
+ // Is this apostrophe a digit separator rather than the start of a
+ // character literal ? If so, there was no string to scan past, so
+ // treat the apostrophe as both open and close.
+ Q_ASSERT(buffer[offset] == '\'' && offset > 0);
+ // Wrap std::isdigit() to package the casting to unsigned char.
+ const auto isDigit = [](unsigned char c) { return std::isdigit(c); };
+ if (isDigit(buffer[offset - 1]) && offset + 1 < buffer_len && isDigit(buffer[offset + 1])) {
+ // One exception: u8'0' is a perfectly good character literal.
+ if (offset < 2 || buffer[offset - 1] != '8' || buffer[offset - 2] != 'u')
+ return offset;
+ }
}
if (israw) {
diff --git a/tests/auto/tools/qmake/testdata/findMocs/digitseparated.h b/tests/auto/tools/qmake/testdata/findMocs/digitseparated.h
new file mode 100644
index 0000000000..ddedac26e3
--- /dev/null
+++ b/tests/auto/tools/qmake/testdata/findMocs/digitseparated.h
@@ -0,0 +1,8 @@
+#include <QObject>
+
+class AfterDigitSeparator : public QObject
+{
+ Q_OBJECT
+public:
+ AfterDigitSeparator() : QObject(nullptr) {}
+};
diff --git a/tests/auto/tools/qmake/testdata/findMocs/findMocs.pro b/tests/auto/tools/qmake/testdata/findMocs/findMocs.pro
index af672c2621..de2fdff3d2 100644
--- a/tests/auto/tools/qmake/testdata/findMocs/findMocs.pro
+++ b/tests/auto/tools/qmake/testdata/findMocs/findMocs.pro
@@ -1,5 +1,6 @@
DESTDIR = ./
HEADERS += object1.h object2.h object3.h object4.h \
- object5.h object6.h object7.h object8.h object9.h
+ object5.h object6.h object7.h object8.h object9.h \
+ digitseparated.h
SOURCES += main.cpp
diff --git a/tests/auto/tools/qmake/testdata/findMocs/main.cpp b/tests/auto/tools/qmake/testdata/findMocs/main.cpp
index 2123fca958..441df50d9e 100644
--- a/tests/auto/tools/qmake/testdata/findMocs/main.cpp
+++ b/tests/auto/tools/qmake/testdata/findMocs/main.cpp
@@ -1,7 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
#include <moc_object1.cpp>
#include <moc_object2.cpp>
#include <moc_object3.cpp>
@@ -12,4 +11,9 @@
#include "object8.h"
#include <moc_object9.cpp>
-int main() { return 0; }
+int main() { return 0'000; }
+/* Included *after* the use of a numeric literal with an *odd* number of digit
+ separator tick marks in it (and no subsequent apostrophe to end the
+ "single-quoted character literal" that the old parser though it was thus left
+ in). */
+#include <moc_digitseparated.cpp>