From patchwork Sat Jul 22 15:14:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathaniel Shead X-Patchwork-Id: 124331 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9010:0:b0:3e4:2afc:c1 with SMTP id l16csp854949vqg; Sat, 22 Jul 2023 08:15:42 -0700 (PDT) X-Google-Smtp-Source: APBJJlF47fvVRu1j9IMrIl3SlyTSdulUK5AAJV57bT3k4wTvM7kZy8rHQX8h5H2QN4cE9hYHB49V X-Received: by 2002:a17:906:dc:b0:994:673:8af6 with SMTP id 28-20020a17090600dc00b0099406738af6mr5156497eji.29.1690038942358; Sat, 22 Jul 2023 08:15:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690038942; cv=none; d=google.com; s=arc-20160816; b=MMceM6ZP0Ddov3vMyQndsIvVCcTQurcIZgKFMci6lr/CxCADYbd95i1oNh014wrz0X eKtl6Ln/U0zj5H1eUDZcSoFt2W+suzGIhjTbhl+qLUZ7jZaVSo3XkEaPnjTQEXcji5vX 1HMgGj2OK62ftdogcfzG875KGmRSmZJF+MHcvM0m6DzqNuXSpwv4z90+IEwDyZ+nAWQN VOJhJjebTRZ+lYsgpW55VkcF6aE0mwvwi0YxTAOSVSidXxTnHjTYVxNTRXEchrqTfqA3 yOGqblkITXbc9YnV/uu+SGcHiZ2HOHwKRnRLSBudcdMJ61wD8RZt0oypsTUjJEq9ZNOD IhiQ== 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:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:date:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=0SHn2b9pRriPU9Bii008XExZ9j17JjQ6ysszwEiUgCE=; fh=O6SbEp1Lmu8iWDJwmE5AT4hXTvupzW71de0eJ/uUO/o=; b=IdFec+C7o2iKos1kvXj3lyqLB0tBUMg4B74uudZPqxZodLKMpvJEjHM+BZ619EV6A8 U3Rya1WsCVuGSfBgCAqwgxkI7/5dGUCI46ugHE4rDABjycDqOFUBURy0nEmubX+3swUS Fe1SLdmg+4vt6JRAPFO3LahfbGwYPCCIZdIsh9ZoXZkzKTiJYWhXZh/1ZZOqwhc+uC5f fLtNYckGnG29Tpj3LzFCUN17d8YRjfhP/vnQkMiUoI0rLOhtyru4Hahg8nkZVuSinisc r9ql8xbyCKXsqi+sBVudT/oMd+BQWWtiGb79pJek9QoMTodI0BU5YYNVhZ5whid0oi2p HpEA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=y2EvSBeW; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 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 (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id t2-20020a170906a10200b00991f1e4b041si3729307ejy.737.2023.07.22.08.15.42 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Jul 2023 08:15:42 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=y2EvSBeW; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 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 64A12386D61B for ; Sat, 22 Jul 2023 15:15:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 64A12386D61B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1690038927; bh=0SHn2b9pRriPU9Bii008XExZ9j17JjQ6ysszwEiUgCE=; h=Date:To:Cc:Subject:References:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=y2EvSBeW/SSu9HSNYUjoavkNKLbI3hC0okXRly87TQNtEGV0iWTFJOpLJGL5P7Rxb mwKxL34FRBKt+keqMru18bOhgiEwSd195Sxt/X+SHivNnAV02VEKYkvGMODt/npfph F6xe4fSEvmN9fiJn4+WU/XQ0hAbwj+K09djQ964c= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by sourceware.org (Postfix) with ESMTPS id ADA8D385382B for ; Sat, 22 Jul 2023 15:14:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org ADA8D385382B Received: by mail-pf1-x42a.google.com with SMTP id d2e1a72fcca58-668711086f4so1912017b3a.1 for ; Sat, 22 Jul 2023 08:14:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690038881; x=1690643681; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=0SHn2b9pRriPU9Bii008XExZ9j17JjQ6ysszwEiUgCE=; b=KsiB0tbHwO3XpJzuzwqs3E2VTK88tdt3Mcul7IkP2sObkWQixsOE1cxM4466B1GSTF /IgpIGqf0M7Z8cTwnzLIPxPEjVf6olEmtmins39ZVE1aWySsCimHMdhlKDZ9HXw5Q3Jt znaSh+g3rhE8erwuyklMdVS1Hnbji5hhmej2/IZdrPBw6dbAxTc3lafuxEH9a4ieHRA9 d554Sy5UcywhY35sZSseTwG5Q6ucoP/XqsWk4eW0K/iN7rOw/VxM9YhQ7jLSgweYkWv1 smhrihMXbsvMFq4fKOuQa6eFeXAZX3QrWvm6dN9PPtFpECu2a3zdG9eUFoRevDRgeKPF wa6g== X-Gm-Message-State: ABy/qLa8O5gYjjYrAjGuctUqskJn/sEi8d0KZSWusUvuJprNYMn5TeQo NfbUnls69zL0L/akjawKYIQYmGVmguE= X-Received: by 2002:a05:6a20:918e:b0:134:70b7:238a with SMTP id v14-20020a056a20918e00b0013470b7238amr6737452pzd.12.1690038881378; Sat, 22 Jul 2023 08:14:41 -0700 (PDT) Received: from Thaum.localdomain (59-102-120-25.tpgi.com.au. [59.102.120.25]) by smtp.gmail.com with ESMTPSA id v11-20020a62a50b000000b00682a16f0b00sm4690909pfm.210.2023.07.22.08.14.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Jul 2023 08:14:41 -0700 (PDT) Date: Sun, 23 Jul 2023 01:14:37 +1000 To: gcc-patches@gcc.gnu.org Cc: Jason Merrill , Patrick Palka Subject: [PATCH v5 2/3] c++: Prevent dangling pointers from becoming nullptr in constexpr [PR110619] Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-11.4 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.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: Nathaniel Shead via Gcc-patches From: Nathaniel Shead Reply-To: Nathaniel Shead Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1772134273866471293 X-GMAIL-MSGID: 1772134273866471293 Currently, when typeck discovers that a return statement will refer to a local variable it rewrites to return a null pointer. This causes the error messages for using the return value in a constant expression to be unhelpful, especially for reference return values, and is also a visible change to otherwise valid code (as in the linked PR). The transformation is nonetheless important, however, both as a safety guard against attackers being able to gain a handle to other data on the stack, and to prevent duplicate warnings from later null-dereference warning passes. As such, this patch just delays the transformation until cp_genericize, after constexpr function definitions have been generated. PR c++/110619 gcc/cp/ChangeLog: * cp-gimplify.cc (cp_genericize_r): Transform RETURN_EXPRs to not return dangling pointers. * cp-tree.h (RETURN_EXPR_LOCAL_ADDR_P): New flag. (check_return_expr): Add a new parameter. * semantics.cc (finish_return_stmt): Set flag on RETURN_EXPR when referring to dangling pointer. * typeck.cc (check_return_expr): Disable transformation of dangling pointers, instead pass this information to caller. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-110619.C: New test. Signed-off-by: Nathaniel Shead --- gcc/cp/cp-gimplify.cc | 23 ++++++++++++++++--- gcc/cp/cp-tree.h | 8 ++++++- gcc/cp/semantics.cc | 4 +++- gcc/cp/typeck.cc | 9 ++++---- gcc/testsuite/g++.dg/cpp1y/constexpr-110619.C | 10 ++++++++ 5 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-110619.C diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc index f5734197774..0a5d6300aca 100644 --- a/gcc/cp/cp-gimplify.cc +++ b/gcc/cp/cp-gimplify.cc @@ -1336,9 +1336,26 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) break; case RETURN_EXPR: - if (TREE_OPERAND (stmt, 0) && is_invisiref_parm (TREE_OPERAND (stmt, 0))) - /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */ - *walk_subtrees = 0; + if (TREE_OPERAND (stmt, 0)) + { + if (is_invisiref_parm (TREE_OPERAND (stmt, 0))) + /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */ + *walk_subtrees = 0; + if (RETURN_EXPR_LOCAL_ADDR_P (stmt)) + { + /* Don't return the address of a local variable. */ + tree *p = &TREE_OPERAND (stmt, 0); + while (TREE_CODE (*p) == COMPOUND_EXPR) + p = &TREE_OPERAND (*p, 0); + if (TREE_CODE (*p) == INIT_EXPR) + { + tree op = TREE_OPERAND (*p, 1); + tree new_op = build2 (COMPOUND_EXPR, TREE_TYPE (op), op, + build_zero_cst (TREE_TYPE (op))); + TREE_OPERAND (*p, 1) = new_op; + } + } + } break; case OMP_CLAUSE: diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3de0e154c12..e0c181d9aef 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -447,6 +447,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; INIT_EXPR_NRV_P (in INIT_EXPR) ATOMIC_CONSTR_MAP_INSTANTIATED_P (in ATOMIC_CONSTR) contract_semantic (in ASSERTION_, PRECONDITION_, POSTCONDITION_STMT) + RETURN_EXPR_LOCAL_ADDR_P (in RETURN_EXPR) 1: IDENTIFIER_KIND_BIT_1 (in IDENTIFIER_NODE) TI_PENDING_TEMPLATE_FLAG. TEMPLATE_PARMS_FOR_INLINE. @@ -4071,6 +4072,11 @@ struct GTY(()) lang_decl { (LANG_DECL_FN_CHECK (FUNCTION_DECL_CHECK (NODE)) \ ->u.saved_auto_return_type) +/* In a RETURN_EXPR, whether the expression refers to the address + of a local variable. */ +#define RETURN_EXPR_LOCAL_ADDR_P(NODE) \ + TREE_LANG_FLAG_0 (RETURN_EXPR_CHECK (NODE)) + /* True if NODE is an implicit INDIRECT_REF from convert_from_reference. */ #define REFERENCE_REF_P(NODE) \ (INDIRECT_REF_P (NODE) \ @@ -8139,7 +8145,7 @@ extern tree composite_pointer_type (const op_location_t &, tsubst_flags_t); extern tree merge_types (tree, tree); extern tree strip_array_domain (tree); -extern tree check_return_expr (tree, bool *); +extern tree check_return_expr (tree, bool *, bool *); extern tree spaceship_type (tree, tsubst_flags_t = tf_warning_or_error); extern tree genericize_spaceship (location_t, tree, tree, tree); extern tree cp_build_binary_op (const op_location_t &, diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 8fb47fd179e..720521b7f1a 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -1240,8 +1240,9 @@ finish_return_stmt (tree expr) { tree r; bool no_warning; + bool dangling; - expr = check_return_expr (expr, &no_warning); + expr = check_return_expr (expr, &no_warning, &dangling); if (error_operand_p (expr) || (flag_openmp && !check_omp_return ())) @@ -1259,6 +1260,7 @@ finish_return_stmt (tree expr) } r = build_stmt (input_location, RETURN_EXPR, expr); + RETURN_EXPR_LOCAL_ADDR_P (r) = dangling; if (no_warning) suppress_warning (r, OPT_Wreturn_type); r = maybe_cleanup_point_expr_void (r); diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 859b133a18d..d5c0c85ed51 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -10920,10 +10920,11 @@ maybe_warn_pessimizing_move (tree expr, tree type, bool return_p) change RETVAL into the function return type, and to assign it to the DECL_RESULT for the function. Set *NO_WARNING to true if code reaches end of non-void function warning shouldn't be issued - on this RETURN_EXPR. */ + on this RETURN_EXPR. Set *DANGLING to true if code returns the + address of a local variable. */ tree -check_return_expr (tree retval, bool *no_warning) +check_return_expr (tree retval, bool *no_warning, bool *dangling) { tree result; /* The type actually returned by the function. */ @@ -10935,6 +10936,7 @@ check_return_expr (tree retval, bool *no_warning) location_t loc = cp_expr_loc_or_input_loc (retval); *no_warning = false; + *dangling = false; /* A `volatile' function is one that isn't supposed to return, ever. (This is a G++ extension, used to get better code for functions @@ -11273,8 +11275,7 @@ check_return_expr (tree retval, bool *no_warning) else if (!processing_template_decl && maybe_warn_about_returning_address_of_local (retval, loc) && INDIRECT_TYPE_P (valtype)) - retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval, - build_zero_cst (TREE_TYPE (retval))); + *dangling = true; } /* A naive attempt to reduce the number of -Wdangling-reference false diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-110619.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-110619.C new file mode 100644 index 00000000000..cca13302238 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-110619.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++14 } } +// { dg-options "-Wno-return-local-addr" } +// PR c++/110619 + +constexpr auto f() { + int i = 0; + return &i; +}; + +static_assert( f() != nullptr );