+      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);

     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

Reply via email to