For the testcase typedef struct cpp_token { int type; } cpp_token; typedef struct _cpp_buff { struct _cpp_buff *next; } _cpp_buff; extern cpp_token *cpp_get_token (); extern _cpp_buff *cpp_get_buff (); static void collect_args (_cpp_buff **pragma_buff) { cpp_token *token = _cpp_get_token (); do { if (*pragma_buff == ((void *)0)) { _cpp_buff *next = *pragma_buff; *pragma_buff = _cpp_get_buff (); (*pragma_buff)->next = next; } token = cpp_get_token (); } while (token->type != 0); } void enter_macro_context () { _cpp_buff *pragma_buff = ((void *)0); collect_args (&pragma_buff); }
PTA figures that one of the SSA_NAMEs of pragma_buff is a "non-pointer" variable which makes it ignore its constraints. We end up with an empty PTA solution even though we do dereference this pointer: pragma_buff_4 = &ANYTHING pragma_buff_11 = pragma_buff_4 pragma_buff_5 = pragma_buff_11 *pragma_buff_5 = pragma_buff_2 Equivalence classes for Direct node node id 16:pragma_buff_5 are pointer: 0, location:0 pragma_buff_5 is a non-pointer variable, eliminating edges. pragma_buff_5 is a non-pointer variable,ignoring constraint:pragma_buff_5 = pragma_buff_11 pragma_buff_5 is a non-pointer variable,ignoring constraint:*pragma_buff_5 = pragma_buff_2 pragma_buff_5 = { } <bb 4>: pragma_buff_2 = pragma_buff_8; D.1263_3 = _cpp_get_buff (); pragma_buff_4 = (struct _cpp_buff *) D.1263_3; pragma_buff_11 = pragma_buff_4; pragma_buff_5 = pragma_buff_11; pragma_buff_5->next = pragma_buff_2; We are "safe" from this error only because an empty points-to solution is treated the same as a points-to-anything solution by the operand scanner. -- Summary: PTA results wrong for "non-pointer" variables Product: gcc Version: 4.4.0 Status: UNCONFIRMED Keywords: wrong-code, alias Severity: normal Priority: P3 Component: tree-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: rguenth at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37869