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 [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id EB48D385383E for ; Mon, 26 Jul 2021 19:27:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org EB48D385383E Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-557-lqNXziEMPbyay8AKl5qh8A-1; Mon, 26 Jul 2021 15:27:07 -0400 X-MC-Unique: lqNXziEMPbyay8AKl5qh8A-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D2E40801A92 for ; Mon, 26 Jul 2021 19:27:06 +0000 (UTC) Received: from t14s.localdomain.com (ovpn-113-57.phx2.redhat.com [10.3.113.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 783DB1042A84; Mon, 26 Jul 2021 19:27:06 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Subject: [committed] analyzer: fix uninit false +ve when returning structs Date: Mon, 26 Jul 2021 15:27:05 -0400 Message-Id: <20210726192705.786591-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" X-Spam-Status: No, score=-13.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Jul 2021 19:27:11 -0000 This patch fixes some false positives from -Wanalyzer-use-of-uninitialized-value when returning structs from functions (seen on the Linux kernel). Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as 3a1d168e9e0e3e38adedf5df393e9f8c075fc755. gcc/analyzer/ChangeLog: * region-model.cc (region_model::on_call_pre): Always set conjured LHS, not just for SSA names. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/sock-1.c: New test. * gcc.dg/analyzer/sock-2.c: New test. Signed-off-by: David Malcolm --- gcc/analyzer/region-model.cc | 13 ++- gcc/testsuite/gcc.dg/analyzer/sock-1.c | 112 +++++++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/sock-2.c | 20 +++++ 3 files changed, 137 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/sock-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/sock-2.c diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index c029759cb9b..9d84b8c28a1 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -1066,14 +1066,11 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt, if (tree lhs = gimple_call_lhs (call)) { const region *lhs_region = get_lvalue (lhs, ctxt); - if (TREE_CODE (lhs) == SSA_NAME) - { - const svalue *sval - = m_mgr->get_or_create_conjured_svalue (TREE_TYPE (lhs), call, - lhs_region); - purge_state_involving (sval, ctxt); - set_value (lhs_region, sval, ctxt); - } + const svalue *sval + = m_mgr->get_or_create_conjured_svalue (TREE_TYPE (lhs), call, + lhs_region); + purge_state_involving (sval, ctxt); + set_value (lhs_region, sval, ctxt); } if (gimple_call_internal_p (call)) diff --git a/gcc/testsuite/gcc.dg/analyzer/sock-1.c b/gcc/testsuite/gcc.dg/analyzer/sock-1.c new file mode 100644 index 00000000000..0f3e822492f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/sock-1.c @@ -0,0 +1,112 @@ +typedef unsigned int __u32; +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +typedef __u32 u32; +typedef __s64 s64; +typedef __u64 u64; +typedef long long __kernel_time64_t; +typedef _Bool bool; +typedef __s64 time64_t; +struct __kernel_timespec { + __kernel_time64_t tv_sec; + long long tv_nsec; +}; +struct timespec64 { + time64_t tv_sec; + long tv_nsec; +}; + +extern struct timespec64 ns_to_timespec64(const s64 nsec); +int put_timespec64(const struct timespec64 *ts, + struct __kernel_timespec *uts); + +/* [...snip...] */ + +extern int put_old_timespec32(const struct timespec64 *, void *); + +/* [...snip...] */ + +/* [...snip...] */ + +typedef s64 ktime_t; + +/* [...snip...] */ + +extern void ktime_get_real_ts64(struct timespec64 *tv); + +/* [...snip...] */ + +enum tk_offsets { + TK_OFFS_REAL, + TK_OFFS_BOOT, + TK_OFFS_TAI, + TK_OFFS_MAX, +}; + +extern ktime_t ktime_get(void); +extern ktime_t ktime_get_with_offset(enum tk_offsets offs); +extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs); +extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs); +extern ktime_t ktime_get_raw(void); +extern u32 ktime_get_resolution_ns(void); + + +static ktime_t ktime_get_real(void) +{ + return ktime_get_with_offset(TK_OFFS_REAL); +} + +/* [...snip...] */ + +struct socket { + /* [...snip...] */ + struct sock *sk; + /* [...snip...] */ +}; + +/* [...snip...] */ + +struct sock { + /* [...snip...] */ + ktime_t sk_stamp; + /* [...snip...] */ +}; + +/* [...snip...] */ + +static ktime_t sock_read_timestamp(struct sock *sk) +{ + return *(const volatile typeof(sk->sk_stamp) *)&(sk->sk_stamp); +} + +static void sock_write_timestamp(struct sock *sk, ktime_t kt) +{ + *(volatile typeof(sk->sk_stamp) *)&(sk->sk_stamp) = kt; +} + +/* [...snip...] */ + +int sock_gettstamp(struct socket *sock, void *userstamp, + bool timeval, bool time32) +{ + struct sock *sk = sock->sk; + struct timespec64 ts; + + /* [...snip...] */ + ts = ns_to_timespec64((sock_read_timestamp(sk))); + if (ts.tv_sec == -1) + return -2; + if (ts.tv_sec == 0) { + ktime_t kt = ktime_get_real(); + sock_write_timestamp(sk, kt); + ts = ns_to_timespec64((kt)); + } + + if (timeval) + ts.tv_nsec /= 1000; + + + if (time32) + return put_old_timespec32(&ts, userstamp); + return put_timespec64(&ts, userstamp); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/sock-2.c b/gcc/testsuite/gcc.dg/analyzer/sock-2.c new file mode 100644 index 00000000000..237e0cb6f0b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/sock-2.c @@ -0,0 +1,20 @@ +__extension__ typedef __signed__ long long __s64; +typedef __s64 time64_t; +struct timespec64 { + time64_t tv_sec; + long tv_nsec; +}; + +extern struct timespec64 ns_to_timespec64(void); + +int sock_gettstamp() +{ + struct timespec64 ts; + + /* [...snip...] */ + ts = ns_to_timespec64(); + if (ts.tv_sec == -1) + return -2; + /* [...snip...] */ + return 0; +} -- 2.26.3