Hi,

DEC-C, the DEC compiler provided on VMS, has added to ANSI-C at least one 
extension that is difficult to work-around as it is used in the system headers: 
varargs without named argument.  It makes sense on VMS because of its ABI which 
pass the number of arguments used.

This patch allows such declaration when the new flag -fdecc-extensions is used 
(C and ObjC only as C++ already allows that).

I use the plural for consistency with other -fxxx-extensions and in case where 
others extensions are added.

Bootstrapped on x86_64-darwin, no regressions.

Ok for mainline ?

Tristan.

gcc/
2011-09-29  Tristan Gingold  <ging...@adacore.com>

        * doc/invoke.texi: Document -fdecc-extensions.
        * c-parser.c (c_parser_parms_list_declarator): Handle -fdecc-extensions.

gcc/c-family/
2011-09-29  Tristan Gingold  <ging...@adacore.com>

        * c.opt (fdecc-extensions): New.

gcc/testsuite/
2011-09-29  Tristan Gingold  <ging...@adacore.com>

        * gcc.dg/va-arg-4.c: New test.
        * gcc.dg/va-arg-5.c: Ditto.


diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index e6ac5dc..4879cff 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -739,6 +739,10 @@ fconstexpr-depth=
 C++ ObjC++ Joined RejectNegative UInteger Var(max_constexpr_depth) Init(512)
 -fconstexpr-depth=<number>     Specify maximum constexpr recursion depth
 
+fdecc-extensions
+C ObjC Var(flag_decc_extensions)
+Enable DEC-C language extensions
+
 fdeduce-init-list
 C++ ObjC++ Var(flag_deduce_init_list) Init(1)
 -fno-deduce-init-list  disable deduction of std::initializer_list for a 
template type parameter from a brace-enclosed initializer-list
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index ff376df..788d13c 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -3159,10 +3159,19 @@ c_parser_parms_list_declarator (c_parser *parser, tree 
attrs, tree expr)
   if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
     {
       struct c_arg_info *ret = build_arg_info ();
-      /* Suppress -Wold-style-definition for this case.  */
-      ret->types = error_mark_node;
-      error_at (c_parser_peek_token (parser)->location,
-               "ISO C requires a named argument before %<...%>");
+
+      if (flag_decc_extensions)
+        {
+          /* F (...) is allowed by DEC-C.  */
+          ret->types = NULL_TREE;
+        }
+      else
+        {
+          /* Suppress -Wold-style-definition for this case.  */
+          ret->types = error_mark_node;
+          error_at (c_parser_peek_token (parser)->location,
+                    "ISO C requires a named argument before %<...%>");
+        }
       c_parser_consume_token (parser);
       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
        {
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e166964..1fceace 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -170,7 +170,7 @@ in the following sections.
 @item C Language Options
 @xref{C Dialect Options,,Options Controlling C Dialect}.
 @gccoptlist{-ansi  -std=@var{standard}  -fgnu89-inline @gol
--aux-info @var{filename} @gol
+-aux-info @var{filename} -fdecc-extensions @gol
 -fno-asm  -fno-builtin  -fno-builtin-@var{function} @gol
 -fhosted  -ffreestanding -fopenmp -fms-extensions -fplan9-extensions @gol
 -trigraphs  -no-integrated-cpp  -traditional  -traditional-cpp @gol
@@ -1733,6 +1733,16 @@ fields declared using a typedef.  @xref{Unnamed 
Fields,,Unnamed
 struct/union fields within structs/unions}, for details.  This is only
 supported for C, not C++.
 
+@item -fdecc-extensions
+Accept some non-standard constructs used by DEC-C in VMS header files.
+
+This allows varargs functions without named argument.  VMS is able to
+support this feature because of its call convention which pass the
+number of arguments in a register.  Although it is possible to define
+such a function, this is not very usefull as it is not possible to read
+the arguments.  This is only supported for C as this construct is
+allowed by C++.
+
 @item -trigraphs
 @opindex trigraphs
 Support ISO C trigraphs.  The @option{-ansi} option (and @option{-std}
diff --git a/gcc/testsuite/gcc.dg/va-arg-4.c b/gcc/testsuite/gcc.dg/va-arg-4.c
new file mode 100644
index 0000000..6d737c4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/va-arg-4.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+#include <stdarg.h>
+extern void baz(...);  /* { dg-error "requires a named argument" } */
diff --git a/gcc/testsuite/gcc.dg/va-arg-5.c b/gcc/testsuite/gcc.dg/va-arg-5.c
new file mode 100644
index 0000000..015f592
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/va-arg-5.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-fdecc-extensions" } */
+#include <stdarg.h>
+extern void baz(...);

Reply via email to