Hi, > On Dec 9, 2021, at 12:13 PM, Qing Zhao via Gcc-patches > <gcc-patches@gcc.gnu.org> wrote: >> >>> + 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).
Looks like that using “%qs” + get the IDENTIFIER_POINTER string from var did not work very well for the following testing case: 1 /* PR tree-optimization/45083 */ 2 /* { dg-do compile } */ 3 /* { dg-options "-O2 -Wuninitialized" } */ 4 5 struct S { char *a; unsigned b; unsigned c; }; 6 extern int foo (const char *); 7 extern void bar (int, int); 8 9 static void 10 baz (void) 11 { 12 struct S cs[1]; /* { dg-message "was declared here" } */ 13 switch (cs->b) /* { dg-warning "cs\[^\n\r\]*\\.b\[^\n\r\]*is used uninitialized" } */ 14 { 15 case 101: 16 if (foo (cs->a)) /* { dg-warning "cs\[^\n\r\]*\\.a\[^\n\r\]*may be used uninitialized" } */ 17 bar (cs->c, cs->b); /* { dg-warning "cs\[^\n\r\]*\\.c\[^\n\r\]*may be used uninitialized" } */ 18 } 19 } 20 21 void 22 test (void) 23 { 24 baz (); 25 } For the uninitialized usages at line 13, 16, 17: the IDENTIFIER_POINTER string of var are: cs$0$b, cs$0$a ,cs$0$c However, with %qD, they are printed as cs[0].b, cs[0].a, cs[0].c But with %qs, they are printed as cs$0$b, cs$0$a ,cs$0$c. Looks like that %qD does not simplify print out the IDENTIFIER_POINTER string directly, it specially handle it for some cases. I tried to see how %qD specially handle the strings, but didn’t get it so far. Do you know where the %qD handle this case specially? Thanks. Qing > Both are good suggestions, I will try to update the code based on this. > > Thanks again. > > Qing >> >