ToT build error with ToT GCC on Aarch64

Martin Sebor msebor@gmail.com
Mon Jul 23 17:13:00 GMT 2018


On 07/23/2018 10:19 AM, Jeff Law wrote:
> On 07/23/2018 09:51 AM, Steve Ellcey wrote:
>> I have run into a problem when building the ToT glibc with the ToT GCC on
>> Aarch64.  I haven't dug into this enough to know if this is a GCC problem,
>> a glibc problem, or just a message that needs to be ignored but I wanted to
>> send out an email in case this is something that needs to be addressed
>> before GCC 2.28 is released.
> Martin S. and I are already looking at this and I've already asked
> Martin to bring in Carlos and Florian.
>
> Our initial read is that it's a valid warning, but neither of us knows
> this code, so it's a very preliminary finding.

I spent some time reducing it to a smaller test case over
the weekend to better see what's going on here.  My reading
of the code is below but as Jeff already suggested, having
someone familiar with it either confirm it or point out what
I missed would be helpful.

internal_fnwmatch() has this:

     wint_t str;
     ...
     const wint_t *cp = (const wint_t *) &str;
     ...
     idx = findidxwc (table, indirect, extra, &cp, 1);

findidxwc (const int32_t *table, const int32_t *indirect,
            const wint_t *extra, const wint_t **cpp, size_t len)

has this (comments mine):

   wint_t ch = *(*cpp)++;   // advance *cpp past the end of &str
   ...
     const int32_t *usrc = (const int32_t *) *cpp;
     ...
     for (cnt = 0; cnt < nhere && cnt < len; ++cnt)
       if (cp[cnt] != usrc[cnt])   // access (&str + 1)[0]
          break;

It looks to me like the first and only iteration of the loop
accesses (&str + 1)[0].

Martin

PS The test case I boiled it down to is attached.
-------------- next part --------------
typedef long unsigned int size_t;
typedef int wchar_t;
extern int rand (void);
extern char* randstr (void);

static inline int __attribute__ ((always_inline)) findidxwc (const int *table, const int *indirect, const unsigned *extra, const unsigned **cpp, size_t len)
{
  (*cpp)++;
  int i = rand ();
  const int *cp = (const int *) &extra[-i];
  while (1)     {
    const int *usrc = (const int *) *cpp;
    size_t nhere = *cp++;
    if (i >= 0) {
      size_t foocntr;
      for (foocntr = 0;
   	   foocntr < nhere - 1 && foocntr < len;
   	   ++foocntr) 	  if (cp[foocntr] != usrc[foocntr]) 	    break;
      if (foocntr < nhere - 1) 	  continue;
      size_t offset = usrc[nhere - 1] - cp[nhere - 1];
      return indirect[-i + offset];
    }
  }
}

