From patchwork Mon Oct 9 10:03:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathaniel Shead X-Patchwork-Id: 1845162 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=OH/jEdgr; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4S3vkx2GB3z1yqN for ; Mon, 9 Oct 2023 21:04:09 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 493DF3858C36 for ; Mon, 9 Oct 2023 10:04:07 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by sourceware.org (Postfix) with ESMTPS id 4541C3858C2A for ; Mon, 9 Oct 2023 10:03:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4541C3858C2A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-1c88b467ef8so24061265ad.0 for ; Mon, 09 Oct 2023 03:03:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696845823; x=1697450623; darn=gcc.gnu.org; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=MVB4FxFneYCGKuVawHIQf6ndRIDbrwW9yG5oxFPskss=; b=OH/jEdgrf5ZWlYc0Patkg55RGZd596b5h8V81oiRRLjlPBhTMXwOr9Tlebd7A0DBz3 Xf9XprkiOylOpFnkiRveLvf/7hXI9Hp0+Lme4oVy7J3vniH2mJYao/6Vuk90GKC1hUW5 PDroZKT1ANvGI+lhr0V/wBDXizLk0Rkyo8LSG3vm0lD3oMqt7IkGYJsyGlkK24aQ5r6W Egh+kWQ9AntRZkTm/ke+EJIgTTgaqu94WHNI2yZkFPh5X2tRvnGXmouKR4Tj+FasrnfK QX9W+0KufflFn8R7cYNEWgScj8B9/bz7ybdMe39uOD/hSuXqlXJE4Q/loV10ABFyWOiN qN0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696845823; x=1697450623; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=MVB4FxFneYCGKuVawHIQf6ndRIDbrwW9yG5oxFPskss=; b=idYcXQG6/TJx2sLCSedy9pCZGgMcCDIGk33pWETlMfduzmcUQB8kmV9NrV0LI2NFCQ uEakqEakmWY1jXEifwTAOWGmxWMS4wAGhe0PALteM1bL7DOMDEqqVn6mBV0hZ8SYTNti G1D47w0agfJKdGHKOI2xO0JH1Dm7Yskp+sRw+hmkMerjJum6vE3D2Q73VlptwFfxqbNJ Nskp7crLOYmhgBe2ypV/445/w2Z545ldatMlgDC+7JNXqcZOBpixbegA/0IwbMAloLGJ 3j1coisoIBNq5qMIievgoz9bcC5trl5rASkdy0CH2uMf4FVq0njPnlRaWqI11qJhmFLE QSAw== X-Gm-Message-State: AOJu0YxVDOqe5R7AQDZbYYBhisbIAQDvAsjvc97oyEbviVVzJ9QSiE47 8zFQaVmztFAYEtahIhYJqxWQqX/5DiA= X-Google-Smtp-Source: AGHT+IHEDk/5QNShoVmQf1jfrC8V9bB5qDjBILPg/ReLz0fdJ6L49sIMx5VkM6cjJMa4oWbDU463wg== X-Received: by 2002:a17:902:a511:b0:1c6:3222:c67c with SMTP id s17-20020a170902a51100b001c63222c67cmr11840403plq.23.1696845822781; Mon, 09 Oct 2023 03:03:42 -0700 (PDT) Received: from Thaum. (124-150-88-161.tpgi.com.au. [124.150.88.161]) by smtp.gmail.com with ESMTPSA id z15-20020a170903018f00b001c7276398f1sm9113330plg.164.2023.10.09.03.03.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Oct 2023 03:03:42 -0700 (PDT) Message-ID: <6523cffe.170a0220.653b.72b9@mx.google.com> X-Google-Original-Message-ID: Date: Mon, 9 Oct 2023 21:03:36 +1100 From: Nathaniel Shead To: gcc-patches@gcc.gnu.org Cc: Jason Merrill Subject: [PATCH] c++: Improve diagnostics for constexpr cast from void* MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-11.9 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.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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Bootstrapped and regtested on x86_64-pc-linux-gnu with GXX_TESTSUITE_STDS=98,11,14,17,20,23,26,impcx. -- >8 -- This patch improves the errors given when casting from void* in C++26 to include the expected type if the type of the pointed-to object was not similar to the casted-to type. It also ensures (for all standard modes) that void* casts are checked even for DECL_ARTIFICIAL declarations, such as lifetime-extended temporaries, and is only ignored for cases where we know it's OK (heap identifiers and source_location::current). This provides more accurate diagnostics when using the pointer and ensures that some other casts from void* are now correctly rejected. gcc/cp/ChangeLog: * constexpr.cc (is_std_source_location_current): New. (cxx_eval_constant_expression): Only ignore cast from void* for specific cases and improve other diagnostics. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-cast4.C: New test. Signed-off-by: Nathaniel Shead --- gcc/cp/constexpr.cc | 83 +++++++++++++++++--- gcc/testsuite/g++.dg/cpp0x/constexpr-cast4.C | 7 ++ 2 files changed, 78 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-cast4.C diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 0f948db7c2d..f38d541a662 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -2301,6 +2301,36 @@ is_std_allocator_allocate (const constexpr_call *call) && is_std_allocator_allocate (call->fundef->decl)); } +/* Return true if FNDECL is std::source_location::current. */ + +static inline bool +is_std_source_location_current (tree fndecl) +{ + if (!decl_in_std_namespace_p (fndecl)) + return false; + + tree name = DECL_NAME (fndecl); + if (name == NULL_TREE || !id_equal (name, "current")) + return false; + + tree ctx = DECL_CONTEXT (fndecl); + if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx)) + return false; + + name = DECL_NAME (TYPE_MAIN_DECL (ctx)); + return name && id_equal (name, "source_location"); +} + +/* Overload for the above taking constexpr_call*. */ + +static inline bool +is_std_source_location_current (const constexpr_call *call) +{ + return (call + && call->fundef + && is_std_source_location_current (call->fundef->decl)); +} + /* Return true if FNDECL is __dynamic_cast. */ static inline bool @@ -7850,33 +7880,62 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, if (TYPE_PTROB_P (type) && TYPE_PTR_P (TREE_TYPE (op)) && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (op))) - /* Inside a call to std::construct_at or to - std::allocator::{,de}allocate, we permit casting from void* + /* Inside a call to std::construct_at, + std::allocator::{,de}allocate, or + std::source_location::current, we permit casting from void* because that is compiler-generated code. */ && !is_std_construct_at (ctx->call) - && !is_std_allocator_allocate (ctx->call)) + && !is_std_allocator_allocate (ctx->call) + && !is_std_source_location_current (ctx->call)) { /* Likewise, don't error when casting from void* when OP is &heap uninit and similar. */ tree sop = tree_strip_nop_conversions (op); - if (TREE_CODE (sop) == ADDR_EXPR - && VAR_P (TREE_OPERAND (sop, 0)) - && DECL_ARTIFICIAL (TREE_OPERAND (sop, 0))) + tree decl = NULL_TREE; + if (TREE_CODE (sop) == ADDR_EXPR) + decl = TREE_OPERAND (sop, 0); + if (decl + && VAR_P (decl) + && DECL_ARTIFICIAL (decl) + && (DECL_NAME (decl) == heap_identifier + || DECL_NAME (decl) == heap_uninit_identifier + || DECL_NAME (decl) == heap_vec_identifier + || DECL_NAME (decl) == heap_vec_uninit_identifier)) /* OK */; /* P2738 (C++26): a conversion from a prvalue P of type "pointer to cv void" to a pointer-to-object type T unless P points to an object whose type is similar to T. */ - else if (cxx_dialect > cxx23 - && (sop = cxx_fold_indirect_ref (ctx, loc, - TREE_TYPE (type), sop))) + else if (cxx_dialect > cxx23) { - r = build1 (ADDR_EXPR, type, sop); - break; + r = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop); + if (r) + { + r = build1 (ADDR_EXPR, type, r); + break; + } + if (!ctx->quiet) + { + if (TREE_CODE (sop) == ADDR_EXPR) + { + error_at (loc, "cast from %qT is not allowed because " + "pointed-to type %qT is not similar to %qT", + TREE_TYPE (op), TREE_TYPE (TREE_TYPE (sop)), + TREE_TYPE (type)); + tree obj = build_fold_indirect_ref (sop); + inform (DECL_SOURCE_LOCATION (obj), + "pointed-to object declared here"); + } + else + error_at (loc, "cast from %qT is not allowed", + TREE_TYPE (op)); + } + *non_constant_p = true; + return t; } else { if (!ctx->quiet) - error_at (loc, "cast from %qT is not allowed", + error_at (loc, "cast from %qT is not allowed before C++26", TREE_TYPE (op)); *non_constant_p = true; return t; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-cast4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-cast4.C new file mode 100644 index 00000000000..0e7fd87add8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-cast4.C @@ -0,0 +1,7 @@ +// { dg-do compile { target c++11 } } + +constexpr int&& r = 1 + 2; // { dg-message "pointed-to object declared here" "" { target c++26 } } +constexpr void *vpr = &r; +constexpr int* pi = static_cast(vpr); // { dg-error "cast from .void\\*. is not allowed" "" { target c++23_down } } +constexpr float* pf = static_cast(vpr); // { dg-error "cast from .void\\*. is not allowed" "" { target c++23_down } } +// { dg-error "cast from .void\\*. is not allowed because pointed-to type .int. is not similar to .float." "" { target c++26 } .-1 }