> On Feb 23, 2022, at 11:49 AM, Jakub Jelinek <ja...@redhat.com> wrote:
> 
> On Wed, Feb 23, 2022 at 05:33:57PM +0000, Qing Zhao wrote:
>> From my understanding, __builtin_clear_padding (&object), does not _use_ any 
>> variable,
>> therefore, no uninitialized usage warning should be emitted for it. 
> 
> __builtin_clear_padding (&object)
> sometimes expands to roughly:
> *(int *)((char *)&object + 32) = 0;
> etc., in that case it shouldn't be suppressed in any way, it doesn't read
> anything, only stores.
> Or at other times it is:
> *(int *)((char *)&object + 32) &= 0xfec7dab1;
> etc., in that case it reads bytes from the object which can be
> uninitialized, we mask some bits off and store.

Okay, I see. 
So, only the MEM_REF that will be used to read first should be suppressed 
warning. Then there is only one (out of 4) MEM_REF
should be suppressed warning, that’s the following one (line 4371 and then line 
4382):

4371               tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
4372                                      build_int_cst (buf->alias_type, off));
4373               tree src;
4374               gimple *g;
4375               if (all_ones
4376                   && nonzero_first == start
4377                   && nonzero_last == start + eltsz)
4378                 src = build_zero_cst (type);
4379               else
4380                 {
4381                   src = make_ssa_name (type);
4382                   g = gimple_build_assign (src, unshare_expr (dst));
4383                   gimple_set_location (g, buf->loc);
4384                   gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4385                   tree mask = native_interpret_expr (type,
4386                                                      buf->buf + i + start,
4387                                                      eltsz);
4388                   gcc_assert (mask && TREE_CODE (mask) == INTEGER_CST);
4389                   mask = fold_build1 (BIT_NOT_EXPR, type, mask);
4390                   tree src_masked = make_ssa_name (type);
4391                   g = gimple_build_assign (src_masked, BIT_AND_EXPR,
4392                                            src, mask);
4393                   gimple_set_location (g, buf->loc);
4394                   gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4395                   src = src_masked;
4396                 }
4397               g = gimple_build_assign (dst, src);


All the other 3 MEM_REFs are not read. So, we can just exclude them from 
suppressing warning, right?
Another question, for the above MEM_REF, should I suppress warning for line 
4371 “dst”? Or shall I 
Suppress warning for line 4382 (for the “unshared_expr(dst)”)?

I think that we should suppress warning for the latter, i.e 
“unshared_expr(dst)” at line 4382, right?

> 
> It is similar to what object.bitfld = 3; expands to,
> but usually only after the uninit pass.  Though, we have the
> optimize_bit_field_compare optimization, that is done very early
> and I wonder what uninit does about that.  Perhaps it ignores
> BIT_FIELD_REFs, I'd need to check that.

Yes, I see that uninitialized warning specially handles BIT_INSERT_EXPR as: 
(tree-ssa-uninit.cc)

 573   /* Do not warn if the result of the access is then used for
 574      a BIT_INSERT_EXPR. */
 575   if (lhs && TREE_CODE (lhs) == SSA_NAME)
 576     FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
 577       {
 578         gimple *use_stmt = USE_STMT (luse_p);
 579         /* BIT_INSERT_EXPR first operand should not be considered
 580            a use for the purpose of uninit warnings.  */
 
> 
> Anyway, if we want to disable uninit warnings for __builtin_clear_padding,
> we should do that with suppress_warning on the read stmts that load
> a byte (or more adjacent ones) before they are masked off and stored again,
> so that we don't warn about that.

IN addition to this read stmts, shall we suppress warnings for the following:

/* Emit a runtime loop:
   for (; buf.base != end; buf.base += sz)
     __builtin_clear_padding (buf.base);  */

static void
clear_padding_emit_loop (clear_padding_struct *buf, tree type,
                         tree end, bool for_auto_init)
{

i.e, should we suppress warnings for the above “buf.base != end”, “buf.base += 
sz”?

No need to suppress warning for them since they just read the address of the 
object, not the object itself?

thanks.

Qing

> 
>       Jakub
> 

Reply via email to