This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: cpplib: fix for another obscure macro-expansion bug


I see where you moved the code to remove the no-reexpand marker so that it will be
executed in this case, but what does the change of \n to @ and the handling of the
whitespace markers address? Do yo have a test case that shows how those bits of code were
broken?

Dave

Zack Weinberg wrote:

> cpplib mis-processes the following fragment:
>
> #define FLT_MIN_EXP (-125)
> #define FLT FLT
>
> #define P(a,b) P1(a,b)
> #define P1(a,b) a##b
> #define MIN_EXP P(FLT,_MIN_EXP)
>
> int flt_min_exp = MIN_EXP;
>
> `FLT' gets tagged with a no-reexpand escape.  Then P1 pastes together
> `FLT' and `_MIN_EXP' but doesn't remove the escape, so it's applied to
> the pasted token.
>
> Here is a patch.
>
> zw
>
> 1998-09-27 13:01 -0400  Zack Weinberg  <zack@rabi.phys.columbia.edu>
>
>         * cpplib.c (macroexpand): If arg->raw_before or
>         arg->raw_after, remove any no-reexpansion escape at the
>         beginning of the pasted token.  Correct handling of whitespace
>         markers and no-reexpand markers at the end if arg->raw_after.
>
> --- cpplib.c.bug2       Sun Sep 27 12:11:19 1998
> +++ cpplib.c    Sun Sep 27 12:38:44 1998
> @@ -2874,11 +2874,6 @@
>                   while (p1 != l1 && is_space[*p1]) p1++;
>                   while (p1 != l1 && is_idchar[*p1])
>                     xbuf[totlen++] = *p1++;
> -                 /* Delete any no-reexpansion marker that follows
> -                    an identifier at the beginning of the argument
> -                    if the argument is concatenated with what precedes it.  */
> -                 if (p1[0] == '@' && p1[1] == '-')
> -                   p1 += 2;
>                 }
>               if (ap->raw_after)
>                 {
> @@ -2887,20 +2882,37 @@
>                   while (p1 != l1)
>                     {
>                       if (is_space[l1[-1]]) l1--;
> +                     else if (l1[-1] == '@')
> +                       {
> +                         U_CHAR *p2 = l1 - 1;
> +                         /* If whitespace is preceded by an odd number
> +                            of `@' signs, the last `@' was a whitespace
> +                            marker; drop it too. */
> +                         while (p2 != p1 && p2[-1] == '@') p2--;
> +                         if ((l1 - 1 - p2) & 1)
> +                           l1--;
> +                         break;
> +                       }
>                       else if (l1[-1] == '-')
>                         {
>                           U_CHAR *p2 = l1 - 1;
> -                         /* If a `-' is preceded by an odd number of newlines then it
> -                            and the last newline are a no-reexpansion marker.  */
> -                         while (p2 != p1 && p2[-1] == '\n') p2--;
> -                         if ((l1 - 1 - p2) & 1) {
> +                         /* If a `-' is preceded by an odd number of
> +                            `@' signs then it and the last `@' are
> +                            a no-reexpansion marker.  */
> +                         while (p2 != p1 && p2[-1] == '@') p2--;
> +                         if ((l1 - 1 - p2) & 1)
>                             l1 -= 2;
> -                         }
> -                         else break;
> +                         else
> +                           break;
>                         }
>                       else break;
>                     }
>                 }
> +
> +             /* Delete any no-reexpansion marker that precedes
> +                an identifier at the beginning of the argument. */
> +             if (p1[0] == '@' && p1[1] == '-')
> +               p1 += 2;
>
>               bcopy (p1, xbuf + totlen, l1 - p1);
>               totlen += l1 - p1;





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]