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

            Bug ID: 114726
           Summary: Function-like-macro expansion containing compound
                    literal won't compile
           Product: gcc
           Version: 13.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: preprocessor
          Assignee: unassigned at gcc dot gnu.org
          Reporter: willisahershey at gmail dot com
  Target Milestone: ---

Created attachment 57948
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57948&action=edit
Example source file that triggers the bug

GCC throws error and refuses to compile when a compound literal with more than
one member is used as an argument in a function-like-macro that expects only
one argument.

Minimum reproducible example:

///////////////////////////////////////////////////////////////////////////
#include <stdio.h>

int (*fptr_puts)(const char *str) = puts; //Function pointer alias of puts()
#define macro_puts(a)   puts(a)           //Macro alias of puts()


int main(void){ 
  fptr_puts((const char[]){'T','e','x','t','\0'});  //This is fine
  macro_puts((const char[]){'T','e','x','t','\0'}); //This throws an error
}
//////////////////////////////////////////////////////////////////////////

Compiler output (x86-64 GCC 13.2 via godbolt):

<source>: In function 'main':
<source>:9:50: error: macro "macro_puts" passed 5 arguments, but takes just 1
    9 |   macro_puts((const char[]){'T','e','x','t','\0'});
      |                                                  ^
<source>:4: note: macro "macro_puts" defined here
    4 | #define macro_puts(a)   puts(a)
      | 
<source>:9:3: error: 'macro_puts' undeclared (first use in this function)
    9 |   macro_puts((const char[]){'T','e','x','t','\0'});
      |   ^~~~~~~~~~
<source>:9:3: note: each undeclared identifier is reported only once for each
function it appears in
ASM generation compiler returned: 1

////////////////////////////////////////////////////////////////////////

It appears that the preprocessor incorrectly identifies a compound literal as
multiple arguments rather than a single r-value and refuses to text-replace
before the compiler can take a crack at it.


Output from gcc -v:

///////////////////////////////////////////////////////////////////////////

Using built-in specs.
COLLECT_GCC=/opt/compiler-explorer/gcc-13.2.0/bin/gcc
Target: x86_64-linux-gnu
Configured with: ../gcc-13.2.0/configure
--prefix=/opt/compiler-explorer/gcc-build/staging
--enable-libstdcxx-backtrace=yes --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu --disable-bootstrap
--enable-multiarch --with-abi=m64 --with-multilib-list=m32,m64,mx32
--enable-multilib --enable-clocale=gnu
--enable-languages=c,c++,fortran,ada,objc,obj-c++,go,d,m2 --enable-ld=yes
--enable-gold=yes --enable-libstdcxx-debug --enable-libstdcxx-time=yes
--enable-linker-build-id --enable-lto --enable-plugins --enable-threads=posix
--with-pkgversion=Compiler-Explorer-Build-gcc--binutils-2.40
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 13.2.0 (Compiler-Explorer-Build-gcc--binutils-2.40) 
COLLECT_GCC_OPTIONS='-fdiagnostics-color=always' '-g' '-o' '/app/output.s'
'-masm=intel' '-S' '-v' '-mtune=generic' '-march=x86-64' '-dumpdir' '/app/'

/opt/compiler-explorer/gcc-13.2.0/bin/../libexec/gcc/x86_64-linux-gnu/13.2.0/cc1
-quiet -v -imultiarch x86_64-linux-gnu -iprefix
/opt/compiler-explorer/gcc-13.2.0/bin/../lib/gcc/x86_64-linux-gnu/13.2.0/
<source> -quiet -dumpdir /app/ -dumpbase output.c -dumpbase-ext .c -masm=intel
-mtune=generic -march=x86-64 -g -version -fdiagnostics-color=always -o
/app/output.s
GNU C17 (Compiler-Explorer-Build-gcc--binutils-2.40) version 13.2.0
(x86_64-linux-gnu)
        compiled by GNU C version 11.4.0, GMP version 6.2.1, MPFR version
4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory
"/opt/compiler-explorer/gcc-13.2.0/bin/../lib/gcc/x86_64-linux-gnu/13.2.0/../../../../x86_64-linux-gnu/include"
ignoring duplicate directory
"/opt/compiler-explorer/gcc-13.2.0/bin/../lib/gcc/../../lib/gcc/x86_64-linux-gnu/13.2.0/include"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring duplicate directory
"/opt/compiler-explorer/gcc-13.2.0/bin/../lib/gcc/../../lib/gcc/x86_64-linux-gnu/13.2.0/include-fixed/x86_64-linux-gnu"
ignoring duplicate directory
"/opt/compiler-explorer/gcc-13.2.0/bin/../lib/gcc/../../lib/gcc/x86_64-linux-gnu/13.2.0/include-fixed"
ignoring nonexistent directory
"/opt/compiler-explorer/gcc-13.2.0/bin/../lib/gcc/../../lib/gcc/x86_64-linux-gnu/13.2.0/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:

/opt/compiler-explorer/gcc-13.2.0/bin/../lib/gcc/x86_64-linux-gnu/13.2.0/include

/opt/compiler-explorer/gcc-13.2.0/bin/../lib/gcc/x86_64-linux-gnu/13.2.0/include-fixed/x86_64-linux-gnu

/opt/compiler-explorer/gcc-13.2.0/bin/../lib/gcc/x86_64-linux-gnu/13.2.0/include-fixed
 /usr/local/include
 /opt/compiler-explorer/gcc-13.2.0/bin/../lib/gcc/../../include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
Compiler executable checksum: 8bfe467eb0617fe11318b29a010ce43c

////////////////////////////////////////////////////////////////////////////

I do not have access to this version of GCC outside of Godbolt, so I am unable
to provide the *.i* file that v13.2 produces, but I have attached the *.i* file
from GCC 10.2 which I have installed on my system. I apologize and hope that is
somehow useful.

Reply via email to