Hi. I sent this email to David some time ago, but it should be probably answered on gcc mailing list.
I have idea one to improve gcov tool and I'm interested in more precise locations for gimple statements. For gcov purpose, we dump location in ipa-profile pass, which is an early IPA pass and this data is used by gcov tool to map statements (blocks) to lines of code. I did a small experiment on the place we emit the location data: inform (gimple_location (stmt), "output_location"); and it shows for: $ cat m2.c unsigned int UuT (void) { unsigned int true_var = 1; unsigned int false_var = 0; unsigned int ret = 0; if (true_var) /* count(1) */ { if (false_var) /* count(1) */ ret = 111; /* count(#####) */ } else ret = 999; /* count(#####) */ return ret; } int main (int argc, char **argv) { UuT (); return 0; } $ gcc --coverage m2.c m2.c: In function ‘main’: m2.c:8:3: note: output_location UuT (); ^~~~~~ # .MEM_2 = VDEF <.MEM_1(D)> UuT (); m2.c:9:10: note: output_location return 0; ^ _3 = 0; m2.c: In function ‘UuT’: m2.c:3:16: note: output_location { unsigned int true_var = 1; unsigned int false_var = 0; unsigned int ret = 0; if (true_var) /* count(1) */ { if (false_var) /* count(1) */ ret = 111; /* count(#####) */ } else ret = 999; /* count(#####) */ return ret; } ^~~~~~~~ true_var_3 = 1; m2.c:3:43: note: output_location { unsigned int true_var = 1; unsigned int false_var = 0; unsigned int ret = 0; if (true_var) /* count(1) */ { if (false_var) /* count(1) */ ret = 111; /* count(#####) */ } else ret = 999; /* count(#####) */ return ret; } ^~~~~~~~~ false_var_4 = 0; m2.c:3:71: note: output_location { unsigned int true_var = 1; unsigned int false_var = 0; unsigned int ret = 0; if (true_var) /* count(1) */ { if (false_var) /* count(1) */ ret = 111; /* count(#####) */ } else ret = 999; /* count(#####) */ return ret; } ^~~ ret_5 = 0; m2.c:3:83: note: output_location { unsigned int true_var = 1; unsigned int false_var = 0; unsigned int ret = 0; if (true_var) /* count(1) */ { if (false_var) /* count(1) */ ret = 111; /* count(#####) */ } else ret = 999; /* count(#####) */ return ret; } ^ if (true_var_3 != 0) m2.c:3:114: note: output_location { unsigned int true_var = 1; unsigned int false_var = 0; unsigned int ret = 0; if (true_var) /* count(1) */ { if (false_var) /* count(1) */ ret = 111; /* count(#####) */ } else ret = 999; /* count(#####) */ return ret; } ^ if (false_var_4 != 0) m2.c:3:145: note: output_location { unsigned int true_var = 1; unsigned int false_var = 0; unsigned int ret = 0; if (true_var) /* count(1) */ { if (false_var) /* count(1) */ ret = 111; /* count(#####) */ } else ret = 999; /* count(#####) */ return ret; } ~~~~^~~~~ ret_7 = 111; m2.c:3:182: note: output_location { unsigned int true_var = 1; unsigned int false_var = 0; unsigned int ret = 0; if (true_var) /* count(1) */ { if (false_var) /* count(1) */ ret = 111; /* count(#####) */ } else ret = 999; /* count(#####) */ return ret; } ~~~~^~~~~ ret_6 = 999; m2.c:3:215: note: output_location { unsigned int true_var = 1; unsigned int false_var = 0; unsigned int ret = 0; if (true_var) /* count(1) */ { if (false_var) /* count(1) */ ret = 111; /* count(#####) */ } else ret = 999; /* count(#####) */ return ret; } ^~~ _8 = ret_2; m2.c:3:215: note: output_location # VUSE <.MEM_9(D)> return _8; Which is not optimal, for some assignments I see just LHS (false_var_4 = 0), for return statements only a returned value is displayed. For conditions, only condition beginning is showed. Is this known behavior or do I miss something? Thanks, Martin