aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNeil Booth <neil@daikokuya.co.uk>2002-08-06 20:35:46 +0000
committerNeil Booth <neil@gcc.gnu.org>2002-08-06 20:35:46 +0000
commit58551c2335b3f2f16c8341d3bb409d37f8715696 (patch)
tree6bf828a9fcc79198ebca01c572aeea673134e23a /gcc
parentdaeabcd06bc02b7b91f041c14f932d80b82f45f5 (diff)
downloadgcc-58551c2335b3f2f16c8341d3bb409d37f8715696.zip
gcc-58551c2335b3f2f16c8341d3bb409d37f8715696.tar.gz
gcc-58551c2335b3f2f16c8341d3bb409d37f8715696.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/cppinit.c7
-rw-r--r--gcc/cpplib.h3
-rw-r--r--gcc/cppmacro.c26
-rw-r--r--gcc/doc/cpp.texi11
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/cpp/vararg3.c17
-rw-r--r--gcc/testsuite/gcc.dg/cpp/vararg4.c14
8 files changed, 81 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 185da67..e035658 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2002-08-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * 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 <jakub@redhat.com>
* config/i386/mmintrin.h (__m64): Make the type 64-bit aligned.
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 03f04c1..a7ffeb0 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 8902f53..7282df7 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 f0986b3..7603090 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 73785c1..e8107f2 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 016152a..55fd9a1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2002-08-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * gcc.dg/cpp/vararg3.c, gcc.dg/cpp/vararg4.c: New tests.
+
2002-08-06 Jakub Jelinek <jakub@redhat.com>
* 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 0000000..b17afd8
--- /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 0000000..460cebf
--- /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