Hi, I have attached a bare-bones prototype patch that propagates malloc attribute in ipa-pure-const. As far as I understand, from the doc a function could be annotated with malloc attribute if it returns a pointer to a newly allocated memory block (uninitialized or zeroed) and the pointer does not alias any other valid pointer ? * Analysis The analysis used by the patch in malloc_candidate_p is too conservative, and I would be grateful for suggestions on improving it. Currently it only checks if: 1) The function returns a value of pointer type. 2) SSA_NAME_DEF_STMT (return_value) is either a function call or a phi, and SSA_NAME_DEF_STMT(each element of phi) is function call. 3) The return-value has immediate uses only within comparisons (gcond or gassign) and return_stmt (and likewise a phi arg has immediate use only within comparison or the phi stmt). The intent is that malloc_candidate_p(node) returns true if node returns the return value of it's callee, and the return value is only used for comparisons within node. Then I assume it's safe (although conservative) to decide that node could possibly be a malloc function if callee is found to be malloc ? for eg: void *f(size_t n) { void *p = __builtin_malloc (n); if (p == 0) __builtin_abort (); return p; } malloc_candidate_p would determine f to be a candidate for malloc attribute since it returns the return-value of it's callee (__builtin_malloc) and the return value is used only within comparison and return_stmt. However due to the imprecise analysis it misses this case: char **g(size_t n) { char **p = malloc (sizeof(char *) * 10); for (int i = 0; i < 10; i++) p[i] = malloc (sizeof(char) * n); return p; } I suppose g() could be annotated with malloc here ? The patch uses return_calles_map which is a hash_map such that the return value of node is return value of one of these callees. For above eg it would be The analysis phase populates return_callees_map, and the propagation phase uses it to take the "meet" of callees. * LTO and memory management This is a general question about LTO and memory management. IIUC the following sequence takes place during normal LTO: LGEN: generate_summary, write_summary WPA: read_summary, execute ipa passes, write_opt_summary So I assumed it was OK in LGEN to allocate return_callees_map in generate_summary and free it in write_summary and during WPA, allocate return_callees_map in read_summary and free it after execute (since write_opt_summary does not require return_callees_map). However with fat LTO, it seems the sequence changes for LGEN with execute phase takes place after write_summary. However since return_callees_map is freed in pure_const_write_summary and propagate_malloc() accesses it in execute stage, it results in segmentation fault. To work around this, I am using the following hack in pure_const_write_summary: // FIXME: Do not free if -ffat-lto-objects is enabled. if (!global_options.x_flag_fat_lto_objects) free_return_callees_map (); Is there a better approach for handling this ? Also I am not sure if I have written cgraph_node::set_malloc_flag[_1] correctly. I tried to imitate cgraph_node::set_const_flag. The patch passes bootstrap+test on x86_64 and found a few functions in the source tree (attached func_names.txt) that could be annotated with malloc (I gave a brief look at some of the functions and didn't appear to be false positives but I will recheck thoroughly) Does the patch look in the right direction ? I would be grateful for suggestions on improving it. Thanks, Prathamesh