summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libs/cplusplus/pp-engine.cpp27
-rw-r--r--tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp58
2 files changed, 32 insertions, 53 deletions
diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp
index 718f3dd0df..fa780f77fe 100644
--- a/src/libs/cplusplus/pp-engine.cpp
+++ b/src/libs/cplusplus/pp-engine.cpp
@@ -793,7 +793,25 @@ bool Preprocessor::handleIdentifier(PPToken *tk)
if (macro->isFunctionLike()) {
// Collect individual tokens that form the macro arguments.
QVector<QVector<PPToken> > allArgTks;
- if (!collectActualArguments(tk, &allArgTks)) {
+ bool hasArgs = collectActualArguments(tk, &allArgTks);
+
+ // Check for matching parameter/argument count.
+ bool hasMatchingArgs = false;
+ if (hasArgs) {
+ const int expectedArgCount = macro->formals().size();
+ const int actualArgCount = allArgTks.size();
+ if (expectedArgCount == actualArgCount
+ || (macro->isVariadic() && actualArgCount > expectedArgCount - 1)
+ // Handle '#define foo()' when invoked as 'foo()'
+ || (expectedArgCount == 0
+ && actualArgCount == 1
+ && allArgTks.at(0).isEmpty())) {
+ hasMatchingArgs = true;
+ }
+ }
+
+ if (!hasArgs || !hasMatchingArgs) {
+ //### TODO: error message
pushToken(tk);
*tk = idTk;
return false;
@@ -872,12 +890,6 @@ bool Preprocessor::handleFunctionLikeMacro(PPToken *tk,
int j = 0;
for (; j < formals.size() && expanded.size() < MAX_TOKEN_EXPANSION_COUNT; ++j) {
if (formals[j] == id) {
- if (actuals.size() <= j) {
- // too few actual parameters
- //### TODO: error message
- goto exitNicely;
- }
-
QVector<PPToken> actualsForThisParam = actuals.at(j);
if (id == "__VA_ARGS__" || (macro->isVariadic() && j + 1 == formals.size())) {
unsigned lineno = 0;
@@ -929,7 +941,6 @@ bool Preprocessor::handleFunctionLikeMacro(PPToken *tk,
}
}
-exitNicely:
pushToken(tk);
if (addWhitespaceMarker) {
PPToken forceWhitespacingToken;
diff --git a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp
index e703cf2f34..b5cb82649d 100644
--- a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp
+++ b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp
@@ -300,10 +300,6 @@ protected:
}
static QString simplified(QByteArray buf);
-private /* not corrected yet */:
- void param_expanding_as_multiple_params();
- void macro_argument_expansion();
-
private slots:
void defined();
void defined_data();
@@ -447,49 +443,21 @@ void tst_Preprocessor::macro_args_count()
void tst_Preprocessor::invalid_param_count()
{
- Client *client = 0; // no client.
- Environment env;
-
- Preprocessor preprocess(client, &env);
- // The following is illegal, but shouldn't crash the preprocessor.
- // GCC says: 3:14: error: macro "foo" requires 2 arguments, but only 1 given
- QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"),
- "\n#define foo(a,b) int f(a,b);"
- "\n#define ARGS(t) t a,t b"
- "\nfoo(ARGS(int))",
- true, false);
- // do not verify the output: it's illegal, so anything might be outputted.
-}
-
-void tst_Preprocessor::param_expanding_as_multiple_params()
-{
- Client *client = 0; // no client.
Environment env;
+ QByteArray output;
+ MockClient client(&env, &output);
+ Preprocessor preprocess(&client, &env);
+ // The following are illegal, but shouldn't crash the preprocessor.
+ preprocess.run(QLatin1String("<stdin>"),
+ "\n#define foo(a,b) int f(a,b);"
+ "\n#define ARGS(t) t a,t b"
+ "\nfoo(ARGS(int))"
+ "\nfoo()"
+ "\nfoo(int a, int b, int c)",
+ true, false);
- Preprocessor preprocess(client, &env);
- QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"),
- "\n#define foo(a,b) int f(a,b);"
- "\n#define ARGS(t) t a,t b"
- "\nfoo(ARGS(int))",
- false, true);
- QCOMPARE(simplified(preprocessed), QString("int f(int a,int b);"));
-}
-
-void tst_Preprocessor::macro_argument_expansion() //QTCREATORBUG-7225
-{
- Client *client = 0; // no client.
- Environment env;
-
- Preprocessor preprocess(client, &env);
- QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"),
- "\n#define BAR1 2,3,4"
- "\n#define FOO1(a,b,c) a+b+c"
- "\nvoid test2(){"
- "\nint x=FOO1(BAR1);"
- "\n}",
- false, true);
- QCOMPARE(simplified(preprocessed), QString("void test2(){int x=2+3+4;}"));
-
+ // Output is not that relevant but check that nothing triggered expansion.
+ QCOMPARE(client.macroArgsCount(), QList<int>());
}
void tst_Preprocessor::macro_uses()