public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Qing Zhao <QING.ZHAO@ORACLE.COM>
To: Richard Sandiford <richard.sandiford@arm.com>
Cc: Qing Zhao via Gcc-patches <gcc-patches@gcc.gnu.org>,
	Richard Biener <richard.guenther@gmail.com>
Subject: Re: How to traverse all the local variables that declared in the current routine?
Date: Mon, 7 Dec 2020 11:36:09 -0600	[thread overview]
Message-ID: <23B74D40-BB4F-46AF-94A5-E490585CCCC0@ORACLE.COM> (raw)
In-Reply-To: <mpt360h7d9q.fsf@arm.com>



> On Dec 7, 2020, at 11:10 AM, Richard Sandiford <richard.sandiford@arm.com> wrote:
>>>> 
>>>> Another issue is, in order to check whether an auto-variable has initializer, I plan to add a new bit in “decl_common” as:
>>>> /* In a VAR_DECL, this is DECL_IS_INITIALIZED.  */
>>>> unsigned decl_is_initialized :1;
>>>> 
>>>> /* IN VAR_DECL, set when the decl is initialized at the declaration.  */
>>>> #define DECL_IS_INITIALIZED(NODE) \
>>>> (DECL_COMMON_CHECK (NODE)->decl_common.decl_is_initialized)
>>>> 
>>>> set this bit when setting DECL_INITIAL for the variables in FE. then keep it
>>>> even though DECL_INITIAL might be NULLed.
>>>> 
>>>> 
>>>> For locals it would be more reliable to set this flag during gimplification.
>>>> 
>>>> Do you have any comment and suggestions?
>>>> 
>>>> 
>>>> As said above - do you want to cover registers as well as locals?  I'd do
>>>> the actual zeroing during RTL expansion instead since otherwise you
>>>> have to figure youself whether a local is actually used (see expand_stack_vars)
>>>> 
>>>> Note that optimization will already made have use of "uninitialized" state
>>>> of locals so depending on what the actual goal is here "late" may be too late.
>>>> 
>>>> 
>>>> Haven't thought about this much, so it might be a daft idea, but would a
>>>> compromise be to use a const internal function:
>>>> 
>>>> X1 = .DEFERRED_INIT (X0, INIT)
>>>> 
>>>> where the X0 argument is an uninitialised value and the INIT argument
>>>> describes the initialisation pattern?  So for a decl we'd have:
>>>> 
>>>> X = .DEFERRED_INIT (X, INIT)
>>>> 
>>>> and for an SSA name we'd have:
>>>> 
>>>> X_2 = .DEFERRED_INIT (X_1(D), INIT)
>>>> 
>>>> with all other uses of X_1(D) being replaced by X_2.  The idea is that:
>>>> 
>>>> * Having the X0 argument would keep the uninitialised use of the
>>>> variable around for the later warning passes.
>>>> 
>>>> * Using a const function should still allow the UB to be deleted as dead
>>>> if X1 isn't needed.
>>>> 
>>>> * Having a function in the way should stop passes from taking advantage
>>>> of direct uninitialised uses for optimisation.
>>>> 
>>>> This means we won't be able to optimise based on the actual init
>>>> value at the gimple level, but that seems like a fair trade-off.
>>>> AIUI this is really a security feature or anti-UB hardening feature
>>>> (in the sense that users are more likely to see predictable behaviour
>>>> “in the field” even if the program has UB).
>>>> 
>>>> 
>>>> The question is whether it's in line of peoples expectation that
>>>> explicitely zero-initialized code behaves differently from
>>>> implicitely zero-initialized code with respect to optimization
>>>> and secondary side-effects (late diagnostics, latent bugs, etc.).
>>>> 
>>>> Introducing a new concept like .DEFERRED_INIT is much more
>>>> heavy-weight than an explicit zero initializer.
>>>> 
>>>> 
>>>> What exactly you mean by “heavy-weight”? More difficult to implement or much more run-time overhead or both? Or something else?
>>>> 
>>>> The major benefit of the approach of “.DEFERRED_INIT”  is to enable us keep the current -Wuninitialized analysis untouched and also pass
>>>> the “uninitialized” info from source code level to “pass_expand”.
>>> 
>>> Well, "untouched" is a bit oversimplified.  You do need to handle
>>> .DEFERRED_INIT as not
>>> being an initialization which will definitely get interesting.
>> 
>> Yes, during uninitialized variable analysis pass, we should specially handle the defs with “.DEFERRED_INIT”, to treat them as uninitializations.
> 
> Are you sure we need to do that?  The point of having the first argument
> to .DEFERRED_INIT was that that argument would still provide an
> uninitialised use of the variable.  And the values are passed and
> returned by value, so the lack of initialisation is explicit in
> the gcall itself, without knowing what the target function does.
> 
> The idea is that we can essentially treat .DEFERRED_INIT as a normal
> (const) function call.  I'd be surprised if many passes needed to
> handle it specially.
> 

