On Wed, 18 Jul 2018, Martin Sebor wrote: > > > > + while (TREE_CODE (chartype) != INTEGER_TYPE) > > > > + chartype = TREE_TYPE (chartype); > > > This is a bit concerning. First under what conditions is chartype not > > > going to be an INTEGER_TYPE? And under what conditions will extracting > > > its type ultimately lead to something that is an INTEGER_TYPE? > > > > chartype is usually (maybe even always) pointer type here: > > > > const char a[] = "123"; > > extern int i; > > n = strlen (&a[i]); > > But your hunch was correct that the loop isn't safe because > the element type need not be an integer (I didn't know/forgot > that the function is called for non-strings too). The loop > should be replaced by: > > while (TREE_CODE (chartype) == ARRAY_TYPE > || TREE_CODE (chartype) == POINTER_TYPE) > chartype = TREE_TYPE (chartype);
As this function may be called "late" you need to cope with the middle-end ignoring type changes and thus happily passing int *** directly rather than (char *) of that. Also doesn't the above yield int for int *[]? I guess you really want if (POINTER_TYPE_P (chartype)) chartype = TREE_TYPE (chartype); while (TREE_CODE (chartype) == ARRAY_TYPE) chartype = TREE_TYPE (chartype); ? > if (TREE_CODE (chartype) != INTEGER_TYPE) > return NULL; > > I will update the patch before committing. > > FWIW, it seems like it would be useful to extend the function to > non-string arguments. That way it would be able to return array > initializers in cases like this: > > const struct A { int a[2]; } > a = { { 1, 2 } }, > b = { { 1, 2 } }; > > int f (void) > { > return __builtin_memcmp (&a, &b, sizeof a); > } > > which would in turn make it possible to fold the result of > such calls analogously to strlen or strcmp. > > Martin > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)