Ubuntu 12.10 64-bit GCC 4.8.1 which I built from source: COLLECT_GCC=/opt/custom/gcc-4.8.1/bin/gcc COLLECT_LTO_WRAPPER=/opt/custom/gcc-4.8.1/libexec/gcc/x86_64-unknown-linux-gnu/4.8.1/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ../gcc-4.8.1/configure --prefix=/opt/custom/gcc-4.8.1 --enable-languages=c,c++ Thread model: posix gcc version 4.8.1 (GCC) /opt/custom/gcc-4.8.1/bin/gcc test.cpp test.cpp: In static member function ‘static int_v4<Tp>::Tpv int_v4<Tp>::shuffle(const int_v4<Tp>&, const int_v4<Tp>&, const int_v4<Tp>&)’: test.cpp:8:49: internal compiler error: Segmentation fault return __builtin_shuffle(u1.v, u2.v, s.v); ^ 0x8d7dff crash_signal ../../gcc-4.8.1/gcc/toplev.c:332 0x632761 c_build_vec_perm_expr(unsigned int, tree_node*, tree_node*, tree_node*) ../../gcc-4.8.1/gcc/c-family/c-common.c:2280 0x5965f3 cp_parser_postfix_expression ../../gcc-4.8.1/gcc/cp/parser.c:5558 0x5983bd cp_parser_unary_expression ../../gcc-4.8.1/gcc/cp/parser.c:6729 0x598eef cp_parser_binary_expression ../../gcc-4.8.1/gcc/cp/parser.c:7421 0x59939f cp_parser_assignment_expression ../../gcc-4.8.1/gcc/cp/parser.c:7657 0x59af93 cp_parser_expression ../../gcc-4.8.1/gcc/cp/parser.c:7819 0x5932ce cp_parser_expression ../../gcc-4.8.1/gcc/cp/parser.c:7858 0x5932ce cp_parser_jump_statement ../../gcc-4.8.1/gcc/cp/parser.c:10144 0x5932ce cp_parser_statement ../../gcc-4.8.1/gcc/cp/parser.c:8874 0x593a8e cp_parser_statement_seq_opt ../../gcc-4.8.1/gcc/cp/parser.c:9238 0x593bae cp_parser_compound_statement ../../gcc-4.8.1/gcc/cp/parser.c:9192 0x5a1d28 cp_parser_function_body ../../gcc-4.8.1/gcc/cp/parser.c:17827 0x5a1d28 cp_parser_ctor_initializer_opt_and_function_body ../../gcc-4.8.1/gcc/cp/parser.c:17863 0x5a2a5f cp_parser_function_definition_after_declarator ../../gcc-4.8.1/gcc/cp/parser.c:21843 0x58de44 cp_parser_late_parsing_for_member ../../gcc-4.8.1/gcc/cp/parser.c:22484 0x58de44 cp_parser_class_specifier_1 ../../gcc-4.8.1/gcc/cp/parser.c:18586 0x58de44 cp_parser_class_specifier ../../gcc-4.8.1/gcc/cp/parser.c:18610 0x58de44 cp_parser_type_specifier ../../gcc-4.8.1/gcc/cp/parser.c:13677 0x5a0711 cp_parser_decl_specifier_seq ../../gcc-4.8.1/gcc/cp/parser.c:11003 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. --------- test.cpp --------- template <typename Tp> class int_v4 { typedef Tp Tpv __attribute__((vector_size(4 * sizeof(Tp)))); Tpv v; static Tpv shuffle(const int_v4& u1, const int_v4& u2, const int_v4& s) { return __builtin_shuffle(u1.v, u2.v, s.v); //segfault } Tpv shuffle2(const int_v4& u1, const int_v4& u2, const int_v4& s) { return __builtin_shuffle(v, v, v); //error if shuffle() is removed } }; int main() { int_v4<int> iv4; int_v4<unsigned int> uv4; return 0; } ----------- If: typedef int Tp; is added at the top and the lines with template stuff are removed then it compiles just fine but with the use of templates there is a segfault in shuffle() and if shuffle() is removed then there is: "error: __builtin_shuffle last argument must be an integer vector" in shuffle2(). When compiling with GCC 4.7.2 (which is shipping with Ubuntu 12.10) then everything compiles, even if the line: int_v4<float> fv4; is added to main() (meaning that it was possible to pass non-integer vector as the last argument of __builtin_shuffle in GCC 4.7.2). I'm guessing that the bug is somehow related to the presence/addition of error handling code. It looks like (I am not a GCC developer) GCC is trying to determine the type of the last argument before any variables using the template are even defined (they can be removed and the error message will still be there).
Maybe Marc is interested in this.
(In reply to Paolo Carlini from comment #1) > Maybe Marc is interested in this. ChangeLog says this is probably my fault... c_build_vec_perm_expr is missing some code like we can find in build_x_unary_op for instance: if (processing_template_decl) { if (type_dependent_expression_p (xarg)) return build_min_nt_loc (loc, code, xarg, NULL_TREE); xarg = build_non_dependent_expr (xarg); } RID_BUILTIN_SHUFFLE is handled very early in parser.c which directly calls c_build_vec_perm_expr. I guess we could use build_min_nt(VEC_PERM_EXPR,...) to store the template version, and make sure that c_build_vec_perm_expr is called once the types are instantiated (in tsubst_copy(_and_build)?).
Thanks Marc. Please take your own plan very seriously! ;)
Created attachment 30281 [details] Untested patch There are quite a few issues with the c++ version...
Detail: normally we just pass around tsubst_flags_ts, no complain & tf_error to bool, etc.
(In reply to Paolo Carlini from comment #5) > Detail: normally we just pass around tsubst_flags_ts, no complain & tf_error > to bool, etc. Those flags are not available in c-family, this is not the first place where we pass a bool in this case.
I see, I never fiddled with those.
Patch posted: http://gcc.gnu.org/ml/gcc-patches/2013-06/msg00470.html
r200495 | glisse | 2013-06-27 23:29:22 +0200 (Thu, 27 Jun 2013) | 20 lines 2013-06-27 Marc Glisse <marc.glisse@inria.fr> PR c++/57509 gcc/c-family/ * c-common.h (c_build_vec_perm_expr): New complain argument. * c-common.c (c_build_vec_perm_expr): Likewise. Use save_expr also in C++. gcc/cp/ * typeck.c (cp_build_vec_perm_expr): New function. * cp-tree.h: Declare it. * parser.c (cp_parser_postfix_expression): Call it. * pt.c (tsubst_copy): Handle VEC_PERM_EXPR. (tsubst_copy_and_build): Likewise. gcc/testsuite/ * g++.dg/ext/pr57509.C: New file.