Just checked with a small testing case (to emulate the .DEFERRED_INIT approach):

qinzhao@gcc10:~/Bugs/auto-init$ cat t.c
extern int DEFFERED_INIT (int, int) __attribute__ ((const));

int foo (int n, int r)
{
  int v;

  v = DEFFERED_INIT (v, 0);
  if (n < 10) 
    v = r;

  return v;
}
qinzhao@gcc10:~/Bugs/auto-init$ sh t
/home/qinzhao/Install/latest_write/bin/gcc -O -Wuninitialized -fdump-tree-all -S t.c
t.c: In function ‘foo’:
t.c:7:7: warning: ‘v’ is used uninitialized [-Wuninitialized]
    7 |   v = DEFFERED_INIT (v, 0);
      |       ^~~~~~~~~~~~~~~~~~~~

We can see that the current uninitialized variable analysis treats the new added artificial initialization as the first use of the uninialized variable.  Therefore report the warning there.
However, we should report warning at “return v”. 
So, I think that we still need to specifically handle the new added artificial initialization during uninitialized analysis phase.

Do I still miss anything?

Qing



> Thanks,
> Richard


  reply	other threads:[~2020-12-07 17:36 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-23 23:05 Qing Zhao
2020-11-24  7:32 ` Richard Biener
2020-11-24 15:47   ` Qing Zhao
2020-11-24 15:55     ` Richard Biener
2020-11-24 16:54       ` Qing Zhao
2020-11-25  9:11         ` Richard Biener
2020-11-25 17:41           ` Qing Zhao
2020-12-01 19:47           ` Qing Zhao
2020-12-02  8:45             ` Richard Biener
2020-12-02 15:36               ` Qing Zhao
2020-12-03  8:45                 ` Richard Biener
2020-12-03 16:07                   ` Qing Zhao
2020-12-03 16:36                     ` Richard Biener
2020-12-03 16:40                       ` Qing Zhao
2020-12-03 16:56                       ` Richard Sandiford
2020-11-26  0:08         ` Martin Sebor
2020-11-30 16:23           ` Qing Zhao
2020-11-30 17:18             ` Martin Sebor
2020-11-30 23:05               ` Qing Zhao
2020-12-03 17:32       ` Richard Sandiford
2020-12-03 23:04         ` Qing Zhao
2020-12-04  8:50         ` Richard Biener
2020-12-04 16:19           ` Qing Zhao
2020-12-07  7:12             ` Richard Biener
2020-12-07 16:20               ` Qing Zhao
2020-12-07 17:10                 ` Richard Sandiford
2020-12-07 17:36                   ` Qing Zhao [this message]
2020-12-07 18:05                     ` Richard Sandiford
2020-12-07 18:34                       ` Qing Zhao
2020-12-08  7:35                         ` Richard Biener
2020-12-08  7:40                 ` Richard Biener
2020-12-08 19:54                   ` Qing Zhao
2020-12-09  8:23                     ` Richard Biener
2020-12-09 15:04                       ` Qing Zhao
2020-12-09 15:12                         ` Richard Biener
2020-12-09 16:18                           ` Qing Zhao
2021-01-05 19:05                             ` The performance data for two different implementation of new security feature -ftrivial-auto-var-init Qing Zhao
2021-01-05 19:10                               ` Qing Zhao
2021-01-12 20:34                               ` Qing Zhao
2021-01-13  7:39                                 ` Richard Biener
2021-01-13 15:06                                   ` Qing Zhao
2021-01-13 15:10                                     ` Richard Biener
2021-01-13 15:35                                       ` Qing Zhao
2021-01-13 15:40                                         ` Richard Biener
2021-01-14 21:16                                   ` Qing Zhao
2021-01-15  8:11                                     ` Richard Biener
2021-01-15 16:16                                       ` Qing Zhao
2021-01-15 17:22                                         ` Richard Biener
2021-01-15 17:57                                           ` Qing Zhao
2021-01-18 13:09                                             ` Richard Sandiford
2021-01-18 16:12                                               ` Qing Zhao
2021-02-01 19:12                                                 ` Qing Zhao
2021-02-02  7:43                                                   ` Richard Biener
2021-02-02 15:17                                                     ` Qing Zhao
2021-02-02 23:32                                                       ` Qing Zhao
2020-12-07 17:21           ` How to traverse all the local variables that declared in the current routine? Richard Sandiford

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=23B74D40-BB4F-46AF-94A5-E490585CCCC0@ORACLE.COM \
    --to=qing.zhao@oracle.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=richard.guenther@gmail.com \
    --cc=richard.sandiford@arm.com \
    /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).