From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by sourceware.org (Postfix) with ESMTPS id 40EA03857709 for ; Fri, 16 Feb 2024 19:47:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 40EA03857709 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=oracle.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=oracle.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 40EA03857709 Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=205.220.177.32 ARC-Seal: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1708112867; cv=pass; b=JwZs3siZWuSCzjtm4COH4mDehVEIxfdvfM+oEj4ZCjxkgz7/RH1smyidHEhSR6dDj6zAfj6QQqZyY6IDz5Vqyzdo87O4N5UAx5PLpi6/gU3r0fgLmwl7Djjd8+s5mGw/7dmTgnzlBf01BaRm9MCNeG4wYETfqmXwBw8h+tztono= ARC-Message-Signature: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1708112867; c=relaxed/simple; bh=v96YDIPRMLeWzCtpQxZzXU/W6oaTmJtofHEpeJeg2OE=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-Id: MIME-Version; b=uGmc9Xazt8+rYPxqpMUJuVs5XoFHrs19uWJVhOaQeIvdvUaJ25Hcl47Mb62GKGD754OU5VnlhIjYQEkG928FeSx5aD2r7WbKg7tAJO1zSDKRcoHAG25q7P7PeO2ev3S5rUivm/k4bUBLjhvB1lKoaYKAluq3gaZohw3PLyH53rk= ARC-Authentication-Results: i=2; server2.sourceware.org Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 41GJVF9N003294; Fri, 16 Feb 2024 19:47:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-transfer-encoding : content-type : mime-version; s=corp-2023-11-20; bh=5M2qcrGjKVuogOU4hXr9b12mNHRSVzQRqsWxpD+d7RI=; b=kkGAVNB/3uBeXHMY8Yiv4Rftov/5YykC7rR44xqCJQrSNq0bB5L7jftb0c3+hCdu19hg mvMWQZ0npCrhKxtmRaZ+tUW183Jx+YYn5u40OPH0DJsxNYUB+7BrJMZ74dAhJF6QEGs5 nPCRl1S2FCPQhFYbqKe9lFC1H8V3Dk4rTMJ38GciBZh2ckN7SwDT/aHnbVnO/xj5ffLf DFhwM/FauUlExmktUKhEqHaURvoZ0csRJDQHKKSLMoKUttU/7hzIUgkX8hnddw5tK62C aXSjYU2mGfyEHoXm09tQ0pRNTmWf2TL0EQ3FyHPQflTqMAPn0bbTPnL2ITzDCgSlGvN8 6g== Received: from phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta02.appoci.oracle.com [147.154.114.232]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3w92j0p0ya-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 16 Feb 2024 19:47:43 +0000 Received: from pps.filterd (phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 41GJSqsa014968; Fri, 16 Feb 2024 19:47:42 GMT Received: from nam12-mw2-obe.outbound.protection.outlook.com (mail-mw2nam12lp2040.outbound.protection.outlook.com [104.47.66.40]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 3w5ykcaxdc-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 16 Feb 2024 19:47:42 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Wl4gUUFYcPDANBSisWqK8JuLcr+HSA4LsnYqmf4tf2IOAvvWdnbcvRlb3o58epqpQLHNA9okRknHgab9Fq1Z0Ger0IBpFHtmVTrRTzpGLvS1kFblUerMsSe0xSvbUPfEGyzuvCjSS187QKdW4CIXgG3Wi95aNK7cvDDrGNCtkU56VhsGWgTYx7vQbwowZLRHT8RzjrPtJmhP7iCtLM43A4/9Z8rzyh4jSCoh9P40Kfx1FA1ZCxMg1R469iY8AkyRMEW8DkDuX9t9OabvgeMAckSjhWBwy3In3GjiRFspv1swU1Zx9FzAdeyyuXZTExlBBLBS5SnijTTlGK+6yt4XTA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=5M2qcrGjKVuogOU4hXr9b12mNHRSVzQRqsWxpD+d7RI=; b=MxsCFx+KNjUYcrX2RKGnCPZ3MzsgoCkUpC5k2XK802JqyMMhUM462SI1Q6tv+MvtXN/mySfWbHL6OriAy7hwOfSHM6axRXaHiKlgtbafSTAt+vg4otNpT8YacuJ4wTeDI2L2xGzc5Jka2zry39AIUgkx5icrFUvsWZd5U0HxATxGdnOy0PdSkH9FzmXpLp2t9GEbY5p/ogXCE6zqb12xfXq12xsTG0BcXs3yMX66+baw3sNdGUJ9D+GsGxhKcOAx2eer9+ownvKqYEwy2moBX4fnunQgC67MexyeCER9WSz1MbOa2VBJjJcNvRtJo5E7n1aQOE4/qmJfElB3cSQ6Vg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5M2qcrGjKVuogOU4hXr9b12mNHRSVzQRqsWxpD+d7RI=; b=COCyj9zcTXijS4PTH9cszKZtLbLuiUTVrSVMWFoWHfE39YseqiwxFBdeOuEYtfEyduYqBOCNAynfA2aJn7dpNcQVhHZmoscNaA1q3pK4MGiElGkmfUNaZ5X18CE1BZ0+AtD+DHUbKIZCL3Rg4UBoMS0vE3ZRqGQAaU6Xnp6FeXw= Received: from CH3PR10MB7957.namprd10.prod.outlook.com (2603:10b6:610:1bf::19) by IA1PR10MB7238.namprd10.prod.outlook.com (2603:10b6:208:3f6::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7292.28; Fri, 16 Feb 2024 19:47:39 +0000 Received: from CH3PR10MB7957.namprd10.prod.outlook.com ([fe80::1e58:cfe8:d9f5:6363]) by CH3PR10MB7957.namprd10.prod.outlook.com ([fe80::1e58:cfe8:d9f5:6363%6]) with mapi id 15.20.7292.029; Fri, 16 Feb 2024 19:47:39 +0000 From: Qing Zhao To: josmyers@redhat.com, richard.guenther@gmail.com, siddhesh@gotplt.org, uecker@tugraz.at Cc: keescook@chromium.org, isanbard@gmail.com, gcc-patches@gcc.gnu.org, Qing Zhao Subject: [PATCH v6 2/5] Convert references with "counted_by" attributes to/from .ACCESS_WITH_SIZE. Date: Fri, 16 Feb 2024 19:47:20 +0000 Message-Id: <20240216194723.391359-3-qing.zhao@oracle.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20240216194723.391359-1-qing.zhao@oracle.com> References: <20240216194723.391359-1-qing.zhao@oracle.com> Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: SJ0P220CA0026.NAMP220.PROD.OUTLOOK.COM (2603:10b6:a03:41b::30) To CH3PR10MB7957.namprd10.prod.outlook.com (2603:10b6:610:1bf::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH3PR10MB7957:EE_|IA1PR10MB7238:EE_ X-MS-Office365-Filtering-Correlation-Id: 0b616fd8-9911-4a6c-0861-08dc2f2821d5 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: eqzIWIPXJr1F/KNg6tmRr6yZAck3hIwEUGQE82eKIvrWSNAKtEAFQE2aSTOyuUb9/fMpYDM6J0IhHYzMiWn6KclIh6W2OyTqFbnb0u/VecXixhGhQ4GZgdtQgoKUD6VFpBr2s+umGj68boMZzzyMN0fzugr3+2zE29HabxSKm7V3FlUZOOY4ks3ONQ1ax11oIZTKl9Z/qVICD8AaauOG2iqdEq9TOihg4heGvhwSoSGgWsy1CNYZjy2taETIp/X5q/ix1xHXYaI+J9Lm9VIV5ITdnwb0Lwv3jlWRRjaDmnvaiiks5ZIU72iZCHCjqO5BRQnxtyso4J/QmQv9/YVNGc6Dpk6pLmYPGvhiRNTAJCgq8kh0LUSHdi0dhMtIrc1HbPF26e/itT2sp1eVAXiWQWfMy17wC+xdG3PUV1G9F0YTPJhpyihFSHoSYt2yfpQwB9135HzwXBDd+N/lDkkvOAZr7CXhn6UQQyxRYQyvJQBSd/Wwn1j6cIkTZ1zf+no3++XwAcikKIO5P00JrVHbb4BFAeyLb5DvXSCK9fXI0Xs= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CH3PR10MB7957.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(136003)(376002)(39860400002)(346002)(396003)(366004)(230273577357003)(230922051799003)(451199024)(1800799012)(186009)(64100799003)(4326008)(8936002)(8676002)(5660300002)(6666004)(2906002)(30864003)(83380400001)(86362001)(107886003)(1076003)(36756003)(38100700002)(26005)(66556008)(2616005)(66946007)(316002)(66476007)(6506007)(44832011)(478600001)(6512007)(6486002)(84970400001)(41300700001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?Er2f5jcy6PHllBg7/fMLjrWoKYaoJU5t9JxQ0rGROWrc05/pqQ40WeaoP7Cl?= =?us-ascii?Q?51nFmC5p4vMJk0kwJWajO92cbOHejLCbmuXqtbf2ww+INVSAoZU+IlNrUek+?= =?us-ascii?Q?dy4I12d1/r+pCCHi7KVaEFBBfbq28ANXjoIR81j24CwGyqnVeIjHBxEYx/2v?= =?us-ascii?Q?TzVn1mQ8mgWQfYo2/vSAOL7sE2Dfo+EUhVN3J/av397YFiVyMdbx3oM0sz4m?= =?us-ascii?Q?irbc+SBEhZeLHK+GSjz0ihWFai6Rml8mHEBEAy2PMjmqVa9rUR1htPv3eZls?= =?us-ascii?Q?eklyitdRYZHEjATjN68utz8JzOGV7no6agU3pRioRgcDmk6F5XKHUfgl0SUb?= =?us-ascii?Q?OVsr+g8N1SbrkxeHRzwRKS1cZuwRTZf1m1hl9GgZDBVrB/lNKCyNJrgMekxJ?= =?us-ascii?Q?yvoRYBxjX9qCbiq0OVTXDMmHztQTe4U3ZdNHH4zCq2TEYrhbIx78DtHHjbyD?= =?us-ascii?Q?HBa5sgo4j7HoPs+8yRpcibOPdOVpSdXVa5HPf8OT/ilgYePvq/7g0gfcYQEA?= =?us-ascii?Q?GDWOSOT34m23y4f34EFCAIrTWBWQjLtL4gsOT1zYVOJhCadhl+VnbiwQ1QgR?= =?us-ascii?Q?h/zU03PWtsKC2OpNNWglNx45DmpzGdN6hWDBhF7c7mPIiq7VDJkKlbNC0yLT?= =?us-ascii?Q?okpKGh7fGFwV0ySBQ3putM+9FaANef5j/jUSvofyxldngXG7Z6dIh8/8GyRi?= =?us-ascii?Q?wT31ys56+mAWPBhHSJN/+homXFkBPbmeQoAvdJJzNlFmZlG8fNIh7c+NcNCw?= =?us-ascii?Q?haUaZNjH+dLeCZju5naMjbrhWmY2S9e+wXjfvQxAP6v8NZ1ben5lOxrlFKg+?= =?us-ascii?Q?HYRiAjMqLd5vGzbR5KW4tmY/vSKwwsaa5ftqdZfqSY1eEe/E5ZF0D8DnRxsC?= =?us-ascii?Q?cxvubfeHWmimVP8oa4LAn4bPM13zsuwHqr/r4jMaxPE9n35ggDCkdjLEELUh?= =?us-ascii?Q?YrY1C+9m+Pm7x6ZiV2DR1h+ZRdEKvdXSaL8fbUHAsnNhciKWJq+3wXmE5+SL?= =?us-ascii?Q?ECRKrWnz4SbMemgcnDhnBNEZ4ecJQuphYN4hEp3Xx9L/CJT6NTcJl8yTllyN?= =?us-ascii?Q?jN2vDxgx3oxznHAbEY2vxYGarH49pD/YXPykuK90edyCE7LOPpxENnUfnRxC?= =?us-ascii?Q?X0uMdF0eANl4CXfH/CqIl/2/uaKQgxcMJn+jC4OJtcKJ3BvUtIJuQBKrbnHu?= =?us-ascii?Q?lqfF02ZYiJutVNL4O/mnMDpz+aOYA7HlszqBdxDL5d6SSSFb1ksl9CdzFfAu?= =?us-ascii?Q?3TqgPKEUqIluvysyN8Omsd6+S0QDepUZEoz0VtqnDE001DaZTbL4XCUQEj/Y?= =?us-ascii?Q?3gC6tj+djeu6EHU7L01heMlpARxdzxfaorX7q24oYzMOM18PJTmeX+q7M3xW?= =?us-ascii?Q?CBpO1kXjMXMjtCpeJ2kAcz2MvUExgCq/b7XIdDocNi8Cfrn2RC8dRjCJohYl?= =?us-ascii?Q?ERiBS+CH5G0jFS/8x/QnwB9bDVuXqx0UTixdODlT/hZm5LNnQVbrEZhFclJl?= =?us-ascii?Q?sVJfvjcsOWLG8HDnSiPB3cwOazxNXwLAGxfW20pCVpZlqBO3qXadcIc9flwN?= =?us-ascii?Q?tirNUsMpxidA+dR05fotyPUVmW9tZkVDklDnS8lH?= X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: QF45CgJ+aoIy4h/1pJZq3zn7Vs5ndXai/l5wRZ1iVnlUtyA7B94F1pwnPiefFkWz63WMwf2MAP0EFCQMeNO2c50TDMaAf1R4+OfGIDPM5DqYb07NPD6uEHYzl2PXN2g2zEKQwVrLeSCqzpdsLQfQiVPGh07KpeJLR5NANOVrR9SckKPUV8NXJFbuRyAgSbY0TIUUYrnABlhYwUDUxRayIizmyl8+k+UsYF+FX/M9Z/rYgqUhuAMIIq7SX82VyXg+q2q8vo5x644bJQBhOx4Zt6hs+PJJR5RlCs7Xs7h9v0zc2p1cnek2CoJWByR/9Day+HGN+bZbb2eu+UDZ6Wo7e9cFOzLFJqACG0glsZwafP5MUut6tG326utdq+7yPYEY4KSq3Nu0qdJz7UWd9SgfJ//z2qAiKz8Cs+pnYZcELj+gmpPKyzYSTHeVii6ICxcuYEMm2kO9ZFxEWzDIgW4AIDtDTarF0lXiJCPlKEN3ZyYOuj8JPvuSdDQfm5DuXmpTOGGT2yqqEVJcmQuc52vxmFdpzX5g64wp3fnuaZBfOQev43ehKhb9GbVIa9YeDGZVtWWMnYRA1Z0eeVcaPuEmwKuoqdZZy9A5OTPS7ENybOM= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0b616fd8-9911-4a6c-0861-08dc2f2821d5 X-MS-Exchange-CrossTenant-AuthSource: CH3PR10MB7957.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Feb 2024 19:47:39.4820 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: R9uZekQT1fg2WfFLlLZ0l1Wdy29fEo4KMH7MUUvowHUmeHByBJg5Dsy6COmZkjDL2lA7mUWmSF4sWbhYzGxIYQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR10MB7238 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-16_19,2024-02-16_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 adultscore=0 spamscore=0 mlxlogscore=999 bulkscore=0 phishscore=0 mlxscore=0 suspectscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311290000 definitions=main-2402160154 X-Proofpoint-GUID: -GWR_s8o2-v5SiOF99i02BAEeCSfCX7w X-Proofpoint-ORIG-GUID: -GWR_s8o2-v5SiOF99i02BAEeCSfCX7w X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,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 List-Id: Including the following changes: * The definition of the new internal function .ACCESS_WITH_SIZE in internal-fn.def. * C FE converts every reference to a FAM with a "counted_by" attribute to a call to the internal function .ACCESS_WITH_SIZE. (build_component_ref in c_typeck.cc) This includes the case when the object is statically allocated and initialized. In order to make this working, the routines initializer_constant_valid_p_1 and output_constant in varasm.cc are updated to handle calls to .ACCESS_WITH_SIZE. (initializer_constant_valid_p_1 and output_constant in varasm.c) However, for the reference inside "offsetof", the "counted_by" attribute is ignored since it's not useful at all. (c_parser_postfix_expression in c/c-parser.cc) In addtion to "offsetof", for the reference inside operator "typeof" and "alignof", we ignore counted_by attribute too. When building ADDR_EXPR for the .ACCESS_WITH_SIZE in C FE, replace the call with its first argument. * Convert every call to .ACCESS_WITH_SIZE to its first argument. (expand_ACCESS_WITH_SIZE in internal-fn.cc) * Adjust alias analysis to exclude the new internal from clobbering anything. (ref_maybe_used_by_call_p_1 and call_may_clobber_ref_p_1 in tree-ssa-alias.cc) * Adjust dead code elimination to eliminate the call to .ACCESS_WITH_SIZE when it's LHS is eliminated as dead code. (eliminate_unnecessary_stmts in tree-ssa-dce.cc) * Provide the utility routines to check the call is .ACCESS_WITH_SIZE and get the reference from the call to .ACCESS_WITH_SIZE. (is_access_with_size_p and get_ref_from_access_with_size in tree.cc) gcc/c/ChangeLog: * c-parser.cc (c_parser_postfix_expression): Ignore the counted-by attribute when build_component_ref inside offsetof operator. * c-tree.h (build_component_ref): Add one more parameter. * c-typeck.cc (build_counted_by_ref): New function. (build_access_with_size_for_counted_by): New function. (build_component_ref): Check the counted-by attribute and build call to .ACCESS_WITH_SIZE. (build_unary_op): When building ADDR_EXPR for .ACCESS_WITH_SIZE, use its first argument. (lvalue_p): Accept call to .ACCESS_WITH_SIZE. gcc/ChangeLog: * internal-fn.cc (expand_ACCESS_WITH_SIZE): New function. * internal-fn.def (ACCESS_WITH_SIZE): New internal function. * tree-ssa-alias.cc (ref_maybe_used_by_call_p_1): Special case IFN_ACCESS_WITH_SIZE. (call_may_clobber_ref_p_1): Special case IFN_ACCESS_WITH_SIZE. * tree-ssa-dce.cc (eliminate_unnecessary_stmts): Eliminate the call to .ACCESS_WITH_SIZE when its LHS is dead. * tree.cc (process_call_operands): Adjust side effect for function .ACCESS_WITH_SIZE. (is_access_with_size_p): New function. (get_ref_from_access_with_size): New function. * tree.h (is_access_with_size_p): New prototype. (get_ref_from_access_with_size): New prototype. * varasm.cc (initializer_constant_valid_p_1): Handle call to .ACCESS_WITH_SIZE. (output_constant): Handle call to .ACCESS_WITH_SIZE. gcc/testsuite/ChangeLog: * gcc.dg/flex-array-counted-by-2.c: New test. --- gcc/c/c-parser.cc | 10 +- gcc/c/c-tree.h | 2 +- gcc/c/c-typeck.cc | 128 +++++++++++++++++- gcc/internal-fn.cc | 36 +++++ gcc/internal-fn.def | 4 + .../gcc.dg/flex-array-counted-by-2.c | 112 +++++++++++++++ gcc/tree-ssa-alias.cc | 2 + gcc/tree-ssa-dce.cc | 5 +- gcc/tree.cc | 25 +++- gcc/tree.h | 8 ++ gcc/varasm.cc | 10 ++ 11 files changed, 332 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-2.c diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index c31349dae2ff..a6ed5ac43bb1 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -10850,9 +10850,12 @@ c_parser_postfix_expression (c_parser *parser) if (c_parser_next_token_is (parser, CPP_NAME)) { c_token *comp_tok = c_parser_peek_token (parser); + /* Ignore the counted_by attribute for reference inside + offsetof since the information is not useful at all. */ offsetof_ref = build_component_ref (loc, offsetof_ref, comp_tok->value, - comp_tok->location, UNKNOWN_LOCATION); + comp_tok->location, UNKNOWN_LOCATION, + false); c_parser_consume_token (parser); while (c_parser_next_token_is (parser, CPP_DOT) || c_parser_next_token_is (parser, @@ -10879,11 +10882,14 @@ c_parser_postfix_expression (c_parser *parser) break; } c_token *comp_tok = c_parser_peek_token (parser); + /* Ignore the counted_by attribute for reference inside + offsetof since the information is not useful. */ offsetof_ref = build_component_ref (loc, offsetof_ref, comp_tok->value, comp_tok->location, - UNKNOWN_LOCATION); + UNKNOWN_LOCATION, + false); c_parser_consume_token (parser); } else diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index c7c23edc4840..59b69ca54f0f 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -778,7 +778,7 @@ extern void mark_exp_read (tree); extern tree composite_type (tree, tree); extern tree lookup_field (tree, tree); extern tree build_component_ref (location_t, tree, tree, location_t, - location_t); + location_t, bool = true); extern tree build_array_ref (location_t, tree, tree); extern tree build_omp_array_section (location_t, tree, tree, tree); extern tree build_external_ref (location_t, tree, bool, tree *); diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index cead0a055068..a29a7d7ec029 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -2546,15 +2546,116 @@ should_suggest_deref_p (tree datum_type) return false; } +/* For a SUBDATUM field of a structure or union DATUM, generate a REF to + the object that represents its counted_by per the attribute counted_by + attached to this field if it's a flexible array member field, otherwise + return NULL_TREE. + set COUNTED_BY_TYPE to the TYPE of the counted_by field. + For example, if: + + struct P { + int k; + int x[] __attribute__ ((counted_by (k))); + } *p; + + for: + p->x + + the ref to the object that represents its element count will be: + + &(p->k) + +*/ +static tree +build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type) +{ + tree type = TREE_TYPE (datum); + if (!(c_flexible_array_member_type_p (TREE_TYPE (subdatum)))) + return NULL_TREE; + + tree attr_counted_by = lookup_attribute ("counted_by", + DECL_ATTRIBUTES (subdatum)); + tree counted_by_ref = NULL_TREE; + *counted_by_type = NULL_TREE; + if (attr_counted_by) + { + tree field_id = TREE_VALUE (TREE_VALUE (attr_counted_by)); + counted_by_ref + = build_component_ref (UNKNOWN_LOCATION, + datum, field_id, + UNKNOWN_LOCATION, UNKNOWN_LOCATION); + counted_by_ref = build_fold_addr_expr (counted_by_ref); + + /* get the TYPE of the counted_by field. */ + tree counted_by_field = lookup_field (type, field_id); + gcc_assert (counted_by_field); + + do + { + *counted_by_type = TREE_TYPE (TREE_VALUE (counted_by_field)); + counted_by_field = TREE_CHAIN (counted_by_field); + } + while (counted_by_field); + } + return counted_by_ref; +} + +/* Given a COMPONENT_REF REF with the location LOC, the corresponding + COUNTED_BY_REF, and the COUNTED_BY_TYPE, generate an INDIRECT_REF + to a call to the internal function .ACCESS_WITH_SIZE. + + REF + + to: + + (*.ACCESS_WITH_SIZE (REF, COUNTED_BY_REF, 1, (TYPE_OF_SIZE)0, -1)) + + NOTE: The return type of this function is the POINTER type pointing + to the original flexible array type. + Then the type of the INDIRECT_REF is the original flexible array type. + + The type of the first argument of this function is a POINTER type + to the orignal flexible array type. + + The 4th argument of the call is a constant 0 with the TYPE of the + object pointed by COUNTED_BY_REF. + + */ +static tree +build_access_with_size_for_counted_by (location_t loc, tree ref, + tree counted_by_ref, + tree counted_by_type) +{ + gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref))); + /* The result type of the call is a pointer to the flexible array type. */ + tree result_type = build_pointer_type (TREE_TYPE (ref)); + + tree call + = build_call_expr_internal_loc (loc, IFN_ACCESS_WITH_SIZE, + result_type, 5, + array_to_pointer_conversion (loc, ref), + counted_by_ref, + build_int_cst (integer_type_node, 1), + build_int_cst (counted_by_type, 0), + build_int_cst (integer_type_node, -1)); + /* Wrap the call with an INDIRECT_REF with the flexible array type. */ + call = build1 (INDIRECT_REF, TREE_TYPE (ref), call); + SET_EXPR_LOCATION (call, loc); + return call; +} + /* Make an expression to refer to the COMPONENT field of structure or union value DATUM. COMPONENT is an IDENTIFIER_NODE. LOC is the location of the COMPONENT_REF. COMPONENT_LOC is the location of COMPONENT. ARROW_LOC is the location of the first -> operand if - it is from -> operator. */ + it is from -> operator. + If HANDLE_COUNTED_BY is true, check the counted_by attribute and generate + call to .ACCESS_WITH_SIZE. otherwise, ignore the attribute. */ tree build_component_ref (location_t loc, tree datum, tree component, - location_t component_loc, location_t arrow_loc) + location_t component_loc, location_t arrow_loc, + bool handle_counted_by) { tree type = TREE_TYPE (datum); enum tree_code code = TREE_CODE (type); @@ -2626,7 +2727,13 @@ build_component_ref (location_t loc, tree datum, tree component, int quals; tree subtype; bool use_datum_quals; - + tree counted_by_type = NULL_TREE; + /* Do not handle counted_by when in typeof and alignof operator. */ + handle_counted_by = handle_counted_by && !in_typeof && !in_alignof; + tree counted_by_ref = handle_counted_by + ? build_counted_by_ref (datum, subdatum, + &counted_by_type) + : NULL_TREE; if (TREE_TYPE (subdatum) == error_mark_node) return error_mark_node; @@ -2645,6 +2752,12 @@ build_component_ref (location_t loc, tree datum, tree component, ref = build3 (COMPONENT_REF, subtype, datum, subdatum, NULL_TREE); SET_EXPR_LOCATION (ref, loc); + + if (counted_by_ref) + ref = build_access_with_size_for_counted_by (loc, ref, + counted_by_ref, + counted_by_type); + if (TREE_READONLY (subdatum) || (use_datum_quals && TREE_READONLY (datum))) TREE_READONLY (ref) = 1; @@ -5048,7 +5161,11 @@ build_unary_op (location_t location, enum tree_code code, tree xarg, goto return_build_unary_op; } - /* Ordinary case; arg is a COMPONENT_REF or a decl. */ + /* Ordinary case; arg is a COMPONENT_REF or a decl,or a call to + .ACCESS_WITH_SIZE. */ + if (is_access_with_size_p (arg)) + arg = TREE_OPERAND (TREE_OPERAND (CALL_EXPR_ARG (arg, 0), 0), 0); + argtype = TREE_TYPE (arg); /* If the lvalue is const or volatile, merge that into the type @@ -5195,6 +5312,9 @@ lvalue_p (const_tree ref) case BIND_EXPR: return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE; + case CALL_EXPR: + return is_access_with_size_p (ref); + default: return false; } diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index a07f25f3aee3..331dfe57879b 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -3393,6 +3393,42 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt) } } +/* Expand the IFN_ACCESS_WITH_SIZE function: + ACCESS_WITH_SIZE (REF_TO_OBJ, REF_TO_SIZE, CLASS_OF_SIZE, + TYPE_OF_SIZE, ACCESS_MODE) + which returns the REF_TO_OBJ same as the 1st argument; + + 1st argument REF_TO_OBJ: The reference to the object; + 2nd argument REF_TO_SIZE: The reference to the size of the object, + 3rd argument CLASS_OF_SIZE: The size referenced by the REF_TO_SIZE represents + 0: unknown; + 1: the number of the elements of the object type; + 2: the number of bytes; + 4th argument TYPE_OF_SIZE: A constant 0 with the TYPE of the object + refed by REF_TO_SIZE + 5th argument ACCESS_MODE: + -1: Unknown access semantics + 0: none + 1: read_only + 2: write_only + 3: read_write + + Both the return type and the type of the first argument of this + function have been converted from the incomplete array type to + the corresponding pointer type. + + For each call to a .ACCESS_WITH_SIZE, replace it with its 1st argument. */ +static void +expand_ACCESS_WITH_SIZE (internal_fn, gcall *stmt) +{ + tree lhs = gimple_call_lhs (stmt); + tree ref_to_obj = gimple_call_arg (stmt, 0); + if (lhs) + expand_assignment (lhs, ref_to_obj, false); + else + emit_insn (expand_normal (ref_to_obj)); +} + /* The size of an OpenACC compute dimension. */ static void diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index c14d30365c14..0801c8bfe61d 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -510,6 +510,10 @@ DEF_INTERNAL_FN (PHI, 0, NULL) automatic variable. */ DEF_INTERNAL_FN (DEFERRED_INIT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) +/* A function to associate the access size and access mode information + with the corresponding reference to an object. */ +DEF_INTERNAL_FN (ACCESS_WITH_SIZE, ECF_LEAF | ECF_NOTHROW, NULL) + /* DIM_SIZE and DIM_POS return the size of a particular compute dimension and the executing thread's position within that dimension. DIM_POS is pure (and not const) so that it isn't diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c new file mode 100644 index 000000000000..84899ae620f3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c @@ -0,0 +1,112 @@ +/* test the code generation for the new attribute counted_by. + and also the offsetof operator on such array. */ +/* { dg-do run } */ +/* { dg-options "-O2 -fdump-tree-original" } */ + +#include + +struct annotated { + int b; + char c[] __attribute__ ((counted_by (b))); +} *array_annotated; + +static struct annotated static_annotated = { sizeof "hello", "hello" }; +static char *y = static_annotated.c; + +struct flex { + int b; + char c[]; +}; + +struct nested_annotated { + struct { + union { + int b; + float f; + }; + int n; + }; + char c[] __attribute__ ((counted_by (b))); +} *array_nested_annotated; + +static struct nested_annotated nested_static_annotated + = { sizeof "hello1", 0, "hello1" }; +static char *nested_y = nested_static_annotated.c; + +struct nested_flex { + struct { + union { + int b; + float f; + }; + int n; + }; + char c[]; +}; + +void __attribute__((__noinline__)) setup (int normal_count, int attr_count) +{ + array_annotated + = (struct annotated *)malloc (sizeof (struct annotated) + + attr_count * sizeof (char)); + array_annotated->b = attr_count; + + array_nested_annotated + = (struct nested_annotated *)malloc (sizeof (struct nested_annotated) + + attr_count * sizeof (char)); + array_nested_annotated->b = attr_count; + + return; +} + +void __attribute__((__noinline__)) test (char a, char b) +{ + if (__builtin_offsetof (struct annotated, c[0]) + != __builtin_offsetof (struct flex, c[0])) + abort (); + if (__builtin_offsetof (struct annotated, c[1]) + != __builtin_offsetof (struct flex, c[1])) + abort (); + if (__builtin_offsetof (struct nested_annotated, c[0]) + != __builtin_offsetof (struct nested_flex, c[0])) + abort (); + if (__builtin_offsetof (struct nested_annotated, c[1]) + != __builtin_offsetof (struct nested_flex, c[1])) + abort (); + + if (__builtin_types_compatible_p (typeof (array_annotated->c), + typeof (&(array_annotated->c)[0]))) + abort (); + if (__builtin_types_compatible_p (typeof (array_nested_annotated->c), + typeof (&(array_nested_annotated->c)[0]))) + abort (); + + if (__alignof (array_annotated->c) != __alignof (char)) + abort (); + if (__alignof (array_nested_annotated->c) != __alignof (char)) + abort (); + + if ((unsigned long) array_annotated->c != (unsigned long) &array_annotated->c) + abort (); + if ((unsigned long) array_nested_annotated->c + != (unsigned long) &array_nested_annotated->c) + abort (); + + array_annotated->c[2] = a; + array_nested_annotated->c[3] = b; + + if (y[2] != 'l') abort (); + if (nested_y[4] !='o') abort (); + +} + +int main(int argc, char *argv[]) +{ + setup (10,10); + test ('A', 'B'); + if (array_annotated->c[2] != 'A') abort (); + if (array_nested_annotated->c[3] != 'B') abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "ACCESS_WITH_SIZE" 8 "original" } } */ diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc index e7c1c1aa6243..8c070e173bdd 100644 --- a/gcc/tree-ssa-alias.cc +++ b/gcc/tree-ssa-alias.cc @@ -2823,6 +2823,7 @@ ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *ref, bool tbaa_p) return false; case IFN_MASK_STORE_LANES: case IFN_MASK_LEN_STORE_LANES: + case IFN_ACCESS_WITH_SIZE: goto process_args; case IFN_MASK_LOAD: case IFN_LEN_LOAD: @@ -3073,6 +3074,7 @@ call_may_clobber_ref_p_1 (gcall *call, ao_ref *ref, bool tbaa_p) case IFN_UBSAN_OBJECT_SIZE: case IFN_UBSAN_PTR: case IFN_ASAN_CHECK: + case IFN_ACCESS_WITH_SIZE: return false; case IFN_MASK_STORE: case IFN_LEN_STORE: diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc index 636c471d4c89..a54fb1b754dd 100644 --- a/gcc/tree-ssa-dce.cc +++ b/gcc/tree-ssa-dce.cc @@ -1459,8 +1459,8 @@ eliminate_unnecessary_stmts (bool aggressive) update_stmt (stmt); release_ssa_name (name); - /* GOMP_SIMD_LANE (unless three argument) or ASAN_POISON - without lhs is not needed. */ + /* GOMP_SIMD_LANE (unless three argument), ASAN_POISON + or .ACCESS_WITH_SIZE without lhs is not needed. */ if (gimple_call_internal_p (stmt)) switch (gimple_call_internal_fn (stmt)) { @@ -1470,6 +1470,7 @@ eliminate_unnecessary_stmts (bool aggressive) break; /* FALLTHRU */ case IFN_ASAN_POISON: + case IFN_ACCESS_WITH_SIZE: remove_dead_stmt (&gsi, bb, to_remove_edges); break; default: diff --git a/gcc/tree.cc b/gcc/tree.cc index 3dff8c510832..18b4e729a5bc 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -4068,7 +4068,8 @@ process_call_operands (tree t) int i = call_expr_flags (t); /* Calls have side-effects, except those to const or pure functions. */ - if ((i & ECF_LOOPING_CONST_OR_PURE) || !(i & (ECF_CONST | ECF_PURE))) + if ((i & ECF_LOOPING_CONST_OR_PURE) + || (!(i & (ECF_CONST | ECF_PURE)) && !is_access_with_size_p (t))) side_effects = true; /* Propagate TREE_READONLY of arguments for const functions. */ if (i & ECF_CONST) @@ -13362,6 +13363,28 @@ component_ref_size (tree ref, special_array_member *sam /* = NULL */) ? NULL_TREE : size_zero_node); } +/* Return true if the given node CALL is a call to a .ACCESS_WITH_SIZE + function. */ +bool +is_access_with_size_p (const_tree call) +{ + if (TREE_CODE (call) != CALL_EXPR) + return false; + if (CALL_EXPR_IFN (call) == IFN_ACCESS_WITH_SIZE) + return true; + return false; +} + +/* Get the corresponding reference from the call to a .ACCESS_WITH_SIZE. + * i.e the first argument of this call. return NULL_TREE otherwise. */ +tree +get_ref_from_access_with_size (tree call) +{ + if (is_access_with_size_p (call)) + return CALL_EXPR_ARG (call, 0); + return NULL_TREE; +} + /* Return the machine mode of T. For vectors, returns the mode of the inner type. The main use case is to feed the result to HONOR_NANS, avoiding the BLKmode that a direct TYPE_MODE (T) might return. */ diff --git a/gcc/tree.h b/gcc/tree.h index 972a067a1f7a..73464d3e3ae3 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5760,6 +5760,14 @@ extern special_array_member component_ref_sam_type (tree); cannot be determined. */ extern tree component_ref_size (tree, special_array_member * = NULL); +/* Return true if the given node is a call to a .ACCESS_WITH_SIZE + function. */ +extern bool is_access_with_size_p (const_tree); + +/* Get the corresponding reference from the call to a .ACCESS_WITH_SIZE. + * i.e the first argument of this call. return NULL_TREE otherwise. */ +extern tree get_ref_from_access_with_size (tree); + extern int tree_map_base_eq (const void *, const void *); extern unsigned int tree_map_base_hash (const void *); extern bool tree_map_base_marked_p (const void *); diff --git a/gcc/varasm.cc b/gcc/varasm.cc index fa17eff551e8..0e6e44e0420c 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -5082,6 +5082,11 @@ initializer_constant_valid_p_1 (tree value, tree endtype, tree *cache) } return ret; + case CALL_EXPR: + /* for a call to .ACCESS_WITH_SIZE, check the first argument. */ + if (tree ref = get_ref_from_access_with_size (value)) + return initializer_constant_valid_p_1 (ref, endtype, cache); + /* FALLTHROUGH. */ default: break; } @@ -5276,6 +5281,11 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align, exp = TREE_OPERAND (exp, 0); } + /* for a call to .ACCESS_WITH_SIZE, check the first argument. */ + if (TREE_CODE (exp) == CALL_EXPR) + if (tree ref = get_ref_from_access_with_size (exp)) + exp = ref; + code = TREE_CODE (TREE_TYPE (exp)); thissize = int_size_in_bytes (TREE_TYPE (exp)); -- 2.31.1