From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id C7E56385780E; Thu, 1 Apr 2021 23:10:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C7E56385780E From: "msebor at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/79658] [-Wuninitialized] referencing uninitialized field of POD struct should warn Date: Thu, 01 Apr 2021 23:10:03 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: unknown X-Bugzilla-Keywords: diagnostic X-Bugzilla-Severity: normal X-Bugzilla-Who: msebor at gcc dot gnu.org X-Bugzilla-Status: RESOLVED X-Bugzilla-Resolution: FIXED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: resolution cc bug_status Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Apr 2021 23:10:03 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D79658 Martin Sebor changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |FIXED CC| |msebor at gcc dot gnu.org Status|NEW |RESOLVED --- Comment #10 from Martin Sebor --- Many test cases here... For the test case in comment #0, GCC 11 still diagnoses only the second function. The first was never diagnosed because the variable is optimized = out. That should be expected. When the variable is used it is diagnosed. $ gcc -O2 -S -Wall pr79658-c0.C=20 pr79658-c0.C: In function =E2=80=98void bar()=E2=80=99: pr79658-c0.C:31:15: warning: =E2=80=98f=E2=80=99 is used uninitialized [-Wu= ninitialized] 31 | f =3D (flag) (f | FLAG1); // warning here | ^ pr79658-c0.C:29:8: note: =E2=80=98f=E2=80=99 was declared here 29 | flag f; | ^ For the test case in comment #4, with -O, GCC 11 diagnoses all but the first function. The first function isn't diagnosed because the conditionals are folded away and all the warning sees is an unconditional call to bar().=20 Without optimization, the member functions aren't inlined and so the warning doesn't see the uninitialized reads. That's mostly unavoidable. The warni= ng does have logic to trigger when an uninitialized object is passed to a const-qualified reference (or pointer) but not if the object is passed to a non-const argument by reference prior to that. $ gcc -O2 -S -Wall pr79658-c4.C=20 pr79658-c4.C: In function =E2=80=98void foo_1(int)=E2=80=99: pr79658-c4.C:40:10: warning: =E2=80=98*(unsigned int*)((char*)&f1 + offseto= f(eflags, enum_flags::m_enum_value))=E2=80=99 may be used uninitialized [-Wmaybe-uninitialized] 40 | eflags f1; | ^~ pr79658-c4.C: In function =E2=80=98void foo_2(int)=E2=80=99: pr79658-c4.C:52:10: warning: =E2=80=98*(unsigned int*)((char*)&f2 + offseto= f(eflags, enum_flags::m_enum_value))=E2=80=99 may be used uninitialized [-Wmaybe-uninitialized] 52 | eflags f2; | ^~ pr79658-c4.C: In function =E2=80=98void foo_3(int)=E2=80=99: pr79658-c4.C:64:10: warning: =E2=80=98*(unsigned int*)((char*)&f3 + offseto= f(eflags, enum_flags::m_enum_value))=E2=80=99 may be used uninitialized [-Wmaybe-uninitialized] 64 | eflags f3; | ^~ Finally, for the test case in comment #7, GCC 11 (and prior, including 9, s= ince r264078) diagnoses all four functions: $ gcc -O2 -S -Wall pr79658.c pr79658.c: In function =E2=80=98foo_0=E2=80=99: pr79658.c:13:21: warning: =E2=80=98f0.value=E2=80=99 is used uninitialized = [-Wuninitialized] 13 | struct enum_flags f0; // doesn't warn | ^~ pr79658.c: In function =E2=80=98foo_1=E2=80=99: pr79658.c:3:81: warning: =E2=80=98f1.value=E2=80=99 may be used uninitializ= ed [-Wmaybe-uninitialized] 3 | oid set_flag (struct enum_flags *f, int e) { f->value =3D f->value = | e; } | ~~~~~~~~~^~~ pr79658.c:25:21: note: =E2=80=98f1.value=E2=80=99 was declared here 25 | struct enum_flags f1; // warns | ^~ pr79658.c: In function =E2=80=98foo_2=E2=80=99: pr79658.c:3:81: warning: =E2=80=98f1.value=E2=80=99 may be used uninitializ= ed [-Wmaybe-uninitialized] 3 | oid set_flag (struct enum_flags *f, int e) { f->value =3D f->value = | e; } | ~~~~~~~~~^~~ pr79658.c:25:21: note: =E2=80=98f1.value=E2=80=99 was declared here 25 | struct enum_flags f1; // warns | ^~ pr79658.c: In function =E2=80=98foo_3=E2=80=99: pr79658.c:3:81: warning: =E2=80=98f3.value=E2=80=99 may be used uninitializ= ed [-Wmaybe-uninitialized] 3 | oid set_flag (struct enum_flags *f, int e) { f->value =3D f->value = | e; } | ~~~~~~~~~^~~ pr79658.c:49:21: note: =E2=80=98f3.value=E2=80=99 was declared here 49 | struct enum_flags f3; // warns | ^~ With that, I'm going to resolve this as fixed (for the last test case).=