c6d234
commit e4043b84c49e1cf9bcf1e8320233343ecc34f8eb
c6d234
Author: Joseph Myers <joseph@codesourcery.com>
c6d234
Date:   Tue Jun 27 17:12:13 2017 +0000
c6d234
c6d234
    Fix strftime build with GCC 8.
c6d234
    
c6d234
    Building with current GCC mainline fails with:
c6d234
    
c6d234
    strftime_l.c: In function '__strftime_internal':
c6d234
    strftime_l.c:719:4: error: macro expands to multiple statements [-Werror=multistatement-macros]
c6d234
        digits = d > width ? d : width;          \
c6d234
        ^
c6d234
    strftime_l.c:1260:6: note: in expansion of macro 'DO_NUMBER'
c6d234
          DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
c6d234
          ^~~~~~~~~
c6d234
    strftime_l.c:1259:4: note: some parts of macro expansion are not guarded by this 'else' clause
c6d234
        else
c6d234
        ^~~~
c6d234
    
c6d234
    In fact this particular instance is harmless; the code looks like:
c6d234
    
c6d234
              if (modifier == L_('O'))
c6d234
                goto bad_format;
c6d234
              else
c6d234
                DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
c6d234
    
c6d234
    and because of the goto, it doesn't matter that part of the expansion
c6d234
    isn't under the "else" conditional.  But it's also clearly bad style
c6d234
    to rely on that.  This patch changes DO_NUMBER and DO_NUMBER_SPACEPAD
c6d234
    to use do { } while (0) to avoid such problems.
c6d234
    
c6d234
    Tested (full testsuite) for x86_64 (GCC 6), and with
c6d234
    build-many-glibcs.py with GCC mainline, in conjunction with my libgcc
c6d234
    patch <https://gcc.gnu.org/ml/gcc-patches/2017-06/msg02032.html>.
c6d234
    
c6d234
            * time/strftime_l.c (DO_NUMBER): Define using do { } while (0).
c6d234
            (DO_NUMBER_SPACEPAD): Likewise.
c6d234
c6d234
Index: b/time/strftime_l.c
c6d234
===================================================================
c6d234
--- a/time/strftime_l.c
c6d234
+++ b/time/strftime_l.c
c6d234
@@ -715,12 +715,22 @@ __strftime_internal (CHAR_T *s, size_t m
c6d234
       format_char = *f;
c6d234
       switch (format_char)
c6d234
 	{
c6d234
-#define DO_NUMBER(d, v) \
c6d234
-	  digits = d > width ? d : width;				      \
c6d234
-	  number_value = v; goto do_number
c6d234
-#define DO_NUMBER_SPACEPAD(d, v) \
c6d234
-	  digits = d > width ? d : width;				      \
c6d234
-	  number_value = v; goto do_number_spacepad
c6d234
+#define DO_NUMBER(d, v)				\
c6d234
+	  do					\
c6d234
+	    {					\
c6d234
+	      digits = d > width ? d : width;	\
c6d234
+	      number_value = v;			\
c6d234
+	      goto do_number;			\
c6d234
+	    }					\
c6d234
+	  while (0)
c6d234
+#define DO_NUMBER_SPACEPAD(d, v)		\
c6d234
+	  do					\
c6d234
+	    {					\
c6d234
+	      digits = d > width ? d : width;	\
c6d234
+	      number_value = v;			\
c6d234
+	      goto do_number_spacepad;		\
c6d234
+	    }					\
c6d234
+	  while (0)
c6d234
 
c6d234
 	case L_('%'):
c6d234
 	  if (modifier != 0)