When compiling the following code with C++11 and -Wunused-but-set-parameter on struct Foo { Foo(void* x) : y{static_cast<char*>(x)} {} char* y; }; GCC (tested on 4.7.0 and 4.9.1) incorrectly complains: x.cpp:2:13: warning: parameter 'x' set but not used [-Wunused-but-set-parameter] Which is clear nonsense, as the parameter is used. If the initialization list is changed to use parentheses, or the static_cast is removed and y's type is changed, the warning goes away.
CC-ing Jakub about this too.
For: struct Foo { Foo(void* x) : y{static_cast<char*>(x)} {} char* y; }; struct Bar { Bar(void* x) : y(static_cast<char*>(x)) {} char* y; }; the x parameter in Bar ctor is marked through: #0 mark_exp_read (exp=<parm_decl 0x7ffff19fe380 x>) at ../../gcc/cp/expr.c:135 #1 0x000000000067af84 in mark_exp_read (exp=<nop_expr 0x7ffff19fc5c0>) at ../../gcc/cp/expr.c:146 #2 0x000000000067aea6 in mark_rvalue_use (expr=<nop_expr 0x7ffff19fc5c0>) at ../../gcc/cp/expr.c:99 #3 0x0000000000623e29 in convert_like_real (convs=0x20d65a0, expr=<nop_expr 0x7ffff19fc5c0>, fn=<tree 0x0>, argnum=0, inner=0, issue_conversion_warnings=true, c_cast_p=false, complain=3) at ../../gcc/cp/call.c:6209 #4 0x0000000000630bd3 in perform_implicit_conversion_flags (type=<pointer_type 0x7ffff18d19d8>, expr=<nop_expr 0x7ffff19fc5c0>, complain=3, flags=1) at ../../gcc/cp/call.c:9315 #5 0x00000000007bb105 in convert_for_assignment (type=<pointer_type 0x7ffff18d19d8>, rhs=<nop_expr 0x7ffff19fc5c0>, errtype=ICR_INIT, fndecl=<tree 0x0>, parmnum=0, complain=3, flags=1) at ../../gcc/cp/typeck.c:8233 #6 0x00000000007bb65f in convert_for_initialization (exp=<component_ref 0x7ffff19a1990>, type=<pointer_type 0x7ffff18d19d8>, rhs=<nop_expr 0x7ffff19fc5c0>, flags=1, errtype=ICR_INIT, fndecl=<tree 0x0>, parmnum=0, complain=3) at ../../gcc/cp/typeck.c:8324 #7 0x00000000007b933d in cp_build_modify_expr (lhs=<component_ref 0x7ffff19a1990>, modifycode=INIT_EXPR, rhs=<nop_expr 0x7ffff19fc5c0>, complain=3) at ../../gcc/cp/typeck.c:7593 #8 0x00000000007ced80 in perform_member_init (member=<field_decl 0x7ffff19ee7b8 y>, init=<nop_expr 0x7ffff19fc5c0>) at ../../gcc/cp/init.c:771 #9 0x00000000007d0535 in emit_mem_initializers (mem_inits=<tree_list 0x7ffff1a00190>) at ../../gcc/cp/init.c:1136 #10 0x00000000007f895c in finish_mem_initializers (mem_inits=<tree_list 0x7ffff1a00168>) at ../../gcc/cp/semantics.c:1603 #11 0x0000000000767fa0 in cp_parser_mem_initializer_list (parser=0x7ffff19fe000) at ../../gcc/cp/parser.c:12530 #12 0x0000000000767b21 in cp_parser_ctor_initializer_opt (parser=0x7ffff19fe000) at ../../gcc/cp/parser.c:12441 #13 0x000000000077311c in cp_parser_ctor_initializer_opt_and_function_body (parser=0x7ffff19fe000, in_function_try_block=false) at ../../gcc/cp/parser.c:18993 #14 0x000000000077adce in cp_parser_function_definition_after_declarator (parser=0x7ffff19fe000, inline_p=true) at ../../gcc/cp/parser.c:23173 #15 0x000000000077cc6a in cp_parser_late_parsing_for_member (parser=0x7ffff19fe000, member_function=<function_decl 0x7ffff19f1870 Bar>) at ../../gcc/cp/parser.c:23856 No idea what different code path is used for the {} initialization as opposed to (), but supposedly somewhere in there we should call mark_rvalue_use or mark_exp_read.
And on struct Baz { Baz(char* x) : y{x} {} char* y; }; x is marked through: #0 mark_exp_read (exp=<parm_decl 0x7ffff19fe680 x>) at ../../gcc/cp/expr.c:135 #1 0x000000000067aea6 in mark_rvalue_use (expr=<parm_decl 0x7ffff19fe680 x>) at ../../gcc/cp/expr.c:99 #2 0x00000000007a53e6 in decay_conversion (exp=<parm_decl 0x7ffff19fe680 x>, complain=3) at ../../gcc/cp/typeck.c:1915 #3 0x000000000062492c in convert_like_real (convs=0x20d6630, expr=<parm_decl 0x7ffff19fe680 x>, fn=<tree 0x0>, argnum=0, inner=0, issue_conversion_warnings=true, c_cast_p=false, complain=3) at ../../gcc/cp/call.c:6331 #4 0x0000000000630bd3 in perform_implicit_conversion_flags (type=<pointer_type 0x7ffff18d19d8>, expr=<constructor 0x7ffff19fa8b8>, complain=3, flags=1) at ../../gcc/cp/call.c:9315 #5 0x00000000007bb105 in convert_for_assignment (type=<pointer_type 0x7ffff18d19d8>, rhs=<constructor 0x7ffff19fa8b8>, errtype=ICR_INIT, fndecl=<tree 0x0>, parmnum=0, complain=3, flags=1) at ../../gcc/cp/typeck.c:8233 #6 0x00000000007bb65f in convert_for_initialization (exp=<component_ref 0x7ffff19a1b10>, type=<pointer_type 0x7ffff18d19d8>, rhs=<constructor 0x7ffff19fa8b8>, flags=1, errtype=ICR_INIT, fndecl=<tree 0x0>, parmnum=0, complain=3) at ../../gcc/cp/typeck.c:8324 #7 0x00000000007b933d in cp_build_modify_expr (lhs=<component_ref 0x7ffff19a1b10>, modifycode=INIT_EXPR, rhs=<constructor 0x7ffff19fa8b8>, complain=3) at ../../gcc/cp/typeck.c:7593 #8 0x00000000007ced80 in perform_member_init (member=<field_decl 0x7ffff19eeab0 y>, init=<constructor 0x7ffff19fa8b8>) at ../../gcc/cp/init.c:771 #9 0x00000000007d0535 in emit_mem_initializers (mem_inits=<tree_list 0x7ffff1a004b0>) at ../../gcc/cp/init.c:1136 #10 0x00000000007f895c in finish_mem_initializers (mem_inits=<tree_list 0x7ffff1a00488>) at ../../gcc/cp/semantics.c:1603 cp_build_modify_expr is still called even in the Foo::Foo(void*) case, with a CONSTRUCTOR containing NOP_EXPR of PARM_DECL, so either we should mark_exp_read when creating the CONSTRUCTOR, which would be roughly in cp_parser_initializer_list ??, or when processing the ctor. Jason, any preferences?
Author: jason Date: Sat Sep 20 00:54:55 2014 New Revision: 215413 URL: https://gcc.gnu.org/viewcvs?rev=215413&root=gcc&view=rev Log: PR c++/61465 * call.c (convert_like_real) [ck_identity]: Call mark_rvalue_use after pulling out an element from a CONSTRUCTOR. Added: trunk/gcc/testsuite/g++.dg/warn/Wunused-parm-6.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c
Author: jason Date: Mon Sep 22 18:47:16 2014 New Revision: 215476 URL: https://gcc.gnu.org/viewcvs?rev=215476&root=gcc&view=rev Log: PR c++/61465 * call.c (convert_like_real) [ck_identity]: Call mark_rvalue_use after pulling out an element from a CONSTRUCTOR. Added: branches/gcc-4_9-branch/gcc/testsuite/g++.dg/warn/Wunused-parm-6.C Modified: branches/gcc-4_9-branch/gcc/cp/ChangeLog branches/gcc-4_9-branch/gcc/cp/call.c
Can the bug be marked as resolved?
The testcase in comment 0 seems to have been fixed in 4.9.2
Fixed.