From patchwork Fri Jul 29 06:27:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 291 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6a10:b5d6:b0:2b9:3548:2db5 with SMTP id v22csp647025pxt; Thu, 28 Jul 2022 23:28:55 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vZftA6EIOLRai6BZ4nOjse/2kaiWhJEKfJ0OPd3YRXzJhNDRdubQC5COD3zwiFWp8zlsY5 X-Received: by 2002:a17:906:9c84:b0:6e0:7c75:6f01 with SMTP id fj4-20020a1709069c8400b006e07c756f01mr1832875ejc.103.1659076135353; Thu, 28 Jul 2022 23:28:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659076135; cv=none; d=google.com; s=arc-20160816; b=SvMghD9QJ5QZ8COF2WKMHzbyovRRBQ5WwxyycfCU3PwKF/TuauSCqoD4XVjcmzWQBo 6IQ5mGOEGHuVLebcHGvGJhCtthS9aD2iLeaLPI6osy9aGvKWhtlUqowcdptItxaio9xg TJDn594j1jrVPtKU482IpzwaaGMVCO30ay+jNQ5+Ifd3uGVLc87Pp6SVFI6KhNgHzkGf TKYwzmf1LAWwiiStw5cmHUkD09zY3EAEqjM32679XSiKSKZgaSx3czPM0J9tGoEz3u1p QK6lNkWZXpRqLGtFaevDELDj2RZAaths2BnKWGoYKMTvdfP71stkgdeDXkHlqDKfD2eb g7Lg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :mime-version:user-agent:message-id:in-reply-to:date:references :organization:subject:to:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=DuwRtvhgNEaopDwKUnnOyjxWNVhHDf06EcR25sHmEKo=; b=pckNeA585KbyZGlzmd3cDNBGnsrNr1CuKlCXohTLfgGR/q8WPB6Yuym5pPcaNwRPPW 0w9tmUS3PJyWkmQ80WbxXVRj8p76EmL0BUKil5bh0RLYH2gX0l231a5/Dwo8baim1WOo UdtWzJRUteCS7hl3yQn/5J60BeWPrij0gi2twqeEUk/gVJPYBv6u820HohQfOH83KwXe xwFQ8yKuuLUAP7Yr+qf6cjGXW3HWAg/EdbzAasS/wnlNwnCUYuVtYIR4R6ElvUR2MaYo tZV/6XjAct9j9UR+HBWtjufX2aXA2fjtQ8n8VeieWMJX3AyUSmRcHeMYhs+5v7jyL0li Pvyg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=rqQBsqgg; 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 dm2-20020a170907948200b0070d00528830si2682099ejc.221.2022.07.28.23.28.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jul 2022 23:28:55 -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=rqQBsqgg; 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 997AB3853831 for ; Fri, 29 Jul 2022 06:28:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 997AB3853831 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1659076105; bh=DuwRtvhgNEaopDwKUnnOyjxWNVhHDf06EcR25sHmEKo=; h=To:Subject:References:Date:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=rqQBsqggBNIf9rebyHpdhpZrSzr3lI06vcRLEi3c4b5XyKfD5XPINkOrjg83JvjDt cLw6j0nbnh1NMnQ6vnrrEFWChqB5FlNl47MUnLLKSfl/Ob6EfhkilIhYKHuFOMGK9j Cn13BjtSr7FUKLW13Zv7ikYqQnxbwWExzW7hwC24= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from rock.gnat.com (rock.gnat.com [IPv6:2620:20:4000:0:a9e:1ff:fe9b:1d1]) by sourceware.org (Postfix) with ESMTPS id 5C6EA3851C3A for ; Fri, 29 Jul 2022 06:27:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5C6EA3851C3A Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 0408E1168D2; Fri, 29 Jul 2022 02:27:38 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id pUSQSLdYpqX6; Fri, 29 Jul 2022 02:27:37 -0400 (EDT) Received: from free.home (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPS id B58551168CD; Fri, 29 Jul 2022 02:27:37 -0400 (EDT) Received: from livre (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id 26T6RTFE1852044 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 Jul 2022 03:27:29 -0300 To: gcc-patches@gcc.gnu.org Subject: [PATCH v2 06/10] Introduce strub: attributes Organization: Free thinker, does not speak for AdaCore References: Date: Fri, 29 Jul 2022 03:27:29 -0300 In-Reply-To: (Alexandre Oliva's message of "Fri, 29 Jul 2022 03:16:41 -0300") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Alexandre Oliva via Gcc-patches From: Alexandre Oliva Reply-To: Alexandre Oliva Cc: Jan Hubicka , Jim Wilson , Graham Markall 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?1739667417745998763?= X-GMAIL-MSGID: =?utf-8?q?1739667417745998763?= Ada already has support for the strub attributes stubbed-out, and the front-end code already has support for them and their effects in the type system. for gcc/ChangeLog * attribs.cc: Include ipa-strub.h. (decl_attributes): Support applying attributes to function type, rather than pointer type, at handler's request. (comp_type_attributes): Combine strub_comptypes and target comp_type results. for gcc/c-family/ChangeLog * c-attribs.cc: Include ipa-strub.h. (handle_strub_attribute): New. (c_common_attribute_table): Add strub. for gcc/ada/ChangeLog * gcc-interface/utils.cc: Include ipa-strub.h. (handle_strub_attribute): New. (gnat_internal_attribute_table): Add strub. diff --git a/gcc/attribs.cc b/gcc/attribs.cc index fb89616ff296b..d559cfc1b9f4e 100644 --- a/gcc/attribs.cc +++ b/gcc/attribs.cc @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-core.h" #include "attribs.h" #include "fold-const.h" +#include "ipa-strub.h" #include "stor-layout.h" #include "langhooks.h" #include "plugin.h" @@ -774,12 +775,11 @@ decl_attributes (tree *node, tree attributes, int flags, flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE; } - if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE - && TREE_CODE (*anode) != METHOD_TYPE) + if (spec->function_type_required + && !FUNC_OR_METHOD_TYPE_P (*anode)) { if (TREE_CODE (*anode) == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE)) + && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (*anode))) { /* OK, this is a bit convoluted. We can't just make a copy of the pointer type and modify its TREE_TYPE, because if @@ -887,7 +887,24 @@ decl_attributes (tree *node, tree attributes, int flags, TYPE_NAME (tt) = *node; } - *anode = cur_and_last_decl[0]; + if (*anode != cur_and_last_decl[0]) + { + /* Even if !spec->function_type_required, allow the attribute + handler to request the attribute to be applied to the function + type, rather than to the function pointer type, by setting + cur_and_last_decl[0] to the function type. */ + if (!fn_ptr_tmp + && POINTER_TYPE_P (*anode) + && TREE_TYPE (*anode) == cur_and_last_decl[0] + && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (*anode))) + { + fn_ptr_tmp = TREE_TYPE (*anode); + fn_ptr_quals = TYPE_QUALS (*anode); + anode = &fn_ptr_tmp; + } + *anode = cur_and_last_decl[0]; + } + if (ret == error_mark_node) { warning (OPT_Wattributes, "%qE attribute ignored", name); @@ -1491,9 +1508,20 @@ comp_type_attributes (const_tree type1, const_tree type2) if ((lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type1)) != NULL) ^ (lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type2)) != NULL)) return 0; + int strub_ret = strub_comptypes (CONST_CAST_TREE (type1), + CONST_CAST_TREE (type2)); + if (strub_ret == 0) + return strub_ret; /* As some type combinations - like default calling-convention - might be compatible, we have to call the target hook to get the final result. */ - return targetm.comp_type_attributes (type1, type2); + int target_ret = targetm.comp_type_attributes (type1, type2); + if (target_ret == 0) + return target_ret; + if (strub_ret == 2 || target_ret == 2) + return 2; + if (strub_ret == 1 && target_ret == 1) + return 1; + gcc_unreachable (); } /* PREDICATE acts as a function of type: diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index e4f1d3542f378..08c7d71f827a2 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "common/common-target.h" #include "langhooks.h" #include "tree-inline.h" +#include "ipa-strub.h" #include "toplev.h" #include "tree-iterator.h" #include "opts.h" @@ -69,6 +70,7 @@ static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int, static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *); static tree handle_no_stack_protector_function_attribute (tree *, tree, tree, int, bool *); +static tree handle_strub_attribute (tree *, tree, tree, int, bool *); static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); static tree handle_noclone_attribute (tree *, tree, tree, int, bool *); static tree handle_nocf_check_attribute (tree *, tree, tree, int, bool *); @@ -314,6 +316,8 @@ const struct attribute_spec c_common_attribute_table[] = { "no_stack_protector", 0, 0, true, false, false, false, handle_no_stack_protector_function_attribute, attr_stack_protect_exclusions }, + { "strub", 0, 1, false, true, false, true, + handle_strub_attribute, NULL }, { "noinline", 0, 0, true, false, false, false, handle_noinline_attribute, attr_noinline_exclusions }, @@ -1327,6 +1331,84 @@ handle_noipa_attribute (tree *node, tree name, tree, int, bool *no_add_attrs) return NULL_TREE; } +/* Handle a "strub" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_strub_attribute (tree *node, tree name, + tree args, + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + bool enable = true; + + if (args && FUNCTION_POINTER_TYPE_P (*node)) + *node = TREE_TYPE (*node); + + if (args && FUNC_OR_METHOD_TYPE_P (*node)) + { + switch (strub_validate_fn_attr_parm (TREE_VALUE (args))) + { + case 1: + case 2: + enable = true; + break; + + case 0: + warning (OPT_Wattributes, + "%qE attribute ignored because of argument %qE", + name, TREE_VALUE (args)); + *no_add_attrs = true; + enable = false; + break; + + case -1: + case -2: + enable = false; + break; + + default: + gcc_unreachable (); + } + + args = TREE_CHAIN (args); + } + + if (args) + { + warning (OPT_Wattributes, + "ignoring attribute %qE because of excess arguments" + " starting at %qE", + name, TREE_VALUE (args)); + *no_add_attrs = true; + enable = false; + } + + /* Warn about unmet expectations that the strub attribute works like a + qualifier. ??? Could/should we extend it to the element/field types + here? */ + if (TREE_CODE (*node) == ARRAY_TYPE + || VECTOR_TYPE_P (*node) + || TREE_CODE (*node) == COMPLEX_TYPE) + warning (OPT_Wattributes, + "attribute %qE does not apply to elements" + " of non-scalar type %qT", + name, *node); + else if (RECORD_OR_UNION_TYPE_P (*node)) + warning (OPT_Wattributes, + "attribute %qE does not apply to fields" + " of aggregate type %qT", + name, *node); + + /* If we see a strub-enabling attribute, and we're at the default setting, + implicitly or explicitly, note that the attribute was seen, so that we can + reduce the compile-time overhead to nearly zero when the strub feature is + not used. */ + if (enable && flag_strub < -2) + flag_strub += 2; + + return NULL_TREE; +} + /* Handle a "noinline" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index a57143021a79e..36b1345530d71 100644 --- a/gcc/ada/gcc-interface/utils.cc +++ b/gcc/ada/gcc-interface/utils.cc @@ -39,6 +39,7 @@ #include "varasm.h" #include "toplev.h" #include "opts.h" +#include "ipa-strub.h" #include "output.h" #include "debug.h" #include "convert.h" @@ -6601,9 +6602,77 @@ handle_no_stack_protector_attribute (tree *node, tree name, tree, int, struct attribute_spec.handler. */ static tree -handle_strub_attribute (tree *, tree, tree, int, bool *no_add_attrs) +handle_strub_attribute (tree *node, tree name, + tree args, + int ARG_UNUSED (flags), bool *no_add_attrs) { - *no_add_attrs = true; + bool enable = true; + + if (args && FUNCTION_POINTER_TYPE_P (*node)) + *node = TREE_TYPE (*node); + + if (args && FUNC_OR_METHOD_TYPE_P (*node)) + { + switch (strub_validate_fn_attr_parm (TREE_VALUE (args))) + { + case 1: + case 2: + enable = true; + break; + + case 0: + warning (OPT_Wattributes, + "%qE attribute ignored because of argument %qE", + name, TREE_VALUE (args)); + *no_add_attrs = true; + enable = false; + break; + + case -1: + case -2: + enable = false; + break; + + default: + gcc_unreachable (); + } + + args = TREE_CHAIN (args); + } + + if (args) + { + warning (OPT_Wattributes, + "ignoring attribute %qE because of excess arguments" + " starting at %qE", + name, TREE_VALUE (args)); + *no_add_attrs = true; + enable = false; + } + + /* Warn about unmet expectations that the strub attribute works like a + qualifier. ??? Could/should we extend it to the element/field types + here? */ + if (TREE_CODE (*node) == ARRAY_TYPE + || VECTOR_TYPE_P (*node) + || TREE_CODE (*node) == COMPLEX_TYPE) + warning (OPT_Wattributes, + "attribute %qE does not apply to elements" + " of non-scalar type %qT", + name, *node); + else if (RECORD_OR_UNION_TYPE_P (*node)) + warning (OPT_Wattributes, + "attribute %qE does not apply to fields" + " of aggregate type %qT", + name, *node); + + /* If we see a strub-enabling attribute, and we're at the default setting, + implicitly or explicitly, note that the attribute was seen, so that we can + reduce the compile-time overhead to nearly zero when the strub feature is + not used. */ + if (enable && flag_strub < -2) + flag_strub += 2; + return NULL_TREE; }