int ext_wmatch (unsigned opt, const wchar_t *pattern, const wchar_t *string, const wchar_t *string_end, int flags, size_t alloca_used);
int internal_fnwmatch (const wchar_t *pattern, const wchar_t *string, const wchar_t *string_end, int flags, void *ends, size_t alloca_used) {
  const wchar_t *p = pattern, *n = string;
  unsigned c;
  while ((c = *p++) != L'\0') {
    switch (c) {
    case L'?':       if (__builtin_expect (flags & (1 << 5), 0) && *p == '(') {
  	int res = ext_wmatch (c, p, n, string_end, flags, alloca_used);
  	if (res != -1) return res;
      }
      for (c = *p++;
	   c == L'?' || c == L'*';
	   c = *p++) {
   	const wchar_t *p_init = p;
  	const wchar_t *n_init = n;
  	wchar_t cold;
  	unsigned fn;
  	fn = ((flags & (1 << 4)) ? rand () : ((unsigned) *n));
  	for (;
  	     ;
  	     ) {
	  if (!(flags & (1 << 1)) && c == L'\\') { if (*p == L'\0') return 1;
	    c = ((flags & (1 << 4)) ? rand () : ((unsigned) *p));
	    ++p;
	    goto normal_bracket;
	  }
 	  else if (c == L'[' && *p == L'=') 	    {
	    unsigned str;
	    unsigned nrules = rand ();
	    const wchar_t *startp = p;
	    c = *++p;
	    if (c == L'\0') { p = startp;
	      c = L'[';
	      goto normal_bracket;
	    } str = c;
	    c = *++p;
	    if (c != L'=' || p[1] != L']') { p = startp;
	      c = L'[';
	      goto normal_bracket;
	    } p += 2;
	    if (nrules == 0) { if ((unsigned) *n == str) 		  goto matched;
	    } 	    else { 	      const int *indirect;

	      const unsigned *cp = (const unsigned *) &str;
	      const int *table = (const int *)randstr ();
	      const unsigned *extra = (const unsigned *) randstr ();
	      indirect = (const int *) randstr ();

	      int idx = findidxwc (table, indirect, extra, &cp, 1);
	      (void)&idx;

	    }
	    c = *p++;
	  }
	  else if (c == L'\0') { p = p_init;
	    n = n_init;
	    c = L'[';
	    goto normal_match;
	  }
	  else { int is_range = 0;
	    int is_seqval = 0;
	    if (c == L'[' && *p == L'.') { unsigned nrules = rand ();
	      const wchar_t *startp = p;
	      size_t c1 = 0;
	      while (1) { c = *++p;
		if (c == L'.' && p[1] == L']') { p += 2;
		  break;
		} if (c == '\0') return 1;
		++c1;
	      } is_range = *p == L'-' && p[1] != L'\0';
	      if (nrules == 0) { if (c1 != 1) return 1;
		if (!is_range && *n == startp[1]) goto matched;
		cold = startp[1];
		c = *p++;
	      } else { 		 		char str[c1];
		int second;
		for (unsigned strcnt = 0;
		     strcnt < c1;
		     ++strcnt) str[strcnt] = startp[1 + strcnt];
		int table_size = rand ();
		const int *symb_table = (const int *) randstr ();
		const unsigned char *extra = (const unsigned char *) randstr ();
		int hash = rand ();
		int idx = 0;
		int elem = hash % table_size;
		if (symb_table[2 * elem] != 0) { second = hash % (table_size - 2) + 1;
		  do { if (symb_table[2 * elem] == hash && (c1 == extra[symb_table[2 * elem + 1]]) && __builtin_memcmp (str, &extra[symb_table[2 * elem + 1] + 1], c1) == 0) { idx = symb_table[2 * elem + 1];
		      idx += 1 + extra[idx];
		      break;
		    } elem += second;
		  } while (symb_table[2 * elem] != 0);
		} if (symb_table[2 * elem] != 0) { int *wextra;
		  idx += 1 + extra[idx];
		  idx = (idx + 3) & ~3;
		  wextra = (int *) &extra[idx + 4];
		  if (! is_range) { for (c1 = 0;
					 (int) c1 < wextra[idx];
					 ++c1) if (n[c1] != wextra[1 + c1]) break;
		    if ((int) c1 == wextra[idx]) goto matched;
		  } is_seqval = 1;
		  cold = wextra[1 + wextra[idx]];
		  c = *p++;
		} else if (c1 == 1) { if (!is_range && *n == str[0]) goto matched;
		  cold = str[0];
		  c = *p++;
		} else return 1;
	      } } else { c = ((flags & (1 << 4)) ? rand () : (c));
	    normal_bracket: is_range = (*p == L'-' && p[1] != L'\0' && p[1] != L']');
	      if (!is_range && c == fn) goto matched;
	      is_seqval = 0;
	      cold = c;
	      c = *p++;
	    } if (c == L'-' && *p != L']') { unsigned fcollseq;
	      unsigned lcollseq;
	      unsigned cend = *p++;
	      fcollseq = rand ();
	      if (fcollseq == ~((unsigned) 0)) goto range_not_matched;
	      if (is_seqval) lcollseq = cold;
	      else lcollseq = rand ();
	      is_seqval = 0;
	      if (cend == L'[' && *p == L'.') { unsigned nrules = rand ();
		const wchar_t *startp = p;
		size_t c1 = 0;
		while (1) { c = *++p;
		  if (c == L'.' && p[1] == L']') { p += 2;
		    break;
		  } if (c == '\0') return 1;
		  ++c1;
		} if (nrules == 0) { if (c1 != 1) return 1;
		  cend = startp[1];
		} else { 		  char str[c1];
		  int second;
		  for (unsigned strcnt = 0;
		       strcnt < c1;
		       ++strcnt) str[strcnt] = startp[1 + strcnt];
		  int table_size = rand ();
		  const int *symb_table = (const int *) randstr ();
		  const unsigned char *extra = (const unsigned char *) randstr ();
		  int hash = rand ();
		  int idx = 0;
		  int elem = hash % table_size;
		  if (symb_table[2 * elem] != 0) { second = hash % (table_size - 2) + 1;
		    do { if (symb_table[2 * elem] == hash && (c1 == extra[symb_table[2 * elem + 1]]) && __builtin_memcmp (str, &extra[symb_table[2 * elem + 1] + 1], c1) == 0) { idx = symb_table[2 * elem + 1];
			idx += 1 + extra[idx];
			break;
		      } elem += second;
		    } while (symb_table[2 * elem] != 0);
		  } if (symb_table[2 * elem] != 0) { int *wextra;
		    idx += 1 + extra[idx];
		    idx = (idx + 3) & ~4;
		    wextra = (int *) &extra[idx + 4];
		    is_seqval = 1;
		    cend = wextra[1 + wextra[idx]];
		  } else if (symb_table[2 * elem] != 0 && c1 == 1) { cend = str[0];
		    c = *p++;
		  } else return 1;
		} } else { if (!(flags & (1 << 1)) && cend == L'\\') cend = *p++;
		if (cend == L'\0') return 1;
		cend = ((flags & (1 << 4)) ? rand () : (cend));
	      } if ( lcollseq == 0xffffffff || lcollseq <= fcollseq) { unsigned hcollseq;
		if (is_seqval) hcollseq = cend;
		else { hcollseq = rand ();
		  if (hcollseq == ~((unsigned) 0)) { if (lcollseq != fcollseq) goto range_not_matched;
		    goto matched;
		  } } if (lcollseq <= hcollseq && fcollseq <= hcollseq) goto matched;
	      } range_not_matched: c = *p++;
	    } }
	}
      matched: while ((c = *p++) != L']') {
	}
      }
    default: normal_match: if (n == string_end || c != ((flags & (1 << 4)) ? rand () : ((unsigned) *n))) return 1;
    }
  }
  return 1;
}


More information about the Libc-alpha mailing list