https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69961
Bug ID: 69961 Summary: Segfault when calling constructor from variadic template by referring to T::T Product: gcc Version: 4.8.4 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: chatelet.guillaume at gmail dot com Target Milestone: --- Created attachment 37794 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37794&action=edit The preprocessed file ------------------------------------------------------------------------ - source code (test.cc) - This is the reduced example that triggers the bug, the c ------------------------------------------------------------------------ #include <string> using std::string; class Format { public: explicit Format(string formatted) {} string buffer; }; string StrCat(const string& a) { return ""; } template <typename... AV> Format Message(string msg, const AV&... args) { return Format::Format(StrCat(msg, args...)); } int main(int, char**) { Message("msg"); } ------------------------------------------------------------------------ - Command line ------------------------------------------------------------------------ > g++ -std=c++11 test.cc && ./a.out > segmentation fault (core dumped) ./a.out ------------------------------------------------------------------------ - Description - credits to richard-gccbugzilla at metafoo dot co.uk ------------------------------------------------------------------------ "The relevant language rule was (depending on your interpretation of the old rule) either clarified or changed by C++ core issue 1310: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1310 Format::Format is ambiguous: it either names a constructor of Format or it names the type Format (the name of a class is implicitly injected into the scope of that class, more or less as if it contained a "typedef ::Format Format;"; this is called the injected-class-name). In a function-style explicit cast expression, such as yours above, the name before the left paren must name a type (you cannot explicitly call a constructor). The new language rule says that T::T only names the injected-class-name if the name appears in a context where functions would not even be considered -- specifically, in a nested-name-specifier (T::T::), in an elaborated-type-specifier (class T::T), and in a base-specifier (class U : T::T {...};). (As it happens, there are no other cases where function names are ignored.) Clang does not implement that (new?) rule yet, which is why it accepts the program (and compiles it to working code). GCC *does* implement the rule. However, it apparently has a bug when the call has dependent arguments, and doesn't enforce it in that case. If I were to guess, my guess would be that GCC decides that this must be a static member function call, but whatever the reason, it doesn't pass in a 'this' pointer to the constructor, which seems to be what causes the segfault." ------------------------------------------------------------------------ - gcc environment ------------------------------------------------------------------------ > g++ -v -save-temps -std=c++11 test.cc Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04.1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.1) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++11' '-shared-libgcc' '-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-linux-gnu/4.8/cc1plus -E -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE test.cc -mtune=generic -march=x86-64 -std=c++11 -fpch-preprocess -fstack-protector -Wformat -Wformat-security -o test.ii ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/4.8" ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../x86_64-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/include/c++/4.8 /usr/include/x86_64-linux-gnu/c++/4.8 /usr/include/c++/4.8/backward /usr/lib/gcc/x86_64-linux-gnu/4.8/include /usr/local/include /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed /usr/include/x86_64-linux-gnu /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++11' '-shared-libgcc' '-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-linux-gnu/4.8/cc1plus -fpreprocessed test.ii -quiet -dumpbase test.cc -mtune=generic -march=x86-64 -auxbase test -std=c++11 -version -fstack-protector -Wformat -Wformat-security -o test.s GNU C++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) version 4.8.4 (x86_64-linux-gnu) compiled by GNU C version 4.8.4, GMP version 5.1.3, MPFR version 3.1.2-p3, MPC version 1.0.1 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU C++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) version 4.8.4 (x86_64-linux-gnu) compiled by GNU C version 4.8.4, GMP version 5.1.3, MPFR version 3.1.2-p3, MPC version 1.0.1 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 83f8d9bb238019ed17000f1b7e141e5a COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++11' '-shared-libgcc' '-mtune=generic' '-march=x86-64' as -v --64 -o test.o test.s GNU assembler version 2.24 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.24 COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/ LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++11' '-shared-libgcc' '-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-linux-gnu/4.8/collect2 --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.. test.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o The bug is also triggered on more recent versions of g++ like this one: g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: /build/gcc/src/gcc-5-20160209/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --disable-multilib --disable-werror --enable-checking=release Thread model: posix gcc version 5.3.0 (GCC)