Compiling this line with 'g++ crash.cc' template<typename A> struct Wuh { void f(int i) { i = i ?: 10; } }; Causes a segmentation violation. Thanks to Falk Hueffner for helping shortening this to one line. backtrace of -dH created coredump: #9 type_dependent_expression_p (expression=0x0) at ../../gcc/cp/pt.c:11574 #10 0x0810cba8 in build_x_conditional_expr (ifexp=0x401e28dc, op1=0x0, op2=0x401db924) at ../../gcc/cp/typeck.c:4286 #11 0x080f0005 in cp_parser_question_colon_clause (parser=0x401e0980, logical_or_expr=0x1) at ../../gcc/cp/parser.c:4841 #12 0x080f0087 in cp_parser_assignment_expression (parser=0x401e0980) at ../../gcc/cp/parser.c:4873 #13 0x080f00a6 in cp_parser_assignment_expression (parser=0x401e0980) at ../../gcc/cp/parser.c:4887 #14 0x080f0198 in cp_parser_expression (parser=0x401e0980) at ../../gcc/cp/parser.c:5017 #15 0x080f0568 in cp_parser_expression_statement (parser=0x401e0980, in_statement_expr_p=false) at ../../gcc/cp/parser.c:5299 #16 0x080f02f0 in cp_parser_statement (parser=0x401e0980, in_statement_expr_p=false) at ../../gcc/cp/parser.c:5209 #17 0x080f064e in cp_parser_statement_seq_opt (parser=0x401e0980, in_statement_expr_p=false) at ../../gcc/cp/parser.c:5364 #18 0x080f05d3 in cp_parser_compound_statement (parser=0x401e0980, in_statement_expr_p=false) at ../../gcc/cp/parser.c:5337 #19 0x080f5bb7 in cp_parser_function_body (parser=0x1) at ../../gcc/cp/parser.c:10849 #20 0x080f5beb in cp_parser_ctor_initializer_opt_and_function_body (parser=0x401e0980) at ../../gcc/cp/parser.c:10866 #21 0x080f9468 in cp_parser_function_definition_after_declarator (parser=0x401e0980, inline_p=true) at ../../gcc/cp/parser.c:13600 #22 0x080f9a83 in cp_parser_late_parsing_for_member (parser=0x401e0980, member_function=0x401e2a20) at ../../gcc/cp/parser.c:13870 #23 0x080f6475 in cp_parser_class_specifier (parser=0x401e0980) at ../../gcc/cp/parser.c:11326 #24 0x080f3150 in cp_parser_type_specifier (parser=0x401e0980, flags=CP_PARSER_FLAGS_OPTIONAL, is_friend=false, is_declaration=true, declares_class_or_enum=0xbffff7d4, is_cv_qualifier=0xbffff7db) at ../../gcc/cp/parser.c:8168 #25 0x080f147c in cp_parser_decl_specifier_seq (parser=0x401e0980, flags=CP_PARSER_FLAGS_OPTIONAL, attributes=0xbffff814, declares_class_or_enum=0xbffff818) at ../../gcc/cp/parser.c:6382 #26 0x080f97b8 in cp_parser_single_declaration (parser=0x401e0980, member_p=false, friend_p=0xbffff84b) at ../../gcc/cp/parser.c:13723 #27 0x080f96bc in cp_parser_template_declaration_after_export (parser=0x401e0980, member_p=false) at ../../gcc/cp/parser.c:13660 #28 0x080f1034 in cp_parser_declaration (parser=0x401e0980) at ../../gcc/cp/parser.c:5968 #29 0x080f0e88 in cp_parser_declaration_seq_opt (parser=0x401e0980) at ../../gcc/cp/parser.c:5901
From Phil's regression hunter: Search converges between 2003-07-08-trunk (#337) and 2003-07-09-trunk (#338). Here is a smaller example (removal of the class): template<int> void f(int i) { i = i ?: 10; } It gives a backtrace of: 11574 if (TREE_CODE (expression) == IDENTIFIER_NODE) (gdb) bt #0 type_dependent_expression_p (expression=0x0) at /Volumes/UFS_Partition/pinskia/ src/fsf/gcc-clean/src/gcc/cp/pt.c:11574 #1 0x00065b80 in build_x_conditional_expr (ifexp=0x4160a700, op1=0x0, op2= 0x4160b2d0) at /Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/cp/ typeck.c:4281 #2 0x00058074 in cp_parser_assignment_expression (parser=0x4160b2d0) at / Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/cp/parser.c:4887 #3 0x000587cc in cp_parser_expression (parser=0x4160a540) at /Volumes/ UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/cp/parser.c:5017 #4 0x0005888c in cp_parser_expression_statement (parser=0x4160a540, in_statement_expr_p=false) at /Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/ cp/parser.c:5299 #5 0x00059184 in cp_parser_statement (parser=0x4160a540, in_statement_expr_p= 1096856272) at /Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/cp/ parser.c:5209 #6 0x00059750 in cp_parser_compound_statement (parser=0x4160a540, in_statement_expr_p=false) at /Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/ cp/parser.c:5364 #7 0x00059804 in cp_parser_ctor_initializer_opt_and_function_body (parser= 0x4160a540) at /Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/cp/ parser.c:10849 #8 0x00059a6c in cp_parser_function_definition_after_declarator (parser=0x4160a540, inline_p=false) at /Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/cp/ parser.c:13600 #9 0x00059b90 in cp_parser_function_definition_from_specifiers_and_declarator (parser=0x4160a540, decl_specifiers=0x0, attributes=0x4160b2d0, declarator=0x0) at / Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/cp/parser.c:13546 #10 0x000607fc in cp_parser_function_definition (parser=0x4160a540, friend_p= 0x4160b1c8) at /Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/cp/ parser.c:10835 #11 0x00060960 in cp_parser_single_declaration (parser=0x4160a540, member_p= false, friend_p=0xbffff898) at /Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/cp/ parser.c:13781 #12 0x00060af4 in cp_parser_template_declaration_after_export (parser=0x4160a540, member_p=false) at /Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/cp/ parser.c:13660 #13 0x000617b4 in cp_parser_declaration (parser=0x0) at /Volumes/UFS_Partition/ pinskia/src/fsf/gcc-clean/src/gcc/cp/parser.c:5968 #14 0x00061a3c in cp_parser_declaration_seq_opt (parser=0x4160a540) at /Volumes/ UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/cp/parser.c:5901 #15 0x00061c18 in c_parse_file () at /Volumes/UFS_Partition/pinskia/src/fsf/gcc-clean/ src/gcc/cp/parser.c:2163 #16 0x000afdb0 in c_common_parse_file (set_yydebug=0) at /Volumes/UFS_Partition/ pinskia/src/fsf/gcc-clean/src/gcc/c-opts.c:1230 #17 0x0030dfd8 in toplev_main (argc=4437540, argv=0x4160a540) at /Volumes/ UFS_Partition/pinskia/src/fsf/gcc-clean/src/gcc/toplev.c:1792 #18 0x00001c98 in _start (argc=14, argv=0xbffffbac, envp=0xbffffbe8) at /SourceCache/ Csu/Csu-46/crt.c:267 #19 0x00001b0c in start ()
Even this crashes (no variable involved): template<int> void foo() { 0 ?: 0; }
The regression in PR 12515 was introduced or exposed by this patch: --- gcc/gcc/ChangeLog --- 2003-07-08 Mark Mitchell <mark@codesourcery.com> * fold-const.c (make_range): Do not access operand 1 for a zero-operand operator. --- gcc/gcc/cp/ChangeLog --- 2003-07-08 Mark Mitchell <mark@codesourcery.com> * cp-tree.def (NON_DEPENDENT_EXPR): New node. * cp-tree.h (build_call_from_tree): Remove. (build_member_call): Likewise. (dependent_template_arg_p): Remove. [lots more] The regression hunt took place on i686-pc-linux-gnu using the one-line test case from comment #1.
The code in question, which deals with the type of the resuling value, appears to just not know about the ?: operator. The ternary ?: operator is represented as an ifexp, an op1 and an op2. In case of the gcc extension "a ?: b", which is equal to " a ? a : b", op1 is NULL, which all the regular code knows how to deal with, except the type dependent stuff for templates. I tried adding some simple if(op1) tests but I don't think this is the right direction. Perhaps op1=ifexpr at an early stage would be useful, but this is beyond my ken.
Already fixed in GCC 3.4.
The original testcase doesn't crash anymore, but the even shorter one in comment #2 still causes a segfault: ------------------------------------ template<int> void foo() { 0 ?: 0; } ------------------------------------
Subject: Bug 12515 CVSROOT: /cvs/gcc Module name: gcc Changes by: mmitchel@gcc.gnu.org 2003-11-21 22:16:03 Modified files: gcc/cp : ChangeLog pt.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/g++.dg/ext: cond1.C Log message: PR c++/12515 * pt.c (build_non_dependent_expr): Handle GNU extension to ?: operator. PR c++/12515 * g++.dg/ext/cond1.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.3769&r2=1.3770 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&r1=1.794&r2=1.795 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.3201&r2=1.3202 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/cond1.C.diff?cvsroot=gcc&r1=1.2&r2=1.3
The second testcase is now fixed in GCC 3.4 as well.