From: Chris Lattner Date: Mon, 20 Apr 2009 21:08:10 +0000 (+0000) Subject: fix the second half of PR4006 and rdar://6807000 by treating X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=97e2de171de555feb1ef422e71874082a67498c9;p=clang fix the second half of PR4006 and rdar://6807000 by treating () as being either zero arguments or one empty argument depending on situation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69627 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 330e2a17aa..48c166daba 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -392,7 +392,16 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, if (NumActuals < MinArgsExpected) { // There are several cases where too few arguments is ok, handle them now. - if (NumActuals+1 == MinArgsExpected && MI->isVariadic()) { + if (NumActuals == 0 && MinArgsExpected == 1) { + // #define A(X) or #define A(...) ---> A() + + // If there is exactly one argument, and that argument is missing, + // then we have an empty "()" argument empty list. This is fine, even if + // the macro expects one argument (the argument is just empty). + isVarargsElided = MI->isVariadic(); + } else if (MI->isVariadic() && + (NumActuals+1 == MinArgsExpected || // A(x, ...) -> A(X) + (NumActuals == 0 && MinArgsExpected == 2))) {// A(x,...) -> A() // Varargs where the named vararg parameter is missing: ok as extension. // #define A(x, ...) // A("blah") @@ -404,12 +413,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, // #define B(x, ...) blah(a, ## __VA_ARGS__) // #define C(...) blah(a, ## __VA_ARGS__) // A(x) B(x) C() - isVarargsElided = true; //MI->getNumArgs() > 1; - } else if (NumActuals == 0 && MinArgsExpected == 1) { - assert(!MI->isVariadic() && "Variadic should be handled by case above"); - // If there is exactly one argument, and that argument is missing, - // then we have an empty "()" argument empty list. This is fine, even if - // the macro expects one argument (the argument is just empty). + isVarargsElided = true; } else { // Otherwise, emit the error. Diag(Tok, diag::err_too_few_args_in_macro_invoc); diff --git a/test/Preprocessor/macro_fn.c b/test/Preprocessor/macro_fn.c index 90dc2f06d6..98ebaeea72 100644 --- a/test/Preprocessor/macro_fn.c +++ b/test/Preprocessor/macro_fn.c @@ -4,6 +4,8 @@ #define zero() 0 #define one(x) 0 #define two(x, y) 0 +#define zero_dot(...) 0 /* expected-warning {{variadic macros were introduced in C99}} */ +#define one_dot(x, ...) 0 /* expected-warning {{variadic macros were introduced in C99}} */ zero() zero(1); /* expected-error {{too many arguments provided to function-like macro invocation}} */ @@ -28,6 +30,11 @@ two(,) /* expected-warning 2 {{empty macro arguments were standardized in C -/* PR4006 */ +/* PR4006 & rdar://6807000 */ #define e(...) __VA_ARGS__ /* expected-warning {{variadic macros were introduced in C99}} */ e(x) +e() + +zero_dot() +one_dot(x) /* empty ... argument: expected-warning {{varargs argument missing, but tolerated as an extension}} */ +one_dot() /* empty first argument, elided ...: expected-warning {{varargs argument missing, but tolerated as an extension}} */