Commit 271c3f45 authored by Erik Verbruggen's avatar Erik Verbruggen Committed by Erik Verbruggen

C++: Fix preprocessor blocked macro bug.

By lexing the first token after a macro call (meaning: the token after
the closing parenthesis (which was passed to handleFunctionLikeMacro
which in turn pushed it back into the token buffer)), a token buffer
might be popped, which unblocks the macro that generated the actual
param pack. The effect was that if this happens in the expansion of a
recursive macro (with parameters!), the preprocessor ended up in an
infinite loop.

Task-number: QTCREATORBUG-9015
Task-number: QTCREATORBUG-9447

Change-Id: I0d83c59188ec15c4a948970e9fa944a17d765475
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent d0afdfcc
......@@ -1048,7 +1048,7 @@ bool Preprocessor::handleIdentifier(PPToken *tk)
argRefs);
}
if (!handleFunctionLikeMacro(tk, macro, body, allArgTks, baseLine)) {
if (!handleFunctionLikeMacro(macro, body, allArgTks, baseLine)) {
if (m_client && !idTk.expanded())
m_client->stopExpandingMacro(idTk.offset, *macro);
return false;
......@@ -1119,8 +1119,7 @@ bool Preprocessor::handleIdentifier(PPToken *tk)
return true;
}
bool Preprocessor::handleFunctionLikeMacro(PPToken *tk,
const Macro *macro,
bool Preprocessor::handleFunctionLikeMacro(const Macro *macro,
QVector<PPToken> &body,
const QVector<QVector<PPToken> > &actuals,
unsigned baseLine)
......@@ -1220,9 +1219,6 @@ bool Preprocessor::handleFunctionLikeMacro(PPToken *tk,
body = expanded;
body.squeeze();
// Next token to be lexed after the expansion.
pushToken(tk);
return true;
}
......@@ -1479,9 +1475,9 @@ bool Preprocessor::collectActualArguments(PPToken *tk, QVector<QVector<PPToken>
actuals->append(tokens);
}
if (tk->is(T_RPAREN))
lex(tk);
//###TODO: else error message
if (!tk->is(T_RPAREN)) {
//###TODO: else error message
}
return true;
}
......
......@@ -205,8 +205,7 @@ private:
void lex(PPToken *tk);
void skipPreprocesorDirective(PPToken *tk);
bool handleIdentifier(PPToken *tk);
bool handleFunctionLikeMacro(PPToken *tk,
const Macro *macro,
bool handleFunctionLikeMacro(const Macro *macro,
QVector<PPToken> &body,
const QVector<QVector<PPToken> > &actuals,
unsigned lineRef);
......
#define a(x) b(x) c(x)
#define b(x) c(x) a(x)
#define c(x) a(x) b(x)
b(1)
a(1)
# 1 "data/recursive.2.cpp"
# expansion begin 70,1 ~2 5:2 ~3 5:2 ~3 5:2 ~3 5:2 ~3 5:2 ~3 5:2 ~1
b(1) c(1) b(1) b(1) a(1) b(1)
# expansion end
# expansion begin 75,1 ~2 6:2 ~3 6:2 ~3 6:2 ~3 6:2 ~3 6:2 ~3 6:2 ~1
a(1) b(1) a(1) a(1) c(1) a(1)
# expansion end
# 7 "data/recursive.2.cpp"
......@@ -822,6 +822,8 @@ void tst_Preprocessor::comparisons_data()
<< "reserved.1.cpp" << "reserved.1.out.cpp" << "";
QTest::newRow("recursive 1")
<< "recursive.1.cpp" << "recursive.1.out.cpp" << "";
QTest::newRow("recursive 2")
<< "recursive.2.cpp" << "recursive.2.out.cpp" << "";
QTest::newRow("macro_pounder_fn")
<< "macro_pounder_fn.c" << "" << "";
QTest::newRow("macro_expand")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment