Summary: | [6/7 Regression] Warning about objects through POD mistakenly claims the object is a pointer | ||
---|---|---|---|
Product: | gcc | Reporter: | Steinar H. Gunderson <steinar+gcc> |
Component: | c++ | Assignee: | Jakub Jelinek <jakub> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | jakub, webrown.cpp |
Priority: | P3 | Keywords: | diagnostic |
Version: | 7.3.0 | ||
Target Milestone: | 6.5 | ||
See Also: | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64867 | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2018-03-09 00:00:00 | |
Attachments: | gcc8-pr84076.patch |
Description
Steinar H. Gunderson
2018-01-27 13:11:10 UTC
With -Wconditionally-supported you'd get additional warning: pr84076.C: In function ‘int main()’: pr84076.C:7:27: warning: passing objects of non-trivially-copyable type ‘std::__cxx11::string’ {aka ‘class std::__cxx11::basic_string<char>’} through ‘...’ is conditionally supported [-Wconditionally-supported] printf("%s\n", str); ^ The reason for the std::string * in diagnostics is that is how we actually implement the ... passing of non-trivially-copyable objects, we pass them by invisible reference as they are passed to named arguments, and the -Wformat code can't find anymore whether the user actually passed the std::string object or an address of it. The convert_arg_to_ellipsis call that converts in this case the non-POD class to its address is done very shortly before calling the -Wformat check, but most of the stuff the function is doing is needed for the following check_format_arguments. So, in order to hide this in diagnostics, we'd either need to somehow mark the tree with the argument that check_format_arguments could determine it is implicitly added, or have another on the side array with the argument types for -Wformat* etc. The question is though if we want or don't want to warn for std::string str; printf ("%p\n", str); where str is passed as reference and thus printing address of it would work just fine. printf aside, is this thing actually supported in varargs? I thought non-PODs were not allowed in varargs, period. (If it's not allowed, I'm not sure why the compiler even tries.) (In reply to sgunderson from comment #3) > printf aside, is this thing actually supported in varargs? I thought > non-PODs were not allowed in varargs, period. (If it's not allowed, I'm not > sure why the compiler even tries.) Related: bug 64867 Ah, so it's allowed to send structs and classes, just not non-PODs. So that's why the conversion to a pointer happens. Created attachment 43596 [details] gcc8-pr84076.patch Untested fix. Author: jakub Date: Fri Mar 9 20:39:14 2018 New Revision: 258397 URL: https://gcc.gnu.org/viewcvs?rev=258397&root=gcc&view=rev Log: PR c++/84076 * call.c (convert_arg_to_ellipsis): Instead of cp_build_addr_expr build ADDR_EXPR with REFERENCE_TYPE. (build_over_call): For purposes of check_function_arguments, if argarray[j] is ADDR_EXPR with REFERENCE_TYPE created above, use its operand rather than the argument itself. * g++.dg/warn/Wformat-2.C: New test. Added: trunk/gcc/testsuite/g++.dg/warn/Wformat-2.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/testsuite/ChangeLog Fixed on the trunk so far. Author: jakub Date: Fri Jun 22 20:34:33 2018 New Revision: 261917 URL: https://gcc.gnu.org/viewcvs?rev=261917&root=gcc&view=rev Log: Backported from mainline 2018-03-09 Jason Merrill <jason@redhat.com> Jakub Jelinek <jakub@redhat.com> PR c++/84076 * call.c (convert_arg_to_ellipsis): Instead of cp_build_addr_expr build ADDR_EXPR with REFERENCE_TYPE. (build_over_call): For purposes of check_function_arguments, if argarray[j] is ADDR_EXPR with REFERENCE_TYPE created above, use its operand rather than the argument itself. * g++.dg/warn/Wformat-2.C: New test. Added: branches/gcc-7-branch/gcc/testsuite/g++.dg/warn/Wformat-2.C Modified: branches/gcc-7-branch/gcc/cp/ChangeLog branches/gcc-7-branch/gcc/cp/call.c branches/gcc-7-branch/gcc/testsuite/ChangeLog Author: jakub Date: Mon Jun 25 17:30:03 2018 New Revision: 262073 URL: https://gcc.gnu.org/viewcvs?rev=262073&root=gcc&view=rev Log: Backported from mainline 2018-03-09 Jason Merrill <jason@redhat.com> Jakub Jelinek <jakub@redhat.com> PR c++/84076 * call.c (convert_arg_to_ellipsis): Instead of cp_build_addr_expr build ADDR_EXPR with REFERENCE_TYPE. (build_over_call): For purposes of check_function_arguments, if argarray[j] is ADDR_EXPR with REFERENCE_TYPE created above, use its operand rather than the argument itself. * g++.dg/warn/Wformat-2.C: New test. Added: branches/gcc-6-branch/gcc/testsuite/g++.dg/warn/Wformat-2.C Modified: branches/gcc-6-branch/gcc/cp/ChangeLog branches/gcc-6-branch/gcc/cp/call.c branches/gcc-6-branch/gcc/testsuite/ChangeLog Fixed for 6.5 and 7.4+ too. |