From patchwork Fri Jul 17 19:00:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 1331406 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=bAjANUr5; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4B7gSw4Py9z9sRN for ; Sat, 18 Jul 2020 05:01:19 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0EF5139E100A; Fri, 17 Jul 2020 19:00:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0EF5139E100A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1595012430; bh=8uM8IKwkldxwSWHVUnNy0llaAS8a2AOdfZV1dhhOr7Q=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=bAjANUr5V4innjrnRVBEqkgZ2V/1uAkI6evGxWZIbyuTKq0Qri4XQmn3TYhIK1vJ3 IFqGmUsNVxSJ1pV/fKlBlDJUutTh0Iw/RNkrK2JEwxKaRJVC538/VqGRtz3o+6N2yn W4KVsLPCPgg5lC+UDEzNfN5eq5sJSrmHwmZoVu3c= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qv1-xf29.google.com (mail-qv1-xf29.google.com [IPv6:2607:f8b0:4864:20::f29]) by sourceware.org (Postfix) with ESMTPS id ABC1139A0C0C for ; Fri, 17 Jul 2020 19:00:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org ABC1139A0C0C Received: by mail-qv1-xf29.google.com with SMTP id o2so2186507qvk.6 for ; Fri, 17 Jul 2020 12:00:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-language; bh=8uM8IKwkldxwSWHVUnNy0llaAS8a2AOdfZV1dhhOr7Q=; b=Lv3ZnjYph/yz+2Z6LiI7f39gYwsZRJjz0Zt5aOYCv29XADRhTCpJTW5M8tQncHOI13 Cx4h+OgnQJjOmoXbCJVtrcLYoDBDxvBNdPZGGt/CcWNv9I/5mxFWwijFjOYHHkK+nyKL 9ceno/c//GbYpqrzPdrorX6oG3JtjcvSLdvm3DeDqCinnRdA8JbAaR4PGk4omlCOTtFa tWDdmzsLgLmirvY6FcRf3K9JJMQW0Cb427/peDCgIjqd7kfKoWUAgSwAe8VhM7Aopx6I U3S0vgjdm4lKdfq+JwBuJRx/M/xfcEcsRpsT7JpBcet4WuFyToxRVNYHeqWRYoaC+oMT 61Yg== X-Gm-Message-State: AOAM530JStLCezgpK7G1M0bz+/kvgvs3tv8Pz9BM9ODajFlNjr8oHsP8 9EZUui7dwFg/a9WJsnRjFlU= X-Google-Smtp-Source: ABdhPJxHgkHfC87i86pduCquyg0UueaALwkkXST0yWirjohj4aFcdgK6tJuwhMyjIVwtB/QKgi8Zqg== X-Received: by 2002:a0c:fd85:: with SMTP id p5mr10513773qvr.70.1595012427172; Fri, 17 Jul 2020 12:00:27 -0700 (PDT) Received: from [192.168.0.41] (174-16-106-56.hlrn.qwest.net. [174.16.106.56]) by smtp.gmail.com with ESMTPSA id a3sm10808247qkf.131.2020.07.17.12.00.25 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 17 Jul 2020 12:00:26 -0700 (PDT) To: gcc-patches , Jason Merrill Subject: [PATCH] avoid -Wnonnull on synthesized condition in static_cast (PR 96003) Message-ID: Date: Fri, 17 Jul 2020 13:00:24 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-10.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Martin Sebor via Gcc-patches From: Martin Sebor Reply-To: Martin Sebor Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" The recent enhancement to treat the implicit this pointer argument as nonnull in member functions triggers spurious -Wnonnull for the synthesized conditional expression the C++ front end replaces the pointer with in some static_cast expressions. The front end already sets the no-warning bit for the test but not for the whole conditional expression, so the attached fix extends the same solution to it. The consequence of this fix is that user-written code like this: static_cast(p ? p : 0)->f (); or static_cast(p ? p : nullptr)->f (); don't trigger the warning because they are both transformed into the same expression as: static_cast(p)->f (); What still does trigger it is this: static_cast(p ? p : (T*)0)->f (); because here it's the inner COND_EXPR's no-warning bit that's set (the outer one is clear), whereas in the former expressions it's the other way around. It would be nice if this worked consistently but I didn't see an easy way to do that and more than a quick fix seems outside the scope for this bug. Another case reported by someone else in the same bug involves a dynamic_cast. A simplified test case goes something like this: if (dynamic_cast(p)) dynamic_cast(p)->f (); The root cause is the same: the front end emitting the COND_EXPR ((p != 0) ? ((T*)__dynamic_cast(p, (& _ZTI1B), (& _ZTI1C), 0)) : 0) I decided not to suppress the warning in this case because doing so would also suppress it in unconditional calls with the result of the cast: dynamic_cast(p)->f (); and that doesn't seem helpful. Instead, I'd suggest to make the second cast in the if statement to reference to T&: if (dynamic_cast(p)) dynamic_cast(*p).f (); Martin PR c++/96003 spurious -Wnonnull calling a member on the result of static_cast gcc/c-family/ChangeLog: PR c++/96003 * c-common.c (check_function_arguments_recurse): Return early when no-warning bit is set. gcc/cp/ChangeLog: PR c++/96003 * class.c (build_base_path): Set no-warning bit on the synthesized conditional expression in static_cast. gcc/testsuite/ChangeLog: PR c++/96003 * g++.dg/warn/Wnonnull7.C: New test. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 51ecde69f2d..7ab9966b7c0 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -5821,6 +5821,11 @@ check_function_arguments_recurse (void (*callback) void *ctx, tree param, unsigned HOST_WIDE_INT param_num) { + /* Avoid warning in synthesized expressions like C++ static_cast. + See PR 96003. */ + if (TREE_NO_WARNING (param)) + return; + if (CONVERT_EXPR_P (param) && (TYPE_PRECISION (TREE_TYPE (param)) == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (param, 0))))) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 14380c7a08c..b460f8aefcd 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -516,8 +516,14 @@ build_base_path (enum tree_code code, out: if (null_test) - expr = fold_build3_loc (input_location, COND_EXPR, target_type, null_test, expr, - build_zero_cst (target_type)); + { + expr = fold_build3_loc (input_location, COND_EXPR, target_type, null_test, + expr, build_zero_cst (target_type)); + /* Avoid warning for the whole conditional expression (in addition + to NULL_TEST itself -- see above) in case the result is used in + a nonnull context that the front end -Wnonnull checks. */ + TREE_NO_WARNING (expr) = 1; + } return expr; } diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull7.C b/gcc/testsuite/g++.dg/warn/Wnonnull7.C new file mode 100644 index 00000000000..b7a64c83436 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wnonnull7.C @@ -0,0 +1,25 @@ +/* PR c++/96003 - spurious -Wnonnull calling a member on the result + of static_cast + { dg-do compile } + { dg-options "-Wall" } */ + +struct D; +struct B +{ + B* next; + D* Next (); +}; + +struct D: B +{ + virtual ~D (); +}; + +struct Iterator +{ + D* p; + void advance () + { + p = static_cast(p)->Next (); // { dg-bogus "\\\[-Wnonnull" } + } +};