public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Benjamin Priour <priour.be@gmail.com>
To: gcc-patches@gcc.gnu.org, David Malcolm <dmalcolm@redhat.com>
Subject: [RFC] analyzer: Add optional trim of the analyzer diagnostics going too deep [PR110543]
Date: Tue, 18 Jul 2023 15:30:51 +0200	[thread overview]
Message-ID: <CAKiQ0GGukaF6+BWwTqnJbf0KtBEVjii8TR0awMotA8-0qUztJA@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 5728 bytes --]

Hi,

I'd like to request comments on a patch I am writing for PR110543.
The goal of this patch is to reduce the noise of the analyzer emitted
diagnostics when dealing with
system headers, or simply diagnostic paths that are too long. The new
option only affects the display
of the diagnostics, but doesn't hinder the actual analysis.

I've defaulted the new option to "system", thus preventing the diagnostic
paths from showing system headers.
"never" corresponds to the pre-patch behavior, whereas you can also specify
an unsigned value <maxdepth>
that prevents paths to go deeper than <maxdepth> frames.

fanalyzer-trim-diagnostics=
> Common Joined RejectNegative ToLower Var(flag_analyzer_trim_diagnostics)
> Init("system")
> -fanalyzer-trim-diagnostics=[never|system|<maxdepth>] Trim diagnostics
> path that are too long before emission.
>

Does it sounds reasonable and user-friendly ?

Regstrapping was a success against trunk, although one of the newly added
test case fails for c++14.
Note that the test case below was done with "never", thus behaves exactly
as the pre-patch analyzer
on x86_64-linux-gnu.

/* { dg-additional-options "-fdiagnostics-plain-output
> -fdiagnostics-path-format=inline-events -fanalyzer-trim-diagnostics=never"
> } */
> /* { dg-skip-if "" { c++98_only }  } */
>
> #include <memory>
> struct A {int x; int y;};
>
> int main () {
>   std::shared_ptr<A> a;
>   a->x = 4; /* { dg-line deref_a } */
>   /* { dg-warning "dereference of NULL" "" { target *-*-* } deref_a } */
>
>   return 0;
> }
>
> /* { dg-begin-multiline-output "" }
>   'int main()': events 1-2
>     |
>     |
>     +--> 'std::__shared_ptr_access<_Tp, _Lp, <anonymous>, <anonymous>
> >::element_type* std::__shared_ptr_access<_Tp, _Lp, <anonymous>,
> <anonymous> >::operator->() const [with _Tp = A; __gnu_cxx::_Lock_policy
> _Lp = __gnu_cxx::_S_atomic; bool <anonymous> = false; bool <anonymous> =
> false]': events 3-4
>            |
>            |
>            +--> 'std::__shared_ptr_access<_Tp, _Lp, <anonymous>,
> <anonymous> >::element_type* std::__shared_ptr_access<_Tp, _Lp,
> <anonymous>, <anonymous> >::_M_get() const [with _Tp = A;
> __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic; bool <anonymous> =
> false; bool <anonymous> = false]': events 5-6
>                   |
>                   |
>                   +--> 'std::__shared_ptr<_Tp, _Lp>::element_type*
> std::__shared_ptr<_Tp, _Lp>::get() const [with _Tp = A;
> __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]': events 7-8
>                          |
>                          |
>                   <------+
>                   |
>                 'std::__shared_ptr_access<_Tp, _Lp, <anonymous>,
> <anonymous> >::element_type* std::__shared_ptr_access<_Tp, _Lp,
> <anonymous>, <anonymous> >::_M_get() const [with _Tp = A;
> __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic; bool <anonymous> =
> false; bool <anonymous> = false]': event 9
>                   |
>                   |
>            <------+
>            |
>          'std::__shared_ptr_access<_Tp, _Lp, <anonymous>, <anonymous>
> >::element_type* std::__shared_ptr_access<_Tp, _Lp, <anonymous>,
> <anonymous> >::operator->() const [with _Tp = A; __gnu_cxx::_Lock_policy
> _Lp = __gnu_cxx::_S_atomic; bool <anonymous> = false; bool <anonymous> =
> false]': event 10
>            |
>            |
>     <------+
>     |
>   'int main()': events 11-12
>     |
>     |
>    { dg-end-multiline-output "" } */
>


The first events "'int main()': events 1-2" vary in c++14 (get events 1-3).

>
> // c++14 with fully detailed output
>   ‘int main()’: events 1-3
>     |
>     |    8 | int main () {
>     |      |     ^~~~
>     |      |     |
>     |      |     (1) entry to ‘main’
>     |    9 |   std::shared_ptr<A> a;
>     |      |                      ~
>     |      |                      |
>     |      |                      (2)
> ‘a.std::shared_ptr<A>::<anonymous>.std::__shared_ptr<A,
> __gnu_cxx::_S_atomic>::_M_ptr’ is NULL
>     |   10 |   a->x = 4; /* { dg-line deref_a } */
>     |      |    ~~
>     |      |    |
>     |      |    (3) calling ‘std::__shared_ptr_access<A,
> __gnu_cxx::_S_atomic, false, false>::operator->’ from ‘main’
>

whereas c++17 and posterior give

> // c++17 with fully detailed output
>
// ./xg++ -fanalyzer
>  ../../gcc/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-never.C
>  -B. -shared-libgcc -fanalyzer-trim-diagnostics=never -std=c++17
>
  ‘int main()’: events 1-2
>     |
>     |    8 | int main () {
>     |      |     ^~~~
>     |      |     |
>     |      |     (1) entry to ‘main’
>     |    9 |   std::shared_ptr<A> a;
>     |   10 |   a->x = 4; /* { dg-line deref_a } */
>     |      |    ~~
>     |      |    |
>     |      |    (2) calling ‘std::__shared_ptr_access<A,
> __gnu_cxx::_S_atomic, false, false>::operator->’ from ‘main’
>

Is there a way to make dg-multiline-output check for a regex ? Or would
checking the multiline-output only for c++17 and c++20 be acceptable ?
This divergence results from two slightly different IPA:

// c++14 -fdump-ipa-analyzer
> // std::shared_ptr<A> a; becomes
> a.D.29392._M_ptr = 0B;
> a.D.29392._M_refcount._M_pi = 0B;
>

whereas in c++17

> // c++17 -fdump-ipa-analyzer
> // std::shared_ptr<A> a; becomes
> a = {};
>

I know shared_ptr limited support is a coincidence more than a feature, but
maybe there is still a way to make the above test case work ?
Otherwise, I'd fallback to a supported system function. If you have any
that you fancy, do tell me.

Thanks,
Benjamin.

             reply	other threads:[~2023-07-18 13:31 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-18 13:30 Benjamin Priour [this message]
2023-07-21 15:35 ` [WIP RFC] " Benjamin Priour
2023-07-21 22:04   ` David Malcolm
2023-07-26  9:27     ` Benjamin Priour
2023-07-26 14:26       ` David Malcolm
2023-07-22 14:47   ` Prathamesh Kulkarni

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAKiQ0GGukaF6+BWwTqnJbf0KtBEVjii8TR0awMotA8-0qUztJA@mail.gmail.com \
    --to=priour.be@gmail.com \
    --cc=dmalcolm@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).