PATCH: egcs-1.1.2 cpp SEGV on omitted stringified rest arg

Nathan Kurz nate@valleytel.net
Fri Jul 23 16:47:00 GMT 1999


Hello --

I recently encountered a bug in cpp, and since I had a little extra
time I decided to track it down.  The bug tends to occur when you
attempt to stringify an omitted rest arg, like this:

#define MACRO(dummy,args...) function(dummy,#args) 
MACRO(1);

This should evaluate to 'function(1,"");', but instead tends to result
in a SEGV in cpp.  As it turns out, cccp.c:macarg() is not called for
omitted arguments.  This means that no room is left for "" when
xbuf_len is calculated, and thus cccp.c:macroexpand() writes beyond
the end of the space allocated for xbuf.

The bug exists on at least these two systems and egcs versions:

  Linux wso 2.2.10 #1 SMP Tue Jun 15 23:58:04 EDT 1999 i686 unknown
  GNU CPP version egcs-2.91.66 Debian GNU/Linux (egcs-1.1.2 release) 
  (i386 Linux/ELF)

  Linux trinkpad 2.0.35 #3 Thu Oct 22 19:19:19 EDT 1998 i586 unknown
  GNU CPP version egcs-2.90.29 980515 (egcs-1.0.3 release) 
  (i386 Linux/ELF)

But judging by the source code, it probably exists everywhere...

Here's a patch against egcs-1.1.2/gcc/cccp.c:

-----------------------------------------------------------------------------

*** cccp.c.orig Fri Jul 23 17:57:54 1999
--- cccp.c      Fri Jul 23 18:39:20 1999
***************
*** 8271,8279 ****
         Also count number of times each arg is used.  */
        xbuf_len = defn->length;
        for (ap = defn->pattern; ap != NULL; ap = ap->next) {
!       if (ap->stringify)
!         xbuf_len += args[ap->argno].stringified_length;
!       else if (ap->raw_before != 0 || ap->raw_after != 0 || traditional)
          /* Add 4 for two newline-space markers to prevent
             token concatenation.  */
          xbuf_len += args[ap->argno].raw_length + 4;
--- 8271,8282 ----
         Also count number of times each arg is used.  */
        xbuf_len = defn->length;
        for (ap = defn->pattern; ap != NULL; ap = ap->next) {
!       if (ap->stringify) {
!         /* if stringified length is not yet calculated allow space for "" */
!         if (args[ap->argno].stringified_length == 0) xbuf_len += 2;
!         /* else allow for the calculated length (already counts quotes) */
!         else xbuf_len += args[ap->argno].stringified_length;
!       } else if (ap->raw_before != 0 || ap->raw_after != 0 || traditional)
          /* Add 4 for two newline-space markers to prevent
             token concatenation.  */
          xbuf_len += args[ap->argno].raw_length + 4;

-----------------------------------------------------------------------------

And here is a torture test to check if things are working, or to
verify if this bug does indeed exist on other systems.  Failure of
this test is indicated when cpp dies with SEGV ;)

-----------------------------------------------------------------------------

/* This is a torture test for cpp.  As of egcs-1.1.2 cpp was having
   overwrite problems and would sometimes seg fault on stringified
   omitted rest args.  cppmain seems to handle these fine. */

/* NOTE: Expect warnings about 'MACRO used without args' */

/* this seems to always work correctly */
/* (note three spaces before or after #args) */
#define MACRO1(dummy,args...) function(dummy,   #args) 
MACRO1();
MACRO1(1);
MACRO1(10);

/* egcs-1.1.2 cpp SEGV if arg is 1 or 2 chars long */
/* (note lack of spaces around #args) */
#define MACRO2(dummy,args...) function(dummy,#args) 
MACRO2();
MACRO2(1);
MACRO2(10);

/* egcs-1.1.2 cpp SEGV if arg is 0 or 1 chars long */
/* (note one space before or after #args) */
#define MACRO3(dummy,args...) function(dummy, #args)
MACRO3();
MACRO3(1);
MACRO2(10);

/* egcs-1.1.2 cpp SEGV if arg is "", OK otherwise */
/* (note two spaces along with #args) */
#define MACRO4(dummy,args...) function(dummy, #args ) 
MACRO4();
MACRO2(1);
MACRO2(10);

-----------------------------------------------------------------------------

As I'm not a member of this list, please explicitly 'cc:' me on
responses, particularly if further information is required.

And thanks for producing such a great compiler!

Nathan Kurz
nate@valleytel.net

ps. I'll also note that the immediate workaround is to throw in at
    least three extra spaces when the macro is defined.  


More information about the Gcc-bugs mailing list