From patchwork Fri Mar 29 16:07:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qing Zhao X-Patchwork-Id: 87827 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 91D523857C4F for ; Fri, 29 Mar 2024 16:09:02 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by sourceware.org (Postfix) with ESMTPS id 53D0C3858D32 for ; Fri, 29 Mar 2024 16:07:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 53D0C3858D32 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 53D0C3858D32 Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=205.220.165.32 ARC-Seal: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1711728444; cv=pass; b=gBpRxV+qGIlRopnbtbWMj4eIyAKsKUSyWLSYVti3k9A9q/oRwHvj/dSmCgUTnG1xZk4RoNNWld8gIEfx5imh16xoYQcEqefujuChwtMv6nqUYtOwXPHzHbbaFiuD8Ej8g1gMt8f5IZN5CymrNHyjf9VVb35DKLXM2BK5a+WnHi8= ARC-Message-Signature: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1711728444; c=relaxed/simple; bh=zpIEo5UyVhm2VdnVflkY0u9jwsY/b6zApHStne2OPMM=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-Id: MIME-Version; b=DWiWH1Q4kxU5GTW/WaiymijimT1MDve9BNOCFRYviNjecKAWKD+PB2BkKx48MUSrGrCho8Onv4VH6mWuIJtos6mWOyiGB44P0ZUHmzbmfGnz6qMHj1S0Cj4z8L2TKuoO3M74/TUC0NW6fJ2zPLJRkSM1lYdFaBouvfTeWxIQSAc= ARC-Authentication-Results: i=2; server2.sourceware.org Received: from pps.filterd (m0333521.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 42TFOL7J018649; Fri, 29 Mar 2024 16:07:19 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=nYSX+NXEA1AM0aJqwyfMhf/uW6kqwdBJc02Dg+omPTo=; b=igMbg3fer5T4iJF/qB6zovyVq57edRpOIqvSjYZH3bWRGYmub06CzWkNaaye7muY4VCx lnCuPGtpc9q9WoLEiRRN9qomcnzmh4ZrmZaQhTbKVQUzNTaQtZe3zdf9rxz9jZyu6yAu yC8QQk+2XibZtyzpdZEzon+vs/fZT3EYBwfZkyQxmUjI4Vy+caV7AmfE5pvDcsxS71XY ez/tDCntSEZMDwqPa5LJNX7PykZKt21HCZZpPqqts+Qj590Xjqa3VaTULcleCplHve78 QLtygYQ3D5/wsRcGhZg6LKx7lQkOj0LHWBT3+vp6OkDGM64jRuwl5qj8iFjQcg9Bclay Fw== Received: from phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta03.appoci.oracle.com [138.1.37.129]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3x28ctb8uw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 Mar 2024 16:07:19 +0000 Received: from pps.filterd (phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 42TEkBLQ008903; Fri, 29 Mar 2024 16:07:18 GMT Received: from nam04-bn8-obe.outbound.protection.outlook.com (mail-bn8nam04lp2041.outbound.protection.outlook.com [104.47.74.41]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 3x1nhbw9e4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 Mar 2024 16:07:18 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fEA1vDNeWfDbwVaUmZKe4aNZ7Z0tPurr89/mBFkAK8VJB5vA4N+HzayjG6v4OrSkkqkaTK1XPoJaA8j/5Zs5KeavppS17kSxRZnaD2L53vsFdwTF1eMAePXyCRs5xO3MVEZOaMaNhQSQAB0hJc/2HUh1dQk6NrIOujL2MpNTL8sThWO/SXwJaZmqQoG3TjEeLmEg6NYWV7wBUdSDEs7omBwGBO0f0SNDrr1lV1Qa7BPW/LD2Kfr9tppoB3j/LEsZXtzlnEkmMEkkrXSQswY3/5HL8nh+wrbpK14Vv2Lc+dZbEr42DpvZI7XQevmUFl1gUj1TLrX3OU5AEWU1R8N6PA== 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=nYSX+NXEA1AM0aJqwyfMhf/uW6kqwdBJc02Dg+omPTo=; b=SHrfgoCYjgBRgJOBEP+fK3b9NwjVrd+RGPcjzBeKvPlEA4tzCsBbSLSsdLQLhbcDVfUHEjTPBBbkGVWFz/zHcs12urR2KI8qN1XU3BK8gE6uFjyvyCAKO6TZA+25H8tvAtA2umBuaf7g6R56MSyQ9eod/ZU9+BGZNkdKROl3FSg/6yPUlZldvVhvGeBYJ1onTtJMRInUOaShsPHHQ+37Pq3tAl/w19a2l6EWi9tst8NmC/rGAc9p09CIHXfBmBP0egzG1FxQiu8wk5PprEHGxscWvAtjZRG6FVxawoG3DkCMvdZAMO63YdO53ZieNoLQUAuXGKXV7wjM0hQahMXodg== 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=nYSX+NXEA1AM0aJqwyfMhf/uW6kqwdBJc02Dg+omPTo=; b=sNHakM4Ukvq3gKo3gqDMy3WT2X8lpXvFA6+ormzDevl0l5qwW1QooqYmHh9yeopoaA9DXvyQ7xUi7xB6pTFgBaxI2yHDgaByqudHji3y2Ool9zEFlDdgiG0f9LtIhR6sSHV3iTv++2emaCGeyRgarjZrrgjl9S/VS7L0p0uJSkQ= Received: from CY8PR10MB6538.namprd10.prod.outlook.com (2603:10b6:930:5a::17) by SJ0PR10MB4638.namprd10.prod.outlook.com (2603:10b6:a03:2d8::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7409.31; Fri, 29 Mar 2024 16:07:15 +0000 Received: from CY8PR10MB6538.namprd10.prod.outlook.com ([fe80::2dae:7852:9563:b4bc]) by CY8PR10MB6538.namprd10.prod.outlook.com ([fe80::2dae:7852:9563:b4bc%6]) with mapi id 15.20.7409.039; Fri, 29 Mar 2024 16:07:15 +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 v8 2/5] Convert references with "counted_by" attributes to/from .ACCESS_WITH_SIZE. Date: Fri, 29 Mar 2024 16:07:00 +0000 Message-Id: <20240329160703.4012941-3-qing.zhao@oracle.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20240329160703.4012941-1-qing.zhao@oracle.com> References: <20240329160703.4012941-1-qing.zhao@oracle.com> X-ClientProxiedBy: BY5PR04CA0019.namprd04.prod.outlook.com (2603:10b6:a03:1d0::29) To CY8PR10MB6538.namprd10.prod.outlook.com (2603:10b6:930:5a::17) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY8PR10MB6538:EE_|SJ0PR10MB4638:EE_ X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: cWrYaS/pQVaU6MPYDE+aWzdhlq8ci/U+QrfCSfcScjQ66VzgGpkQxtwIhLTwGoVBZT5bebSgcgHL/sFbdUGdqrswY4BcdOJSaygXfU3z4U9va/SZdOLPi63OBNtcbPahA8hwZSF8q41o9Ne3qpySbmLr+kWcI9LuDRi0bjGYV1GZwS/IbFakBiUW3tJTGRez0AoyDu9Uk6CMzjQtQwvkiT+XAK3ye/h2a9SrFcay0yEKOLHJY2DIiAseorQfSu2Q5tK2K0Hg8N1k1tgQC65Shw5KezBrJpJhg2pHPGSA9F51M8r7gmBAl3YOL9iEjLTKNrVI+T/qBJV3pNCsPSoBTlvOhtAjsT0u+hy9JsbDR0ow/suiJ/W48Ot142DhhxV1rLOvSbA5xxVfaxXFGG3wsKZ/G6XE4gAfvLPTmLGWMO2yd7qgAhSbvPVy8Uhr+y8KUWcQ1Jc75RtHQ9CoEV+PlY4y6mqPIZvNp4WC0eQoKG/qcFg/IPDI8BNS8yJi35aI7CD9cNO1ZOkcycUlbo7tdvWzlOtch16E/hANpvTevfcF+iC+7wuXaXp2skVdbCFNUNVT/APSowpRJxvlSolTVb5qiHpHh+VAzdtfC3uBceU= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CY8PR10MB6538.namprd10.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(376005)(1800799015)(366007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: N0FVsV+qqPI4Qf50DQ50HSUVy4SR5ws47X1HzQhefT9MSiCTOXDVUFy02fu50w0tA49j+bRKIMLmGWe6JAiiGhsd6P++NrJAGb2qIMglpu4Y+M1iskIg2BXvucC0qsZEVc7W62axr1X0bw0d7c/rPPoCHzi9tZbMwc2DLA5MsNRTofuW0gJJyRAXkN5LYTKok0/yX71KPemHwfdALYjCg12eB8rXvzxAlt8+uLJ4iJaqYh08fB/JHMga9rfwX3ovBOAgqA1o3cYOtaf/uWia/wXs9L+FB7crR6Zb8lvpltvz1KR84yn1EUpPRm5qRvff6D4Zy1nT5XbOINDCZGAmZk/xgCjAKyqcu+2P5oPYMFFAgrP+zoykkqJSuztEUWErKzs5JqiKwSZiFvF03M26Nx/OkwRf7T8UoMLVLKv5/0YrBehqNsF1ZbzQk6t0xHRGNW5m9TTxpmt6q40jl1rCKMr1KivGIyhQA0kSz3SYWaUXkTViUZvi4kizhgI+uNAHHoWikh4reQ7QQRJhSyYpBRA8zofl/wrdzVnV616semG8ghHdv+P/RJ0lv7J1QZJE2fWhBdswImTZWsqhzN+XgQlJmGAUxxMBJKuarp+f0LmE5Og0zt4h8LjlebpBJ8c2YHhW3TptlfJZdzZUEp1ZljhAECLXRPiQ3X0QxOA7XPGbyPbr0ySNrxj74oHaynoadSIc1b7F/Y0SV9TcMHOm6/L1EfK0uXZ2qOWBTNH4YtDvm8Hvdfe4XNO0DHIV8XFlkaCHKW8e+pB6qPJgZfmwd4c2LHL7qfRl/tRvVW9ms7LZJWSyOTccUGMgvqHSUOzSIwAwm3+8teKQ+bsHLgwxrG2nf3SjVmuSeccCAPRQeAXHapNSe6EtAX6ieHthaIGDQ1lPrIrT7/76MO5RbeOz98bSeu6ygHwGlK53wMej1lfvf1VYh4rBSy/v0kmyBL+ySA8Lxfs2CfwSXIYnM8Y1/rjdn3s1io4tNXMntZ6ZmLwkgepfc/v3z0lrPQtvo8dE/O4ITZReLBhb6EEbXkLSod6Q7u9o7Jwbbcww1PBQzQXxGiKW2RLeok4Z8OLBpywXPhPCc/+Rwp3XOxtxasjk5D+/WqxzUWm3JXFGHzzB7nXm1Lk3ELIAahhJ/WwxfrLAMGvT2RiXnlFprYuCYBZetv7lZx0bh2DeYf8kYfPkLZnxwhYZhCybx+iiW0GGE3DgzGX+F/6S0bKlqDAu3njptHBXLNF+lsgw9yZqXUPHTRMOwoLR7I7jhtgcoNcsjuEBrm4iJy1AXygNBLbcSjTbb8ze5+RcpYn7iFnpEnTB9hpa98TwLvIk+G5f1//xFTcSnXC9rufwtnYPEE4XsomJJ4sap0i7mHNwcstJmeapHIXJ7r1rzTtR/PRd1xKNjQREdvLJdxcADy2y6fW3/UOCXdBM6DXzcpylXoUYUAmZJ0Yad9aeA4s5JTZLr/aMlzpGdcb8GK/q4YahX2rglbnlVlKMoqOF3F2f5tqwi5yEG3N93cwWpgrUlJPiMnjZWpILUhtJWaWvwDKdNhTzLKFyFrp8Vebgju2gdcVtASeML1HTtpmn74GV4JDMEdsA+10/ X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: zKVsqv7PDc8CwXkFCO1xTCuldFywGbS9ZzKbcLpkoXppS4SPiQMPZiwey68KSZjkEieKKegATe5dlyMkL2xp+UQXplZnuq7ShzbBxCRpol/Df2SmTVZW99NZGNJsHz04+NOufKZ1xzMmvl73yh3ptpVmTIaXhJGJo+waiT3GOCTzBLzuskQT126TL1BI4PZkuO8mXTNnYiJHkr5WEudFimlfQQmzMIoKBRMgvugcWKzBFJxyRXKVnU/FcTF0QhkaiwhgCazSnXdYonXPdzYAH9aFOzz4+hBMpDVtHKsHiEAU3LFtmnDVU2sC+AnoWRxMWyzuuWpD3N8L/x2YNCKGO3P9mngWLrPBIhbzEA6eqMTG2lhYFi1PNvTEwxn6ETqYsA8kZE31CSg7wKtXweXlG8jSzDTeZLZodYi3OsPwzlYLQnltMAZS37AxTMJOdwau/+/6QW5nwiZNIg6pgJ+dCaNdVMnpoZb0HTiPtUN/OD3DudWAAOAbR0QSNVGrnJZOXHCE1CYyT7aeBjtXUIWovS4M+HdqlZO19rFKaQ6nOjZJ8dQjdyr1cef55mGzwBgtSiZ+oUU68I0kiRXNRvaPHZxLtQYi6qqvZWeOlmaxrAQ= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: e7e4c308-f41f-4e60-a516-08dc500a4d1d X-MS-Exchange-CrossTenant-AuthSource: CY8PR10MB6538.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Mar 2024 16:07:15.5107 (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: czitwIkFWXbRtyiBmFy1Y6TvaXiil4/HwW1Coe61VTxCJYhsR4ZoY79kxHEMbqrJjcahXuLgzZapRwmM6SlFKA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ0PR10MB4638 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-03-29_13,2024-03-28_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 bulkscore=0 spamscore=0 adultscore=0 mlxscore=0 suspectscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2403210000 definitions=main-2403290142 X-Proofpoint-GUID: QGos2LajYZo0Nwktg8IF9uEeWAgi1S3s X-Proofpoint-ORIG-GUID: QGos2LajYZo0Nwktg8IF9uEeWAgi1S3s X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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+patchwork=sourceware.org@gcc.gnu.org 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 | 35 +++++ 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, 331 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..f7b0e08459b0 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 original 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 + a 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..e744080ee670 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -3393,6 +3393,41 @@ 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: the number of bytes. + 1: the number of the elements of the object type; + 4th argument TYPE_OF_SIZE: A constant 0 with its TYPE being the same as the TYPE + of the object referenced 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..d4899a63af3c --- /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..5fdb425f612a 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..fbaef3e5fb5c 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..d75b23668925 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));