From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 2F7A63858D3C for ; Sat, 15 Jul 2023 11:19:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2F7A63858D3C Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=xry111.site Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xry111.site DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1689419949; bh=une7s+eVFSoL/VI1+LMADqyq8AwPhxwQ23wV/27JR1s=; h=Subject:From:To:Date:In-Reply-To:References:From; b=C95lvzAFIKMPlNGx3dQcPz3UfmNNiVgJpRtfsGOmLZ0/g9+fWZh3sCyfu1LAQdvU4 WMYhvyVlUbin9jDQtHPJu80JDOwvK4cGzoYAf8ApULAE/G00rL5NDSDKx7HRquJFnn hq4oWC53aNyam+v1p4q7CwQBMp+8TLCL14E2DvCA= Received: from [IPv6:240e:358:1143:400:dc73:854d:832e:4] (unknown [IPv6:240e:358:1143:400:dc73:854d:832e:4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id B3EE96629F; Sat, 15 Jul 2023 07:19:07 -0400 (EDT) Message-ID: <334b2a3602914ce0f677de119cbeba7d8db8be41.camel@xry111.site> Subject: Re: Question about declaring an array in the stack on runtime From: Xi Ruoyao To: James R T , gcc-help@gcc.gnu.org Date: Sat, 15 Jul 2023 19:19:02 +0800 In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.48.4 MIME-Version: 1.0 X-Spam-Status: No, score=0.2 required=5.0 tests=BAYES_00,BODY_8BITS,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,LIKELY_SPAM_FROM,SPF_HELO_PASS,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Sat, 2023-07-15 at 18:43 +0800, James R T via Gcc-help wrote: > Hi folks, >=20 > I hope that this is the correct mailing list to ask this question. >=20 > I have the following C code snippet: >=20 > ```c > #include >=20 > int main() { > =C2=A0=C2=A0=C2=A0 unsigned int* arr; > =C2=A0=C2=A0=C2=A0 int some_var =3D 7; >=20 > =C2=A0=C2=A0=C2=A0 if (some_var =3D=3D 7) { > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 arr =3D (unsigned int[7]){9, 1= 0, 11, 12, 13, 14, 15}; > =C2=A0=C2=A0=C2=A0 } >=20 > =C2=A0=C2=A0=C2=A0 printf("Value of arr:\n"); > =C2=A0=C2=A0=C2=A0 for (unsigned int i =3D 0; i < 7; i++) { > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf("%u ", arr[i]); > =C2=A0=C2=A0=C2=A0 } >=20 > =C2=A0=C2=A0=C2=A0 return 0; > } > ``` >=20 > I have included the relevant Godbolt link here: > https://godbolt.org/z/b4rbn6eGT >=20 > I have a few questions related to this code snippet: >=20 > 1. Is the conditional assignment to `arr` considered undefined > behavior? No. But the usage of arr[i] in the printf call is considered undefined behavior. > If it is, which exact clause of the C standard does this > code snippet violate and why? >From C23 6.5.2.5p5: A compound literal provides an unnamed object whose value, type, storage duration and other properties are as if given by the definition syntax in the constraints; if the storage duration is automatic, the lifetime of the instance of the unnamed object is the current execution of the enclosing block. And 6.2.4p2: If an object is referred to outside of its lifetime, the behavior is undefined. And 6.8p1: primary-block: compound-statement selection-statement iteration-statement And 6.8p3: A block is either a primary block, a secondary block, or the block associated with a function definition; So here the "enclosing block" is the if statement, after the if statement the lifetime of the unnamed object provided by the compound literal has ended, thus referring it in the printf call is undefined. > 2. Regardless of whether this is UB or not, is it possible for GCC to > also output a warning in `-O0` as in `-O2`? If the behavior changes > across different optimization levels, it seems that it's worth a > warning or two. It can be a different warning instead of > `-Wdangling-pointer` since looking at the produced assembly code, GCC > seems to simply optimize out the whole conditional assignment block in > `-O2`. If it is UB, I understand that it is impossible to catch all > UB, but I am just checking on whether it is possible to catch this > specific one from GCC's perspective. It's very difficult. The emit of the warning depends on the optimizing of the loop. Without optimization the compiler doesn't even know the loop will be iterated at least once, so there will be no warning is produced at -O0. > Just FYI, I have also tried using > `-fsanitize=3Daddress` and `-fsanitize=3Dundefined` and it seems that > AddressSanitizer would throw a `stack-use-after-scope` error in GCC if > `-fsanitize=3Daddress` is specified for both `-O0` and `-O2`, but not in > Clang. `-fsanitize=3Dundefined` does not seem to be able to detect > anything. It seems Clang completely unroll the loop and produced a series of printf calls at -O2: leaq .str.1(%rip), %rbx movq %rbx, %rdi movl $9, %esi xorl %eax, %eax callq printf@PLT movq %rbx, %rdi movl $10, %esi xorl %eax, %eax callq printf@PLT ... ... So obviously -fsanitize=3Daddress won't work because there is no memory access at all. On the contrary, clang -fsanitize=3Daddress -O0 is able to detect the issue. And this is just completely out of the capability of - fsanitize=3Dundefined. Despite the naming, -fsanitize=3Dundefined can only catch a *small* subset of undefined behaviors. Generally sanitizers are useful tools, but not silver bullets. > If the GCC maintainers consider this an acceptable proposal to add the > warning, I am also willing to post a bug report and develop the > corresponding patch for it, although I would appreciate some guidance > since I am not very familiar with GCC's codebase. I believe there has been a lot of duplicates about "no warnings at -O0". And as I've said, these are very difficult to fix. A lot of warnings just inherently needs some information from the optimizer, or there will be either too many false positives, or too many false negatives. If you need such warnings, you should enable the optimization. --=20 Xi Ruoyao School of Aerospace Science and Technology, Xidian University