On Tue, Dec 8, 2015 at 3:22 PM, Uday P. Khedker <u...@cse.iitb.ac.in> wrote: > > > Richard Biener wrote on 12/03/2015 03:32 PM: >> >> On Thu, Dec 3, 2015 at 8:54 AM, Uday P. Khedker <u...@cse.iitb.ac.in> >> wrote: >>> >>> We are implementing points-to analysis in GCC 4.7.2 and need to >>> distinguish >>> between >>> pointers to scalars and the pointers to structures. This distinction by >>> using the TYPE (TREE_TYPE) >>> hierarchy of the tree node of the pointer. We have two questions: >>> >>> (a) Is it sufficient to check for the presence of RECORD_TYPE in type >>> hierarchy? >>> (b) Is it safe to assume that the RECORD_TYPE always appears as a leaf >>> node >>> in >>> the type description of any pointer to structure? >>> >>> As an example, the tree nodes of a pointer to an integer (y) and a >>> pointer >>> to a structure (f) >>> below. It seems to support our hunch. >> >> Yes, your observations are correct with respect to types. >> >> But you can't rely on the pointer type for determining what kind of >> object apointer points to. >> First because of int *p = &s.i; with struct { int i; ... } s; points >> to an int but it also points >> to the start of an aggregate (and so can be trivially casted to a >> pointer to s). Second because >> GCCs middle-end (thus GIMPLE) ignores pointer types completely so you can >> have >> an SSA name a_1 of type int *X and a dereference a_1->b.c (thus a_1 points >> to a >> structure object even though it is of type int *). >> > > Thanks for this word of caution :) > > We understand your example (where SSA variable a_1 is of type int * and it > is dereferenced as a_1->b.c) with the following explanation: Since GIMPLE > based transformations ignore the type information completely, it could > differ flow sensitively for variables and is left implicit. In other words, > the type of a variable in an expression could differ from its type available > in VAR_DECL. For the above example, the type of a_1 in VAR_DECL is int * > whereas it is actually used as a pointer to a struct in the expression > a_1->b.c because of some code transformations. > > Fortunately, we do not need the flow sensitive type of a variable in every > expression. > > Our basic need is much simpler: We would like to know if a pointer is used > for iteratively accessing a recursive data structure (such as a list), in a > loop or recursive invocation as illustrated below. Due to some > transformations, can a pointer to int show up for such accesses in GIMPLE or > would it always have RECORD_TYPE in its type expression for such limited > situations? > > while (...) > { > x = x->f; > ... > } > > At the source level, x is guaranteed to be a pointer to a struct. Our > question is: Does this guarantee hold in GIMPLE in the limited situations of > such iterative accesses to a recursive data structure?
No, it doesn't. > In particular, if this guarantee does not hold for a sequential access > pattern such as below, it is a non-issue for us. > > x = x->f; > x = x->f; > x = x->f; struct X { struct X *f; }; struct X *foo (void *p) { p = ((struct X *)p)->f; p = ((struct X *)p)->f; p = ((struct X *)p)->f; return p; } is represented as foo (void * p) { <bb 2>: p_3 = MEM[(struct X *)p_2(D)].f; p_4 = MEM[(struct X *)p_3].f; p_5 = MEM[(struct X *)p_4].f; return p_5; } all pointer types are void *. At accesses you have types of access of course, but the pointers themselves can have any pointer type (such as void * here or int * if you change the type of p). Richard. > What gives us a ray of hope is our hunch that the code transformations for > iterative accesses are far more limited than they are for sequential > accesses. > > Thanks and regards, > > Uday. > > >