https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96295
Bug ID: 96295 Summary: Wmaybe-uninitialized warning for range operator with empty range struct Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: vries at gcc dot gnu.org Target Milestone: --- Consider test-case tui-winsource.c (minimized from gdb sources, filed as gdb PR https://sourceware.org/bugzilla/show_bug.cgi?id=26282): ... struct tui_source_window_iterator { public: typedef tui_source_window_iterator self_type; typedef void *value_type; explicit tui_source_window_iterator (void *it, void *end) {} explicit tui_source_window_iterator (void *it) {} bool operator!= (const self_type &other) const { return false; } value_type operator* () const { return (value_type)0; } self_type &operator++ () { return *this; } }; struct tui_source_windows { tui_source_window_iterator begin () const { return tui_source_window_iterator ((void *)0, (void *)0); } tui_source_window_iterator end () const { return tui_source_window_iterator ((void*)0); } }; void foo (void) { for (void *win : tui_source_windows ()) { (void)win; } } ... With gcc-10, we have: ... $ g++-10 -x c++ -Wall -O0 -g -c tui-winsource.c ... And with gcc-11 (g++-11 (SUSE Linux) 11.0.0 20200720 (experimental) [revision 8764e9a3fc43f1117db77d1f056b6c3f15a29db3]): ... $ g++-11 -x c++ -Wall -O0 -g -c tui-winsource.c tui-winsource.c: In function ‘void foo()’: tui-winsource.c:34:40: warning: ‘<unknown>’ may be used uninitialized [-Wmaybe-uninitialized] 34 | for (void *win : tui_source_windows ()) | ^ tui-winsource.c:20:30: note: by argument 1 of type ‘const tui_source_windows*’ to ‘tui_source_window_iterator tui_source_windows::begin() const’ declared here 20 | tui_source_window_iterator begin () const | ^~~~~ tui-winsource.c:34:40: note: ‘<anonymous>’ declared here 34 | for (void *win : tui_source_windows ()) | ^ ... At gimple, we have: ... struct tui_source_windows & __for_range; struct tui_source_windows D.2465; try { __for_range = &D.2465; tui_source_windows::begin (__for_range); tui_source_windows::end (__for_range); ... So, strictly speaking the warning is correct, because &D.2465 is not initialized, and consequently __for_range is not initialized when it is passed as argument to tui_source_windows::begin. But it shouldn't matter, because struct tui_source_windows is an empty struct. Workaround is to add: ... struct tui_source_windows { + tui_source_windows () {} tui_source_window_iterator begin () const ... which gives us: ... struct tui_source_windows & __for_range; struct tui_source_windows D.2469; try { tui_source_windows::tui_source_windows (&D.2469); __for_range = &D.2469; tui_source_windows::begin (__for_range); tui_source_windows::end (__for_range); ...