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 57D6B3858D35 for ; Fri, 8 Sep 2023 14:25:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 57D6B3858D35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=oracle.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=oracle.com Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 388EEe0s020960; Fri, 8 Sep 2023 14:24:57 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-id : content-transfer-encoding : mime-version; s=corp-2023-03-30; bh=24WZsAjKjjOl4cswNm7cqAHca3AG6QcAFZZDlDK7umY=; b=lr6g7QkXjJPnE4dT5PEFZRG//e2TjJD8a2a+SFV2Ukb+aS+BKY6yKPVoXt1FF1lpZvFP SuNfqwMl3AZEMMSsCJWAhp72JDEfI77Pa1X/9Ypft3jVhV+vSgKu3ZIEW6YNazPKbYd/ r2OBHvVP1lRF7gkjqL3q4dk3/49CkcpBBycRTx4bAfi0F/ZUL6o8VzrHzfXY822nkuS4 YHvZC3cNh7l6+VPks9azhyz4gIwxWaF76/zP784dFzVlSYn7X1jE54i0PT31cFb3ERHC 342nTyyae0RO+WbD5z+Cd0BAB2005dT21GqftoUIBm1qe9ySjWuAFx02VpI5k29HcoYb zw== Received: from phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta03.appoci.oracle.com [138.1.37.129]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3t056s80m5-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 08 Sep 2023 14:24:57 +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 388CZICv017206; Fri, 8 Sep 2023 14:12:48 GMT Received: from nam12-bn8-obe.outbound.protection.outlook.com (mail-bn8nam12lp2176.outbound.protection.outlook.com [104.47.55.176]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 3suug9pp3q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 08 Sep 2023 14:12:48 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=a/07iDSKPwamUxvEg8B4AN/zaOe7oBFzZ8j44/ck5PoM3KmCEBRwi3VclCuGJ5A+3imfLecXv8p1uHI9adhsxSu3AYVqJiniPc+sOFhBm0T8m+Bm08/vtu3+OU/K6m+byU1TDABNlcWa3UdIjZyHCVK6WA/LbzyP+3DN7Gu7MGEjqCOt8Iu7YygpaW90p6N3rM767IcZndy6AnU1mmYMjVFH/7OoeYqkar+qBAaEszZ4JRbY5clhqOVhB/80oPfkQnjRitcc0YvvLWUMFcOVdDVJxySIxPm/AgEAch6XP5CJ4gHIaX/CJaoRspm5qv/fa7hvNMpokv8Rx2xTFd46Hw== 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=24WZsAjKjjOl4cswNm7cqAHca3AG6QcAFZZDlDK7umY=; b=UIBDmmQAOPVI1JXYAOgIjCmOf9fMhNFw0r5EOXLu3Se1FMJmYd88Y7ipkfeM7ZUDUApwGzvaewIljjvNh2Un7wkVNfTuPyOHrqxP43vEO8ne6D3MKjrM6HxtLtN7p3h2YD5orsbdiFCZmi2Vgk8nWMod2JpzMcNUIIRwAwUNZngIGdK1s+0HL5TBxmuaJE+nPBmE1MvFN5VhE1pDgz3wBTh73GUBbhAei7rYQiheTtb+IOVngf0K9IRJzoNlblZWD2eahu7lNjlaAcGgQQJmmyGdHCZ2UxSAHFO9ImJLdP4Z3P2dH32EwTP9u0XVRSpz/pIcjLrGnZuFhDOhSY1PjA== 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=24WZsAjKjjOl4cswNm7cqAHca3AG6QcAFZZDlDK7umY=; b=oQRmLT8sn3BQ27qYbzHM9MIZ+mCQDSL0zUw3bEI5Xj+9Ynkscq8dAgTYAzgRYB2FePjUXH4CzYahZjZNoli6mkemTmxsn3KQDKzBmQLa9BT2uKk8OwAdsNJT+tI2eEogLIr9SuLd+t4w2eEQVVajzwggVXGY7lw79W9CyFIsIR4= Received: from CH2PR10MB4344.namprd10.prod.outlook.com (2603:10b6:610:af::19) by BN0PR10MB5189.namprd10.prod.outlook.com (2603:10b6:408:117::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6768.30; Fri, 8 Sep 2023 14:12:45 +0000 Received: from CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::5afd:d02a:38ef:94ba]) by CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::5afd:d02a:38ef:94ba%7]) with mapi id 15.20.6768.029; Fri, 8 Sep 2023 14:12:45 +0000 From: Qing Zhao To: Joseph Myers , Richard Biener , "jakub@redhat.com" , "gcc-patches@gcc.gnu.org" CC: "keescook@chromium.org" , "siddhesh@gotplt.org" , "uecker@tugraz.at" , "isanbard@gmail.com" Subject: Re: [V3][PATCH 2/3] Use the counted_by atribute info in builtin object size [PR108896] Thread-Topic: [V3][PATCH 2/3] Use the counted_by atribute info in builtin object size [PR108896] Thread-Index: AQHZ12hD/pjqZRPtiUSxFdbyfbHYILARDkEA Date: Fri, 8 Sep 2023 14:12:45 +0000 Message-ID: <5EA1C1AB-A9D7-409F-A566-D273423D636C@oracle.com> References: <20230825152425.2417656-1-qing.zhao@oracle.com> <20230825152425.2417656-3-qing.zhao@oracle.com> In-Reply-To: <20230825152425.2417656-3-qing.zhao@oracle.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-mailer: Apple Mail (2.3696.120.41.1.3) x-ms-publictraffictype: Email x-ms-traffictypediagnostic: CH2PR10MB4344:EE_|BN0PR10MB5189:EE_ x-ms-office365-filtering-correlation-id: 55cf1b12-7049-4401-82d1-08dbb075aca2 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: mHP7WqURmbUcc0xQGWmT1saDSu8MreD4b0N/8hsUkzkLCnSis2B6j7gJQ9XLqKV9G+bkOKTazgvCsq3K8FRNf7+f7lupfYFZaHSXf57FLTCtqjkiGdFrEAQMOh3xGk5PQKiBWBzItOpdYGmvAEa1Yy+UT5qJ7e1ik/4XLlINcT/2hvFH/T4tEeJMNCQYsgFOqkBuBRPKZlJU7VjLBjPqul/S1k4q1tBozY7kjggjuZcirO4ZuyPvqxmli4fgzy3QPjTKbHkucmM+UFRkMFGIZuUuS/Rkb62YzxjUjccI0JcnbFkqFiQD+oV1Tq+6AmfvlqxVweL7tIkT5iIHcGOGhJsrAP5K08r0sgO5iNgjdozvsiEVj+l909gssc5w4LFvTVoOZEIsK1kDzSHXHzMDyp2Fu6PF4rnosDSuKwrvDIZRKLv1vnPQ1L5Vbt6pnvMWS9+UiW1PQnq4aZis67jeVaz1qORJaa4Woj8p/UBvf1qRwFBuO6AhbLjeZeRR81RJYwmetz/wKnchDJ+KQra1cZepQlGofbl2BwEEZTFiid3Zki7RN29KoqgMcqsM/TJ2JS77iEBfDdyzewpEAtmTf0z/AXheybpo9Iafnhg86Qll7cvCiTozJxyp3cR6Kvf/NiA5p3PC49dtfE7DhWtoTD+In+7mjjCEhdjSIY/F1GI= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CH2PR10MB4344.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(346002)(39860400002)(396003)(376002)(366004)(136003)(186009)(451199024)(1800799009)(8676002)(5660300002)(4326008)(8936002)(41300700001)(30864003)(76116006)(66446008)(66946007)(54906003)(64756008)(66476007)(66556008)(44832011)(84970400001)(316002)(91956017)(110136005)(2906002)(122000001)(38070700005)(38100700002)(83380400001)(53546011)(33656002)(2616005)(26005)(86362001)(6512007)(966005)(71200400001)(478600001)(6486002)(36756003)(6506007)(45980500001)(579004);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?RxEBI2rpwKd+PNiEfJ3SB6RGf6gW86FzTwUoIP1ZRmekxVlJS0irpNH4sJor?= =?us-ascii?Q?lcCAsrUsMTa0oymPq1lfV3M18S0ERRPUMSbzZGh6wEuzLiV6k4yjCljxlHUP?= =?us-ascii?Q?xpEe/O8kWA1lnslqswJXjB+OZ3NCpKd3L+dX1bOmm7W11waqLRtlgtGiCq1X?= =?us-ascii?Q?6a0JAGmp55SsjO4RG7eNEJfBk99kUyZGd0lzJVhw81j5sPwsvEAHicVFB3vo?= =?us-ascii?Q?dVu7OdBKma9B88ZdljYQmJvJxAz2xQUc4RLpxZs6Mh8b5mMtF4+T4k/Knp+W?= =?us-ascii?Q?d6wHUbwhI12vJOrPT130U1JOboWjJQyaJPC5rofObMVCVnRpTapAMrULoW6c?= =?us-ascii?Q?YfyT+SL2GWaoN/EaAJPcIhFB4EdrwcJ+B8dNr/mxc4REtNIP0c4uSfa8aLf5?= =?us-ascii?Q?FCiT20phhJzXGGWBNTF9DRzZX5M4FJSjFXKXAUCnp9SeEA/9gjUGw/3rxciU?= =?us-ascii?Q?JgTSKf84YqNnk63XQfM7mZnSF2Rg/clp6WJVPy4vyWuQKK4uUUWbici4eJGr?= =?us-ascii?Q?ix2ipqEuytkX9t2RM6NbzNjDfGV+3eOUjq3LMumsX6I8BaYrooviSO6O9oRq?= =?us-ascii?Q?ebkR+DNXen8QOVbON7A1uS0YpIwpP/YYGSpm83oGr5dpuiOm4a/qQI9JJSxg?= =?us-ascii?Q?SJ7bYGbol9X1dHlhDpE3jeeWh/AOjPQGBDkObD5gWa1/hQIGvC+OGOs+aUOJ?= =?us-ascii?Q?C3oS8fKRqGRhgxFozPyVng0K+adYuSFNVFu295aJNirbVc3go5N4TRQzW/Cp?= =?us-ascii?Q?2ns6bM9V9AhrOYioZpp4mMN71p+pI55ABjS4mLCFwGfmu5aAHB9Tcyb88x+G?= =?us-ascii?Q?2rtDganutPDnvs8PuaL4AyRXaBO0/C5Vk9/LCrE8Lfm2nSsT3kYVVi16jYAF?= =?us-ascii?Q?R3h751TTIOpwj6X/tebSizFrWqNquehcx7Zn+xOqAiJ41D0RnQXKCx1EQ9G+?= =?us-ascii?Q?L2h1ZAdCq6LWtJIdPElAgNj962FrOD/0PuBhYuoBx9wiHG1OoiN1Zen2lZmj?= =?us-ascii?Q?Z4EiEQDmjG4PQ1NXwp4dg7gE3vmg+LwwIWrBOLv8S8Vj5MA1ips56VJO37m6?= =?us-ascii?Q?WFeccx8OY2ZOGpPIvD7GCCQqyI0NggtfGjjpl5Z///n2C3jkgPjy4EBytgz6?= =?us-ascii?Q?hx3klWXWAmyLfqZ2OLtn//92+c5LkRkjGcEDeQPeq4keGU1JTfkppZA0hDxh?= =?us-ascii?Q?Hv8vyQEcDNVRY/nRrSm6LZg0Qws++uWhPZiSz5arjQ7MPq8rGFtZxO8v8yRE?= =?us-ascii?Q?1/aVWqH4Nb5hYG4GYnOQenG6QYRjQfcH0grymZE9U0dn+zuVzKkLw1HazHTo?= =?us-ascii?Q?NhstkhjG2gBt9MeoTy4P77/G+beUPAQhi8PxjvdwQXsMinq3RIBCU6W5VMo8?= =?us-ascii?Q?e4cWrwPATNZeoLd/Dqu9yH9WReTj7cEN80snArRWqwCKQNCtgNhAQtlNMdKI?= =?us-ascii?Q?Om5IGD/V+FhW/crJ2hmjAA1QEBy4o1W5s1RyjXzBljrmjV9UDddAbYh+somZ?= =?us-ascii?Q?lN6iDZ7wFwtgHmq6KMNLqYD5iUSapd5YoTgxBVFrUo1V/HmPEjgrvrM6HFVd?= =?us-ascii?Q?BLquTTxxH3J1zzF9eDbVPxBR1o5mMFo2lLB3/UCV?= Content-Type: text/plain; charset="us-ascii" Content-ID: <4CDA9FDFCAF1C24483D5B0BF4BB6004E@namprd10.prod.outlook.com> Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: =?us-ascii?Q?R62u6gdVRtUcTKerxtzrmfAWOcpLzNF9FeW/Nxqpb7vp+izZeQ8ri2hdDg6h?= =?us-ascii?Q?Vh1v85JHsSoPJvDaey1rR4M/pJviShUCj/kFY0OiHWN8URs4iyfW6mZYIJ6h?= =?us-ascii?Q?2vWVJz1y9a+ro94/hh8wstd7lQ+v6NDohx3guQjbKwoOSCJkrwVOrV48Y3/5?= =?us-ascii?Q?+yMonmH35t8qGuGWsYuDkxeZ0zKVzymiiVx14MTwVJBKl4OuufoirwF19m7B?= =?us-ascii?Q?9ToWMYDThuucxub7HjMWTASfkT2zb7/+M/i5rvYBOUgR8H5b5HX8lqfTYGdj?= =?us-ascii?Q?GQHFMy10ZLaIyUrQAnGOSuYJalGcFrgf79TgbN+Mpl3gyNP/kP1Em4es/+Xw?= =?us-ascii?Q?0XFAOmuj0qI2RCZTA9NbR9wJQiao9BXiGNmYk3LLRxYfCXAmZVG5Dn548QdN?= =?us-ascii?Q?G8PoJtJCvrdU30t/i7axUszV2AQPXkoufGbCUmf4ptMmHBYcbHtx5NBIYL4b?= =?us-ascii?Q?v4M+2EA6zZ4G8VrlzrGddVnrfc7S55EtC5Lq+5pLTUMTyc/JJWQlsJUrXICj?= =?us-ascii?Q?jLWDEPRz83/J6TR3nzHsf+M3FiFJdOnFs1IluC7VrjLLHy8TCGtqmDsjyqlo?= =?us-ascii?Q?pO9x6MHGiCH8smavKxn6Me6HOoaXDdptj9pbM3OvmZJ0KEKVsyz9IjOBurJ3?= =?us-ascii?Q?ucUEOIdHKiEnL7yyOJvHiyinuzu5WpA1YIOR+dOmoKiPlyVzWSbmbdEWZc7l?= =?us-ascii?Q?or3VfXlLN1XYR4drEPXRkKKw83oNc5j4bkPIW9wCmtfpWQxI3El6gE8htdvf?= =?us-ascii?Q?ZU1sXTbwvNxoOvJMCGj2o2PEa2u9DfkYK4w0k6XpB4RDoinTG6Qnoyj+erHY?= =?us-ascii?Q?Yz3KsraZKp9McMbzoeW5pz4OsIHuLAu2TuOmUucd3xX9ePPgvRY1Vzjyw/tl?= =?us-ascii?Q?Ih9OEZfWjoRedGUV576bO1heh4IctavkSNJB+KVliJExP7WuGWbuui8sS+7j?= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CH2PR10MB4344.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 55cf1b12-7049-4401-82d1-08dbb075aca2 X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Sep 2023 14:12:45.6789 (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: l9ziyQG3S/mk55QTq1FATwJ+PBNxQkjpVUdnSFLk9QCXnZAWoVwgFXkNc0BlO22AoakAu3t4eIydtVeejS/btA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN0PR10MB5189 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-09-08_10,2023-09-05_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 phishscore=0 bulkscore=0 adultscore=0 suspectscore=0 malwarescore=0 spamscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2308100000 definitions=main-2309080131 X-Proofpoint-GUID: aB2t61urHNsfKQM3J4d4qh-4pz73tDIN X-Proofpoint-ORIG-GUID: aB2t61urHNsfKQM3J4d4qh-4pz73tDIN X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H5,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 List-Id: Ping. thanks. Qing > On Aug 25, 2023, at 11:24 AM, Qing Zhao wrote: >=20 > Use the counted_by atribute info in builtin object size to compute the > subobject size for flexible array members. >=20 > gcc/ChangeLog: >=20 > PR C/108896 > * tree-object-size.cc (addr_object_size): Use the counted_by > attribute info. > * tree.cc (component_ref_has_counted_by_p): New function. > (component_ref_get_counted_by): New function. > * tree.h (component_ref_has_counted_by_p): New prototype. > (component_ref_get_counted_by): New prototype. >=20 > gcc/testsuite/ChangeLog: >=20 > PR C/108896 > * gcc.dg/flex-array-counted-by-2.c: New test. > * gcc.dg/flex-array-counted-by-3.c: New test. > --- > .../gcc.dg/flex-array-counted-by-2.c | 74 ++++++ > .../gcc.dg/flex-array-counted-by-3.c | 210 ++++++++++++++++++ > gcc/tree-object-size.cc | 37 ++- > gcc/tree.cc | 95 +++++++- > gcc/tree.h | 10 + > 5 files changed, 418 insertions(+), 8 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-2.c > create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-3.c >=20 > diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c b/gcc/testsui= te/gcc.dg/flex-array-counted-by-2.c > new file mode 100644 > index 000000000000..ec580c1f1f01 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c > @@ -0,0 +1,74 @@ > +/* test the attribute counted_by and its usage in > + * __builtin_dynamic_object_size. */=20 > +/* { dg-do run } */ > +/* { dg-options "-O2" } */ > + > +#include "builtin-object-size-common.h" > + > +#define expect(p, _v) do { \ > + size_t v =3D _v; \ > + if (p =3D=3D v) \ > + __builtin_printf ("ok: %s =3D=3D %zd\n", #p, p); \ > + else \ > + { \ > + __builtin_printf ("WAT: %s =3D=3D %zd (expected %zd)\n", #p, p, v); \ > + FAIL (); \ > + } \ > +} while (0); > + > +struct flex { > + int b; > + int c[]; > +} *array_flex; > + > +struct annotated { > + int b; > + int c[] __attribute__ ((counted_by (b))); > +} *array_annotated; > + > +struct nested_annotated { > + struct { > + union { > + int b; > + float f;=09 > + }; > + int n; > + }; > + int c[] __attribute__ ((counted_by (b))); > +} *array_nested_annotated; > + > +void __attribute__((__noinline__)) setup (int normal_count, int attr_cou= nt) > +{ > + array_flex > + =3D (struct flex *)malloc (sizeof (struct flex) > + + normal_count * sizeof (int)); > + array_flex->b =3D normal_count; > + > + array_annotated > + =3D (struct annotated *)malloc (sizeof (struct annotated) > + + attr_count * sizeof (int)); > + array_annotated->b =3D attr_count; > + > + array_nested_annotated > + =3D (struct nested_annotated *)malloc (sizeof (struct nested_annotat= ed) > + + attr_count * sizeof (int)); > + array_nested_annotated->b =3D attr_count; > + > + return; > +} > + > +void __attribute__((__noinline__)) test () > +{ > + expect(__builtin_dynamic_object_size(array_flex->c, 1), -1); > + expect(__builtin_dynamic_object_size(array_annotated->c, 1), > + array_annotated->b * sizeof (int)); > + expect(__builtin_dynamic_object_size(array_nested_annotated->c, 1), > + array_nested_annotated->b * sizeof (int)); > +} > + > +int main(int argc, char *argv[]) > +{ > + setup (10,10); =20 > + test (); > + DONE (); > +} > diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c b/gcc/testsui= te/gcc.dg/flex-array-counted-by-3.c > new file mode 100644 > index 000000000000..a0c3cb88ec71 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c > @@ -0,0 +1,210 @@ > +/* test the attribute counted_by and its usage in > +__builtin_dynamic_object_size: what's the correct behavior when the > +allocation size mismatched with the value of counted_by attribute? */ > +/* { dg-do run } */ > +/* { dg-options "-O -fstrict-flex-arrays=3D3" } */ > + > +#include "builtin-object-size-common.h" > + > +struct annotated { > + size_t foo; > + char others; > + char array[] __attribute__((counted_by (foo))); > +}; > + > +#define expect(p, _v) do { \ > + size_t v =3D _v; \ > + if (p =3D=3D v) \ > + __builtin_printf ("ok: %s =3D=3D %zd\n", #p, p); \ > + else \ > + { \ > + __builtin_printf ("WAT: %s =3D=3D %zd (expected %zd)\n", #p, p= , v); \ > + FAIL (); \ > + } \ > +} while (0); > + > +#define noinline __attribute__((__noinline__)) > +#define SIZE_BUMP 10=20 > +#define MAX(a, b) ((a) > (b) ? (a) : (b)) > +#define MIN(a, b) ((a) < (b) ? (a) : (b)) > + > +/* In general, Due to type casting, the type for the pointee of a pointe= r > + does not say anything about the object it points to, > + So, __builtin_object_size can not directly use the type of the pointe= e > + to decide the size of the object the pointer points to. > + > + there are only two reliable ways: > + A. observed allocations (call to the allocation functions in the rou= tine) > + B. observed accesses (read or write access to the location of the > + pointer points to) > + > + that provide information about the type/existence of an object at > + the corresponding address. > + > + for A, we use the "alloc_size" attribute for the corresponding alloca= tion > + functions to determine the object size; > + > + For B, we use the SIZE info of the TYPE attached to the corresponding= access. > + (We treat counted_by attribute as a complement to the SIZE info of th= e TYPE > + for FMA) > + > + The only other way in C which ensures that a pointer actually points > + to an object of the correct type is 'static': > + > + void foo(struct P *p[static 1]); > + > + See https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624814.html > + for more details. */ > + > +/* in the following function, malloc allocated more space than the value > + of counted_by attribute. Then what's the correct behavior we expect > + the __builtin_dynamic_object_size should have for each of the cases? = */ > + > +static struct annotated * noinline alloc_buf_more (size_t index) > +{ > + struct annotated *p; > + size_t allocated_size > + =3D MAX (sizeof (struct annotated), > + (__builtin_offsetof (struct annotated, array[0]) > + + (index + SIZE_BUMP) * sizeof (char))); > + p =3D (struct annotated *) malloc (allocated_size); > + > + p->foo =3D index; > + > + /*when checking the observed access p->array, we have info on both > + observered allocation and observed access, > + A. from observed allocation:=20 > + allocated_size - offsetof (struct annotated, array[0]) > + B. from observed access: p->foo * sizeof (char) > + */ > + > + /* for size in the whole object: always uses A. */ > + /* for size in the sub-object: chose the smaller of A and B. > + * Please see https://gcc.gnu.org/pipermail/gcc-patches/2023-July/6258= 91.html > + * for details on why. */ > + > + /* for MAXIMUM size in the whole object: use the allocation size > + for the whole object. */ > + expect(__builtin_dynamic_object_size(p->array, 0), > + allocated_size - __builtin_offsetof (struct annotated, array[0])); > + > + /* for MAXIMUM size in the sub-object. use the smaller of A and B. */ > + expect(__builtin_dynamic_object_size(p->array, 1), > + MIN (allocated_size - __builtin_offsetof (struct annotated, array[0]), > + (p->foo) * sizeof(char))); > + > + /* for MINIMUM size in the whole object: use the allocation size > + for the whole object. */ > + expect(__builtin_dynamic_object_size(p->array, 2), > + allocated_size - __builtin_offsetof (struct annotated, array[0])); > + > + /* for MINIMUM size in the sub-object: use the smaller of A and B. */ > + expect(__builtin_dynamic_object_size(p->array, 3), > + MIN (allocated_size - __builtin_offsetof (struct annotated, array[0]), > + (p->foo) * sizeof(char))); > + > + /*when checking the pointer p, we only have info on the observed alloc= ation. > + So, the object size info can only been obtained from the call to mal= loc. > + for both MAXIMUM and MINIMUM: A =3D (index + SIZE_BUMP) * sizeof (ch= ar) */ > + expect(__builtin_dynamic_object_size(p, 0), allocated_size); > + expect(__builtin_dynamic_object_size(p, 1), allocated_size); > + expect(__builtin_dynamic_object_size(p, 2), allocated_size); > + expect(__builtin_dynamic_object_size(p, 3), allocated_size); > + return p; > +} > + > +/* in the following function, malloc allocated less space than the value > + of counted_by attribute. Then what's the correct behavior we expect > + the __builtin_dynamic_object_size should have for each of the cases? > + NOTE: this is an user error, GCC should issue warnings for such case. > + this is a seperate issue we should address later. */ > + > +static struct annotated * noinline alloc_buf_less (size_t index) > +{ > + struct annotated *p; > + size_t allocated_size > + =3D MAX (sizeof (struct annotated), > + (__builtin_offsetof (struct annotated, array[0]) > + + (index) * sizeof (char))); > + p =3D (struct annotated *) malloc (allocated_size); > + > + p->foo =3D index + SIZE_BUMP; > + > + /*when checking the observed access p->array, we have info on both > + observered allocation and observed access, > + A. from observed allocation: > + allocated_size - offsetof (struct annotated, array[0]) > + B. from observed access: p->foo * sizeof (char) > + */ > + > + /* for size in the whole object: always uses A. */ > + /* for size in the sub-object: chose the smaller of A and B. > + * Please see https://gcc.gnu.org/pipermail/gcc-patches/2023-July/6258= 91.html > + * for details on why. */ > + > + /* for MAXIMUM size in the whole object: use the allocation size > + for the whole object. */ > + expect(__builtin_dynamic_object_size(p->array, 0), > + allocated_size - __builtin_offsetof (struct annotated, array[0])); > + > + /* for MAXIMUM size in the sub-object. use the smaller of A and B. */ > + expect(__builtin_dynamic_object_size(p->array, 1), > + MIN (allocated_size - __builtin_offsetof (struct annotated, array[0]), > + (p->foo) * sizeof(char))); > + > + /* for MINIMUM size in the whole object: use the allocation size > + for the whole object. */ > + expect(__builtin_dynamic_object_size(p->array, 2), > + allocated_size - __builtin_offsetof (struct annotated, array[0])); > + > + /* for MINIMUM size in the sub-object: use the smaller of A and B. */ > + expect(__builtin_dynamic_object_size(p->array, 3), > + MIN (allocated_size - __builtin_offsetof (struct annotated, array[0]), > + (p->foo) * sizeof(char))); > + > + /*when checking the pointer p, we only have info on the observed > + allocation. So, the object size info can only been obtained from > + the call to malloc. */ > + expect(__builtin_dynamic_object_size(p, 0), allocated_size); > + expect(__builtin_dynamic_object_size(p, 1), allocated_size); > + expect(__builtin_dynamic_object_size(p, 2), allocated_size); > + expect(__builtin_dynamic_object_size(p, 3), allocated_size); > + return p; > +} > + > +int main () > +{ > + struct annotated *p, *q; > + p =3D alloc_buf_more (10); > + q =3D alloc_buf_less (10); > + > + /*when checking the observed access p->array, we only have info on the > + observed access, i.e, the TYPE_SIZE info from the access. We don't h= ave > + info on the whole object. */ > + expect(__builtin_dynamic_object_size(p->array, 0), -1); > + expect(__builtin_dynamic_object_size(p->array, 1), p->foo * sizeof(cha= r)); > + expect(__builtin_dynamic_object_size(p->array, 2), 0); > + expect(__builtin_dynamic_object_size(p->array, 3), p->foo * sizeof(cha= r)); > + /*when checking the pointer p, we have no observed allocation nor obse= rved > + access, therefore, we cannot determine the size info here. */ > + expect(__builtin_dynamic_object_size(p, 0), -1); > + expect(__builtin_dynamic_object_size(p, 1), -1); > + expect(__builtin_dynamic_object_size(p, 2), 0); > + expect(__builtin_dynamic_object_size(p, 3), 0); > + > + /*when checking the observed access p->array, we only have info on the > + observed access, i.e, the TYPE_SIZE info from the access. We don't h= ave > + info on the whole object. */ > + expect(__builtin_dynamic_object_size(q->array, 0), -1); > + expect(__builtin_dynamic_object_size(q->array, 1), q->foo * sizeof(cha= r)); > + expect(__builtin_dynamic_object_size(q->array, 2), 0); > + expect(__builtin_dynamic_object_size(q->array, 3), q->foo * sizeof(cha= r)); > + /*when checking the pointer p, we have no observed allocation nor obse= rved > + access, therefore, we cannot determine the size info here. */ > + expect(__builtin_dynamic_object_size(q, 0), -1); > + expect(__builtin_dynamic_object_size(q, 1), -1); > + expect(__builtin_dynamic_object_size(q, 2), 0); > + expect(__builtin_dynamic_object_size(q, 3), 0); > + > + DONE (); > +} > diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc > index a62af0500563..cf7843c5684b 100644 > --- a/gcc/tree-object-size.cc > +++ b/gcc/tree-object-size.cc > @@ -585,6 +585,7 @@ addr_object_size (struct object_size_info *osi, const= _tree ptr, > if (pt_var !=3D TREE_OPERAND (ptr, 0)) > { > tree var; > + tree counted_by_ref =3D NULL_TREE; >=20 > if (object_size_type & OST_SUBOBJECT) > { > @@ -600,11 +601,12 @@ addr_object_size (struct object_size_info *osi, con= st_tree ptr, > var =3D TREE_OPERAND (var, 0); > if (var !=3D pt_var && TREE_CODE (var) =3D=3D ARRAY_REF) > var =3D TREE_OPERAND (var, 0); > - if (! TYPE_SIZE_UNIT (TREE_TYPE (var)) > + if (! component_ref_has_counted_by_p (var) > + && ((! TYPE_SIZE_UNIT (TREE_TYPE (var)) > || ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (var))) > || (pt_var_size && TREE_CODE (pt_var_size) =3D=3D INTEGER_CST > && tree_int_cst_lt (pt_var_size, > - TYPE_SIZE_UNIT (TREE_TYPE (var))))) > + TYPE_SIZE_UNIT (TREE_TYPE (var))))))) > var =3D pt_var; > else if (var !=3D pt_var && TREE_CODE (pt_var) =3D=3D MEM_REF) > { > @@ -612,6 +614,7 @@ addr_object_size (struct object_size_info *osi, const= _tree ptr, > /* For &X->fld, compute object size if fld isn't a flexible array > member. */ > bool is_flexible_array_mem_ref =3D false; > + > while (v && v !=3D pt_var) > switch (TREE_CODE (v)) > { > @@ -660,6 +663,8 @@ addr_object_size (struct object_size_info *osi, const= _tree ptr, > /* Now the ref is to an array type. */ > gcc_assert (TREE_CODE (TREE_TYPE (v)) =3D=3D ARRAY_TYPE); > is_flexible_array_mem_ref =3D array_ref_flexible_size_p (v); > + counted_by_ref =3D component_ref_get_counted_by (v); > + > while (v !=3D pt_var && TREE_CODE (v) =3D=3D COMPONENT_REF) > if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) > !=3D UNION_TYPE > @@ -673,8 +678,11 @@ addr_object_size (struct object_size_info *osi, cons= t_tree ptr, > =3D=3D RECORD_TYPE) > { > /* compute object size only if v is not a > - flexible array member. */ > - if (!is_flexible_array_mem_ref) > + flexible array member or the flexible array member > + has a known element count indicated by the user > + through attribute counted_by. */ > + if (!is_flexible_array_mem_ref > + || counted_by_ref) > { > v =3D NULL_TREE; > break; > @@ -707,9 +715,24 @@ addr_object_size (struct object_size_info *osi, cons= t_tree ptr, >=20 > if (var !=3D pt_var) > { > - var_size =3D TYPE_SIZE_UNIT (TREE_TYPE (var)); > - if (!TREE_CONSTANT (var_size)) > - var_size =3D get_or_create_ssa_default_def (cfun, var_size); > + if (!counted_by_ref) > + { > + var_size =3D TYPE_SIZE_UNIT (TREE_TYPE (var)); > + if (!TREE_CONSTANT (var_size)) > + var_size =3D get_or_create_ssa_default_def (cfun, var_size); > + } > + else > + { > + gcc_assert (TREE_CODE (var) =3D=3D COMPONENT_REF > + && TREE_CODE (TREE_TYPE (var)) =3D=3D ARRAY_TYPE); > + tree element_size =3D TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (var))= ); > + var_size > + =3D size_binop (MULT_EXPR, > + fold_convert (sizetype, counted_by_ref), > + fold_convert (sizetype, element_size)); > + if (!todo) > + todo =3D TODO_update_ssa_only_virtuals; > + } > if (!var_size) > return false; > } > diff --git a/gcc/tree.cc b/gcc/tree.cc > index fcd36ae0cd74..3b6ddcbdcbf8 100644 > --- a/gcc/tree.cc > +++ b/gcc/tree.cc > @@ -12745,6 +12745,32 @@ array_ref_element_size (tree exp) > return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), ex= p); > } >=20 > +/* For a component_ref that has an array type ARRAY_REF, return TRUE wh= en > + an counted_by attribute attached to the corresponding FIELD_DECL. > + return FALSE otherwise. */ > +bool > +component_ref_has_counted_by_p (tree array_ref) > +{ > + if (TREE_CODE (array_ref) !=3D COMPONENT_REF) > + return false; > + > + if (TREE_CODE (TREE_TYPE (array_ref)) !=3D ARRAY_TYPE) > + return false; > + > + tree struct_object =3D TREE_OPERAND (array_ref, 0); > + tree struct_type =3D TREE_TYPE (struct_object); > + > + if (!RECORD_OR_UNION_TYPE_P (struct_type)) > + return false; > + tree field_decl =3D TREE_OPERAND (array_ref, 1); > + tree attr_counted_by =3D lookup_attribute ("counted_by", > + DECL_ATTRIBUTES (field_decl)); > + > + if (!attr_counted_by) > + return false; > + return true; > +} > + > /* Given a field list, FIELDLIST, of a structure/union, return a TREE_LIS= T, > with each TREE_VALUE a FIELD_DECL stepping down the chain to the FIELD > whose name is FIELDNAME, which is the last TREE_VALUE of the list. > @@ -12771,7 +12797,7 @@ get_named_field (tree fieldlist, const char *fiel= dname) > fields inside it recursively. */ > else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))) > if ((named_field =3D get_named_field (TYPE_FIELDS (TREE_TYPE (field)), > - fieldname)) !=3D NULL_TREE) > + fieldname)) !=3D NULL_TREE) > { > named_field =3D tree_cons (NULL_TREE, field, named_field); > break; > @@ -12784,6 +12810,73 @@ get_named_field (tree fieldlist, const char *fie= ldname) > return named_field; > } >=20 > +/* For a component_ref that has an array type ARRAY_REF, get the object = that > + represents its counted_by per the attribute counted_by attached to > + the corresponding FIELD_DECL. return NULL_TREE when cannot find such > + object. > + For example, if: > + > + struct P { > + int k; > + int x[] __attribute__ ((counted_by (k))); > + } *p; > + > + for the following reference: > + > + p->x[b] > + > + the object that represents its element count will be: > + > + p->k > + > + So, when component_ref_get_counted_by (p->x[b]) is called, p->k shou= ld be > + returned. > +*/ > + > +tree > +component_ref_get_counted_by (tree array_ref) > +{ > + if (! component_ref_has_counted_by_p (array_ref)) > + return NULL_TREE; > + > + tree struct_object =3D TREE_OPERAND (array_ref, 0); > + tree struct_type =3D TREE_TYPE (struct_object); > + tree field_decl =3D TREE_OPERAND (array_ref, 1); > + tree attr_counted_by =3D lookup_attribute ("counted_by", > + DECL_ATTRIBUTES (field_decl)); > + gcc_assert (attr_counted_by); > + > + /* If there is an counted_by attribute attached to the field, > + get the field that maps to the counted_by. */ > + > + const char *fieldname > + =3D IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (attr_counted_by))); > + > + tree counted_by_field =3D get_named_field (TYPE_FIELDS (struct_type), > + fieldname); > + > + gcc_assert (counted_by_field); > + > + /* generate the tree node that represent the counted_by of this array > + ref. This is a (possible nested) COMPONENT_REF to the counted_by_f= ield > + of the containing structure. */ > + > + tree counted_by_ref =3D NULL_TREE; > + tree object =3D struct_object; > + do > + { > + tree field =3D TREE_VALUE (counted_by_field); > + > + counted_by_ref =3D build3 (COMPONENT_REF, > + TREE_TYPE (field), > + unshare_expr (object), field, > + NULL_TREE); > + object =3D counted_by_ref; > + counted_by_field =3D TREE_CHAIN (counted_by_field); > + } > + while (counted_by_field); > + return counted_by_ref; > +} >=20 > /* Return a tree representing the lower bound of the array mentioned in > EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ > diff --git a/gcc/tree.h b/gcc/tree.h > index 4859becaa1e7..07eed7219835 100644 > --- a/gcc/tree.h > +++ b/gcc/tree.h > @@ -5619,11 +5619,21 @@ extern tree get_base_address (tree t); > of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ > extern tree array_ref_element_size (tree); >=20 > +/* Give a component_ref that has an array type, return true when an > + attribute counted_by attached to the corresponding FIELD_DECL. */ > +extern bool component_ref_has_counted_by_p (tree); > + > /* Given a field list, FIELDLIST, of a structure/union, return the FIELD = whose > name is FIELDNAME, return NULL_TREE if such field is not found. > searching nested anonymous structure/union recursively. */ > extern tree get_named_field (tree, const char *); >=20 > +/* Give a component_ref that has an array type, return the object that > + represents its counted_by per the attribute counted_by attached to > + the corresponding FIELD_DECL. return NULL_TREE when cannot find such > + object. */ > +extern tree component_ref_get_counted_by (tree); > + > /* Return a typenode for the "standard" C type with a given name. */ > extern tree get_typenode_from_name (const char *); >=20 > --=20 > 2.31.1 >=20