]> granicus.if.org Git - clang/commitdiff
fix the second half of PR4006 and rdar://6807000 by treating
authorChris Lattner <sabre@nondot.org>
Mon, 20 Apr 2009 21:08:10 +0000 (21:08 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 20 Apr 2009 21:08:10 +0000 (21:08 +0000)
() 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

lib/Lex/PPMacroExpansion.cpp
test/Preprocessor/macro_fn.c

index 330e2a17aa39c55aa75da1d57a5984adc6e24d58..48c166daba26891bc1d528e6432894cbf124f3a5 100644 (file)
@@ -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);
index 90dc2f06d68f7e5d72c8c7cacdf4928764c77e92..98ebaeea72919ca9d61416e5495bbc3f64713740 100644 (file)
@@ -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}} */