https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83063

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
More complete testcase:

#define f1(...) int b##__VA_OPT__(c)
#define f2(...) int __VA_OPT__(c)##d
#define f3(...) int e##__VA_OPT__()
#define f4(...) int __VA_OPT__()##f
#define f5(...) int g##__VA_OPT__(h)##i
#define f6(...) int j##__VA_OPT__()##k
#define f7(...) int l##__VA_OPT__()
#define f8(...) int __VA_OPT__()##m
#define f9(...) int n##__VA_OPT__()##o
f1 (1, 2, 3);
f1 ();
f2 (1, 2);
f2 ();
f3 (1);
f4 (2);
f5 (6, 7);
f5 ();
f6 (8);
f7 ();
f8 ();
f9 ();

int
main ()
{
  return bc + b + cd + d + f + ghi + gi + jk + l + m + no;
}


I have so far following patch:
--- libcpp/macro.c.jj   2018-01-03 10:42:55.938763447 +0100
+++ libcpp/macro.c      2018-01-08 20:36:52.733255700 +0100
@@ -105,6 +105,7 @@ class vaopt_state {
     : m_pfile (pfile),
     m_allowed (any_args),
     m_variadic (is_variadic),
+    m_any_tokens (false),
     m_state (0),
     m_last_was_paste (false),
     m_paste_location (0),
@@ -116,7 +117,8 @@ class vaopt_state {
   {
     ERROR,
     DROP,
-    INCLUDE
+    INCLUDE,
+    PADDING
   };

   /* Given a token, update the state of this tracker and return a
@@ -191,9 +193,10 @@ class vaopt_state {
                    return ERROR;
                  }

-               return DROP;
+               return m_any_tokens ? DROP : PADDING;
              }
          }
+        m_any_tokens |= m_allowed;
        return m_allowed ? INCLUDE : DROP;
       }

@@ -220,6 +223,8 @@ class vaopt_state {
   bool m_allowed;
   /* True if the macro is variadic.  */
   bool m_variadic;
+  /* True if any tokens inside of __VA_OPT__ content were INCLUDE.  */
+  bool m_any_tokens;

   /* The state variable:
      0 means not parsing
@@ -1839,8 +1844,22 @@ replace_args (cpp_reader *pfile, cpp_has
       const cpp_token **tmp_token_ptr;

       /* __VA_OPT__ handling.  */
-      if (vaopt_tracker.update (src) != vaopt_state::INCLUDE)
-       continue;
+      vaopt_state::update_type vaopt_state = vaopt_tracker.update (src);
+      if (vaopt_state != vaopt_state::INCLUDE)
+       {
+         if (vaopt_state == vaopt_state::PADDING)
+           {
+             const cpp_token *t = padding_token (pfile, src);
+             unsigned index = expanded_token_index (pfile, macro, src, i);
+             /* Allocate a virtual location for the padding token and
+                append the token and its location to BUFF and
+                VIRT_LOCS.   */
+             tokens_buff_add_token (buff, virt_locs, t,
+                                    t->src_loc, t->src_loc,
+                                    map, index);
+           }
+         continue;
+       }

       if (src->type != CPP_MACRO_ARG)
        {

and while it fixes the ICEs, it doesn't still preprocess it properly.

Reply via email to