From patchwork Wed Feb 23 02:57:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Wei Liew X-Patchwork-Id: 51317 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DFE583947425 for ; Wed, 23 Feb 2022 02:58:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DFE583947425 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1645585112; bh=U3293IJQn+JBSqieVHV6oF6EFmcZ53UNSCIKtpNPN0w=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=lDoq3QS7Smg1CwJOzTJIceS5KR5LZoPx1BZK2cdwXupeQy1MH5dlNJ4lG93GrLWxI apDZtYsoksNNUcqZa5MG4Oyzhl4dIwYFEk3Ser5qxnNljIeWklg8s8U5xUr7LSrq94 ++4rtl5Pr2LygK/RWyHQWeiRIJ5/FFlw26iS01hA= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-io1-xd36.google.com (mail-io1-xd36.google.com [IPv6:2607:f8b0:4864:20::d36]) by sourceware.org (Postfix) with ESMTPS id C1CBF3858406 for ; Wed, 23 Feb 2022 02:58:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C1CBF3858406 Received: by mail-io1-xd36.google.com with SMTP id d19so12252713ioc.8 for ; Tue, 22 Feb 2022 18:58:03 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=U3293IJQn+JBSqieVHV6oF6EFmcZ53UNSCIKtpNPN0w=; b=cx0MLW33YC5kqNvmcDPqW+CucL8Xs6TCa1tqIILNRBfCz/CLuptf8hxUNxDg34Ba4P SBYwSgTDs99Lb8ThiJXdzc02cu9oqGoCNi+ptsI2lLFHP3DKyi1ZP1yFLsX/e/IMTFsx Ci0+i9YFJykPCnj3wMaLsG/DuCfxIyqjKv+IBRviws76R6Ouk65zV6KGH2nAHbwh4K6a UJIdPddMzLtC4KyXCXByEaUAVBmLT4IKpc8lwnJ66XIsDRYMVm9hOKoLArE9G+BgdlKb 0cpHyMZ8ExPUjuzCZrnUaPwnNXoDCRsei3u6wrlP/iB/WOsF5EEe2NKIpq3zS5rcIXft 3+Tg== X-Gm-Message-State: AOAM531SOm4TXHH4p6Z592hJlbq3Jk3oRnFjSh85Z9Ha+EXXC1M7q+Jv Oglb0L/SRCeWdGkTuCkoPjO8GyKfohj1pCEpjteJWlBJxOYHCA== X-Google-Smtp-Source: ABdhPJyPDVc2o+JrL9HzqGDPfLk7NMQrx51biNL9tRs9FFPp+T2k2QRSNkvPJnbOjWXHLBxSJx/4s/5GGmihHNbz/M4= X-Received: by 2002:a05:6602:26d3:b0:63d:aa17:8742 with SMTP id g19-20020a05660226d300b0063daa178742mr21455816ioo.198.1645585082820; Tue, 22 Feb 2022 18:58:02 -0800 (PST) MIME-Version: 1.0 Date: Wed, 23 Feb 2022 10:57:26 +0800 Message-ID: Subject: [PATCH][RFC] c++/96765: warn when casting Base* to Derived* in Base ctor/dtor To: GCC Patches X-Spam-Status: No, score=-9.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, T_SCC_BODY_TEXT_LINE 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-Patchwork-Original-From: Zhao Wei Liew via Gcc-patches From: Zhao Wei Liew Reply-To: Zhao Wei Liew Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi! This patch aims to add a warning when casting "this" in a base class constructor to a derived class type. It works on the test cases provided, but I'm still running regression tests. However, I have a few doubts: 1. Am I missing out any cases? Right now, I'm identifying the casts by checking that TREE_CODE (expr) == NOP_EXPR && is_this_parameter (TREE_OPERAND (expr, 0)). It seems fine to me but perhaps there is a function that I can use to express this more concisely? 2. -Wcast-qual doesn't seem to be the right flag for this warning. However, I can't seem to find an appropriate flag. Maybe I should place it under -Wextra or -Wall? Appreciate any feedback on the aforementioned doubts or otherwise. Thanks, and have a great day! From 8a1f352f3db06faf264bc823387714a4a9e638b6 Mon Sep 17 00:00:00 2001 From: Zhao Wei Liew Date: Tue, 22 Feb 2022 16:03:17 +0800 Subject: [PATCH] c++: warn on Base* to Derived* cast in Base ctor/dtor [PR96765] Casting "this" in a base class constructor to a derived class type is undefined behaviour, but there is no warning when doing so. Add a warning for this. Signed-off-by: Zhao Wei Liew PR c++/96765 gcc/cp/ChangeLog: * typeck.cc (build_static_cast_1): Add a warning when casting Base * to Derived * in Base constructor and destructor. gcc/testsuite/ChangeLog: * g++.dg/warn/Wcast-qual3.C: New test. --- gcc/cp/typeck.cc | 8 ++++++ gcc/testsuite/g++.dg/warn/Wcast-qual3.C | 33 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 gcc/testsuite/g++.dg/warn/Wcast-qual3.C diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index f796337f73c..bbc40b25547 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -8080,6 +8080,14 @@ build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p, { tree base; + if ((DECL_CONSTRUCTOR_P (current_function_decl) + || DECL_DESTRUCTOR_P (current_function_decl)) + && TREE_CODE (expr) == NOP_EXPR + && is_this_parameter (TREE_OPERAND (expr, 0))) + warning_at(loc, OPT_Wcast_qual, + "invalid % from type %qT to type %qT before the latter is constructed", + intype, type); + if (processing_template_decl) return expr; diff --git a/gcc/testsuite/g++.dg/warn/Wcast-qual3.C b/gcc/testsuite/g++.dg/warn/Wcast-qual3.C new file mode 100644 index 00000000000..8c44a23bd68 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wcast-qual3.C @@ -0,0 +1,33 @@ +// PR c++/96765 +// { dg-options "-Wcast-qual" } + +struct Derived; +struct Base { + Derived *x; + Derived *y; + Base(); + ~Base(); +}; + +struct Derived : Base {}; + +Base::Base() + : x(static_cast(this)), // { dg-warning "invalid 'static_cast'" } + y((Derived *)this) // { dg-warning "invalid 'static_cast'" } +{ + static_cast(this); // { dg-warning "invalid 'static_cast'" } + (Derived *)this; // { dg-warning "invalid 'static_cast'" } +} + +Base::~Base() { + static_cast(this); // { dg-warning "invalid 'static_cast'" } + (Derived *)this; // { dg-warning "invalid 'static_cast'" } +} + +struct Other { + Other() { + Base b; + static_cast(&b); + (Derived *)(&b); + } +};