$ cat tc2.c struct tree2; struct tree_vector2 { tree2 *elts[1]; }; struct tree2 { struct { tree_vector2 vector; } u; }; int const_with_all_bytes_same (tree2 *val) { int i; const_with_all_bytes_same ((val->u.vector.elts[i])); return 1; } $ g++ tc2.c -Wuninitialized -c (empty) $ clang++ tc2.c -Wuninitialized -c clang-3.8: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated tc2.c:17:50: warning: variable 'i' is uninitialized when used here [-Wuninitialized] const_with_all_bytes_same ((val->u.vector.elts[i])); ^ tc2.c:16:8: note: initialize the variable 'i' to silence this warning int i; ^ = 0 1 warning generated. The test-case used to be catch in 4.6.x era.
Looks like warn_uninit() suppresses the warning on 'i' because the TREE_NO_WARNING flag is set on the ARRAY_REF by the C++ FE (in finish_parenthesized_expr(), for an unrelated purpose).
A simpler testcase without infinite recursion: struct tree2; struct tree_vector2 { tree2 *elts[1]; }; struct tree2 { struct { tree_vector2 vector; } u; }; tree2 * const_with_all_bytes_same (tree2 *val) { int i; return ((val->u.vector.elts[i])); } And I would say this is a C++ problem, but unfortunately, it is a problem throughout GCC of abusing TREE_NO_WARNING.
Started most likely with r177667, r177670 doesn't warn, r177661 does.
(In reply to Patrick Palka from comment #1) > Looks like warn_uninit() suppresses the warning on 'i' because the > TREE_NO_WARNING flag is set on the ARRAY_REF by the C++ FE (in > finish_parenthesized_expr(), for an unrelated purpose). I wonder if a quick work-around for this case in particular is to check for: if (TREE_CODE (expr) == MODIFY_EXPR) like the C parser does: /* A parenthesized expression. */ location_t loc_open_paren = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); expr = c_parser_expression (parser); if (TREE_CODE (expr.value) == MODIFY_EXPR) TREE_NO_WARNING (expr.value) = 1; if (expr.original_code != C_MAYBE_CONST_EXPR) expr.original_code = ERROR_MARK; /* Don't change EXPR.ORIGINAL_TYPE. */ location_t loc_close_paren = c_parser_peek_token (parser)->location; set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); Then the bug will only trigger for code such as ((lhs=rhs)), which is what TREE_NO_WARNING is trying to avoid warning for.
(In reply to Manuel López-Ibáñez from comment #5) > (In reply to Patrick Palka from comment #1) > > Looks like warn_uninit() suppresses the warning on 'i' because the > > TREE_NO_WARNING flag is set on the ARRAY_REF by the C++ FE (in > > finish_parenthesized_expr(), for an unrelated purpose). > > I wonder if a quick work-around for this case in particular is to check for: > > if (TREE_CODE (expr) == MODIFY_EXPR) > > like the C parser does: > > /* A parenthesized expression. */ > location_t loc_open_paren = c_parser_peek_token (parser)->location; > c_parser_consume_token (parser); > expr = c_parser_expression (parser); > if (TREE_CODE (expr.value) == MODIFY_EXPR) > TREE_NO_WARNING (expr.value) = 1; > if (expr.original_code != C_MAYBE_CONST_EXPR) > expr.original_code = ERROR_MARK; > /* Don't change EXPR.ORIGINAL_TYPE. */ > location_t loc_close_paren = c_parser_peek_token (parser)->location; > set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren); > c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, > "expected %<)%>"); > > Then the bug will only trigger for code such as ((lhs=rhs)), which is what > TREE_NO_WARNING is trying to avoid warning for. Unfortunately it looks like the purpose of setting TREE_NO_WARNING in finish_parenthesized_expr() is not limited to assignments within conditionals, it's also important for the -Wparentheses warning about confusing precedence (e.g. warn for "a + b << c" but not for "a + (b << c)")
We really need fine grained TREE_NO_WARNING, will see if I manage to implement something for stage3.
GCC 5 branch is being closed
*** Bug 82609 has been marked as a duplicate of this bug. ***
Author: msebor Date: Mon Jan 15 21:45:06 2018 New Revision: 256709 URL: https://gcc.gnu.org/viewcvs?rev=256709&root=gcc&view=rev Log: PR testsuite/83869 - c-c++-common/attr-nonstring-3.c fails starting with r256683 testsuite/CHangeLog: * c-c++-common/attr-nonstring-3.c: Work around bug c++/74762. Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/c-c++-common/attr-nonstring-3.c
*** Bug 85119 has been marked as a duplicate of this bug. ***
GCC 6 branch is being closed
The GCC 7 branch is being closed, re-targeting to GCC 8.4.
GCC 8.4.0 has been released, adjusting target milestone.
No change in GCC 11.
GCC 8 branch is being closed.
Patch: https://gcc.gnu.org/pipermail/gcc-patches/2021-May/571120.html
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
does the TREE_NO_WARNING overhaul that Martin Sebor did affect this?
Yes, this was indeed resolved by r12-1804 and related. One of the last patches in the series (yet to be committed) adds a test for this to the test suite: https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571984.html
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>: https://gcc.gnu.org/g:40c64c9ea565230817f08b5e66a30a1c94ec880c commit r12-1861-g40c64c9ea565230817f08b5e66a30a1c94ec880c Author: Martin Sebor <msebor@redhat.com> Date: Mon Jun 28 15:14:50 2021 -0600 Regression tests for TREE_NO_WARNING enhancement to warning groups [PR74765, PR74762]. PR middle-end/74765 - missing uninitialized warning (parenthesis, TREE_NO_WARNING abuse) PR middle-end/74762 - [9/10/11/12 Regression] missing uninitialized warning (C++, parenthesized expr, TREE_NO_WARNING) gcc/testsuite/ChangeLog: * g++.dg/uninit-pr74762.C: New test. * g++.dg/warn/uninit-pr74765.C: Same.