On Fri, Oct 2, 2015 at 5:22 PM, mats petersson <m...@planetcatfish.com> wrote: > > > On 2 October 2015 at 22:07, Aaron Ballman <aa...@aaronballman.com> wrote: >> >> On Fri, Oct 2, 2015 at 4:01 PM, mats petersson <m...@planetcatfish.com> >> wrote: >> > Since "varargs" often involve some kind of special passing mechanisms >> > [I've >> > seen implementations that build data block and pass a pointer to that, >> > rather than passing on the stack, for example], or additional code in >> > the >> > recipient function, I would say that `f2()` does not mean `f2(...)`. >> >> I kind of wondered if that was the case. If that's reality, perhaps we >> may want to consider naming it FunctionDecl::hasVarArgs() or something >> that specifies the difference is in whether we need to care about >> packaging up the argument list so it can be used with va_start() and >> friends? > > > My understanding of the meaning of `isVariadic` is indeed "needs to use va_* > to get arguments". > > I believe it's technically valid to do something like: > > void f2(); > > .... > f2(42); > .... > > voif f2(int x) > { > ... use x ... > } > > and no special code should be required. Of course, the results of changing > `f2(42);` int `f2(4.2);` or `f2("foo");` and retaining the `int x` parameter > will lead to undefined behaviour, and compiler can do anything it likes with > that... :)
That is correct, and why I was originally surprised that isVaridic() was returning false for such a declaration. However, what you can't do with an empty parameter declaration list, but can do with a trailing varargs, is get a va_list out of the final parameter. AFAIK, you cannot do this: void f2(); void f2(int x, ...) { va_list va; va_start(va, x); va_end(va); } int main(void) { f2(12, 1.2, "this is one reason why I hate C"); } ~Aaron > > -- > Mats >> >> >> ~Aaron >> >> > >> > -- >> > Mats >> > >> > On 2 October 2015 at 20:16, Aaron Ballman via cfe-commits >> > <cfe-commits@lists.llvm.org> wrote: >> >> >> >> Given the following two function declarations: >> >> >> >> void f1(...); >> >> void f2(); >> >> >> >> It makes sense to me that isVariadic() returns true for f1 in both C >> >> and C++. It makes sense to me that isVariadic() returns false for f2 >> >> in C++. I am confused as to why it returns false instead of true for >> >> C, however. >> >> >> >> In C11, 6.7.6.3p9 states: If the list terminates with an ellipsis (, >> >> ...), no information about the number or types of the parameters after >> >> the comma is supplied. >> >> >> >> p14 states, in part: "The empty list in a function declarator that is >> >> not part of a definition of that function specifies that no >> >> information about the number or types of the parameters is supplied." >> >> >> >> It seems to me that for function *declarations* (not definitions), >> >> isVariadic() should return true for f2 in C. Is there a reason it >> >> doesn't currently behave that way, or is this a bug? >> >> >> >> I ask because I was writing an AST matcher for isVariadic() for an >> >> in-progress checker, but the checker was failing to catch that f2 was >> >> a variadic function. I am not certain whether >> >> FunctionDecl::isVariadic() should be changed, whether the AST matcher >> >> isVariadic() should be smarter about C code, or whether the checker >> >> itself needs to be smarter about this particular behavior in C code. >> >> My gut reaction is that FunctionDecl::isVariadic() has a bug, but from >> >> looking at code elsewhere, everything seems to assume isVariadic() >> >> implies the ellipsis, which makes me think I just need to make my >> >> checker smarter. >> >> >> >> Thanks! >> >> >> >> ~Aaron >> >> _______________________________________________ >> >> cfe-commits mailing list >> >> cfe-commits@lists.llvm.org >> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > >> > > > _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits