From patchwork Fri Aug 5 23:52:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 413 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6a10:20da:b0:2d3:3019:e567 with SMTP id n26csp510399pxc; Fri, 5 Aug 2022 16:53:37 -0700 (PDT) X-Google-Smtp-Source: AA6agR41JoiwXSdEkNi79E7gVJGYg2EPPD4/Q1NwAW7hthlwgp6MAFjsXwb3eEbXB3W9IomdT506 X-Received: by 2002:a17:906:cc0c:b0:730:8bbb:69ac with SMTP id ml12-20020a170906cc0c00b007308bbb69acmr6770972ejb.392.1659743617115; Fri, 05 Aug 2022 16:53:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659743617; cv=none; d=google.com; s=arc-20160816; b=rMUiQuTlfuV2t9TuWClOdVTmTPB3Ow8LKXSw2cbKa38eFTENVmlXPUY5eYzSfd4pmE qZLSYRfpepXiiSfwvnHn6PQoMXGkhi0AUZgX1kZRLTqO7UqARdppknAPngrHgOsajhcD MUS/TIZ0z0XlgywwhswYZwrO4ZsQZrykWfXZ4QLOzgEgo1Mlzabq6t7ZW5uRrZlFI6wu fnU1AeGOV9dtZs+Cc5paTB8ICjLzOvKQxM6HubOktyYr7TZbEjSNOXO+llRjVq/twBnu mAMVuEqZqSq98OSH0aVMHTtiSdqmyTbWOkPO6olwPzxssyNubr1pvq3d33Y9UleOyCuU jntg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:to :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=nBhRZPN0cAvLk1z8Z8H/9XQwqh9okPOeQU+4+wOt0Ho=; b=uRqb/kMgneJs4dLggySpN78GDyu6V3RH0hBXM5OcCJv75TMaHOH8qB2jFzql47M5ex VLoVUuwsdRe2KeH2xhUJMdQ8tymQjExoNt98tIBWQNKMrAzoK/UR+sxP98zcYk6U1rtl qeqXHvArv88O8s9Dra+kF+LTRj9T3V9FKOBP9IgVmOS/eMrm3pQMvDiRbQvH128RANjk 4zjTvL+OsMrvqjqDBsvTA5HehL+vV4M4Y6gRGFotJKsI7/SLef6bXsI3/I2wxaMj5yqi 1zLLS+pAyd1Xx92y5bJTokRfWfcCZZeDM3dHU3R6UEpB2xo66I3WcE/a1UyVSGu2H4BN BhvA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=TNvlIyYF; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id cm22-20020a0564020c9600b0043bb8c45f26si751759edb.128.2022.08.05.16.53.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Aug 2022 16:53:37 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=TNvlIyYF; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id ACED53858427 for ; Fri, 5 Aug 2022 23:53:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org ACED53858427 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1659743615; bh=nBhRZPN0cAvLk1z8Z8H/9XQwqh9okPOeQU+4+wOt0Ho=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=TNvlIyYFxUJJLp1/O05SSuwyS3vNbg3JpU4rDMShensEZgix5192gQ8eQw/DlDcaj +dUZlYWuwIxo98HFVWl4LKuwPNS+mCRLgptwn4QokRX5/hj27VJJggJ09/JsaeChBa xSChVvyKCxnMvHi7tU62mxuhV3AAkgi2HTj6laLY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 8D7A53858427 for ; Fri, 5 Aug 2022 23:52:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8D7A53858427 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-572-AG1QyDIQOYigGILOX6uyBg-1; Fri, 05 Aug 2022 19:52:47 -0400 X-MC-Unique: AG1QyDIQOYigGILOX6uyBg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A493F3C025D0 for ; Fri, 5 Aug 2022 23:52:47 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.2.16.233]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7F3BB1415122; Fri, 5 Aug 2022 23:52:47 +0000 (UTC) To: gcc-patches@gcc.gnu.org Subject: [committed] New warning: -Wanalyzer-jump-through-null [PR105947] Date: Fri, 5 Aug 2022 19:52:45 -0400 Message-Id: <20220805235245.2795809-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.3 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_NONE, 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 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-Patchwork-Original-From: David Malcolm via Gcc-patches From: David Malcolm Reply-To: David Malcolm Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1740367323206375315?= X-GMAIL-MSGID: =?utf-8?q?1740367323206375315?= This patch adds a new warning to -fanalyzer for jumps through NULL function pointers. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r13-1979-ge1a9168153d2bf. gcc/analyzer/ChangeLog: PR analyzer/105947 * analyzer.opt (Wanalyzer-jump-through-null): New option. * engine.cc (class jump_through_null): New. (exploded_graph::process_node): Complain about jumps through NULL function pointers. gcc/ChangeLog: PR analyzer/105947 * doc/invoke.texi: Add -Wanalyzer-jump-through-null. gcc/testsuite/ChangeLog: PR analyzer/105947 * gcc.dg/analyzer/function-ptr-5.c: New test. Signed-off-by: David Malcolm --- gcc/analyzer/analyzer.opt | 4 ++ gcc/analyzer/engine.cc | 49 +++++++++++++++++++ gcc/doc/invoke.texi | 12 +++++ .../gcc.dg/analyzer/function-ptr-5.c | 42 ++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c diff --git a/gcc/analyzer/analyzer.opt b/gcc/analyzer/analyzer.opt index 808ff36ac54..c6d9c53d9c3 100644 --- a/gcc/analyzer/analyzer.opt +++ b/gcc/analyzer/analyzer.opt @@ -98,6 +98,10 @@ Wanalyzer-free-of-non-heap Common Var(warn_analyzer_free_of_non_heap) Init(1) Warning Warn about code paths in which a non-heap pointer is freed. +Wanalyzer-jump-through-null +Common Var(warn_analyzer_jump_through_null) Init(1) Warning +Warn about code paths in which a NULL function pointer is called. + Wanalyzer-malloc-leak Common Var(warn_analyzer_malloc_leak) Init(1) Warning Warn about code paths in which a heap-allocated pointer leaks. diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index 85b7c5e1227..e8db00d7e18 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -3705,6 +3705,46 @@ private: bool m_terminate_path; }; +/* A subclass of pending_diagnostic for complaining about jumps through NULL + function pointers. */ + +class jump_through_null : public pending_diagnostic_subclass +{ +public: + jump_through_null (const gcall *call) + : m_call (call) + {} + + const char *get_kind () const final override + { + return "jump_through_null"; + } + + bool operator== (const jump_through_null &other) const + { + return m_call == other.m_call; + } + + int get_controlling_option () const final override + { + return OPT_Wanalyzer_jump_through_null; + } + + bool emit (rich_location *rich_loc) final override + { + return warning_at (rich_loc, get_controlling_option (), + "jump through null pointer"); + } + + label_text describe_final_event (const evdesc::final_event &ev) final override + { + return ev.formatted_print ("jump through null pointer here"); + } + +private: + const gcall *m_call; +}; + /* The core of exploded_graph::process_worklist (the main analysis loop), handling one node in the worklist. @@ -4046,6 +4086,15 @@ exploded_graph::process_node (exploded_node *node) logger); if (!call_discovered) { + /* Check for jump through NULL. */ + if (tree fn_ptr = gimple_call_fn (call)) + { + const svalue *fn_ptr_sval + = model->get_rvalue (fn_ptr, &ctxt); + if (fn_ptr_sval->all_zeroes_p ()) + ctxt.warn (new jump_through_null (call)); + } + /* An unknown function or a special function was called at this point, in such case, don't terminate the analysis of the current function. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index e8cd60103e4..c6dac6a1273 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -453,6 +453,7 @@ Objective-C and Objective-C++ Dialects}. -Wno-analyzer-fd-use-without-check @gol -Wno-analyzer-file-leak @gol -Wno-analyzer-free-of-non-heap @gol +-Wno-analyzer-jump-through-null @gol -Wno-analyzer-malloc-leak @gol -Wno-analyzer-mismatching-deallocation @gol -Wno-analyzer-null-argument @gol @@ -9756,6 +9757,7 @@ Enabling this option effectively enables the following warnings: -Wanalyzer-fd-use-without-check @gol -Wanalyzer-file-leak @gol -Wanalyzer-free-of-non-heap @gol +-Wanalyzer-jump-through-null @gol -Wanalyzer-malloc-leak @gol -Wanalyzer-mismatching-deallocation @gol -Wanalyzer-null-argument @gol @@ -9942,6 +9944,16 @@ is called on a non-heap pointer (e.g. an on-stack buffer, or a global). See @uref{https://cwe.mitre.org/data/definitions/590.html, CWE-590: Free of Memory not on the Heap}. +@item -Wno-analyzer-jump-through-null +@opindex Wanalyzer-jump-through-null +@opindex Wno-analyzer-jump-through-null +This warning requires @option{-fanalyzer}, which enables it; use +@option{-Wno-analyzer-jump-through-null} +to disable it. + +This diagnostic warns for paths through the code in which a @code{NULL} +function pointer is called. + @item -Wno-analyzer-malloc-leak @opindex Wanalyzer-malloc-leak @opindex Wno-analyzer-malloc-leak diff --git a/gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c b/gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c new file mode 100644 index 00000000000..3c46f289082 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c @@ -0,0 +1,42 @@ +#define NULL ((void *)0) + +void calling_null_fn_ptr_1 (void) +{ + void (*fn_ptr) (void) = NULL; + fn_ptr (); /* { dg-warning "jump through null pointer" } */ +} + +int calling_null_fn_ptr_2 (void) +{ + int (*fn_ptr) (void) = NULL; + return fn_ptr (); /* { dg-warning "jump through null pointer" } */ +} + +typedef void (*void_void_fn_ptr) (void); + +void calling_const_fn_ptr (void) +{ + void_void_fn_ptr fn_ptr = (void_void_fn_ptr)0xffd2; + return fn_ptr (); +} + +void skipping_init (int flag) +{ + void_void_fn_ptr fn_ptr = NULL; + if (flag) /* { dg-message "branch" } */ + fn_ptr = (void_void_fn_ptr)0xffd2; + fn_ptr (); /* { dg-warning "jump through null pointer" } */ +} + +struct callbacks +{ + void_void_fn_ptr on_redraw; + void_void_fn_ptr on_cleanup; +}; + +void test_callbacks (void) +{ + struct callbacks cb; + __builtin_memset (&cb, 0, sizeof (cb)); + cb.on_cleanup (); /* { dg-warning "jump through null pointer" } */ +}