From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id C94973858C20; Tue, 7 Mar 2023 18:14:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C94973858C20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1678212886; bh=BJg7wRUOF5vf6twuqLbPNlDoj5LWBx2j3OUv4pM57Es=; h=From:To:Subject:Date:From; b=xpjJ1MpJC1AXZkiPRdVr4HgZkLP9+2f4tzZlUeeaUFcB+x3SjpEAWYE63eF+4mq4s Kb3Ja7bM02cp4+HfbO2SesIywLAgg4YlYj1aYNUIepXvwhjk0pY356Dy1Glzte+lW3 FPBKw2CQykJrAW6ovnmUr4tpQEJzg11NUB1m0lNE= From: "dmalcolm at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug analyzer/109058] New: RFE: analyzer should elide repeated calls to strcmp in execution paths Date: Tue, 07 Mar 2023 18:14:46 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: analyzer X-Bugzilla-Version: 13.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: dmalcolm at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: dmalcolm at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: 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 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D109058 Bug ID: 109058 Summary: RFE: analyzer should elide repeated calls to strcmp in execution paths Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: analyzer Assignee: dmalcolm at gcc dot gnu.org Reporter: dmalcolm at gcc dot gnu.org Target Milestone: --- Seen on a diagnostic in haproxy's cfgparse-global.c: cfg_parse_global Consider: -------------------------------------------------------------------------- #include #include "analyzer-decls.h" int test (char **args) { if (strcmp (args[0], "opt-001") =3D=3D 0) { do_opt (1); } else if (strcmp (args[0], "opt-002") =3D=3D 0) { do_opt (2); } else if (strcmp (args[0], "opt-003") =3D=3D 0) { do_opt (3); } else if (strcmp (args[0], "opt-004") =3D=3D 0) { do_opt (4); } else if (strcmp (args[0], "opt-005") =3D=3D 0) { do_opt (5); } else if (strcmp (args[0], "opt-006") =3D=3D 0) { do_opt (6); } else if (strcmp (args[0], "opt-007") =3D=3D 0) { do_opt (7); } else if (strcmp (args[0], "opt-008") =3D=3D 0) { do_opt (8); } else if (strcmp (args[0], "opt-009") =3D=3D 0) { do_opt (9); } else if (strcmp (args[0], "opt-010") =3D=3D 0) { do_opt (10); __analyzer_dump_path (); } } -------------------------------------------------------------------------- for which we currently emit: -------------------------------------------------------------------------- ../../src/gcc/testsuite/gcc.dg/analyzer/strcmp-path-1.c:27:5: note: path 27 | __analyzer_dump_path (); | ^~~~~~~~~~~~~~~~~~~~~~~ =E2=80=98test=E2=80=99: events 1-21 | | 7 | if (strcmp (args[0], "opt-001") =3D=3D 0) { | | ^ | | | | | (1) following =E2=80=98false=E2=80=99 branch (when the st= rings are non-equal)... | 8 | do_opt (1); | 9 | } else if (strcmp (args[0], "opt-002") =3D=3D 0) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(2) ...to here | | (3) following =E2=80=98false=E2=80=99 branch (when= the strings are non-equal)... | 10 | do_opt (2); | 11 | } else if (strcmp (args[0], "opt-003") =3D=3D 0) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(4) ...to here | | (5) following =E2=80=98false=E2=80=99 branch (when= the strings are non-equal)... | 12 | do_opt (3); | 13 | } else if (strcmp (args[0], "opt-004") =3D=3D 0) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(6) ...to here | | (7) following =E2=80=98false=E2=80=99 branch (when= the strings are non-equal)... | 14 | do_opt (4); | 15 | } else if (strcmp (args[0], "opt-005") =3D=3D 0) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(8) ...to here | | (9) following =E2=80=98false=E2=80=99 branch (when= the strings are non-equal)... | 16 | do_opt (5); | 17 | } else if (strcmp (args[0], "opt-006") =3D=3D 0) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(10) ...to here | | (11) following =E2=80=98false=E2=80=99 branch (whe= n the strings are non-equal)... | 18 | do_opt (6); | 19 | } else if (strcmp (args[0], "opt-007") =3D=3D 0) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(12) ...to here | | (13) following =E2=80=98false=E2=80=99 branch (whe= n the strings are non-equal)... | 20 | do_opt (7); | 21 | } else if (strcmp (args[0], "opt-008") =3D=3D 0) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(14) ...to here | | (15) following =E2=80=98false=E2=80=99 branch (whe= n the strings are non-equal)... | 22 | do_opt (8); | 23 | } else if (strcmp (args[0], "opt-009") =3D=3D 0) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(16) ...to here | | (17) following =E2=80=98false=E2=80=99 branch (whe= n the strings are non-equal)... | 24 | do_opt (9); | 25 | } else if (strcmp (args[0], "opt-010") =3D=3D 0) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(18) ...to here | | (19) following =E2=80=98true=E2=80=99 branch (when= the strings are equal)... | 26 | do_opt (10); | | ~~~~~~~~~~~ | | | | | (20) ...to here | 27 | __analyzer_dump_path (); | | ~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (21) here | -------------------------------------------------------------------------- We should probably elide all the repeated : following =E2=80=98false=E2=80=99 branch (when the strings are non-equal)= ... ...to here events before the: following =E2=80=98true=E2=80=99 branch (when the strings are equal)... assuming that all they're checking the same string against a series of poss= ible values. This would simplify the execution path to just: -------------------------------------------------------------------------- ../../src/gcc/testsuite/gcc.dg/analyzer/strcmp-path-1.c:27:5: note: path 27 | __analyzer_dump_path (); | ^~~~~~~~~~~~~~~~~~~~~~~ =E2=80=98test=E2=80=99: events 1-3 | | 25 | } else if (strcmp (args[0], "opt-010") =3D=3D 0) { | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (1) following =E2=80=98true=E2=80=99 branch (when = the strings are equal)... | 26 | do_opt (10); | | ~~~~~~~~~~~ | | | | | (2) ...to here | 27 | __analyzer_dump_path (); | | ~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (3) here | --------------------------------------------------------------------------=