tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

macro directives inside macro arguments undefined



Hi

according to the C99 spec section 6.10.3 clause 11

| If there are sequences of preprocessing tokens within the list of
| arguments that would otherwise act as preprocessing directives, the
| behavior is undefined.

this was discussed on the pcc list last year:
  http://marc.info/?t=128991333400003&r=1&w=2

but I found an problem in our sources because in <ssp/stdio.h> we turn
sprint() into a macro

| #if __SSP_FORTIFY_LEVEL > 0
|
| #define sprintf(str, ...) \
|    __builtin___sprintf_chk(str, 0, __ssp_bos(str), __VA_ARGS__)

which triggers a problem in ipf/ipmon because of USE_FORT=yes coinciding
with a sprintf containing preprocessor directives in the argument list:

                sprintf(t,
#ifdef  USE_QUAD_T
#ifdef  PRId64
                        " Forward: Pkts in %" PRId64 " Bytes in %" PRId64
                        " Pkts out %" PRId64 " Bytes out %" PRId64
                        " Backward: Pkts in %" PRId64 " Bytes in %" PRId64
                        " Pkts out %" PRId64 " Bytes out %" PRId64,
#else
                        " Forward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes 
out %qd Backward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes out %qd",
#endif /* PRId64 */
#else
                        " Forward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes 
out %ld Backward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes out %ld",
#endif
                        sl->isl_pkts[0], sl->isl_bytes[0],
                        sl->isl_pkts[1], sl->isl_bytes[1],
                        sl->isl_pkts[2], sl->isl_bytes[2],
                        sl->isl_pkts[3], sl->isl_bytes[3]);

The patch attached fixes building this with pcc (for which the behaviour
is to error out with a syntax error), by moving the directives away from
the arguments, any objections to commit?

regards,
iain
Index: ipmon.c
===================================================================
RCS file: /cvsroot/src/dist/ipf/tools/ipmon.c,v
retrieving revision 1.16
diff -u -r1.16 ipmon.c
--- ipmon.c     19 Aug 2009 08:35:32 -0000      1.16
+++ ipmon.c     24 Feb 2011 11:22:39 -0000
@@ -903,20 +903,21 @@
                (void) sprintf(t, " tag %u", sl->isl_tag);
                t += strlen(t);
        }
-       if (sl->isl_type != ISL_NEW) {
-               sprintf(t,
 #ifdef USE_QUAD_T
 #ifdef PRId64
-                       " Forward: Pkts in %" PRId64 " Bytes in %" PRId64
-                       " Pkts out %" PRId64 " Bytes out %" PRId64
-                       " Backward: Pkts in %" PRId64 " Bytes in %" PRId64
-                       " Pkts out %" PRId64 " Bytes out %" PRId64,
+#define        FMT     PRId64
 #else
-                       " Forward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes 
out %qd Backward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes out %qd",
-#endif /* PRId64 */
+#define        FMT     "qd"
+#endif
 #else
-                       " Forward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes 
out %ld Backward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes out %ld",
+#define        FMT     "ld"
 #endif
+       if (sl->isl_type != ISL_NEW) {
+               sprintf(t,
+                       " Forward: Pkts in %" FMT " Bytes in %" FMT
+                       " Pkts out %" FMT " Bytes out %" FMT
+                       " Backward: Pkts in %" FMT " Bytes in %" FMT
+                       " Pkts out %" FMT " Bytes out %" FMT,
                        sl->isl_pkts[0], sl->isl_bytes[0],
                        sl->isl_pkts[1], sl->isl_bytes[1],
                        sl->isl_pkts[2], sl->isl_bytes[2],
@@ -924,6 +925,7 @@
 
                t += strlen(t);
        }
+#undef FMT
 
        *t++ = '\n';
        *t++ = '\0';


Home | Main Index | Thread Index | Old Index