Given the following test case: #define f(x, y) "x y" extern void abort (void); int main () { const char *str1 = f("a", "\"a\""); const char *str2 = f( \t, " \t"); if (strcmp (str1, "\"a\" \"\\\"a\\\"\"")) abort (); if (strcmp (str2, "\t \" \\t\"")) abort (); return 0; } Gcc 2.95.3 will accept it and do the right thing: $ gcc -v Reading specs from /opt/local/fsf/lib/gcc-lib/i686-pc-linux-gnu/2.95.3/specs gcc version 2.95.3 20010315 (release) $ gcc -traditional-cpp -o macroargs macroargs.c $ ./macroargs $ Current gcc 4.X fails to accept this code. For example, using the Fedora Core 6 compiler: $ /usr/bin/gcc -v Using built-in specs. Target: i386-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux Thread model: posix gcc version 4.1.1 20061011 (Red Hat 4.1.1-30) $ /usr/bin/gcc -traditional-cpp -o macroargs macroargs.c macroargs.c: In function ‘main’: macroargs.c:7: error: expected ‘,’ or ‘;’ before ‘a’ macroargs.c:7: error: stray ‘\’ in program macroargs.c:7: error: missing terminating " character macroargs.c:8: error: stray ‘\’ in program macroargs.c:12: error: ‘str2’ undeclared (first use in this function) macroargs.c:12: error: (Each undeclared identifier is reported only once macroargs.c:12: error: for each function it appears in.) The attached patch (also posted to gcc-patches) will fix it, although it's handling of quoted arguments is not exactly identical to gcc 2.95.3. Notice the difference between the test case above, and the test case included with the patch. Here is an example of a patched gcc's behavior: $ /opt/specifix/experimental/bin/gcc -v Using built-in specs. Target: i686-pc-linux-gnu Configured with: /src/specifix/experimental/src/gcc/configure --enable-languages=c,c++,fortran --prefix=/opt/specifix/experimental --disable-werror --disable-bootstrap --with-mpfr=/opt/specifix/experimental --with-gmp=/opt/specifix/experimental --cache-file=/dev/null --srcdir=/src/specifix/experimental/src/gcc Thread model: posix gcc version 4.3.0 20061231 (experimental) $ /opt/specifix/experimental/bin/gcc -traditional-cpp -o macroargs macroargs.c $ Note however that the above test case WILL abort if run, while the test case included with the patch will not, due to the handling of leading and trailing whitespace in macro args. See the code inside "#if 0 ... #endif" in the patch and the associated comments. Either the current gcc testsuite is wrong in how it tests for this whitespace, or gcc 2.95.3 is wrong. It's not clear to me which behavior is more correct.
Confirmed, a regression from 3.2.3.
Created attachment 12867 [details] Patch to fix reported problem
won't fix in GCC-4.0.x. Adjusting milestone.
Open regression with no activity since February 14. Ping?
I'll review the patch at least.
Subject: Bug 30363 Author: tromey Date: Mon Jan 7 17:23:40 2008 New Revision: 131379 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=131379 Log: libcpp 2008-01-07 Fred Fish <fnf@specifix.com> PR preprocessor/30363: * traditional.c (replace_args_and_push): Add local variable cxtquote, calculate the replacement text size assuming a worst case of every input character quoted with backslash, and properly handle output quoting of quote characters in actual arguments used in function-like macros. gcc/testsuite 2008-01-07 Fred Fish <fnf@specifix.com> PR preprocessor/30363: * gcc.dg/cpp/trad/macroargs.c: Add code to test quoting in macro expansions. Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/cpp/trad/macroargs.c trunk/libcpp/ChangeLog trunk/libcpp/traditional.c
Slightly modified version of this patch checked in on trunk.
Closing 4.1 branch.
Closing 4.2 branch, fixed in 4.3.