diff options
-rw-r--r-- | qmake/generators/makefiledeps.cpp | 25 | ||||
-rw-r--r-- | tests/auto/tools/qmake/testdata/findMocs/digitseparated.h | 8 | ||||
-rw-r--r-- | tests/auto/tools/qmake/testdata/findMocs/findMocs.pro | 3 | ||||
-rw-r--r-- | tests/auto/tools/qmake/testdata/findMocs/main.cpp | 8 |
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> |