MOC: pass the erroneous Symbol as an arg to Parser::error() overload
We already know the Symbol while parsing, passing a reference to it to error() makes it simpler to construct the error message. This fixes an issue where reporting an error about "NONSENSE" in e.g.: Q_PROPERTY(Foo* foo NONSENSE foo) would be off-by-one and the error message would say: path/to/file.h:11:1: error: Parse error at "foo" instead of 'at "NONSENSE"', which is where the parser actually found an unexpected attribute. Fixes: QTBUG-36367 Pick-to: 6.5 Change-Id: Ief70e544af41f7575fbeea9b936fa8197c3ef43d Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
328680b34b
commit
d2242c353f
@ -1300,7 +1300,8 @@ void Moc::parsePropertyAttributes(PropertyDef &propDef)
|
|||||||
};
|
};
|
||||||
|
|
||||||
while (test(IDENTIFIER)) {
|
while (test(IDENTIFIER)) {
|
||||||
const QByteArray l = lexem();
|
const Symbol &lsym = symbol();
|
||||||
|
const QByteArray l = lsym.lexem();
|
||||||
if (l[0] == 'C' && l == "CONSTANT") {
|
if (l[0] == 'C' && l == "CONSTANT") {
|
||||||
propDef.constant = true;
|
propDef.constant = true;
|
||||||
continue;
|
continue;
|
||||||
@ -1327,11 +1328,11 @@ void Moc::parsePropertyAttributes(PropertyDef &propDef)
|
|||||||
} else if (test(INTEGER_LITERAL)) {
|
} else if (test(INTEGER_LITERAL)) {
|
||||||
v = lexem();
|
v = lexem();
|
||||||
if (l != "REVISION")
|
if (l != "REVISION")
|
||||||
error(1);
|
error(lsym);
|
||||||
} else if (test(DEFAULT)) {
|
} else if (test(DEFAULT)) {
|
||||||
v = lexem();
|
v = lexem();
|
||||||
if (l != "READ" && l != "WRITE")
|
if (l != "READ" && l != "WRITE")
|
||||||
error(1);
|
error(lsym);
|
||||||
} else {
|
} else {
|
||||||
next(IDENTIFIER);
|
next(IDENTIFIER);
|
||||||
v = lexem();
|
v = lexem();
|
||||||
@ -1345,7 +1346,7 @@ void Moc::parsePropertyAttributes(PropertyDef &propDef)
|
|||||||
if (l == "MEMBER")
|
if (l == "MEMBER")
|
||||||
propDef.member = v;
|
propDef.member = v;
|
||||||
else
|
else
|
||||||
error(2);
|
error(lsym);
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
if (l == "READ")
|
if (l == "READ")
|
||||||
@ -1356,10 +1357,10 @@ void Moc::parsePropertyAttributes(PropertyDef &propDef)
|
|||||||
bool ok = false;
|
bool ok = false;
|
||||||
const int minor = v.toInt(&ok);
|
const int minor = v.toInt(&ok);
|
||||||
if (!ok || !QTypeRevision::isValidSegment(minor))
|
if (!ok || !QTypeRevision::isValidSegment(minor))
|
||||||
error(1);
|
error(lsym);
|
||||||
propDef.revision = QTypeRevision::fromMinorVersion(minor).toEncodedVersion<int>();
|
propDef.revision = QTypeRevision::fromMinorVersion(minor).toEncodedVersion<int>();
|
||||||
} else
|
} else
|
||||||
error(2);
|
error(lsym);
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
if (l == "SCRIPTABLE") {
|
if (l == "SCRIPTABLE") {
|
||||||
@ -1369,27 +1370,27 @@ void Moc::parsePropertyAttributes(PropertyDef &propDef)
|
|||||||
propDef.stored = v + v2;
|
propDef.stored = v + v2;
|
||||||
checkIsFunction(propDef.stored, "STORED");
|
checkIsFunction(propDef.stored, "STORED");
|
||||||
} else
|
} else
|
||||||
error(2);
|
error(lsym);
|
||||||
break;
|
break;
|
||||||
case 'W': if (l != "WRITE") error(2);
|
case 'W': if (l != "WRITE") error(lsym);
|
||||||
propDef.write = v;
|
propDef.write = v;
|
||||||
break;
|
break;
|
||||||
case 'B': if (l != "BINDABLE") error(2);
|
case 'B': if (l != "BINDABLE") error(lsym);
|
||||||
propDef.bind = v;
|
propDef.bind = v;
|
||||||
break;
|
break;
|
||||||
case 'D': if (l != "DESIGNABLE") error(2);
|
case 'D': if (l != "DESIGNABLE") error(lsym);
|
||||||
propDef.designable = v + v2;
|
propDef.designable = v + v2;
|
||||||
checkIsFunction(propDef.designable, "DESIGNABLE");
|
checkIsFunction(propDef.designable, "DESIGNABLE");
|
||||||
break;
|
break;
|
||||||
case 'N': if (l != "NOTIFY") error(2);
|
case 'N': if (l != "NOTIFY") error(lsym);
|
||||||
propDef.notify = v;
|
propDef.notify = v;
|
||||||
break;
|
break;
|
||||||
case 'U': if (l != "USER") error(2);
|
case 'U': if (l != "USER") error(lsym);
|
||||||
propDef.user = v + v2;
|
propDef.user = v + v2;
|
||||||
checkIsFunction(propDef.user, "USER");
|
checkIsFunction(propDef.user, "USER");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error(2);
|
error(lsym);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (propDef.constant && !propDef.write.isNull()) {
|
if (propDef.constant && !propDef.write.isNull()) {
|
||||||
|
@ -20,17 +20,24 @@ static const char *error_msg = nullptr;
|
|||||||
#define ErrorFormatString "%s:%d:%d: "
|
#define ErrorFormatString "%s:%d:%d: "
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Parser::error(int rollback) {
|
static void defaultErrorMsg(const QByteArray &fileName, const Symbol &sym)
|
||||||
index -= rollback;
|
{
|
||||||
error();
|
fprintf(stderr, ErrorFormatString "error: Parse error at \"%s\"\n",
|
||||||
|
fileName.constData(), sym.lineNum, 1, sym.lexem().data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parser::error(const Symbol &sym)
|
||||||
|
{
|
||||||
|
defaultErrorMsg(currentFilenames.top(), sym);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
void Parser::error(const char *msg) {
|
void Parser::error(const char *msg) {
|
||||||
if (msg || error_msg)
|
if (msg || error_msg)
|
||||||
fprintf(stderr, ErrorFormatString "error: %s\n",
|
fprintf(stderr, ErrorFormatString "error: %s\n",
|
||||||
currentFilenames.top().constData(), symbol().lineNum, 1, msg?msg:error_msg);
|
currentFilenames.top().constData(), symbol().lineNum, 1, msg?msg:error_msg);
|
||||||
else
|
else
|
||||||
fprintf(stderr, ErrorFormatString "error: Parse error at \"%s\"\n",
|
defaultErrorMsg(currentFilenames.top(), symbol());
|
||||||
currentFilenames.top().constData(), symbol().lineNum, 1, symbol().lexem().data());
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ public:
|
|||||||
inline QByteArray unquotedLexem() { return symbols.at(index-1).unquotedLexem();}
|
inline QByteArray unquotedLexem() { return symbols.at(index-1).unquotedLexem();}
|
||||||
inline const Symbol &symbol() { return symbols.at(index-1);}
|
inline const Symbol &symbol() { return symbols.at(index-1);}
|
||||||
|
|
||||||
Q_NORETURN void error(int rollback);
|
Q_NORETURN void error(const Symbol &symbol);
|
||||||
Q_NORETURN void error(const char *msg = nullptr);
|
Q_NORETURN void error(const char *msg = nullptr);
|
||||||
void warning(const char * = nullptr);
|
void warning(const char * = nullptr);
|
||||||
void note(const char * = nullptr);
|
void note(const char * = nullptr);
|
||||||
|
@ -62,6 +62,8 @@
|
|||||||
|
|
||||||
#include "qmlmacro.h"
|
#include "qmlmacro.h"
|
||||||
|
|
||||||
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
#ifdef Q_MOC_RUN
|
#ifdef Q_MOC_RUN
|
||||||
// check that moc can parse these constructs, they are being used in Windows winsock2.h header
|
// check that moc can parse these constructs, they are being used in Windows winsock2.h header
|
||||||
#define STRING_HASH_HASH(x) ("foo" ## x ## "bar")
|
#define STRING_HASH_HASH(x) ("foo" ## x ## "bar")
|
||||||
@ -2371,6 +2373,13 @@ void tst_Moc::warnings_data()
|
|||||||
<< QString()
|
<< QString()
|
||||||
<< QString("standard input:3:1: error: Parse error at \"decltype\"");
|
<< QString("standard input:3:1: error: Parse error at \"decltype\"");
|
||||||
|
|
||||||
|
QTest::newRow("QTBUG-36367: report correct error location")
|
||||||
|
<< "class X { \n Q_PROPERTY(Foo* foo NONSENSE foo) \n };"_ba
|
||||||
|
<< QStringList()
|
||||||
|
<< 1
|
||||||
|
<< QString()
|
||||||
|
<< u"standard input:2:1: error: Parse error at \"NONSENSE\""_s;
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX // Limit to Unix because the error message is platform-dependent
|
#ifdef Q_OS_UNIX // Limit to Unix because the error message is platform-dependent
|
||||||
QTest::newRow("Q_PLUGIN_METADATA: unreadable file")
|
QTest::newRow("Q_PLUGIN_METADATA: unreadable file")
|
||||||
<< QByteArray("class X { \n Q_PLUGIN_METADATA(FILE \".\") \n };")
|
<< QByteArray("class X { \n Q_PLUGIN_METADATA(FILE \".\") \n };")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user