public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
From: James R T <jamestiotio@gmail.com>
To: Xi Ruoyao <xry111@xry111.site>, jscott@posteo.net
Cc: gcc-help@gcc.gnu.org
Subject: Re: Question about declaring an array in the stack on runtime
Date: Sat, 15 Jul 2023 20:57:38 +0800	[thread overview]
Message-ID: <CAA_Li+sohrszhS89Y88OL8XEGs4RvG-1RKi1gDPONNfYgW-+9g@mail.gmail.com> (raw)
In-Reply-To: <334b2a3602914ce0f677de119cbeba7d8db8be41.camel@xry111.site>

On Sat, Jul 15, 2023 at 6:49 PM John Scott <jscott@posteo.net> wrote:
> It's not the assignment that's the problem. The problem is that you're
> using a compound literal, and a compound literal, like typical
> automatically allocated variables, has a lifetime determined by its
> scope.
>
> In other words, the following:
> if (some_var == 7) {
> arr = (unsigned int[7]){9, 10, 11, 12, 13, 14, 15};
> }
>
> is the same as
> if (some_var == 7) {
> unsigned int baz[7] = {9, 10, 11, 12, 13, 14, 15};
> arr = baz;
> }
>
> I hope this makes the problem a little more obvious: after you leave the
> '}', the array doesn't exist anymore, and arr is a dangling pointer to
> an object that doesn't exist.

Ah thank you for this John, the rearranged code is particularly illuminating.

On Sat, Jul 15, 2023 at 7:19 PM Xi Ruoyao <xry111@xry111.site> wrote:
> No.  But the usage of arr[i] in the printf call is considered undefined
> behavior.

Got it.

> 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.

Understood, thank you for the references to the specific clauses. Will
personally study these notes on the lifetimes of compound literals
more for my understanding.

> 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.

Ah alright, understood.

> 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
>
> ... ...

Yes, I noticed that. I would assume that this is more of an artifact
of me hardcoding the value of `some_var`. If the value of `some_var`
cannot be determined at compile time, then I would assume that Clang
would not be able to unroll the loop and all bets are off, especially
since it is UB.

> So obviously -fsanitize=address won't work because there is no memory
> access at all.  On the contrary, clang -fsanitize=address -O0 is able to
> detect the issue.

Oh, interesting. Attempting to specify `-fsanitize=address` on Godbolt
for Clang `-O0` does not seem to detect the issue. I have not tried it
locally though.

> And this is just completely out of the capability of -
> fsanitize=undefined.  Despite the naming, -fsanitize=undefined can only
> catch a *small* subset of undefined behaviors.
>
> Generally sanitizers are useful tools, but not silver bullets.

Noted the part on `-fsanitize=undefined`. Yes, of course, I understand
that sanitizers would not be able to catch all issues.

> 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.

Understood, no worries. I was just checking on this specific issue.

Thank you for your responses, Xi and John. I hope that both of you
have a great day ahead.

Best regards,
James Raphael Tiovalen

  reply	other threads:[~2023-07-15 12:58 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-15 10:43 James R T
2023-07-15 10:49 ` John Scott
2023-07-15 11:19 ` Xi Ruoyao
2023-07-15 12:57   ` James R T [this message]
2023-07-17 12:45 ` David Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAA_Li+sohrszhS89Y88OL8XEGs4RvG-1RKi1gDPONNfYgW-+9g@mail.gmail.com \
    --to=jamestiotio@gmail.com \
    --cc=gcc-help@gcc.gnu.org \
    --cc=jscott@posteo.net \
    --cc=xry111@xry111.site \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).