From 58551c2335b3f2f16c8341d3bb409d37f8715696 Mon Sep 17 00:00:00 2001 From: Neil Booth Date: Tue, 6 Aug 2002 20:35:46 +0000 Subject: [PATCH] cppinit.c (struct lang_flags): Rename trigraphs std. * cppinit.c (struct lang_flags): Rename trigraphs std. (set_lang): Update. * cpplib.h (struct cpp_options): New member std. * cppmacro.c (_cpp_builtin_macro_text): Use std. (collect_args): Flag whether to swallow a possible future comma pasted with varargs. (replace_args): Use this flag. * doc/cpp.texi: Update varargs extension documentation. testsuite: * gcc.dg/cpp/vararg3.c, gcc.dg/cpp/vararg4.c: New tests. From-SVN: r56077 --- gcc/ChangeLog | 11 +++++++++++ gcc/cppinit.c | 7 ++++--- gcc/cpplib.h | 3 +++ gcc/cppmacro.c | 26 ++++++++++++++++++-------- gcc/doc/cpp.texi | 11 ++++++++++- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/cpp/vararg3.c | 17 +++++++++++++++++ gcc/testsuite/gcc.dg/cpp/vararg4.c | 14 ++++++++++++++ 8 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/vararg3.c create mode 100644 gcc/testsuite/gcc.dg/cpp/vararg4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 185da67d8f9..e0356589b87 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2002-08-06 Neil Booth + + * cppinit.c (struct lang_flags): Rename trigraphs std. + (set_lang): Update. + * cpplib.h (struct cpp_options): New member std. + * cppmacro.c (_cpp_builtin_macro_text): Use std. + (collect_args): Flag whether to swallow a possible future + comma pasted with varargs. + (replace_args): Use this flag. + * doc/cpp.texi: Update varargs extension documentation. + 2002-08-06 Jakub Jelinek * config/i386/mmintrin.h (__m64): Make the type 64-bit aligned. diff --git a/gcc/cppinit.c b/gcc/cppinit.c index 03f04c1a5d6..a7ffeb03d9a 100644 --- a/gcc/cppinit.c +++ b/gcc/cppinit.c @@ -384,7 +384,7 @@ struct lang_flags char c99; char cplusplus; char extended_numbers; - char trigraphs; + char std; char dollars_in_ident; char cplusplus_comments; char digraphs; @@ -392,7 +392,7 @@ struct lang_flags /* ??? Enable $ in identifiers in assembly? */ static const struct lang_flags lang_defaults[] = -{ /* c99 c++ xnum trig dollar c++comm digr */ +{ /* c99 c++ xnum std dollar c++comm digr */ /* GNUC89 */ { 0, 0, 1, 0, 1, 1, 1 }, /* GNUC99 */ { 1, 0, 1, 0, 1, 1, 1 }, /* STDC89 */ { 0, 0, 0, 1, 0, 0, 0 }, @@ -416,7 +416,8 @@ set_lang (pfile, lang) CPP_OPTION (pfile, c99) = l->c99; CPP_OPTION (pfile, cplusplus) = l->cplusplus; CPP_OPTION (pfile, extended_numbers) = l->extended_numbers; - CPP_OPTION (pfile, trigraphs) = l->trigraphs; + CPP_OPTION (pfile, std) = l->std; + CPP_OPTION (pfile, trigraphs) = l->std; CPP_OPTION (pfile, dollars_in_ident) = l->dollars_in_ident; CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments; CPP_OPTION (pfile, digraphs) = l->digraphs; diff --git a/gcc/cpplib.h b/gcc/cpplib.h index 8902f536902..7282df7f07d 100644 --- a/gcc/cpplib.h +++ b/gcc/cpplib.h @@ -367,6 +367,9 @@ struct cpp_options /* Nonzero for the 1999 C Standard, including corrigenda and amendments. */ unsigned char c99; + /* Nonzero if we are conforming to a specific C or C++ standard. */ + unsigned char std; + /* Nonzero means give all the error messages the ANSI standard requires. */ unsigned char pedantic; diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c index f0986b353cb..76030903089 100644 --- a/gcc/cppmacro.c +++ b/gcc/cppmacro.c @@ -191,8 +191,7 @@ _cpp_builtin_macro_text (pfile, node) enum c_lang lang = CPP_OPTION (pfile, lang); if (CPP_IN_SYSTEM_HEADER (pfile) && CPP_OPTION (pfile, stdc_0_in_system_headers) - && !(lang == CLK_STDC89 || lang == CLK_STDC94 - || lang == CLK_STDC99)) /* || lang == CLK_CXX98 ? */ + && !CPP_OPTION (pfile,std)) number = 0; else number = 1; @@ -672,7 +671,20 @@ collect_args (pfile, node) if (argc == 1 && macro->paramc == 0 && args[0].count == 0) argc = 0; if (_cpp_arguments_ok (pfile, macro, node, argc)) - return base_buff; + { + /* GCC has special semantics for , ## b where b is a varargs + parameter: we remove the comma if b was omitted entirely. + If b was merely an empty argument, the comma is retained. + If the macro takes just one (varargs) parameter, then we + retain the comma only if we are standards conforming. + + If FIRST is NULL replace_args () swallows the comma. */ + if (macro->variadic && (argc < macro->paramc + || (argc == 1 && args[0].count == 0 + && !CPP_OPTION (pfile, std)))) + args[macro->paramc - 1].first = NULL; + return base_buff; + } } /* An error occurred. */ @@ -861,15 +873,13 @@ replace_args (pfile, node, macro, args) count = arg->count, from = arg->first; if (dest != first) { - /* GCC has special semantics for , ## b where b is a - varargs parameter: the comma disappears if b was - given no actual arguments (not merely if b is an - empty argument); otherwise the paste flag is removed. */ if (dest[-1]->type == CPP_COMMA && macro->variadic && src->val.arg_no == macro->paramc) { - if (count == 0) + /* Swallow a pasted comma if from == NULL, otherwise + drop the paste flag. */ + if (from == NULL) dest--; else paste_flag = dest - 1; diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 73785c13794..e8107f2acc4 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -1620,7 +1620,7 @@ The @code{eprintf} macro above could be written @end example @noindent -using this extension. You cannot use @code{__VA_ARGS__} and this +using this extension. You cannot use @code{@w{__VA_ARGS__}} and this extension in the same macro. You can have named arguments as well as variable arguments in a variadic @@ -1670,6 +1670,15 @@ eprintf ("success!\n") @expansion{} fprintf(stderr, "success!\n"); @end example +@noindent +The above explanation is ambiguous about the case where the only macro +parameter is a variable arguments parameter, as it is meaningless to +try to distinguish whether no argument at all is an empty argument or +a missing argument. In this case the C99 standard is clear that the +comma must remain, however the existing GCC extension used to swallow +the comma. So CPP retains the comma when conforming to a specific C +standard, and drops it otherwise. + C99 mandates that the only place the identifier @code{@w{__VA_ARGS__}} can appear is in the replacement list of a variadic macro. It may not be used as a macro name, macro argument name, or within a different type diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 016152af1d1..55fd9a1aeb2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-08-06 Neil Booth + + * gcc.dg/cpp/vararg3.c, gcc.dg/cpp/vararg4.c: New tests. + 2002-08-06 Jakub Jelinek * g++.dg/abi/bitfield3.C: New test. diff --git a/gcc/testsuite/gcc.dg/cpp/vararg3.c b/gcc/testsuite/gcc.dg/cpp/vararg3.c new file mode 100644 index 00000000000..b17afd89ea7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/vararg3.c @@ -0,0 +1,17 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. */ + +/* { dg-do preprocess } */ +/* { dg-options "-std=c99" } */ + +/* Source: Neil Booth, 6 Aug 2002. + + Tests that we DTRT with varargs commas for a single-parameter macro + when in standards-conforming mode. */ + +#define f(...) , ## __VA_ARGS__ + +/* The comma from f's expansion should be retained (standards + conforming mode only). Tests that it isn't in non-standards mode + include macro8.c and vararg1.c. */ +#if 2 f() 3 /* { dg-bogus "missing binary operator" } */ +#endif diff --git a/gcc/testsuite/gcc.dg/cpp/vararg4.c b/gcc/testsuite/gcc.dg/cpp/vararg4.c new file mode 100644 index 00000000000..460cebf2833 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/vararg4.c @@ -0,0 +1,14 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. */ + +/* { dg-do preprocess } */ +/* { dg-options -std=gnu99 } */ + +/* Source: Neil Booth, 6 Aug 2002. + + Tests that we DTRT with varargs commas. */ + +#define g(a, ...) a , ## __VA_ARGS__ + +/* The comma from g's expansion should be retained. */ +#if g (2, ) 3 /* { dg-bogus "missing binary operator" } */ +#endif -- 2.30.2