Hi, Martin,

Thanks a lot for your review and comments.

> On Dec 9, 2021, at 11:43 AM, Martin Sebor <mse...@gmail.com> wrote:
>> 
>> diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
>> index 1df0bcc42c0..85d1ba866fc 100644
>> --- a/gcc/tree-ssa-uninit.c
>> +++ b/gcc/tree-ssa-uninit.c
>> @@ -182,9 +182,22 @@ warn_uninit (opt_code opt, tree t, tree var, const char 
>> *gmsgid,
>>      }
>>      /* Anonymous SSA_NAMEs shouldn't be uninitialized, but 
>> ssa_undefined_value_p
>> -     can return true if the def stmt of an anonymous SSA_NAME is 
>> COMPLEX_EXPR
>> -     created for conversion from scalar to complex.  Use the underlying var 
>> of
>> -     the COMPLEX_EXPRs real part in that case.  See PR71581.  */
>> +     can return true if the def stmt of an anonymous SSA_NAME is
>> +     1. A COMPLEX_EXPR created for conversion from scalar to complex.  Use 
>> the
>> +     underlying var of the COMPLEX_EXPRs real part in that case.  See 
>> PR71581.
>> +
>> +     2. A call to .DEFERRED_INIT internal function. Since the original 
>> variable
>> +     has been eliminated by optimziation, we need to get the variable name,
>> +     and variable declaration location from this call. At the same time, we
>> +     should use the temporary variable that was created to replace the 
>> original
>> +     variable as a placeholder to record the information on whether the 
>> warning
>> +     message for the variable has been issued or not.  */
>> +
>> +  tree var_name = NULL_TREE;
>> +  const char *var_name_str = NULL;
>> +  location_t var_decl_loc = UNKNOWN_LOCATION;
>> +  tree repl_var = NULL_TREE;
>> +
>>    if (!var && !SSA_NAME_VAR (t))
>>      {
>>        gimple *def_stmt = SSA_NAME_DEF_STMT (t);
>> @@ -197,9 +210,34 @@ warn_uninit (opt_code opt, tree t, tree var, const char 
>> *gmsgid,
>>            && zerop (gimple_assign_rhs2 (def_stmt)))
>>          var = SSA_NAME_VAR (v);
>>      }
>> +
>> +      if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
>> +    {
>> +      /* Get the variable name from the 3rd argument of call.  */
>> +      var_name = gimple_call_arg (def_stmt, 2);
>> +      var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
>> +      var_name_str = TREE_STRING_POINTER (var_name);
>> +
>> +      if (is_gimple_assign (context)
>> +          && TREE_CODE (gimple_assign_lhs (context)) == VAR_DECL
>> +          && DECL_NAME (gimple_assign_lhs (context))
>> +          && IDENTIFIER_POINTER (DECL_NAME (gimple_assign_lhs (context))))
>> +        if (strcmp
>> +              (IDENTIFIER_POINTER (DECL_NAME (gimple_assign_lhs (context))),
>> +               var_name_str) == 0)
> 
> For what it's worth, although the style in GCC is pervasive
> of repeating the same expression in operands of subsequent
> subexpressions of a logical exoression, I think it gets more
> and more difficult to read as the expression become increasingly
> deeply nested.  I find it far more readable when temporaries
> are added for the subexpressions (if it makes the nesting too
> deep I take it as a sign that the logic might be better factored
> out into a helper function).

Agreed. I will add some temporaries with meaningful name to make the above more 
readable.

> 
>> +          return;
>> +
>> +      /* Get the variable declaration location from the def_stmt.  */
>> +      var_decl_loc = gimple_location (def_stmt);
>> +
>> +      /* The LHS of the call is a temporary variable, we use it as a
>> +         placeholder to record the information on whether the warning
>> +         has been issued or not.  */
>> +      repl_var = gimple_call_lhs (def_stmt);
>> +    }
>>      }
>>  -  if (var == NULL_TREE)
>> +  if (var == NULL_TREE && var_name == NULL_TREE)
>>      return;
>>      /* Avoid warning if we've already done so or if the warning has been
>> @@ -207,36 +245,56 @@ warn_uninit (opt_code opt, tree t, tree var, const 
>> char *gmsgid,
>>    if (((warning_suppressed_p (context, OPT_Wuninitialized)
>>      || (gimple_assign_single_p (context)
>>          && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
>> -      || get_no_uninit_warning (var))
>> +      || (var && get_no_uninit_warning (var))
>> +      || (repl_var && get_no_uninit_warning (repl_var)))
>>      return;
>>      /* Use either the location of the read statement or that of the PHI
>>       argument, or that of the uninitialized variable, in that order,
>>       whichever is valid.  */
>> -  location_t location;
>> +  location_t location = UNKNOWN_LOCATION;
>>    if (gimple_has_location (context))
>>      location = gimple_location (context);
>>    else if (phi_arg_loc != UNKNOWN_LOCATION)
>>      location = phi_arg_loc;
>> -  else
>> +  else if (var)
>>      location = DECL_SOURCE_LOCATION (var);
>> +  else if (var_name)
>> +    location = var_decl_loc;
>> +
>>    location = linemap_resolve_location (line_table, location,
>>                                     LRK_SPELLING_LOCATION, NULL);
>>      auto_diagnostic_group d;
>> -  if (!warning_at (location, opt, gmsgid, var))
>> +  char *gmsgid_final = XNEWVEC (char, strlen (gmsgid) + 5);
>> +  gmsgid_final[0] = 0;
>> +  if (var)
>> +    strcat (gmsgid_final, "%qD ");
>> +  else if (var_name)
>> +    strcat (gmsgid_final, "%qs ");
>> +  strcat (gmsgid_final, gmsgid);
>> +
>> +  if (var && !warning_at (location, opt, gmsgid_final, var))
>> +    return;
>> +  else if (var_name && !warning_at (location, opt, gmsgid_final, 
>> var_name_str))
>>      return;
> 
> Dynamically creating the string seems quite cumbersome here, and
> it leaks the allocated block.  I wonder if it might be better to
> remove the gmsgid argument from the function and assign it to
> one of the literals based on the other arguments.
> 
> Since only one of var and var_name is used, I also wonder if
> the %qs form could be used for both to simplify the overall
> logic.  (I.e., get the IDENTIFIER_POINTER string from var and
> use it instead of %qD).

Both are good suggestions, I will try to update the code based on this.

Thanks again.

Qing
> 

Reply via email to