From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 6F4B53855587 for ; Fri, 21 Jul 2023 22:04:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6F4B53855587 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1689977079; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lponxSqTRSItU0v7IS5oO51VIq1FgXUFaG7NQ+3xkC4=; b=d+w733UwZWNZVIJvW6GdGQmae/OCQoZvR1JhDnpkSDpug6oyOYzANVYdmEGKtj/Ofwl8x+ +Pfp6PbQQQ/keiTBmZ4eK4jr3t/jm+jC1BVTZ/IMWgkNSJvp/Od0KszXielqp+Bc8d8Cu1 7ehGcaEQR2qlncxSe5OU0I6HiXjoqOg= Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-133-fWaRJGynMQO0v-mCnTzPAw-1; Fri, 21 Jul 2023 18:04:37 -0400 X-MC-Unique: fWaRJGynMQO0v-mCnTzPAw-1 Received: by mail-qk1-f198.google.com with SMTP id af79cd13be357-7656cf70228so347325085a.2 for ; Fri, 21 Jul 2023 15:04:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689977076; x=1690581876; h=mime-version:user-agent:content-transfer-encoding:references :in-reply-to:date:to:from:subject:message-id:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=lponxSqTRSItU0v7IS5oO51VIq1FgXUFaG7NQ+3xkC4=; b=DrYXKuVbl3PfHPD6qIeXgfSgwikICuMacgakjwogFEFdxwBHefYzHTPYcZa4nC2RaV r0QFdUbqsExUPwJdViDndFr7Z7Mc0ySdPlZB4iPCkLwmIrmTBImf/lMgX4gf4Berq2ls E9dkUcz2m6x0iu0FoBZpR3C5bX+qX3YvzQbN9+E4gMTIGZIoX2fEUN3l91onD4PD9mJ5 CVuEJrBhPY7UDEdxVvTmxXA1hE/17i5zWj0MTACsEl6D3zLHAaQiEVhI70aoeT3VO2Og 1f7bNTkcO7DCYJdIuGU6rsY86H7mbUmq8mVa0g7WqbpHEw9MbWQAaq23xzBFL5Un/Zsa icgw== X-Gm-Message-State: ABy/qLZYMJ6MbKKLpuQrftGJUiOl3Z9GrAHMpGSs78dnxoN02sieUawT dmcQALjAxKBcr/deuy1M8/AMMb2lF4oyhTNhqCPy1oXY5b6L2M4IcNrYgn+JlObKbgKp9vhcN+i RkRpXMcYHLndvfcYHu+id1f3bmA== X-Received: by 2002:a05:620a:4509:b0:767:1293:f43e with SMTP id t9-20020a05620a450900b007671293f43emr1503794qkp.49.1689977076607; Fri, 21 Jul 2023 15:04:36 -0700 (PDT) X-Google-Smtp-Source: APBJJlHu8GiyBTRu6yyOXz5NAQjOniRNdwU25Yh60sU/Ii9cHtxoNGSGk0RqvbAIiTmQUexGIsv/9w== X-Received: by 2002:a05:620a:4509:b0:767:1293:f43e with SMTP id t9-20020a05620a450900b007671293f43emr1503780qkp.49.1689977076329; Fri, 21 Jul 2023 15:04:36 -0700 (PDT) Received: from t14s.localdomain (c-76-28-97-5.hsd1.ma.comcast.net. [76.28.97.5]) by smtp.gmail.com with ESMTPSA id p4-20020a05620a15e400b0076768dfe53esm1404254qkm.105.2023.07.21.15.04.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Jul 2023 15:04:35 -0700 (PDT) Message-ID: Subject: Re: [WIP RFC] analyzer: Add optional trim of the analyzer diagnostics going too deep [PR110543] From: David Malcolm To: Benjamin Priour , gcc-patches@gcc.gnu.org Date: Fri, 21 Jul 2023 18:04:34 -0400 In-Reply-To: References: User-Agent: Evolution 3.44.4 (3.44.4-2.fc36) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-9.8 required=5.0 tests=BAYES_00,BODY_8BITS,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Fri, 2023-07-21 at 17:35 +0200, Benjamin Priour wrote: > Hi, >=20 > Upon David's request I've joined the in progress patch to the below > email. > I hope it makes more sense now. >=20 > Best, > Benjamin. Thanks for posting the work-in-progress patch; it makes the idea clearer. Some thoughts about this: - I like the idea of defaulting to *not* showing events within system headers, which the patch achieves - I don't like the combination of never/system with maxdepth, in that it seems complicated and I don't think a user is likely to experiment with different depths. - Hence I think it would work better as a simple boolean, perhaps "-fanalyzer-show-events-in-system-headers" or somesuch? It seems like the sort of thing that we want to provide a sensible default for, but have the option of turning off for debugging the analyzer itself, but I don't expect an end-user to touch that option. FWIW the patch seems to have been mangled somewhat via email, so I don't have a sense of what the actual output from patched analyzer looks like. What should we output to the user with -fanalyzer and no other options for the case in PR 110543? Currently,=C2=A0for https://godbolt.org/z/sb9dM9Gqa trunk emits 12 events, of which probably only this last one is useful: (12) dereference of NULL 'a.std::__shared_ptr_access::operator->()' What does the output look like with your patch? Thanks Dave >=20 > ---------- Forwarded message --------- > From: Benjamin Priour > Date: Tue, Jul 18, 2023 at 3:30=E2=80=AFPM > Subject: [RFC] analyzer: Add optional trim of the analyzer > diagnostics > going too deep [PR110543] > To: , David Malcolm >=20 >=20 > Hi, >=20 > 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. >=20 > 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 > that prevents paths to go deeper than frames. >=20 > fanalyzer-trim-diagnostics=3D > > Common Joined RejectNegative ToLower > > Var(flag_analyzer_trim_diagnostics) > > Init("system") > > -fanalyzer-trim-diagnostics=3D[never|system|] Trim > > diagnostics > > path that are too long before emission. > >=20 >=20 > Does it sounds reasonable and user-friendly ? >=20 > 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. >=20 > /* { dg-additional-options "-fdiagnostics-plain-output > > -fdiagnostics-path-format=3Dinline-events -fanalyzer-trim- > > diagnostics=3Dnever" > > } */ > > /* { dg-skip-if "" { c++98_only }=C2=A0 } */ > >=20 > > #include > > struct A {int x; int y;}; > >=20 > > int main () { > > =C2=A0 std::shared_ptr a; > > =C2=A0 a->x =3D 4; /* { dg-line deref_a } */ > > =C2=A0 /* { dg-warning "dereference of NULL" "" { target *-*-* } deref_= a > > } */ > >=20 > > =C2=A0 return 0; > > } > >=20 > > /* { dg-begin-multiline-output "" } > > =C2=A0 'int main()': events 1-2 > > =C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0 +--> 'std::__shared_ptr_access<_Tp, _Lp, = , > > > > > ::element_type* std::__shared_ptr_access<_Tp, _Lp, , > > >::operator->() const [with _Tp =3D A; > > __gnu_cxx::_Lock_policy > > _Lp =3D __gnu_cxx::_S_atomic; bool =3D false; bool > > =3D > > false]': events 3-4 > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 +--> 'std:= :__shared_ptr_access<_Tp, _Lp, , > > >::element_type* std::__shared_ptr_access<_Tp, _Lp, > > , >::_M_get() const [with _Tp =3D A; > > __gnu_cxx::_Lock_policy _Lp =3D __gnu_cxx::_S_atomic; bool > > =3D > > false; bool =3D false]': events 5-6 > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 +--> 'std::__shared_ptr<_Tp, _Lp>::elemen= t_type* > > std::__shared_ptr<_Tp, _Lp>::get() const [with _Tp =3D A; > > __gnu_cxx::_Lock_policy _Lp =3D __gnu_cxx::_S_atomic]': events 7-8 > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= | > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= | > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <------+ > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 'std::__shared_ptr_access<_Tp, _Lp, , > > >::element_type* std::__shared_ptr_access<_Tp, _Lp, > > , >::_M_get() const [with _Tp =3D A; > > __gnu_cxx::_Lock_policy _Lp =3D __gnu_cxx::_S_atomic; bool > > =3D > > false; bool =3D false]': event 9 > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <------+ > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 'std::__shared_ptr_acc= ess<_Tp, _Lp, , > > > > > ::element_type* std::__shared_ptr_access<_Tp, _Lp, , > > >::operator->() const [with _Tp =3D A; > > __gnu_cxx::_Lock_policy > > _Lp =3D __gnu_cxx::_S_atomic; bool =3D false; bool > > =3D > > false]': event 10 > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0 <------+ > > =C2=A0=C2=A0=C2=A0 | > > =C2=A0 'int main()': events 11-12 > > =C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0 { dg-end-multiline-output "" } */ > >=20 >=20 >=20 > The first events "'int main()': events 1-2" vary in c++14 (get events > 1-3). >=20 > >=20 > > // c++14 with fully detailed output > > =C2=A0 =E2=80=98int main()=E2=80=99: events 1-3 > > =C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 8 | int main () { > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0= =C2=A0 ^~~~ > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0= =C2=A0 | > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0= =C2=A0 (1) entry to =E2=80=98main=E2=80=99 > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 9 |=C2=A0=C2=A0 std::shared_ptr<= A> a; > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ~ > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (2) > > =E2=80=98a.std::shared_ptr::.std::__shared_ptr > __gnu_cxx::_S_atomic>::_M_ptr=E2=80=99 is NULL > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0 10 |=C2=A0=C2=A0 a->x =3D 4; /* { dg-l= ine deref_a } */ > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 = ~~ > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 = | > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 = (3) calling =E2=80=98std::__shared_ptr_access > __gnu_cxx::_S_atomic, false, false>::operator->=E2=80=99 from =E2=80=98= main=E2=80=99 > >=20 >=20 > whereas c++17 and posterior give >=20 > > // c++17 with fully detailed output > >=20 > // ./xg++ -fanalyzer > > =C2=A0../../gcc/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim- > > diagnostics-never.C > > =C2=A0-B. -shared-libgcc -fanalyzer-trim-diagnostics=3Dnever -std=3Dc++= 17 > >=20 > =C2=A0 =E2=80=98int main()=E2=80=99: events 1-2 > > =C2=A0=C2=A0=C2=A0 | > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 8 | int main () { > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0= =C2=A0 ^~~~ > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0= =C2=A0 | > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0= =C2=A0 (1) entry to =E2=80=98main=E2=80=99 > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 9 |=C2=A0=C2=A0 std::shared_ptr<= A> a; > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0 10 |=C2=A0=C2=A0 a->x =3D 4; /* { dg-l= ine deref_a } */ > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 = ~~ > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 = | > > =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 = (2) calling =E2=80=98std::__shared_ptr_access > __gnu_cxx::_S_atomic, false, false>::operator->=E2=80=99 from =E2=80=98= main=E2=80=99 > >=20 >=20 > 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: >=20 > // c++14 -fdump-ipa-analyzer > > // std::shared_ptr a; becomes > > a.D.29392._M_ptr =3D 0B; > > a.D.29392._M_refcount._M_pi =3D 0B; > >=20 >=20 > whereas in c++17 >=20 > > // c++17 -fdump-ipa-analyzer > > // std::shared_ptr a; becomes > > a =3D {}; > >=20 >=20 > 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. >=20 > Thanks, > Benjamin. >=20 > --- > =C2=A0gcc/analyzer/analyzer.cc=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 |=C2=A0=C2=A0 2 +- > =C2=A0gcc/analyzer/analyzer.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0=C2=A0 1 + > =C2=A0gcc/analyzer/analyzer.opt=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 |=C2=A0=C2=A0 4 + > =C2=A0gcc/analyzer/diagnostic-manager.cc=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | 132 > ++++++++++++++++++ > =C2=A0gcc/analyzer/diagnostic-manager.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0 7 + > =C2=A0.../analyzer/fanalyzer-trim-diagnostics-0.C=C2=A0=C2=A0 |=C2=A0 19 = +++ > =C2=A0.../analyzer/fanalyzer-trim-diagnostics-1.C=C2=A0=C2=A0 |=C2=A0 28 = ++++ > =C2=A0.../analyzer/fanalyzer-trim-diagnostics-2.C=C2=A0=C2=A0 |=C2=A0 44 = ++++++ > =C2=A0.../fanalyzer-trim-diagnostics-default.C=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 |=C2=A0 21 +++ > =C2=A0.../fanalyzer-trim-diagnostics-never.C=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0 44 ++++++ > =C2=A0.../fanalyzer-trim-diagnostics-system.C=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 |=C2=A0 19 +++ > =C2=A011 files changed, 320 insertions(+), 1 deletion(-) > =C2=A0create mode 100644 > gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-0.C > =C2=A0create mode 100644 > gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-1.C > =C2=A0create mode 100644 > gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-2.C > =C2=A0create mode 100644 > gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-default.C > =C2=A0create mode 100644 > gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-never.C > =C2=A0create mode 100644 > gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-system.C >=20 > diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc > index 5091fb7a583..b27d8e359db 100644 > --- a/gcc/analyzer/analyzer.cc > +++ b/gcc/analyzer/analyzer.cc > @@ -274,7 +274,7 @@ is_named_call_p (const_tree fndecl, const char > *funcname) > =C2=A0=C2=A0=C2=A0 Compare with cp/typeck.cc: decl_in_std_namespace_p, bu= t this > doesn't > =C2=A0=C2=A0=C2=A0 rely on being the C++ FE (or handle inline namespaces = inside of > std). > =C2=A0*/ >=20 > -static inline bool > +bool > =C2=A0is_std_function_p (const_tree fndecl) > =C2=A0{ > =C2=A0=C2=A0 tree name_decl =3D DECL_NAME (fndecl); > diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h > index 579517c23e6..31597079153 100644 > --- a/gcc/analyzer/analyzer.h > +++ b/gcc/analyzer/analyzer.h > @@ -386,6 +386,7 @@ extern bool is_special_named_call_p (const gcall > *call, > const char *funcname, > =C2=A0extern bool is_named_call_p (const_tree fndecl, const char > *funcname); > =C2=A0extern bool is_named_call_p (const_tree fndecl, const char > *funcname, > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const gcall *call, unsigned int num_args); > +extern bool is_std_function_p (const_tree fndecl); > =C2=A0extern bool is_std_named_call_p (const_tree fndecl, const char > *funcname); > =C2=A0extern bool is_std_named_call_p (const_tree fndecl, const char > *funcname, > =C2=A0 const gcall *call, unsigned int num_args); > diff --git a/gcc/analyzer/analyzer.opt b/gcc/analyzer/analyzer.opt > index 2760aaa8151..78ff2c07483 100644 > --- a/gcc/analyzer/analyzer.opt > +++ b/gcc/analyzer/analyzer.opt > @@ -362,4 +362,8 @@ fdump-analyzer-untracked > =C2=A0Common RejectNegative Var(flag_dump_analyzer_untracked) > =C2=A0Emit custom warnings with internal details intended for analyzer > developers. >=20 > +fanalyzer-trim-diagnostics=3D > +Common Joined RejectNegative ToLower > Var(flag_analyzer_trim_diagnostics) > Init("system") > +-fanalyzer-trim-diagnostics=3D[never|system|] Trim > diagnostics > path that are too long before emission. > + > =C2=A0; This comment is to ensure we retain the blank line above. > diff --git a/gcc/analyzer/diagnostic-manager.cc > b/gcc/analyzer/diagnostic-manager.cc > index cfca305d552..d946ad5bac7 100644 > --- a/gcc/analyzer/diagnostic-manager.cc > +++ b/gcc/analyzer/diagnostic-manager.cc > @@ -20,9 +20,11 @@ along with GCC; see the file COPYING3.=C2=A0 If not se= e >=20 > =C2=A0#include "config.h" > =C2=A0#define INCLUDE_MEMORY > +#define INCLUDE_VECTOR > =C2=A0#include "system.h" > =C2=A0#include "coretypes.h" > =C2=A0#include "tree.h" > +#include "input.h" > =C2=A0#include "pretty-print.h" > =C2=A0#include "gcc-rich-location.h" > =C2=A0#include "gimple-pretty-print.h" > @@ -60,6 +62,37 @@ along with GCC; see the file COPYING3.=C2=A0 If not se= e >=20 > =C2=A0#if ENABLE_ANALYZER >=20 > +/* Return positive value of fanalyzer-trim-diagnostics if a depth > was given > +=C2=A0 or a negative value otherwise.=C2=A0 */ > + > +long trim_diagnostics_depth () > +{ > +=C2=A0 if (trim_diagnostics_system_p () ||=C2=A0 trim_diagnostics_never_= p ()) > +=C2=A0=C2=A0=C2=A0 return -1; > + > +=C2=A0 char *end =3D NULL; > +=C2=A0 long depth =3D strtol (flag_analyzer_trim_diagnostics, &end, 10); > +=C2=A0 gcc_assert (end =3D=3D NULL || *end =3D=3D '\0'); > +=C2=A0 gcc_assert (!(end =3D=3D flag_analyzer_trim_diagnostics && depth = =3D=3D > 0)); > +=C2=A0 return depth; > +} > + > +/* Return true if fanalyzer-trim-diagnostics is set to "system".=C2=A0 *= / > + > +bool trim_diagnostics_system_p () > +{ > +=C2=A0 int len =3D strlen (flag_analyzer_trim_diagnostics); > +=C2=A0 return len =3D=3D 6 && strcmp (flag_analyzer_trim_diagnostics, > "system") =3D=3D > 0; > +} > + > +/* Return true if fanalyzer-trim-diagnostics is set to "never".=C2=A0 */ > + > +bool trim_diagnostics_never_p () > +{ > +=C2=A0 int len =3D strlen (flag_analyzer_trim_diagnostics); > +=C2=A0 return len =3D=3D 5 && strcmp (flag_analyzer_trim_diagnostics, > "never") =3D=3D 0; > +} > + > =C2=A0namespace ana { >=20 > =C2=A0class feasible_worklist; > @@ -2281,6 +2314,8 @@ diagnostic_manager::prune_path (checker_path > *path, > =C2=A0=C2=A0 path->maybe_log (get_logger (), "path"); > =C2=A0=C2=A0 prune_for_sm_diagnostic (path, sm, sval, state); > =C2=A0=C2=A0 prune_interproc_events (path); > +=C2=A0 if (! trim_diagnostics_never_p ()) > +=C2=A0=C2=A0=C2=A0 trim_diagnostic_path (path); > =C2=A0=C2=A0 consolidate_conditions (path); > =C2=A0=C2=A0 finish_pruning (path); > =C2=A0=C2=A0 path->maybe_log (get_logger (), "pruned"); > @@ -2667,6 +2702,103 @@ diagnostic_manager::prune_interproc_events > (checker_path *path) const > =C2=A0=C2=A0 while (changed); > =C2=A0} >=20 > +void > +diagnostic_manager::trim_diagnostic_path (checker_path *path) const > +{ > +=C2=A0 if (trim_diagnostics_system_p ()) > +=C2=A0=C2=A0=C2=A0 prune_system_headers (path); > +=C2=A0 else > +=C2=A0=C2=A0=C2=A0 prune_events_too_deep (path); > +} > + > +/* Remove everything within ]callsite, IDX].=C2=A0 */ > +static void > +prune_within_frame (checker_path *path, int &idx) > +{ > +=C2=A0 int nesting =3D 1; > +=C2=A0 while (idx >=3D 0 && nesting !=3D 0) > +=C2=A0=C2=A0=C2=A0 { > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (path->get_checker_event (idx)->is_cal= l_p ()) > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 nesting--; > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 else if (path->get_checker_event (idx)->i= s_return_p ()) > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 nesting++; > + > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 path->delete_event (idx--); > +=C2=A0=C2=A0=C2=A0 } > +} > + > +void > +diagnostic_manager::prune_system_headers (checker_path *path) const > +{ > +=C2=A0 int idx =3D (signed)path->num_events () - 1; > +=C2=A0 while (idx >=3D 0) > +=C2=A0=C2=A0=C2=A0 { > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const checker_event *event =3D path->get_= checker_event (idx); > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* Prune everything between [..., system = call, (...), system > return, > ...].=C2=A0 */ > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (event->is_return_p () > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && in_system_head= er_at (event->get_location ())) > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 { > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 int ret_idx =3D idx; > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 prune_within_frame (path, idx= ); > + > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (get_logger ()) > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 { > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 label_text desc > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (path= ->get_checker_event (idx)->get_desc (false)); > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 log ("filtering e= vent %i-%i:" > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 " system header event: %s", > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 idx, ret_idx, desc.get ()); > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // delete callsite > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (idx >=3D 0) > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 path->delete_even= t (idx); > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } > + > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 idx--; > +=C2=A0=C2=A0=C2=A0 } > +} > + > +void > +diagnostic_manager::prune_events_too_deep (checker_path *path) const > +{ > +=C2=A0 long depth =3D 0; > +=C2=A0 long maxdepth =3D trim_diagnostics_depth (); > +=C2=A0 gcc_assert (maxdepth >=3D 0); > +=C2=A0 int idx =3D (signed)path->num_events () - 1; > +=C2=A0 if (idx >=3D 0) > +=C2=A0 { > +=C2=A0=C2=A0=C2=A0 depth =3D path->get_checker_event (0)->get_stack_dept= h (); > +=C2=A0=C2=A0=C2=A0 maxdepth +=3D depth; > +=C2=A0 } > + > +=C2=A0 while (idx >=3D 0) > +=C2=A0=C2=A0=C2=A0 { > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const checker_event *event =3D path->get_= checker_event (idx); > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* Prune everything between [..., call to= o deep, (...), return > too > deep, ...].=C2=A0 */ > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (event->is_return_p () > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && event->get_sta= ck_depth () > maxdepth) > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 { > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 int ret_idx =3D idx; > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 prune_within_frame (path, idx= ); > + > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (get_logger ()) > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 { > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 label_text desc > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (path= ->get_checker_event (idx)->get_desc (false)); > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 log ("filtering e= vent %i-%i:" > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 " event too deep: %s", > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 idx, ret_idx, desc.get ()); > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // delete callsite > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (idx >=3D 0) > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 path->delete_even= t (idx); > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } > + > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 idx--; > +=C2=A0=C2=A0=C2=A0 } > + > +} > + > =C2=A0/* Return true iff event IDX within PATH is on the same line as > REF_EXP_LOC.=C2=A0 */ >=20 > =C2=A0static bool > diff --git a/gcc/analyzer/diagnostic-manager.h > b/gcc/analyzer/diagnostic-manager.h > index 9b3e903fc5d..9afef0975be 100644 > --- a/gcc/analyzer/diagnostic-manager.h > +++ b/gcc/analyzer/diagnostic-manager.h > @@ -21,6 +21,10 @@ along with GCC; see the file COPYING3.=C2=A0 If not se= e > =C2=A0#ifndef GCC_ANALYZER_DIAGNOSTIC_MANAGER_H > =C2=A0#define GCC_ANALYZER_DIAGNOSTIC_MANAGER_H >=20 > +long trim_diagnostics_depth (); > +bool trim_diagnostics_system_p (); > +bool trim_diagnostics_never_p (); > + > =C2=A0namespace ana { >=20 > =C2=A0class epath_finder; > @@ -180,6 +184,9 @@ private: > =C2=A0 state_machine::state_t state) const; > =C2=A0=C2=A0 void update_for_unsuitable_sm_exprs (tree *expr) const; > =C2=A0=C2=A0 void prune_interproc_events (checker_path *path) const; > +=C2=A0 void trim_diagnostic_path (checker_path *path) const; > +=C2=A0 void prune_system_headers (checker_path *path) const; > +=C2=A0 void prune_events_too_deep (checker_path *path) const; > =C2=A0=C2=A0 void consolidate_conditions (checker_path *path) const; > =C2=A0=C2=A0 void finish_pruning (checker_path *path) const; >=20 > diff --git a/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim- > diagnostics-0.C > b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-0.C > new file mode 100644 > index 00000000000..ddf39ed1690 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-0.C > @@ -0,0 +1,19 @@ > +/* { dg-additional-options "-fdiagnostics-plain-output > -fdiagnostics-path-format=3Dinline-events -fanalyzer-trim- > diagnostics=3D0" } */ > +/* { dg-skip-if "" { c++98_only }=C2=A0 } */ > + > +#include > + > +struct A {int x; int y;}; > + > +int main () { > +=C2=A0 std::shared_ptr a; > +=C2=A0 a->x =3D 4; /* { dg-line deref_a } */ > +=C2=A0 /* { dg-warning "dereference of NULL" "" { target *-*-* } deref_a > } */ > + > +=C2=A0 return 0; > +} > +/* { dg-begin-multiline-output "" } > +=C2=A0 'int main()': events 1-2 > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0 { dg-end-multiline-output "" } */ > \ No newline at end of file > diff --git a/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim- > diagnostics-1.C > b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-1.C > new file mode 100644 > index 00000000000..83a132078a1 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-1.C > @@ -0,0 +1,28 @@ > +/* { dg-additional-options "-fdiagnostics-plain-output > -fdiagnostics-path-format=3Dinline-events -fanalyzer-trim- > diagnostics=3D1" } */ > +/* { dg-skip-if "" { c++98_only }=C2=A0 } */ > + > +#include > + > +struct A {int x; int y;}; > + > +int main () { > +=C2=A0 std::shared_ptr a; > +=C2=A0 a->x =3D 4; /* { dg-line deref_a } */ > +=C2=A0 /* { dg-warning "dereference of NULL" "" { target *-*-* } deref_a > } */ > + > +=C2=A0 return 0; > +} > + > +/* { dg-begin-multiline-output "" } > +=C2=A0 'int main()': events 1-2 > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 +--> 'std::__shared_ptr_access<_Tp, _Lp, , > > > ::element_type* std::__shared_ptr_access<_Tp, _Lp, , > >::operator->() const [with _Tp =3D A; > __gnu_cxx::_Lock_policy > _Lp =3D __gnu_cxx::_S_atomic; bool =3D false; bool > =3D > false]': event 3 > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 <------+ > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0 'int main()': events 4-5 > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0 { dg-end-multiline-output "" } */ > \ No newline at end of file > diff --git a/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim- > diagnostics-2.C > b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-2.C > new file mode 100644 > index 00000000000..cf065929ec9 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-2.C > @@ -0,0 +1,44 @@ > +/* { dg-additional-options "-fdiagnostics-plain-output > -fdiagnostics-path-format=3Dinline-events -fanalyzer-trim- > diagnostics=3D2" } */ > +/* { dg-skip-if "" { c++98_only }=C2=A0 } */ > + > +#include > + > +struct A {int x; int y;}; > + > +int main () { > +=C2=A0 std::shared_ptr a; > +=C2=A0 a->x =3D 4; /* { dg-line deref_a } */ > +=C2=A0 /* { dg-warning "dereference of NULL" "" { target *-*-* } deref_a > } */ > + > +=C2=A0 return 0; > +} > + > +/* { dg-begin-multiline-output "" } > +=C2=A0 'int main()': events 1-2 > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 +--> 'std::__shared_ptr_access<_Tp, _Lp, , > > > ::element_type* std::__shared_ptr_access<_Tp, _Lp, , > >::operator->() const [with _Tp =3D A; > __gnu_cxx::_Lock_policy > _Lp =3D __gnu_cxx::_S_atomic; bool =3D false; bool > =3D > false]': events 3-4 > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 +--> 'std::= __shared_ptr_access<_Tp, _Lp, , > >::element_type* std::__shared_ptr_access<_Tp, _Lp, > , >::_M_get() const [with _Tp =3D A; > __gnu_cxx::_Lock_policy _Lp =3D __gnu_cxx::_S_atomic; bool > =3D > false; bool =3D false]': events 5-6 > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 +--> 'std::__shared_ptr<_Tp, _Lp>::element_t= ype* > std::__shared_ptr<_Tp, _Lp>::get() const [with _Tp =3D A; > __gnu_cxx::_Lock_policy _Lp =3D __gnu_cxx::_S_atomic]': events 7-8 > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <------+ > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 'std::__shared_ptr_access<_Tp, _Lp, , > >::element_type* std::__shared_ptr_access<_Tp, _Lp, > , >::_M_get() const [with _Tp =3D A; > __gnu_cxx::_Lock_policy _Lp =3D __gnu_cxx::_S_atomic; bool > =3D > false; bool =3D false]': event 9 > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <------+ > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 'std::__shared_ptr_acce= ss<_Tp, _Lp, , > > > ::element_type* std::__shared_ptr_access<_Tp, _Lp, , > >::operator->() const [with _Tp =3D A; > __gnu_cxx::_Lock_policy > _Lp =3D __gnu_cxx::_S_atomic; bool =3D false; bool > =3D > false]': event 10 > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 <------+ > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0 'int main()': events 11-12 > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0 { dg-end-multiline-output "" } */ > \ No newline at end of file > diff --git > a/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-default.C > b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-default.C > new file mode 100644 > index 00000000000..fc271309d4e > --- /dev/null > +++ b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics- > default.C > @@ -0,0 +1,21 @@ > +/* { dg-additional-options "-O0 -fdiagnostics-plain-output > -fdiagnostics-path-format=3Dinline-events" } */ > +/* { dg-skip-if "" { c++98_only }=C2=A0 } */ > + > +// Must behave like -fanalyzer-trim-diagnostics=3Dsystem > + > +#include > + > +struct A {int x; int y;}; > + > +int main () { > +=C2=A0 std::shared_ptr a; > +=C2=A0 a->x =3D 4; /* { dg-line deref_a } */ > +=C2=A0 /* { dg-warning "dereference of NULL" "" { target *-*-* } deref_a > } */ > + > +=C2=A0 return 0; > +} > +/* { dg-begin-multiline-output "" } > +=C2=A0 'int main()': events 1-2 > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0 { dg-end-multiline-output "" } */ > \ No newline at end of file > diff --git > a/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-never.C > b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-never.C > new file mode 100644 > index 00000000000..a69416608da > --- /dev/null > +++ b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics- > never.C > @@ -0,0 +1,44 @@ > +/* { dg-additional-options "-fdiagnostics-plain-output > -fdiagnostics-path-format=3Dinline-events -fanalyzer-trim- > diagnostics=3Dnever" > } */ > +/* { dg-skip-if "" { c++98_only }=C2=A0 } */ > + > +#include > + > +struct A {int x; int y;}; > + > +int main () { > +=C2=A0 std::shared_ptr a; > +=C2=A0 a->x =3D 4; /* { dg-line deref_a } */ > +=C2=A0 /* { dg-warning "dereference of NULL" "" { target *-*-* } deref_a > } */ > + > +=C2=A0 return 0; > +} > + > +/* { dg-begin-multiline-output "" } > +=C2=A0 'int main()': events 1-2 > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 +--> 'std::__shared_ptr_access<_Tp, _Lp, , > > > ::element_type* std::__shared_ptr_access<_Tp, _Lp, , > >::operator->() const [with _Tp =3D A; > __gnu_cxx::_Lock_policy > _Lp =3D __gnu_cxx::_S_atomic; bool =3D false; bool > =3D > false]': events 3-4 > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 +--> 'std::= __shared_ptr_access<_Tp, _Lp, , > >::element_type* std::__shared_ptr_access<_Tp, _Lp, > , >::_M_get() const [with _Tp =3D A; > __gnu_cxx::_Lock_policy _Lp =3D __gnu_cxx::_S_atomic; bool > =3D > false; bool =3D false]': events 5-6 > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 +--> 'std::__shared_ptr<_Tp, _Lp>::element_t= ype* > std::__shared_ptr<_Tp, _Lp>::get() const [with _Tp =3D A; > __gnu_cxx::_Lock_policy _Lp =3D __gnu_cxx::_S_atomic]': events 7-8 > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <------+ > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 'std::__shared_ptr_access<_Tp, _Lp, , > >::element_type* std::__shared_ptr_access<_Tp, _Lp, > , >::_M_get() const [with _Tp =3D A; > __gnu_cxx::_Lock_policy _Lp =3D __gnu_cxx::_S_atomic; bool > =3D > false; bool =3D false]': event 9 > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <------+ > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 'std::__shared_ptr_acce= ss<_Tp, _Lp, , > > > ::element_type* std::__shared_ptr_access<_Tp, _Lp, , > >::operator->() const [with _Tp =3D A; > __gnu_cxx::_Lock_policy > _Lp =3D __gnu_cxx::_S_atomic; bool =3D false; bool > =3D > false]': event 10 > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 <------+ > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0 'int main()': events 11-12 > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0 { dg-end-multiline-output "" } */ > \ No newline at end of file > diff --git > a/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-system.C > b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics-system.C > new file mode 100644 > index 00000000000..22fadc84e75 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/analyzer/fanalyzer-trim-diagnostics- > system.C > @@ -0,0 +1,19 @@ > +/* { dg-additional-options "-fdiagnostics-plain-output > -fdiagnostics-path-format=3Dinline-events -fanalyzer-trim- > diagnostics=3Dsystem" > } */ > +/* { dg-skip-if "" { c++98_only }=C2=A0 } */ > + > +#include > + > +struct A {int x; int y;}; > + > +int main () { > +=C2=A0 std::shared_ptr a; > +=C2=A0 a->x =3D 4; /* { dg-line deref_a } */ > +=C2=A0 /* { dg-warning "dereference of NULL" "" { target *-*-* } deref_a > } */ > + > +=C2=A0 return 0; > +} > +/* { dg-begin-multiline-output "" } > +=C2=A0 'int main()': events 1-2 > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0=C2=A0 | > +=C2=A0=C2=A0 { dg-end-multiline-output "" } */ > \ No newline at end of file