* Re: [PATCH] convert braced initializers to strings (PR 71625) @ 2018-08-08 17:33 Bernd Edlinger 2018-08-08 18:34 ` Bernd Edlinger 0 siblings, 1 reply; 43+ messages in thread From: Bernd Edlinger @ 2018-08-08 17:33 UTC (permalink / raw) To: Martin Sebor, Jason Merrill; +Cc: gcc-patches, Joseph Myers Hi Martin, sorry, I hope you forgive me, when I add a few comments to your patch. > + unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (ctor); > + tree eltype = TREE_TYPE (type); ... > + /* Bail if the CTOR has a block of more than 256 embedded nuls > + due to implicitly initialized elements. */ > + unsigned nelts = (idx - str.length ()) + 1; > + if (nelts > 256) > + return NULL_TREE; nelts shadows previous nelts. > + if (!nelts || str.length () < i) I don't understand when is str.length () < i ? > + /* Append a nul for the empty initializer { } and for the last > + explicit initializer in the loop above that is a nul. */ > + str.safe_push (0); > + > + /* Build a string literal but return the embedded STRING_CST. */ > + tree res = build_string_literal (str.length (), str.begin ()); > + res = TREE_OPERAND (TREE_OPERAND (res, 0), 0); > + return res; > +} res has a different type than the object you initialize. I think you should use: tree res = build_string (str.length (), str.begin ()); TREE_TYPE (res) = type; return res; Bernd. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-08 17:33 [PATCH] convert braced initializers to strings (PR 71625) Bernd Edlinger @ 2018-08-08 18:34 ` Bernd Edlinger 2018-08-08 19:50 ` Martin Sebor 0 siblings, 1 reply; 43+ messages in thread From: Bernd Edlinger @ 2018-08-08 18:34 UTC (permalink / raw) To: Martin Sebor, Jason Merrill; +Cc: gcc-patches, Joseph Myers On 08/08/18 19:33, Bernd Edlinger wrote: > Hi Martin, > > sorry, I hope you forgive me, when I add a few comments to your patch. > >> + unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (ctor); >> + tree eltype = TREE_TYPE (type); > ... >> + /* Bail if the CTOR has a block of more than 256 embedded nuls >> + due to implicitly initialized elements. */ >> + unsigned nelts = (idx - str.length ()) + 1; >> + if (nelts > 256) >> + return NULL_TREE; > > nelts shadows previous nelts. > >> + if (!nelts || str.length () < i) > > I don't understand when is str.length () < i ? > >> + /* Append a nul for the empty initializer { } and for the last >> + explicit initializer in the loop above that is a nul. */ >> + str.safe_push (0); >> + >> + /* Build a string literal but return the embedded STRING_CST. */ >> + tree res = build_string_literal (str.length (), str.begin ()); >> + res = TREE_OPERAND (TREE_OPERAND (res, 0), 0); >> + return res; >> +} > > > res has a different type than the object you initialize. > I think you should use: > > tree res = build_string (str.length (), str.begin ()); > TREE_TYPE (res) = type; > return res; > Sorry, again, but could it be possible that this test case changed with your patch? $ cat w.c const char x[] = { }; int main() { __builtin_printf("%ld\n", sizeof(x)); return 0; } $ gcc w.c $ ./a.out 1 without your patch $ ./a.out 0 Bernd. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-08 18:34 ` Bernd Edlinger @ 2018-08-08 19:50 ` Martin Sebor 2018-08-08 20:35 ` Bernd Edlinger 2018-08-08 20:48 ` Joseph Myers 0 siblings, 2 replies; 43+ messages in thread From: Martin Sebor @ 2018-08-08 19:50 UTC (permalink / raw) To: Jason Merrill; +Cc: Bernd Edlinger, gcc-patches, Joseph Myers > Sorry, again, but could it be possible that this test case changed > with your patch? > > $ cat w.c > const char x[] = { }; > int main() > { > __builtin_printf("%ld\n", sizeof(x)); > return 0; > } > $ gcc w.c > $ ./a.out > 1 > > without your patch > $ ./a.out > 0 > Jason/Joseph, is this meant to be accepted? It's rejected with a hard error with -Wpedantic but I don't see any tests for it: warning: ISO C forbids empty initializer braces [-Wpedantic] const char x[] = { }; ^ error: zero or negative size array âbâ const char x[] = { }; ^ I'll avoid handling it but I'm not sure I should add a test case for it if it's accepted by mistake (and if I should open a bug to reject it instead). The comment above complete_array_type() in c-common.c and the code kind of suggest it's on purpose but the odd failure mode (hard error with -Wpedantic, silence otherwise) and the absence of tests make me wonder. Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-08 19:50 ` Martin Sebor @ 2018-08-08 20:35 ` Bernd Edlinger 2018-08-08 20:48 ` Joseph Myers 1 sibling, 0 replies; 43+ messages in thread From: Bernd Edlinger @ 2018-08-08 20:35 UTC (permalink / raw) To: Martin Sebor, Jason Merrill; +Cc: gcc-patches, Joseph Myers On 08/08/18 21:50, Martin Sebor wrote: >> Sorry, again, but could it be possible that this test case changed >> with your patch? >> >> $ cat w.c >> const char x[] = { }; >> int main() >> { >> __builtin_printf("%ld\n", sizeof(x)); >> return 0; >> } >> $ gcc w.c >> $ ./a.out >> 1 >> >> without your patch >> $ ./a.out >> 0 >> > > Jason/Joseph, is this meant to be accepted? It's rejected with > a hard error with -Wpedantic but I don't see any tests for it: > > warning: ISO C forbids empty initializer braces [-Wpedantic] > const char x[] = { }; > ^ > error: zero or negative size array ‘b’ > const char x[] = { }; > ^ > > I'll avoid handling it but I'm not sure I should add a test case > for it if it's accepted by mistake (and if I should open a bug > to reject it instead). > > The comment above complete_array_type() in c-common.c and > the code kind of suggest it's on purpose but the odd failure > mode (hard error with -Wpedantic, silence otherwise) and > the absence of tests make me wonder. > This is also a bit odd: $ cat w.cc $ g++ w.cc w.cc:1:26: error: initializer-string for array of chars is too long [-fpermissive] char x[3] = { 1,2,3,4 }; $ cat w1.cc char x[3] = { 1,2,3,4,5 }; int main() { __builtin_printf("%ld\n", sizeof(x)); return 0; } $ g++ w.cc w1.cc:1:28: error: too many initializers for 'char [3]' char x[3] = { 1,2,3,4,5 }; This suggests, that it might be better to fold the initializer at where my C/C++ FE patch shortens the string constants? It would have the advantage, that the array size is already known there. And it would avoid changing the array size accidentally, because the decl is already laid out? What do you think? Bernd. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-08 19:50 ` Martin Sebor 2018-08-08 20:35 ` Bernd Edlinger @ 2018-08-08 20:48 ` Joseph Myers 2018-08-09 0:23 ` Martin Sebor 1 sibling, 1 reply; 43+ messages in thread From: Joseph Myers @ 2018-08-08 20:48 UTC (permalink / raw) To: Martin Sebor; +Cc: Jason Merrill, Bernd Edlinger, gcc-patches [-- Attachment #1: Type: text/plain, Size: 809 bytes --] On Wed, 8 Aug 2018, Martin Sebor wrote: > Jason/Joseph, is this meant to be accepted? It's rejected with > a hard error with -Wpedantic but I don't see any tests for it: > > warning: ISO C forbids empty initializer braces [-Wpedantic] > const char x[] = { }; > ^ > error: zero or negative size array âbâ > const char x[] = { }; > ^ > > I'll avoid handling it but I'm not sure I should add a test case > for it if it's accepted by mistake (and if I should open a bug > to reject it instead). It's a perfectly ordinary combination of two GNU extensions (zero-size arrays, and empty initializer braces), so yes, it should be accepted, and have size 0 (but -pedantic should produce a pedwarn, not a hard error). -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-08 20:48 ` Joseph Myers @ 2018-08-09 0:23 ` Martin Sebor 2018-08-09 10:47 ` Joseph Myers 0 siblings, 1 reply; 43+ messages in thread From: Martin Sebor @ 2018-08-09 0:23 UTC (permalink / raw) To: Joseph Myers; +Cc: Jason Merrill, Bernd Edlinger, gcc-patches On 08/08/2018 02:48 PM, Joseph Myers wrote: > On Wed, 8 Aug 2018, Martin Sebor wrote: > >> Jason/Joseph, is this meant to be accepted? It's rejected with >> a hard error with -Wpedantic but I don't see any tests for it: >> >> warning: ISO C forbids empty initializer braces [-Wpedantic] >> const char x[] = { }; >> ^ >> error: zero or negative size array âbâ >> const char x[] = { }; >> ^ >> >> I'll avoid handling it but I'm not sure I should add a test case >> for it if it's accepted by mistake (and if I should open a bug >> to reject it instead). > > It's a perfectly ordinary combination of two GNU extensions (zero-size > arrays, and empty initializer braces), so yes, it should be accepted, and > have size 0 (but -pedantic should produce a pedwarn, not a hard error). Okay, let me fix that separately. As an aside, while adding tests for the zero-size array, I found the handling of these extensions less than intuitive. The empty braced initializer makes the array complete and gives it a zero size. I suppose that makes sense. But for a declaration at file scope and without an initializer, GCC warns that the array is assumed to have one element, but then gives an error when sizeof is applied to it: const char a[]; // warning: array âaâ assumed to have one element const int n = sizeof a; // error: invalid application of âsizeofâ to incomplete type âconst char[]â even though the array does have a size of 1. (I guess that's because of the [] syntax but the warning sure makes the sizeof error surprising.) Auto declarations of arrays with no bound and with no intializer are rejected with an error: char a[]; // error: array size missing in âaâ I'm sure there's some explanation for this too but that doesn't make it intuitive to work with. It would be nice to say something about how this works and maybe even why in the manual. The documentation for zero-length arrays doesn't describe these kinds of extensions or the subtle nuances (it only talks about the [0] form where the zero is explicit, or flexible array members). Without tests it's hard to tell what's meant to be valid and what could be accepted by accident. With the patch accepted tests will exist, but unless it's discussed somewhere I missed I'll put together a patch to update the docs. Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-09 0:23 ` Martin Sebor @ 2018-08-09 10:47 ` Joseph Myers 0 siblings, 0 replies; 43+ messages in thread From: Joseph Myers @ 2018-08-09 10:47 UTC (permalink / raw) To: Martin Sebor; +Cc: Jason Merrill, Bernd Edlinger, gcc-patches [-- Attachment #1: Type: text/plain, Size: 1275 bytes --] On Thu, 9 Aug 2018, Martin Sebor wrote: > But for a declaration at file scope and without an initializer, > GCC warns that the array is assumed to have one element, but > then gives an error when sizeof is applied to it: That's how tentative definitions (C17 6.9.2) work. There's an implicit initializer of { 0 }, but only at the end of the translation unit, so the type is incomplete until then and sizeof cannot be applied to it. > even though the array does have a size of 1. (I guess that's > because of the [] syntax but the warning sure makes the sizeof > error surprising.) Auto declarations of arrays with no bound > and with no intializer are rejected with an error: > > char a[]; // error: array size missing in âaâ Tentative definitions only exist at file scope (and in standard C they can't have an incomplete type if they have internal linkage). See 6.7#7, "If an identifier for an object is declared with no linkage, the type for the object shall be complete by the end of its declarator, or by the end of its init-declarator if it has an initializer; in the case of function parameters (including in prototypes), it is the adjusted type (see 6.7.6.3) that is required to be complete." -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625)
@ 2018-08-16 6:37 Bernd Edlinger
2018-08-17 22:26 ` Bernd Edlinger
0 siblings, 1 reply; 43+ messages in thread
From: Bernd Edlinger @ 2018-08-16 6:37 UTC (permalink / raw)
To: Jeff Law, Martin Sebor, Joseph S. Myers
Cc: James Greenhalgh, Jason Merrill, GCC Patches, nd
Jeff Law wrote:
> I wonder if the change to how we set up the initializers is ultimately
> changing the section those go into and ultimately causing an overflow of
> the .sdata section.
Yes, that is definitely the case.
Due to the -fmerge-all-constants option used
named arrays with brace initializer look like string initializers
and can go into the merge section if there are no embedded nul chars.
But the string constants can now be huge.
See my other patch about string merging:
[PATCH] Handle not explicitly zero terminated strings in merge sections
https://gcc.gnu.org/ml/gcc-patches/2018-08/msg00481.html
Can this section overflow?
Bernd.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-16 6:37 Bernd Edlinger @ 2018-08-17 22:26 ` Bernd Edlinger 2018-08-18 4:13 ` Jeff Law 2018-08-18 10:40 ` Richard Sandiford 0 siblings, 2 replies; 43+ messages in thread From: Bernd Edlinger @ 2018-08-17 22:26 UTC (permalink / raw) To: Jeff Law, Martin Sebor, Joseph S. Myers Cc: James Greenhalgh, Jason Merrill, GCC Patches, nd [-- Attachment #1: Type: text/plain, Size: 853 bytes --] Hi everybody, On 08/16/18 08:36, Bernd Edlinger wrote: > Jeff Law wrote: >> I wonder if the change to how we set up the initializers is ultimately >> changing the section those go into and ultimately causing an overflow of >> the .sdata section. > > > Yes, that is definitely the case. > Due to the -fmerge-all-constants option used > named arrays with brace initializer look like string initializers > and can go into the merge section if there are no embedded nul chars. > But the string constants can now be huge. > > See my other patch about string merging: > [PATCH] Handle not explicitly zero terminated strings in merge sections > https://gcc.gnu.org/ml/gcc-patches/2018-08/msg00481.html > > > Can this section overflow? > could someone try out if this (untested) patch fixes the issue? Thanks, Bernd. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: patch-alpha.diff --] [-- Type: text/x-patch; name="patch-alpha.diff", Size: 1444 bytes --] 2018-08-18 Bernd Edlinger <bernd.edlinger@hotmail.de> * expmed.c (simple_mem_bitfield_p): Do shift right signed. * config/alpha/alpha.h (CONSTANT_ADDRESS_P): Avoid signed integer overflow. Index: gcc/config/alpha/alpha.h =================================================================== --- gcc/config/alpha/alpha.h (revision 263611) +++ gcc/config/alpha/alpha.h (working copy) @@ -678,7 +678,7 @@ enum reg_class { #define CONSTANT_ADDRESS_P(X) \ (CONST_INT_P (X) \ - && (unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000) + && (UINTVAL (X) + 0x8000) < 0x10000) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check its validity for a certain class. Index: gcc/expmed.c =================================================================== --- gcc/expmed.c (revision 263611) +++ gcc/expmed.c (working copy) @@ -579,8 +579,12 @@ static bool simple_mem_bitfield_p (rtx op0, poly_uint64 bitsize, poly_uint64 bitnum, machine_mode mode, poly_uint64 *bytenum) { + poly_int64 ibit = bitnum; + poly_int64 ibyte; + if (!multiple_p (ibit, BITS_PER_UNIT, &ibyte)) + return false; + *bytenum = ibyte; return (MEM_P (op0) - && multiple_p (bitnum, BITS_PER_UNIT, bytenum) && known_eq (bitsize, GET_MODE_BITSIZE (mode)) && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (op0)) || (multiple_p (bitnum, GET_MODE_ALIGNMENT (mode)) ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-17 22:26 ` Bernd Edlinger @ 2018-08-18 4:13 ` Jeff Law 2018-08-18 10:40 ` Richard Sandiford 1 sibling, 0 replies; 43+ messages in thread From: Jeff Law @ 2018-08-18 4:13 UTC (permalink / raw) To: Bernd Edlinger, Martin Sebor, Joseph S. Myers Cc: James Greenhalgh, Jason Merrill, GCC Patches, nd On 08/17/2018 04:26 PM, Bernd Edlinger wrote: > Hi everybody, > > On 08/16/18 08:36, Bernd Edlinger wrote: >> Jeff Law wrote: >>> I wonder if the change to how we set up the initializers is ultimately >>> changing the section those go into and ultimately causing an overflow of >>> the .sdata section. >> >> >> Yes, that is definitely the case. >> Due to the -fmerge-all-constants option used >> named arrays with brace initializer look like string initializers >> and can go into the merge section if there are no embedded nul chars. >> But the string constants can now be huge. >> >> See my other patch about string merging: >> [PATCH] Handle not explicitly zero terminated strings in merge sections >> https://gcc.gnu.org/ml/gcc-patches/2018-08/msg00481.html >> >> >> Can this section overflow? >> > > > could someone try out if this (untested) patch fixes the issue? It seems to in my limited testing. jeff ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-17 22:26 ` Bernd Edlinger 2018-08-18 4:13 ` Jeff Law @ 2018-08-18 10:40 ` Richard Sandiford 2018-08-18 14:25 ` Bernd Edlinger 1 sibling, 1 reply; 43+ messages in thread From: Richard Sandiford @ 2018-08-18 10:40 UTC (permalink / raw) To: Bernd Edlinger Cc: Jeff Law, Martin Sebor, Joseph S. Myers, James Greenhalgh, Jason Merrill, GCC Patches, nd Bernd Edlinger <bernd.edlinger@hotmail.de> writes: > Hi everybody, > > On 08/16/18 08:36, Bernd Edlinger wrote: >> Jeff Law wrote: >>> I wonder if the change to how we set up the initializers is ultimately >>> changing the section those go into and ultimately causing an overflow of >>> the .sdata section. >> >> >> Yes, that is definitely the case. >> Due to the -fmerge-all-constants option used >> named arrays with brace initializer look like string initializers >> and can go into the merge section if there are no embedded nul chars. >> But the string constants can now be huge. >> >> See my other patch about string merging: >> [PATCH] Handle not explicitly zero terminated strings in merge sections >> https://gcc.gnu.org/ml/gcc-patches/2018-08/msg00481.html >> >> >> Can this section overflow? >> > > > could someone try out if this (untested) patch fixes the issue? > > > Thanks, > Bernd. > > > 2018-08-18 Bernd Edlinger <bernd.edlinger@hotmail.de> > > * expmed.c (simple_mem_bitfield_p): Do shift right signed. > * config/alpha/alpha.h (CONSTANT_ADDRESS_P): Avoid signed > integer overflow. > > Index: gcc/config/alpha/alpha.h > =================================================================== > --- gcc/config/alpha/alpha.h (revision 263611) > +++ gcc/config/alpha/alpha.h (working copy) > @@ -678,7 +678,7 @@ enum reg_class { > > #define CONSTANT_ADDRESS_P(X) \ > (CONST_INT_P (X) \ > - && (unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000) > + && (UINTVAL (X) + 0x8000) < 0x10000) > > /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx > and check its validity for a certain class. > Index: gcc/expmed.c > =================================================================== > --- gcc/expmed.c (revision 263611) > +++ gcc/expmed.c (working copy) > @@ -579,8 +579,12 @@ static bool > simple_mem_bitfield_p (rtx op0, poly_uint64 bitsize, poly_uint64 bitnum, > machine_mode mode, poly_uint64 *bytenum) > { > + poly_int64 ibit = bitnum; > + poly_int64 ibyte; > + if (!multiple_p (ibit, BITS_PER_UNIT, &ibyte)) > + return false; > + *bytenum = ibyte; > return (MEM_P (op0) > - && multiple_p (bitnum, BITS_PER_UNIT, bytenum) > && known_eq (bitsize, GET_MODE_BITSIZE (mode)) > && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (op0)) > || (multiple_p (bitnum, GET_MODE_ALIGNMENT (mode)) Do we have a genuinely negative bit offset here? Seems like the callers would need to be updated if so, since the code is consistent in treating the offset as unsigned. Thanks, Richard ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-18 10:40 ` Richard Sandiford @ 2018-08-18 14:25 ` Bernd Edlinger 2018-08-18 16:46 ` Richard Sandiford 0 siblings, 1 reply; 43+ messages in thread From: Bernd Edlinger @ 2018-08-18 14:25 UTC (permalink / raw) To: Jeff Law, Martin Sebor, Joseph S. Myers, James Greenhalgh, Jason Merrill, GCC Patches, nd, richard.sandiford On 08/18/18 12:40, Richard Sandiford wrote: > Bernd Edlinger <bernd.edlinger@hotmail.de> writes: >> Hi everybody, >> >> On 08/16/18 08:36, Bernd Edlinger wrote: >>> Jeff Law wrote: >>>> I wonder if the change to how we set up the initializers is ultimately >>>> changing the section those go into and ultimately causing an overflow of >>>> the .sdata section. >>> >>> >>> Yes, that is definitely the case. >>> Due to the -fmerge-all-constants option used >>> named arrays with brace initializer look like string initializers >>> and can go into the merge section if there are no embedded nul chars. >>> But the string constants can now be huge. >>> >>> See my other patch about string merging: >>> [PATCH] Handle not explicitly zero terminated strings in merge sections >>> https://gcc.gnu.org/ml/gcc-patches/2018-08/msg00481.html >>> >>> >>> Can this section overflow? >>> >> >> >> could someone try out if this (untested) patch fixes the issue? >> >> >> Thanks, >> Bernd. >> >> >> 2018-08-18 Bernd Edlinger <bernd.edlinger@hotmail.de> >> >> * expmed.c (simple_mem_bitfield_p): Do shift right signed. >> * config/alpha/alpha.h (CONSTANT_ADDRESS_P): Avoid signed >> integer overflow. >> >> Index: gcc/config/alpha/alpha.h >> =================================================================== >> --- gcc/config/alpha/alpha.h (revision 263611) >> +++ gcc/config/alpha/alpha.h (working copy) >> @@ -678,7 +678,7 @@ enum reg_class { >> >> #define CONSTANT_ADDRESS_P(X) \ >> (CONST_INT_P (X) \ >> - && (unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000) >> + && (UINTVAL (X) + 0x8000) < 0x10000) >> >> /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx >> and check its validity for a certain class. >> Index: gcc/expmed.c >> =================================================================== >> --- gcc/expmed.c (revision 263611) >> +++ gcc/expmed.c (working copy) >> @@ -579,8 +579,12 @@ static bool >> simple_mem_bitfield_p (rtx op0, poly_uint64 bitsize, poly_uint64 bitnum, >> machine_mode mode, poly_uint64 *bytenum) >> { >> + poly_int64 ibit = bitnum; >> + poly_int64 ibyte; >> + if (!multiple_p (ibit, BITS_PER_UNIT, &ibyte)) >> + return false; >> + *bytenum = ibyte; >> return (MEM_P (op0) >> - && multiple_p (bitnum, BITS_PER_UNIT, bytenum) >> && known_eq (bitsize, GET_MODE_BITSIZE (mode)) >> && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (op0)) >> || (multiple_p (bitnum, GET_MODE_ALIGNMENT (mode)) > > Do we have a genuinely negative bit offset here? Seems like the callers > would need to be updated if so, since the code is consistent in treating > the offset as unsigned. > Aehm, yes. The test case plural.i contains this: static const yytype_int8 yypgoto[] = { -10, -10, -1 }; static const yytype_uint8 yyr1[] = { 0, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; yyn = yyr1[yyn]; yystate = yypgoto[yyn - 16] + *yyssp; There will probably a reason why yyn can never be 0 in yyn = yyr1[yyn]; but it is not really obvious. In plural.i.228t.optimized we have: pretmp_400 = yypgoto[-16]; _385 = (int) pretmp_400; goto <bb 69>; [100.00%] which is expanded to: (insn 927 926 928 59 (set (reg/f:DI 369) (symbol_ref:DI ("yypgoto") [flags 0x6] <var_decl 0x7f76af1d1c60 yypgoto>)) -1 (nil)) (insn 928 927 929 59 (set (reg:DI 372) (const_int 1 [0x1])) -1 (nil)) (insn 929 928 930 59 (set (reg:DI 371) (ashift:DI (reg:DI 372) (const_int 61 [0x3d]))) -1 (expr_list:REG_EQUAL (const_int 2305843009213693952 [0x2000000000000000]) (nil))) (insn 930 929 931 59 (set (reg/f:DI 370) (plus:DI (reg/f:DI 369) (reg:DI 371))) -1 (nil)) (insn 931 930 932 59 (set (reg:DI 375) (plus:DI (reg/f:DI 370) (const_int 1 [0x1]))) -1 (nil)) (insn 932 931 933 59 (set (reg:DI 376) (mem/u/c:DI (and:DI (plus:DI (reg/f:DI 370) (const_int -16 [0xfffffffffffffff0])) (const_int -8 [0xfffffffffffffff8])) [0 S8 A64])) -1 (nil)) (insn 933 932 934 59 (set (reg:DI 377) (ashift:DI (reg:DI 376) (minus:DI (const_int 64 [0x40]) (ashift:DI (and:DI (reg:DI 375) (const_int 7 [0x7])) (const_int 3 [0x3]))))) -1 (nil)) (insn 934 933 935 59 (set (reg:DI 374) (ashiftrt:DI (reg:DI 377) (const_int 56 [0x38]))) -1 (nil)) Certainly there is also a target bug, because (define_insn "*movdi" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,r, m, *f,*f, Q, r,*f") (match_operand:DI 1 "input_operand" "rJ,K,L,T,s,n,s,m,rJ,*fJ, Q,*f,*f, r"))] "register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode)" "@ mov %r1,%0 lda %0,%1($31) ldah %0,%h1($31) # # # lda %0,%1 ldq%A1 %0,%1 stq%A0 %r1,%0 fmov %R1,%0 ldt %0,%1 stt %R1,%0 ftoit %1,%0 itoft %1,%0" overload 7 of 14, has constraint op0 = r, op1 = s. and assembles to lda %0,%1 so s matches symbol_ref+any_integer I think even without the bug in the expansion, that could happen if I write volatile x = 0; if (x) { char *y = &yypgoto[0x20000000000000]; } I think there should be a splitter for large offsets that gets enabled after reload and splits the mov r,s+x into mov r,s; add r,x or something appropriate. So let's see, how does insn 929 get expanded? Index: emit-rtl.c =================================================================== --- emit-rtl.c (Revision 263644) +++ emit-rtl.c (Arbeitskopie) @@ -4023,6 +4023,8 @@ insn = as_a <rtx_insn *> (rtx_alloc (INSN)); INSN_UID (insn) = cur_insn_uid++; + if (INSN_UID (insn) == 929) + asm ("int3"); PATTERN (insn) = pattern; INSN_CODE (insn) = -1; REG_NOTES (insn) = NULL; gdb --args ../gcc-build-alpha-linux-gnu/gcc/cc1 -fpreprocessed plural.i -quiet -dumpbase plural.i -mlong-double-128 -mieee "-mfp-rounding-mode=d" -auxbase plural -g -O2 -Wall -Werror -Wundef -Wwrite-strings -Wstrict-prototypes -Wold-style-definition "-std=gnu11" -fgnu89-inline -fmerge-all-constants -fno-stack-protector -frounding-math -fno-math-errno "-ftls-model=initial-exec" -o plural.s #0 make_insn_raw (pattern=pattern@entry=0x7ffff6e60c30) at ../../gcc-trunk/gcc/emit-rtl.c:4031 #1 0x00000000007fde49 in emit_insn (x=x@entry=0x7ffff6e60c30) at ../../gcc-trunk/gcc/emit-rtl.c:5108 #2 0x0000000000a92623 in expand_binop_directly (icode=CODE_FOR_ashldi3, mode=mode@entry=E_DImode, binoptab=binoptab@entry=ashl_optab, op0=op0@entry=0x7ffff6e60be8, op1=op1@entry=0x7ffff6ecf860, target=target@entry=0x7ffff6e60bd0, unsignedp=unsignedp@entry=0, methods=methods@entry=OPTAB_WIDEN, last=last@entry=0x7ffff6e618c0) at ../../gcc-trunk/gcc/optabs.c:1114 #3 0x0000000000a8fe62 in expand_binop (mode=mode@entry=E_DImode, binoptab=<optimized out>, binoptab@entry=ashl_optab, op0=op0@entry=0x7ffff6e60be8, op1=<optimized out>, target=target@entry=0x7ffff6e60bd0, unsignedp=unsignedp@entry=0, methods=methods@entry=OPTAB_WIDEN) at ../../gcc-trunk/gcc/optabs.c:1186 #4 0x0000000000f1421b in alpha_emit_set_const_1 (target=target@entry=0x7ffff6e60bd0, mode=mode@entry=E_DImode, c=c@entry=2305843009213693952, n=n@entry=2, no_output=no_output@entry=false) at ../../gcc-trunk/gcc/config/alpha/alpha.c:1925 #5 0x0000000000f147a0 in alpha_emit_set_const (target=0x7ffff6e60bd0, mode=E_DImode, c=2305843009213693952, n=3, no_output=<optimized out>) at ../../gcc-trunk/gcc/config/alpha/alpha.c:2048 #6 0x0000000000f1545a in alpha_split_const_mov (mode=mode@entry=E_DImode, operands=operands@entry=0x7fffffffc7b0) at ../../gcc-trunk/gcc/config/alpha/alpha.c:2214 #7 0x0000000000f15536 in alpha_expand_mov (mode=mode@entry=E_DImode, operands=operands@entry=0x7fffffffc7b0) at ../../gcc-trunk/gcc/config/alpha/alpha.c:2263 #8 0x00000000010f0f67 in gen_movdi (operand0=0x7ffff6e60bd0, operand1=0x7ffff6da8580) at ../../gcc-trunk/gcc/config/alpha/alpha.md:4062 #9 0x0000000000833893 in operator() (a1=0x7ffff6da8580, a0=0x7ffff6e60bd0, this=<optimized out>) at ../../gcc-trunk/gcc/recog.h:301 #10 emit_move_insn_1 (x=x@entry=0x7ffff6e60bd0, y=y@entry=0x7ffff6da8580) at ../../gcc-trunk/gcc/expr.c:3694 #11 0x0000000000833b86 in emit_move_insn (x=x@entry=0x7ffff6e60bd0, y=y@entry=0x7ffff6da8580) at ../../gcc-trunk/gcc/expr.c:3790 #12 0x0000000000810aa0 in copy_to_mode_reg (mode=mode@entry=E_DImode, x=0x7ffff6da8580) at ../../gcc-trunk/gcc/explow.c:632 #13 0x0000000000a8b69a in maybe_legitimize_operand (op=0x7fffffffca40, opno=<optimized out>, icode=CODE_FOR_adddi3) at ../../gcc-trunk/gcc/optabs.c:7168 #14 maybe_legitimize_operands (icode=icode@entry=CODE_FOR_adddi3, opno=opno@entry=0, nops=nops@entry=3, ops=ops@entry=0x7fffffffca10) at ../../gcc-trunk/gcc/optabs.c:7292 #15 0x0000000000a8bcde in maybe_gen_insn (icode=icode@entry=CODE_FOR_adddi3, nops=nops@entry=3, ops=ops@entry=0x7fffffffca10) at ../../gcc-trunk/gcc/optabs.c:7311 #16 0x0000000000a925ff in expand_binop_directly (icode=CODE_FOR_adddi3, mode=mode@entry=E_DImode, binoptab=binoptab@entry=add_optab, op0=op0@entry=0x7ffff6e60b40, op1=op1@entry=0x7ffff6da8580, target=target@entry=0x0, unsignedp=unsignedp@entry=1, methods=methods@entry=OPTAB_LIB_WIDEN, last=last@entry=0x7ffff6e61880) at ../../gcc-trunk/gcc/optabs.c:1098 #17 0x0000000000a8fe62 in expand_binop (mode=mode@entry=E_DImode, binoptab=<optimized out>, op0=op0@entry=0x7ffff6e60b40, op1=<optimized out>, target=target@entry=0x0, unsignedp=unsignedp@entry=1, methods=OPTAB_LIB_WIDEN) at ../../gcc-trunk/gcc/optabs.c:1186 #18 0x0000000000a923e3 in expand_simple_binop (mode=mode@entry=E_DImode, code=code@entry=PLUS, op0=op0@entry=0x7ffff6e60b40, op1=<optimized out>, target=target@entry=0x0, unsignedp=unsignedp@entry=1, methods=<optimized out>, methods@entry=OPTAB_LIB_WIDEN) at ../../gcc-trunk/gcc/optabs.c:917 #19 0x0000000000f12d6f in alpha_legitimize_address_1 (x=0x7ffff6e60b40, x@entry=0x7ffff6e60ba0, scratch=scratch@entry=0x0, mode=<optimized out>) at ../../gcc-trunk/gcc/config/alpha/alpha.c:1159 #20 0x0000000000f133cb in alpha_legitimize_address (x=0x7ffff6e60ba0, oldx=<optimized out>, mode=<optimized out>) at ../../gcc-trunk/gcc/config/alpha/alpha.c:1177 #21 0x0000000000810922 in memory_address_addr_space (mode=E_QImode, x=0x7ffff6e60ba0, as=<optimized out>) at ../../gcc-trunk/gcc/explow.c:450 #22 0x00000000007f689d in change_address_1 (memref=memref@entry=0x7ffff6e60b88, mode=mode@entry=E_QImode, addr=addr@entry=0x7ffff6e60ba0, validate=validate@entry=1, inplace=inplace@entry=false) at ../../gcc-trunk/gcc/emit-rtl.c:2288 #23 0x00000000007fab5c in adjust_address_1 (memref=memref@entry=0x7ffff6e60b88, mode=mode@entry=E_QImode, offset=..., validate=validate@entry=1, adjust_address=adjust_address@entry=1, adjust_object=adjust_object@entry=1, size=..., size@entry=...) at ../../gcc-trunk/gcc/emit-rtl.c:2420 #24 0x000000000081942a in extract_bit_field_1 (str_rtx=str_rtx@entry=0x7ffff6e60b88, bitsize=bitsize@entry=..., bitnum=..., bitnum@entry=..., unsignedp=unsignedp@entry=0, target=target@entry=0x0, mode=mode@entry=E_QImode, tmode=<optimized out>, tmode@entry=E_QImode, reverse=reverse@entry=false, fallback_p=fallback_p@entry=true, alt_rtl=alt_rtl@entry=0x0) at ../../gcc-trunk/gcc/expmed.c:1805 #25 0x000000000081a063 in extract_bit_field (str_rtx=0x7ffff6e60b88, bitsize=..., bitnum=..., unsignedp=0, target=target@entry=0x0, mode=mode@entry=E_QImode, tmode=tmode@entry=E_QImode, reverse=false, alt_rtl=alt_rtl@entry=0x0) at ../../gcc-trunk/gcc/expmed.c:2097 #26 0x000000000082f828 in expand_expr_real_1 (exp=<optimized out>, target=<optimized out>, tmode=<optimized out>, modifier=EXPAND_NORMAL, alt_rtl=0x0, inner_reference_p=<optimized out>) at ../../gcc-trunk/gcc/expr.c:10801 #27 0x000000000083047a in expand_expr_real_1 (exp=0x7ffff6df8f30, target=<optimized out>, tmode=E_SImode, modifier=EXPAND_NORMAL, alt_rtl=0x0, inner_reference_p=<optimized out>) at ../../gcc-trunk/gcc/expr.c:9861 #28 0x000000000083d9de in expand_expr (modifier=EXPAND_NORMAL, mode=E_SImode, target=0x0, exp=0x7ffff6df8f30) at ../../gcc-trunk/gcc/expr.h:279 #29 expand_expr_real_2 (ops=ops@entry=0x7fffffffd8a0, target=<optimized out>, tmode=E_SImode, modifier=modifier@entry=EXPAND_NORMAL) at ../../gcc-trunk/gcc/expr.c:8455 #30 0x000000000070ba16 in expand_gimple_stmt_1 (stmt=stmt@entry=0x7ffff6e0eb40) at ../../gcc-trunk/gcc/cfgexpand.c:3674 #31 0x000000000070d4ad in expand_gimple_stmt (stmt=stmt@entry=0x7ffff6e0eb40) at ../../gcc-trunk/gcc/cfgexpand.c:3734 #32 0x000000000070dbbe in expand_gimple_basic_block (bb=0x7ffff6deb478, disable_tail_calls=disable_tail_calls@entry=false) at ../../gcc-trunk/gcc/cfgexpand.c:5770 #33 0x0000000000713597 in (anonymous namespace)::pass_expand::execute (this=<optimized out>, fun=0x7ffff70ab4d0) at ../../gcc-trunk/gcc/cfgexpand.c:6373 #34 0x0000000000ab4e25 in execute_one_pass (pass=pass@entry=0x1b28700) at ../../gcc-trunk/gcc/passes.c:2446 #35 0x0000000000ab5738 in execute_pass_list_1 (pass=0x1b28700) at ../../gcc-trunk/gcc/passes.c:2535 #36 0x0000000000ab5795 in execute_pass_list (fn=0x7ffff70ab4d0, pass=<optimized out>) at ../../gcc-trunk/gcc/passes.c:2546 #37 0x000000000074efe8 in cgraph_node::expand (this=0x7ffff6cfb840) at ../../gcc-trunk/gcc/cgraphunit.c:2116 #38 0x00000000007508a1 in expand_all_functions () at ../../gcc-trunk/gcc/cgraphunit.c:2254 #39 symbol_table::compile (this=this@entry=0x7ffff6ecc000) at ../../gcc-trunk/gcc/cgraphunit.c:2605 #40 0x0000000000752c75 in symbol_table::finalize_compilation_unit (this=0x7ffff6ecc000) at ../../gcc-trunk/gcc/cgraphunit.c:2698 #41 0x0000000000b97d6d in compile_file () at ../../gcc-trunk/gcc/toplev.c:480 #42 0x000000000059cb5e in do_compile () at ../../gcc-trunk/gcc/toplev.c:2165 #43 toplev::main (this=this@entry=0x7fffffffdce0, argc=argc@entry=28, argv=argv@entry=0x7fffffffdde8) at ../../gcc-trunk/gcc/toplev.c:2300 #44 0x000000000059ecb7 in main (argc=28, argv=0x7fffffffdde8) at ../../gcc-trunk/gcc/main.c:39 (gdb) frame 26 #26 0x000000000082f828 in expand_expr_real_1 (exp=<optimized out>, target=<optimized out>, tmode=<optimized out>, modifier=EXPAND_NORMAL, alt_rtl=0x0, inner_reference_p=<optimized out>) at ../../gcc-trunk/gcc/expr.c:10801 10801 ext_mode, ext_mode, reversep, alt_rtl); (gdb) list 10796 reversep = TYPE_REVERSE_STORAGE_ORDER (type); 10797 10798 op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp, 10799 (modifier == EXPAND_STACK_PARM 10800 ? NULL_RTX : target), 10801 ext_mode, ext_mode, reversep, alt_rtl); 10802 10803 /* If the result has a record type and the mode of OP0 is an 10804 integral mode then, if BITSIZE is narrower than this mode 10805 and this is for big-endian data, we must put the field (gdb) p bitpos $1 = {<poly_int_pod<1u, long>> = {coeffs = {-128}}, <No data fields>} (gdb) frame 25 #25 0x000000000081a063 in extract_bit_field (str_rtx=0x7ffff6e60b88, bitsize=..., bitnum=..., unsignedp=0, target=target@entry=0x0, mode=mode@entry=E_QImode, tmode=tmode@entry=E_QImode, reverse=false, alt_rtl=alt_rtl@entry=0x0) at ../../gcc-trunk/gcc/expmed.c:2097 2097 target, mode, tmode, reverse, true, alt_rtl); (gdb) list 2092 return extract_bit_field_1 (str_rtx, ibitsize, ibitnum, unsignedp, 2093 target, mode, tmode, reverse, true, alt_rtl); 2094 } 2095 2096 return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, 2097 target, mode, tmode, reverse, true, alt_rtl); 2098 } 2099 ^L 2100 /* Use shifts and boolean operations to extract a field of BITSIZE bits 2101 from bit BITNUM of OP0. If OP0_MODE is defined, it is the mode of OP0, (gdb) p/x bitnum $3 = {<poly_int_pod<1u, unsigned long>> = {coeffs = {0xffffffffffffff80}}, <No data fields>} (gdb) frame 24 #24 0x000000000081942a in extract_bit_field_1 (str_rtx=str_rtx@entry=0x7ffff6e60b88, bitsize=bitsize@entry=..., bitnum=..., bitnum@entry=..., unsignedp=unsignedp@entry=0, target=target@entry=0x0, mode=mode@entry=E_QImode, tmode=<optimized out>, tmode@entry=E_QImode, reverse=reverse@entry=false, fallback_p=fallback_p@entry=true, alt_rtl=alt_rtl@entry=0x0) at ../../gcc-trunk/gcc/expmed.c:1805 1805 op0 = adjust_bitfield_address (op0, mode1, bytenum); (gdb) list 1800 /* Extraction of a full MODE1 value can be done with a load as long as 1801 the field is on a byte boundary and is sufficiently aligned. */ 1802 poly_uint64 bytenum; 1803 if (simple_mem_bitfield_p (op0, bitsize, bitnum, mode1, &bytenum)) 1804 { 1805 op0 = adjust_bitfield_address (op0, mode1, bytenum); 1806 if (reverse) 1807 op0 = flip_storage_order (mode1, op0); 1808 return convert_extracted_bit_field (op0, mode, tmode, unsignedp); 1809 } (gdb) p/x bytenum $5 = {<poly_int_pod<1u, unsigned long>> = {coeffs = {0x1ffffffffffffff0}}, <No data fields>} The byte offset is completely wrong now, due to the bitnum was initially a negative integer and got converted to unsigned. At the moment when that is converted to byte offsets it is done wrong. I think it is too much to change everything to signed arithmetics, but at least when converting a bit pos to a byte pos, it should be done in signed arithmetics. So yes, I think a negative offset can happen. And it must be handled correctly. Thanks Bernd. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-18 14:25 ` Bernd Edlinger @ 2018-08-18 16:46 ` Richard Sandiford 2018-08-18 17:09 ` Bernd Edlinger 0 siblings, 1 reply; 43+ messages in thread From: Richard Sandiford @ 2018-08-18 16:46 UTC (permalink / raw) To: Bernd Edlinger Cc: Jeff Law, Martin Sebor, Joseph S. Myers, James Greenhalgh, Jason Merrill, GCC Patches, nd Bernd Edlinger <bernd.edlinger@hotmail.de> writes: > On 08/18/18 12:40, Richard Sandiford wrote: >> Bernd Edlinger <bernd.edlinger@hotmail.de> writes: >>> Hi everybody, >>> >>> On 08/16/18 08:36, Bernd Edlinger wrote: >>>> Jeff Law wrote: >>>>> I wonder if the change to how we set up the initializers is ultimately >>>>> changing the section those go into and ultimately causing an overflow of >>>>> the .sdata section. >>>> >>>> >>>> Yes, that is definitely the case. >>>> Due to the -fmerge-all-constants option used >>>> named arrays with brace initializer look like string initializers >>>> and can go into the merge section if there are no embedded nul chars. >>>> But the string constants can now be huge. >>>> >>>> See my other patch about string merging: >>>> [PATCH] Handle not explicitly zero terminated strings in merge sections >>>> https://gcc.gnu.org/ml/gcc-patches/2018-08/msg00481.html >>>> >>>> >>>> Can this section overflow? >>>> >>> >>> >>> could someone try out if this (untested) patch fixes the issue? >>> >>> >>> Thanks, >>> Bernd. >>> >>> >>> 2018-08-18 Bernd Edlinger <bernd.edlinger@hotmail.de> >>> >>> * expmed.c (simple_mem_bitfield_p): Do shift right signed. >>> * config/alpha/alpha.h (CONSTANT_ADDRESS_P): Avoid signed >>> integer overflow. >>> >>> Index: gcc/config/alpha/alpha.h >>> =================================================================== >>> --- gcc/config/alpha/alpha.h (revision 263611) >>> +++ gcc/config/alpha/alpha.h (working copy) >>> @@ -678,7 +678,7 @@ enum reg_class { >>> >>> #define CONSTANT_ADDRESS_P(X) \ >>> (CONST_INT_P (X) \ >>> - && (unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000) >>> + && (UINTVAL (X) + 0x8000) < 0x10000) >>> >>> /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx >>> and check its validity for a certain class. >>> Index: gcc/expmed.c >>> =================================================================== >>> --- gcc/expmed.c (revision 263611) >>> +++ gcc/expmed.c (working copy) >>> @@ -579,8 +579,12 @@ static bool >>> simple_mem_bitfield_p (rtx op0, poly_uint64 bitsize, poly_uint64 bitnum, >>> machine_mode mode, poly_uint64 *bytenum) >>> { >>> + poly_int64 ibit = bitnum; >>> + poly_int64 ibyte; >>> + if (!multiple_p (ibit, BITS_PER_UNIT, &ibyte)) >>> + return false; >>> + *bytenum = ibyte; >>> return (MEM_P (op0) >>> - && multiple_p (bitnum, BITS_PER_UNIT, bytenum) >>> && known_eq (bitsize, GET_MODE_BITSIZE (mode)) >>> && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (op0)) >>> || (multiple_p (bitnum, GET_MODE_ALIGNMENT (mode)) >> >> Do we have a genuinely negative bit offset here? Seems like the callers >> would need to be updated if so, since the code is consistent in treating >> the offset as unsigned. >> > > Aehm, yes. > > The test case plural.i contains this: > > static const yytype_int8 yypgoto[] = > { > -10, -10, -1 > }; > > static const yytype_uint8 yyr1[] = > { > 0, 16, 17, 18, 18, 18, 18, 18, 18, 18, > 18, 18, 18, 18 > }; > > yyn = yyr1[yyn]; > > yystate = yypgoto[yyn - 16] + *yyssp; > > > There will probably a reason why yyn can never be 0 > in yyn = yyr1[yyn]; but it is not really obvious. > > In plural.i.228t.optimized we have: > > pretmp_400 = yypgoto[-16]; > _385 = (int) pretmp_400; > goto <bb 69>; [100.00%] Ah, ok. [...] > (gdb) frame 26 > #26 0x000000000082f828 in expand_expr_real_1 (exp=<optimized out>, target=<optimized out>, > tmode=<optimized out>, modifier=EXPAND_NORMAL, alt_rtl=0x0, inner_reference_p=<optimized out>) > at ../../gcc-trunk/gcc/expr.c:10801 > 10801 ext_mode, ext_mode, reversep, alt_rtl); > (gdb) list > 10796 reversep = TYPE_REVERSE_STORAGE_ORDER (type); > 10797 > 10798 op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp, > 10799 (modifier == EXPAND_STACK_PARM > 10800 ? NULL_RTX : target), > 10801 ext_mode, ext_mode, reversep, alt_rtl); > 10802 > 10803 /* If the result has a record type and the mode of OP0 is an > 10804 integral mode then, if BITSIZE is narrower than this mode > 10805 and this is for big-endian data, we must put the field > (gdb) p bitpos > $1 = {<poly_int_pod<1u, long>> = {coeffs = {-128}}, <No data fields>} The get_inner_reference->store_field path in expand_assignment has: /* Make sure bitpos is not negative, it can wreak havoc later. */ if (maybe_lt (bitpos, 0)) { gcc_assert (offset == NULL_TREE); offset = size_int (bits_to_bytes_round_down (bitpos)); bitpos = num_trailing_bits (bitpos); } So maybe this is what havoc looks like. It's not my area, but I think we should be doing something similar for the get_inner_reference->expand_bit_field path in expand_expr_real_1. Haven't checked whether the offset == NULL_TREE assert would be guaranteed there though. > $5 = {<poly_int_pod<1u, unsigned long>> = {coeffs = {0x1ffffffffffffff0}}, <No data fields>} > > The byte offset is completely wrong now, due to the bitnum was > initially a negative integer and got converted to unsigned. At the > moment when that is converted to byte offsets it is done wrong. I > think it is too much to change everything to signed arithmetics, but > at least when converting a bit pos to a byte pos, it should be done in > signed arithmetics. But then we'd mishandle a real 1ULL << 63 bitpos (say). Realise it's unlikely in real code, but it'd still probably be possible to construct a variant of the original test case in which the bias was +0x1000000000000000 rather than -16. Thanks, Richard ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-18 16:46 ` Richard Sandiford @ 2018-08-18 17:09 ` Bernd Edlinger 0 siblings, 0 replies; 43+ messages in thread From: Bernd Edlinger @ 2018-08-18 17:09 UTC (permalink / raw) To: Jeff Law, Martin Sebor, Joseph S. Myers, James Greenhalgh, Jason Merrill, GCC Patches, nd, richard.sandiford [-- Attachment #1: Type: text/plain, Size: 6446 bytes --] On 08/18/18 18:46, Richard Sandiford wrote: > Bernd Edlinger <bernd.edlinger@hotmail.de> writes: >> On 08/18/18 12:40, Richard Sandiford wrote: >>> Bernd Edlinger <bernd.edlinger@hotmail.de> writes: >>>> Hi everybody, >>>> >>>> On 08/16/18 08:36, Bernd Edlinger wrote: >>>>> Jeff Law wrote: >>>>>> I wonder if the change to how we set up the initializers is ultimately >>>>>> changing the section those go into and ultimately causing an overflow of >>>>>> the .sdata section. >>>>> >>>>> >>>>> Yes, that is definitely the case. >>>>> Due to the -fmerge-all-constants option used >>>>> named arrays with brace initializer look like string initializers >>>>> and can go into the merge section if there are no embedded nul chars. >>>>> But the string constants can now be huge. >>>>> >>>>> See my other patch about string merging: >>>>> [PATCH] Handle not explicitly zero terminated strings in merge sections >>>>> https://gcc.gnu.org/ml/gcc-patches/2018-08/msg00481.html >>>>> >>>>> >>>>> Can this section overflow? >>>>> >>>> >>>> >>>> could someone try out if this (untested) patch fixes the issue? >>>> >>>> >>>> Thanks, >>>> Bernd. >>>> >>>> >>>> 2018-08-18 Bernd Edlinger <bernd.edlinger@hotmail.de> >>>> >>>> * expmed.c (simple_mem_bitfield_p): Do shift right signed. >>>> * config/alpha/alpha.h (CONSTANT_ADDRESS_P): Avoid signed >>>> integer overflow. >>>> >>>> Index: gcc/config/alpha/alpha.h >>>> =================================================================== >>>> --- gcc/config/alpha/alpha.h (revision 263611) >>>> +++ gcc/config/alpha/alpha.h (working copy) >>>> @@ -678,7 +678,7 @@ enum reg_class { >>>> >>>> #define CONSTANT_ADDRESS_P(X) \ >>>> (CONST_INT_P (X) \ >>>> - && (unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000) >>>> + && (UINTVAL (X) + 0x8000) < 0x10000) >>>> >>>> /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx >>>> and check its validity for a certain class. >>>> Index: gcc/expmed.c >>>> =================================================================== >>>> --- gcc/expmed.c (revision 263611) >>>> +++ gcc/expmed.c (working copy) >>>> @@ -579,8 +579,12 @@ static bool >>>> simple_mem_bitfield_p (rtx op0, poly_uint64 bitsize, poly_uint64 bitnum, >>>> machine_mode mode, poly_uint64 *bytenum) >>>> { >>>> + poly_int64 ibit = bitnum; >>>> + poly_int64 ibyte; >>>> + if (!multiple_p (ibit, BITS_PER_UNIT, &ibyte)) >>>> + return false; >>>> + *bytenum = ibyte; >>>> return (MEM_P (op0) >>>> - && multiple_p (bitnum, BITS_PER_UNIT, bytenum) >>>> && known_eq (bitsize, GET_MODE_BITSIZE (mode)) >>>> && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (op0)) >>>> || (multiple_p (bitnum, GET_MODE_ALIGNMENT (mode)) >>> >>> Do we have a genuinely negative bit offset here? Seems like the callers >>> would need to be updated if so, since the code is consistent in treating >>> the offset as unsigned. >>> >> >> Aehm, yes. >> >> The test case plural.i contains this: >> >> static const yytype_int8 yypgoto[] = >> { >> -10, -10, -1 >> }; >> >> static const yytype_uint8 yyr1[] = >> { >> 0, 16, 17, 18, 18, 18, 18, 18, 18, 18, >> 18, 18, 18, 18 >> }; >> >> yyn = yyr1[yyn]; >> >> yystate = yypgoto[yyn - 16] + *yyssp; >> >> >> There will probably a reason why yyn can never be 0 >> in yyn = yyr1[yyn]; but it is not really obvious. >> >> In plural.i.228t.optimized we have: >> >> pretmp_400 = yypgoto[-16]; >> _385 = (int) pretmp_400; >> goto <bb 69>; [100.00%] > > Ah, ok. > > [...] > >> (gdb) frame 26 >> #26 0x000000000082f828 in expand_expr_real_1 (exp=<optimized out>, target=<optimized out>, >> tmode=<optimized out>, modifier=EXPAND_NORMAL, alt_rtl=0x0, inner_reference_p=<optimized out>) >> at ../../gcc-trunk/gcc/expr.c:10801 >> 10801 ext_mode, ext_mode, reversep, alt_rtl); >> (gdb) list >> 10796 reversep = TYPE_REVERSE_STORAGE_ORDER (type); >> 10797 >> 10798 op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp, >> 10799 (modifier == EXPAND_STACK_PARM >> 10800 ? NULL_RTX : target), >> 10801 ext_mode, ext_mode, reversep, alt_rtl); >> 10802 >> 10803 /* If the result has a record type and the mode of OP0 is an >> 10804 integral mode then, if BITSIZE is narrower than this mode >> 10805 and this is for big-endian data, we must put the field >> (gdb) p bitpos >> $1 = {<poly_int_pod<1u, long>> = {coeffs = {-128}}, <No data fields>} > > The get_inner_reference->store_field path in expand_assignment has: > > /* Make sure bitpos is not negative, it can wreak havoc later. */ > if (maybe_lt (bitpos, 0)) > { > gcc_assert (offset == NULL_TREE); > offset = size_int (bits_to_bytes_round_down (bitpos)); > bitpos = num_trailing_bits (bitpos); > } > > So maybe this is what havoc looks like. > > It's not my area, but I think we should be doing something similar for > the get_inner_reference->expand_bit_field path in expand_expr_real_1. > Haven't checked whether the offset == NULL_TREE assert would be > guaranteed there though. > Yes, I come to the same conclusion. The offset==NULL assertion reflects the logic around the "wreak havoc" comment in get_inner_reference, so that is guaranteed to hold, at least immediately after get_inner_reference returns. >> $5 = {<poly_int_pod<1u, unsigned long>> = {coeffs = {0x1ffffffffffffff0}}, <No data fields>} >> >> The byte offset is completely wrong now, due to the bitnum was >> initially a negative integer and got converted to unsigned. At the >> moment when that is converted to byte offsets it is done wrong. I >> think it is too much to change everything to signed arithmetics, but >> at least when converting a bit pos to a byte pos, it should be done in >> signed arithmetics. > > But then we'd mishandle a real 1ULL << 63 bitpos (say). Realise it's > unlikely in real code, but it'd still probably be possible to construct > a variant of the original test case in which the bias was > +0x1000000000000000 rather than -16. > Yes, I see, thanks. Additionally I think we need some assertions, when signed bit quantities are passed to store_bit_field and expand_bit_field. Thanks Bernd. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: patch-expr.diff --] [-- Type: text/x-patch; name="patch-expr.diff", Size: 1952 bytes --] 2018-08-19 Bernd Edlinger <bernd.edlinger@hotmail.de> * expr.c (expand_assignment): Assert that bitpos is positive. (store_field): Likewise (expand_expr_real_1): Make sure that bitpos is positive. Index: gcc/expr.c =================================================================== --- gcc/expr.c (Revision 263644) +++ gcc/expr.c (Arbeitskopie) @@ -5270,6 +5270,7 @@ expand_assignment (tree to, tree from, bool nontem MEM_VOLATILE_P (to_rtx) = 1; } + gcc_assert (known_ge (bitpos, 0)); if (optimize_bitfield_assignment_op (bitsize, bitpos, bitregion_start, bitregion_end, mode1, to_rtx, to, from, @@ -7046,6 +7047,7 @@ store_field (rtx target, poly_int64 bitsize, poly_ } /* Store the value in the bitfield. */ + gcc_assert (known_ge (bitpos, 0)); store_bit_field (target, bitsize, bitpos, bitregion_start, bitregion_end, mode, temp, reverse); @@ -10545,6 +10547,14 @@ expand_expr_real_1 (tree exp, rtx target, machine_ mode2 = CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0); + /* Make sure bitpos is not negative, it can wreak havoc later. */ + if (maybe_lt (bitpos, 0)) + { + gcc_assert (offset == NULL_TREE); + offset = size_int (bits_to_bytes_round_down (bitpos)); + bitpos = num_trailing_bits (bitpos); + } + /* If we have either an offset, a BLKmode result, or a reference outside the underlying object, we must force it to memory. Such a case can occur in Ada if we have unchecked conversion @@ -10795,6 +10805,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_ && GET_MODE_CLASS (ext_mode) == MODE_INT) reversep = TYPE_REVERSE_STORAGE_ORDER (type); + gcc_assert (known_ge (bitpos, 0)); op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp, (modifier == EXPAND_STACK_PARM ? NULL_RTX : target), ^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH] convert braced initializers to strings (PR 71625) @ 2018-07-30 23:51 Martin Sebor 2018-07-31 13:39 ` Jason Merrill 2018-08-06 16:41 ` Martin Sebor 0 siblings, 2 replies; 43+ messages in thread From: Martin Sebor @ 2018-07-30 23:51 UTC (permalink / raw) To: Gcc Patch List; +Cc: Jason Merrill, Joseph Myers [-- Attachment #1: Type: text/plain, Size: 946 bytes --] The middle-end contains code to determine the lengths of constant character arrays initialized by string literals. The code is used in a number of optimizations and warnings. However, the code is unable to deal with constant arrays initialized using the braced initializer syntax, as in const char a[] = { '1', '2', '\0' }; The attached patch extends the C and C++ front-ends to convert such initializers into a STRING_CST form. The goal of this work is to both enable existing optimizations for such arrays, and to help detect bugs due to using non-nul terminated arrays where nul-terminated strings are expected. The latter is an extension of the GCC 8 _Wstringop-overflow and -Wstringop-truncation warnings that help detect or prevent reading past the end of dynamically created character arrays. Future work includes detecting potential past-the-end reads from uninitialized local character arrays. Tested on x86_64-linux. Martin [-- Attachment #2: gcc-71625.diff --] [-- Type: text/x-patch, Size: 10206 bytes --] PR tree-optimization/71625 - missing strlen optimization on different array initialization style gcc/c/ChangeLog: PR tree-optimization/71625 * c-parser.c (c_parser_declaration_or_fndef): Call convert_braced_list_to_string. gcc/c-family/ChangeLog: PR tree-optimization/71625 * c-common.c (convert_braced_list_to_string): New function. * c-common.h (convert_braced_list_to_string): Declare it. gcc/cp/ChangeLog: PR tree-optimization/71625 * parser.c (cp_parser_init_declarator): Call convert_braced_list_to_string. gcc/testsuite/ChangeLog: PR tree-optimization/71625 * g++.dg/init/string2.C: New test. * g++.dg/init/string3.C: New test. * gcc.dg/strlenopt-55.c: New test. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 422d668..9a93175 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -8345,4 +8345,72 @@ maybe_add_include_fixit (rich_location *richloc, const char *header) free (text); } +/* Attempt to convert a braced array initializer list CTOR into + a STRING_CST for convenience and efficiency. When non-null, + use EVAL to attempt to evalue constants (used by C++). + MAXELTS gives the maximum number of elements to accept. + Return the converted string on success or null on failure. */ + +tree +convert_braced_list_to_string (tree ctor, tree (*eval)(tree), + unsigned HOST_WIDE_INT maxelts) +{ + unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (ctor); + + auto_vec<char> str; + str.reserve (nelts + 1); + + unsigned HOST_WIDE_INT i; + tree index, value; + + FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, index, value) + { + unsigned HOST_WIDE_INT idx = index ? tree_to_uhwi (index) : i; + + /* auto_vec is limited to UINT_MAX elements. */ + if (idx > UINT_MAX) + return NULL_TREE; + + /* Attempt to evaluate constants. */ + if (eval) + value = eval (value); + + /* Avoid non-constant initializers. */ + if (!tree_fits_uhwi_p (value)) + return NULL_TREE; + + /* Skip over embedded nuls. */ + unsigned val = tree_to_uhwi (value); + if (!val) + continue; + + /* Bail if the CTOR has a block of more than 256 embedded nuls + due to implicitly initialized elements. */ + unsigned nelts = (idx - str.length ()) + 1; + if (nelts > 256) + return NULL_TREE; + + if (nelts > 1) + { + str.reserve (idx); + str.quick_grow_cleared (idx); + } + + if (idx > maxelts) + return NULL_TREE; + + str.safe_insert (idx, val); + } + + /* Append a nul for the empty initializer { } and for the last + explicit initializer in the loop above that is a nul. */ + if (!nelts || str.length () < i) + str.safe_push (0); + + /* Build a string literal but return the embedded STRING_CST. */ + tree res = build_string_literal (str.length (), str.begin ()); + res = TREE_OPERAND (TREE_OPERAND (res, 0), 0); + return res; +} + #include "gt-c-family-c-common.h" diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index fcec95b..343a1ae 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1331,6 +1331,8 @@ extern void maybe_add_include_fixit (rich_location *, const char *); extern void maybe_suggest_missing_token_insertion (rich_location *richloc, enum cpp_ttype token_type, location_t prev_token_loc); +extern tree convert_braced_list_to_string (tree, tree (*)(tree) = NULL, + unsigned HOST_WIDE_INT = -1); #if CHECKING_P namespace selftest { diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 7a92628..e12d270 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -2126,6 +2126,23 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, if (d != error_mark_node) { maybe_warn_string_init (init_loc, TREE_TYPE (d), init); + + /* Convert a string CONSTRUCTOR into a STRING_CST. */ + tree valtype = TREE_TYPE (init.value); + if (TREE_CODE (init.value) == CONSTRUCTOR + && TREE_CODE (valtype) == ARRAY_TYPE) + { + valtype = TREE_TYPE (valtype); + if (TYPE_STRING_FLAG (valtype)) + if (tree str + = convert_braced_list_to_string (init.value)) + { + /* Replace the initializer with the string + constant. The resu*/ + init.value = str; + } + } + finish_decl (d, init_loc, init.value, init.original_type, asm_name); } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d44a6b8..c35c2f1 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -19825,6 +19825,32 @@ cp_parser_init_declarator (cp_parser* parser, finish_lambda_scope (); if (initializer == error_mark_node) cp_parser_skip_to_end_of_statement (parser); + else if (decl) + { + tree valtype = TREE_TYPE (decl); + if (TREE_CODE (valtype) == ARRAY_TYPE + && TYPE_STRING_FLAG (TREE_TYPE (valtype)) + && TYPE_MAIN_VARIANT (TREE_TYPE (valtype)) == char_type_node) + { + /* If the array has an explicit bound, use it to + constrain the size of the string. */ + unsigned HOST_WIDE_INT maxelts = HOST_WIDE_INT_M1U; + if (tree nelts = DECL_SIZE_UNIT (decl)) + if (tree_fits_uhwi_p (nelts)) + maxelts = tree_to_uhwi (nelts); + + /* Convert a string CONSTRUCTOR into a STRING_CST. */ + if (TREE_CODE (initializer) == CONSTRUCTOR + && TREE_TYPE (initializer) == init_list_type_node) + { + if (tree str + = convert_braced_list_to_string (initializer, + scalar_constant_value, + maxelts)) + initializer = str; + } + } + } } } diff --git a/gcc/testsuite/g++.dg/init/string2.C b/gcc/testsuite/g++.dg/init/string2.C new file mode 100644 index 0000000..acb2f5b --- /dev/null +++ b/gcc/testsuite/g++.dg/init/string2.C @@ -0,0 +1,49 @@ +// PR tree-optimization/71625 - missing strlen optimization on different +// array initialization style +// +// Verify that strlen() calls with constant character array arguments +// initialized with string constants are folded. (This is a small +// subset of pr63989). +// { dg-do compile } +// { dg-options "-O0 -fdump-tree-gimple" } + +const char a0[] = { 'a', 'b', 'c', '\0' }; + +int len0 () +{ + return __builtin_strlen (a0); +} + +const char c = 0; +const char a1[] = { 'a', 'b', 'c', c }; + +int len1 () +{ + return __builtin_strlen (a1); +} + +#if 0 + +// The following aren't handled. + +const char &cref = c; +const char a2[] = { 'a', 'b', 'c', cref }; + +int len2 () +{ + return __builtin_strlen (a2); +} + + +const char* const cptr = &cref; +const char a3[] = { 'a', 'b', 'c', *cptr }; + +int len3 () +{ + return __builtin_strlen (a3); +} + +#endif + +// { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } diff --git a/gcc/testsuite/g++.dg/init/string3.C b/gcc/testsuite/g++.dg/init/string3.C new file mode 100644 index 0000000..f7c7f2f --- /dev/null +++ b/gcc/testsuite/g++.dg/init/string3.C @@ -0,0 +1,37 @@ +// PR tree-optimization/71625 - missing strlen optimization on different +// array initialization style +// +// Verify that strlen() call with a constant character array argument +// initialized with non-constant elements isn't folded. (This is a small +// subset of pr63989). +// +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-optimized" } + + +extern const char c; +const char a0[] = { 'a', 'b', 'c', c }; + +int len0 () +{ + return __builtin_strlen (a0); +} + +const char &ref = c; +const char a1[] = { 'a', 'b', 'c', ref }; + +int len1 () +{ + return __builtin_strlen (a1); +} + +const char* const ptr = &c; +const char a2[] = { 'a', 'b', 'c', *ptr }; + +int len2 () +{ + return __builtin_strlen (a2); +} + +// { dg-final { scan-tree-dump-times "strlen" 3 "optimized" } } diff --git a/gcc/testsuite/gcc.dg/strlenopt-55.c b/gcc/testsuite/gcc.dg/strlenopt-55.c new file mode 100644 index 0000000..68c7f1d --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-55.c @@ -0,0 +1,83 @@ +/* PR tree-optimization/71625 - missing strlen optimization on different + array initialization style + + Verify that strlen() of braced initialized array is folded + { dg-do compile } + { dg-options "-O0 -Wall -fdump-tree-gimple -fdump-tree-optimized" } */ + +#include "strlenopt.h" + +const char a2_implicit[2] = { }; +const char a3_implicit[3] = { }; + +const char a3_nul[3] = { 0 }; +const char a5_nul1[3] = { [1] = 0 }; +const char a7_nul2[3] = { [2] = 0 }; + +const char ax_2_nul[] = { '1', '2', '\0' }; +const char ax_3_nul[] = { '1', '2', '3', '\0' }; + +const char ax_3_des_nul[] = { [3] = 0, [2] = '3', [1] = '2', [0] = '1' }; + +const char ax_3[] = { '1', '2', '3' }; +const char a3_3[3] = { '1', '2', '3' }; + +const char a100_3[] = { '1', '2', '3', [100] = '\0' }; + +#define CONCAT(x, y) x ## y +#define CAT(x, y) CONCAT (x, y) +#define FAILNAME(name) CAT (call_ ## name ##_on_line_, __LINE__) + +#define FAIL(name) do { \ + extern void FAILNAME (name) (void); \ + FAILNAME (name)(); \ + } while (0) + +/* Macro to emit a call to funcation named + call_in_true_branch_not_eliminated_on_line_NNN() + for each call that's expected to be eliminated. The dg-final + scan-tree-dump-time directive at the bottom of the test verifies + that no such call appears in output. */ +#define ELIM(expr) \ + if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0 + +#define T(s, n) ELIM (strlen (s) == n) + +void test_nulstring (void) +{ + T (a2_implicit, 0); + T (a3_implicit, 0); + + T (a3_nul, 0); + T (a5_nul1, 0); + T (a7_nul2, 0); + + T (ax_2_nul, 2); + T (ax_3_nul, 3); + T (ax_3_des_nul, 3); + + T (a100_3, 3); +} + +/* Verify that excessively large initializers don't run out of + memory. */ + +const char large_string[] = { 'a', [__INT_MAX__] = '\0' }; + +const int test_large_string (void) +{ + return large_string[0] + large_string[__INT_MAX__ - 1]; +} + + +const char very_large_string[] = { 'a', [__LONG_MAX__ / 2] = '\0' }; + +const int test_very_large_string (void) +{ + return very_large_string[0] + very_large_string[__LONG_MAX__ / 2 - 1]; +} + + +/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } + { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */ ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-07-30 23:51 Martin Sebor @ 2018-07-31 13:39 ` Jason Merrill 2018-07-31 14:49 ` Martin Sebor 2018-08-06 16:41 ` Martin Sebor 1 sibling, 1 reply; 43+ messages in thread From: Jason Merrill @ 2018-07-31 13:39 UTC (permalink / raw) To: Martin Sebor; +Cc: Gcc Patch List, Joseph Myers On Tue, Jul 31, 2018 at 9:51 AM, Martin Sebor <msebor@gmail.com> wrote: > The middle-end contains code to determine the lengths of constant > character arrays initialized by string literals. The code is used > in a number of optimizations and warnings. > > However, the code is unable to deal with constant arrays initialized > using the braced initializer syntax, as in > > const char a[] = { '1', '2', '\0' }; > > The attached patch extends the C and C++ front-ends to convert such > initializers into a STRING_CST form. > > The goal of this work is to both enable existing optimizations for > such arrays, and to help detect bugs due to using non-nul terminated > arrays where nul-terminated strings are expected. The latter is > an extension of the GCC 8 _Wstringop-overflow and > -Wstringop-truncation warnings that help detect or prevent reading > past the end of dynamically created character arrays. Future work > includes detecting potential past-the-end reads from uninitialized > local character arrays. > && TYPE_MAIN_VARIANT (TREE_TYPE (valtype)) == char_type_node) Why? Don't we want this for other character types as well? Jason ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-07-31 13:39 ` Jason Merrill @ 2018-07-31 14:49 ` Martin Sebor 2018-08-07 8:58 ` Jason Merrill 0 siblings, 1 reply; 43+ messages in thread From: Martin Sebor @ 2018-07-31 14:49 UTC (permalink / raw) To: Jason Merrill; +Cc: Gcc Patch List, Joseph Myers On 07/31/2018 07:38 AM, Jason Merrill wrote: > On Tue, Jul 31, 2018 at 9:51 AM, Martin Sebor <msebor@gmail.com> wrote: >> The middle-end contains code to determine the lengths of constant >> character arrays initialized by string literals. The code is used >> in a number of optimizations and warnings. >> >> However, the code is unable to deal with constant arrays initialized >> using the braced initializer syntax, as in >> >> const char a[] = { '1', '2', '\0' }; >> >> The attached patch extends the C and C++ front-ends to convert such >> initializers into a STRING_CST form. >> >> The goal of this work is to both enable existing optimizations for >> such arrays, and to help detect bugs due to using non-nul terminated >> arrays where nul-terminated strings are expected. The latter is >> an extension of the GCC 8 _Wstringop-overflow and >> -Wstringop-truncation warnings that help detect or prevent reading >> past the end of dynamically created character arrays. Future work >> includes detecting potential past-the-end reads from uninitialized >> local character arrays. > >> && TYPE_MAIN_VARIANT (TREE_TYPE (valtype)) == char_type_node) > > Why? Don't we want this for other character types as well? It suppresses narrowing warnings for things like signed char a[] = { 0xff }; (there are a couple of tests that exercise this). At the same time, STRING_CST is supposed to be able to represent strings of any integer type so there should be a way to make it work. On the flip side, recent discussions of changes in this area suggest there may be bugs in the wide character handling of STRING_CST so those would need to be fixed before relying on it for robust support. In any case, if you have a suggestion for how to make it work for at least the narrow character types I'll adjust the patch. Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-07-31 14:49 ` Martin Sebor @ 2018-08-07 8:58 ` Jason Merrill 2018-08-07 23:04 ` Martin Sebor 0 siblings, 1 reply; 43+ messages in thread From: Jason Merrill @ 2018-08-07 8:58 UTC (permalink / raw) To: Martin Sebor; +Cc: Gcc Patch List, Joseph Myers On Wed, Aug 1, 2018 at 12:49 AM, Martin Sebor <msebor@gmail.com> wrote: > On 07/31/2018 07:38 AM, Jason Merrill wrote: >> >> On Tue, Jul 31, 2018 at 9:51 AM, Martin Sebor <msebor@gmail.com> wrote: >>> >>> The middle-end contains code to determine the lengths of constant >>> character arrays initialized by string literals. The code is used >>> in a number of optimizations and warnings. >>> >>> However, the code is unable to deal with constant arrays initialized >>> using the braced initializer syntax, as in >>> >>> const char a[] = { '1', '2', '\0' }; >>> >>> The attached patch extends the C and C++ front-ends to convert such >>> initializers into a STRING_CST form. >>> >>> The goal of this work is to both enable existing optimizations for >>> such arrays, and to help detect bugs due to using non-nul terminated >>> arrays where nul-terminated strings are expected. The latter is >>> an extension of the GCC 8 _Wstringop-overflow and >>> -Wstringop-truncation warnings that help detect or prevent reading >>> past the end of dynamically created character arrays. Future work >>> includes detecting potential past-the-end reads from uninitialized >>> local character arrays. >> >> >>> && TYPE_MAIN_VARIANT (TREE_TYPE (valtype)) == char_type_node) >> >> >> Why? Don't we want this for other character types as well? > > It suppresses narrowing warnings for things like > > signed char a[] = { 0xff }; > > (there are a couple of tests that exercise this). Why is plain char different in this respect? Presumably one of char a[] = { -1 }; char b[] = { 0xff }; should give the same narrowing warning, depending on whether char is signed. > At the same time, STRING_CST is supposed to be able to represent > strings of any integer type so there should be a way to make it > work. On the flip side, recent discussions of changes in this > area suggest there may be bugs in the wide character handling of > STRING_CST so those would need to be fixed before relying on it > for robust support. > > In any case, if you have a suggestion for how to make it work for > at least the narrow character types I'll adjust the patch. I suppose braced_list_to_string should call check_narrowing for C++. Currently it uses tree_fits_shwi_p (signed host_wide_int) and then stores the extracted value in a host unsigned int, which is then converted to host char. Does the right thing happen for -fsigned-char or targets with a different character set? Jason ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-07 8:58 ` Jason Merrill @ 2018-08-07 23:04 ` Martin Sebor 2018-08-08 11:09 ` Jason Merrill 0 siblings, 1 reply; 43+ messages in thread From: Martin Sebor @ 2018-08-07 23:04 UTC (permalink / raw) To: Jason Merrill; +Cc: Gcc Patch List, Joseph Myers [-- Attachment #1: Type: text/plain, Size: 3011 bytes --] On 08/07/2018 02:57 AM, Jason Merrill wrote: > On Wed, Aug 1, 2018 at 12:49 AM, Martin Sebor <msebor@gmail.com> wrote: >> On 07/31/2018 07:38 AM, Jason Merrill wrote: >>> >>> On Tue, Jul 31, 2018 at 9:51 AM, Martin Sebor <msebor@gmail.com> wrote: >>>> >>>> The middle-end contains code to determine the lengths of constant >>>> character arrays initialized by string literals. The code is used >>>> in a number of optimizations and warnings. >>>> >>>> However, the code is unable to deal with constant arrays initialized >>>> using the braced initializer syntax, as in >>>> >>>> const char a[] = { '1', '2', '\0' }; >>>> >>>> The attached patch extends the C and C++ front-ends to convert such >>>> initializers into a STRING_CST form. >>>> >>>> The goal of this work is to both enable existing optimizations for >>>> such arrays, and to help detect bugs due to using non-nul terminated >>>> arrays where nul-terminated strings are expected. The latter is >>>> an extension of the GCC 8 _Wstringop-overflow and >>>> -Wstringop-truncation warnings that help detect or prevent reading >>>> past the end of dynamically created character arrays. Future work >>>> includes detecting potential past-the-end reads from uninitialized >>>> local character arrays. >>> >>> >>>> && TYPE_MAIN_VARIANT (TREE_TYPE (valtype)) == char_type_node) >>> >>> >>> Why? Don't we want this for other character types as well? >> >> It suppresses narrowing warnings for things like >> >> signed char a[] = { 0xff }; >> >> (there are a couple of tests that exercise this). > > Why is plain char different in this respect? Presumably one of > > char a[] = { -1 }; > char b[] = { 0xff }; > > should give the same narrowing warning, depending on whether char is signed. Right. I've added more tests to verify that it does. >> At the same time, STRING_CST is supposed to be able to represent >> strings of any integer type so there should be a way to make it >> work. On the flip side, recent discussions of changes in this >> area suggest there may be bugs in the wide character handling of >> STRING_CST so those would need to be fixed before relying on it >> for robust support. >> >> In any case, if you have a suggestion for how to make it work for >> at least the narrow character types I'll adjust the patch. > > I suppose braced_list_to_string should call check_narrowing for C++. I see. I've made that change. That has made it possible to convert arrays of all character types. Thanks! > Currently it uses tree_fits_shwi_p (signed host_wide_int) and then > stores the extracted value in a host unsigned int, which is then > converted to host char. Does the right thing happen for -fsigned-char > or targets with a different character set? I believe so. I've added tests for these too (ASCII and EBCDIC) and also changed the type of the extracted value to HWI to match (it doesn't change the results of the tests). Attached is an updated patch with these changes plus more tests as suggested by Joseph. Martin [-- Attachment #2: gcc-71625.diff --] [-- Type: text/x-patch, Size: 22717 bytes --] PR tree-optimization/71625 - missing strlen optimization on different array initialization style gcc/c/ChangeLog: PR tree-optimization/71625 * c-parser.c (c_parser_declaration_or_fndef): Call braced_list_to_string. gcc/c-family/ChangeLog: PR tree-optimization/71625 * c-common.c (braced_list_to_string): New function. * c-common.h (braced_list_to_string): Declare it. gcc/cp/ChangeLog: PR tree-optimization/71625 * parser.c (cp_parser_init_declarator): Call braced_list_to_string. (eval_check_narrowing): New function. gcc/testsuite/ChangeLog: PR tree-optimization/71625 * g++.dg/init/string2.C: New test. * g++.dg/init/string3.C: New test. * gcc.dg/strlenopt-55.c: New test. * gcc.dg/strlenopt-56.c: New test. Index: gcc/c/c-parser.c =================================================================== --- gcc/c/c-parser.c (revision 263372) +++ gcc/c/c-parser.c (working copy) @@ -2126,6 +2126,15 @@ c_parser_declaration_or_fndef (c_parser *parser, b if (d != error_mark_node) { maybe_warn_string_init (init_loc, TREE_TYPE (d), init); + + /* Try to convert a string CONSTRUCTOR into a STRING_CST. */ + tree valtype = TREE_TYPE (init.value); + if (TREE_CODE (init.value) == CONSTRUCTOR + && TREE_CODE (valtype) == ARRAY_TYPE + && TYPE_STRING_FLAG (TREE_TYPE (valtype))) + if (tree str = braced_list_to_string (valtype, init.value)) + init.value = str; + finish_decl (d, init_loc, init.value, init.original_type, asm_name); } Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c (revision 263372) +++ gcc/c-family/c-common.c (working copy) @@ -8509,4 +8509,84 @@ maybe_add_include_fixit (rich_location *richloc, c free (text); } +/* Attempt to convert a braced array initializer list CTOR for array + TYPE into a STRING_CST for convenience and efficiency. When non-null, + use EVAL to attempt to evalue constants (used by C++). Return + the converted string on success or null on failure. */ + +tree +braced_list_to_string (tree type, tree ctor, tree (*eval)(tree, tree)) +{ + /* If the array has an explicit bound, use it to constrain the size + of the string. If it doesn't, be sure to create a string that's + as long as implied by the index of the last zero specified via + a designator, as in: + const char a[] = { [7] = 0 }; */ + unsigned HOST_WIDE_INT maxelts = HOST_WIDE_INT_M1U; + if (tree nelts = TYPE_SIZE_UNIT (type)) + if (tree_fits_uhwi_p (nelts)) + { + maxelts = tree_to_uhwi (nelts); + maxelts /= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type))); + } + + unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (ctor); + tree eltype = TREE_TYPE (type); + + auto_vec<char> str; + str.reserve (nelts + 1); + + unsigned HOST_WIDE_INT i; + tree index, value; + + FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, index, value) + { + unsigned HOST_WIDE_INT idx = index ? tree_to_uhwi (index) : i; + + /* auto_vec is limited to UINT_MAX elements. */ + if (idx > UINT_MAX) + return NULL_TREE; + + /* Attempt to evaluate constants. */ + if (eval) + value = eval (eltype, value); + + /* Avoid non-constant initializers. */ + if (!tree_fits_shwi_p (value)) + return NULL_TREE; + + /* Skip over embedded nuls. */ + HOST_WIDE_INT val = tree_to_shwi (value); + if (!val && i + 1 < nelts) + continue; + + /* Bail if the CTOR has a block of more than 256 embedded nuls + due to implicitly initialized elements. */ + unsigned nelts = (idx - str.length ()) + 1; + if (nelts > 256) + return NULL_TREE; + + if (nelts > 1) + { + str.reserve (idx); + str.quick_grow_cleared (idx); + } + + if (idx > maxelts) + return NULL_TREE; + + str.safe_insert (idx, val); + } + + if (!nelts || str.length () < i) + /* Append a nul for the empty initializer { } and for the last + explicit initializer in the loop above that is a nul. */ + str.safe_push (0); + + /* Build a string literal but return the embedded STRING_CST. */ + tree res = build_string_literal (str.length (), str.begin ()); + res = TREE_OPERAND (TREE_OPERAND (res, 0), 0); + return res; +} + #include "gt-c-family-c-common.h" Index: gcc/c-family/c-common.h =================================================================== --- gcc/c-family/c-common.h (revision 263372) +++ gcc/c-family/c-common.h (working copy) @@ -1331,6 +1331,7 @@ extern void maybe_add_include_fixit (rich_location extern void maybe_suggest_missing_token_insertion (rich_location *richloc, enum cpp_ttype token_type, location_t prev_token_loc); +extern tree braced_list_to_string (tree, tree, tree (*)(tree, tree) = NULL); #if CHECKING_P namespace selftest { Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 263372) +++ gcc/cp/parser.c (working copy) @@ -19419,6 +19419,30 @@ strip_declarator_types (tree type, cp_declarator * return type; } +/* Attempt to determine the constant VALUE of integral type and convert + it to TYPE, issuing narrowing warnings/errors as necessary. Return + the constant result or null on failure. Callback for + braced_list_to_string. */ + +static tree +eval_check_narrowing (tree type, tree value) +{ + if (tree valtype = TREE_TYPE (value)) + { + if (TREE_CODE (valtype) != INTEGER_TYPE) + return NULL_TREE; + } + else + return NULL_TREE; + + value = scalar_constant_value (value); + if (!value) + return NULL_TREE; + + check_narrowing (type, value, tf_warning_or_error); + return value; +} + /* Declarators [gram.dcl.decl] */ /* Parse an init-declarator. @@ -19825,6 +19849,18 @@ cp_parser_init_declarator (cp_parser* parser, finish_lambda_scope (); if (initializer == error_mark_node) cp_parser_skip_to_end_of_statement (parser); + else if (decl) + { + /* Try to convert a string CONSTRUCTOR into a STRING_CST. */ + tree valtype = TREE_TYPE (decl); + if (TREE_CODE (valtype) == ARRAY_TYPE + && TYPE_STRING_FLAG (TREE_TYPE (valtype)) + && TREE_CODE (initializer) == CONSTRUCTOR + && TREE_TYPE (initializer) == init_list_type_node) + if (tree str = braced_list_to_string (valtype, initializer, + eval_check_narrowing)) + initializer = str; + } } } Index: gcc/testsuite/g++.dg/init/string2.C =================================================================== --- gcc/testsuite/g++.dg/init/string2.C (nonexistent) +++ gcc/testsuite/g++.dg/init/string2.C (working copy) @@ -0,0 +1,85 @@ +// PR tree-optimization/71625 - missing strlen optimization on different +// array initialization style +// +// Verify that strlen() calls with constant character array arguments +// initialized with string constants are folded. (This is a small +// subset of pr63989). +// { dg-do compile } +// { dg-options "-O0 -Wno-error=narrowing -fdump-tree-gimple" } + +#define A(expr) do { typedef char A[-1 + 2 * !!(expr)]; } while (0) + +const char a0[] = { 'a', 'b', 'c', '\0' }; + +int len0 () +{ + return __builtin_strlen (a0); +} + +// Verify that narrowing warnings are preserved. +const signed char +sa0[] = { 'a', 'b', 255, '\0' }; // { dg-warning "\\\[\(-Wnarrowing|-Woverflow\)" "" { target { ! c++98_only } } } + +int lens0 () +{ + return __builtin_strlen ((const char*)sa0); +} + +const unsigned char +ua0[] = { 'a', 'b', -1, '\0' }; // { dg-warning "\\\[\(-Wnarrowing|-Woverflow\)" "" { target { ! c++98_only } } } + +int lenu0 () +{ + return __builtin_strlen ((const char*)ua0); +} + +const char c = 0; +const char a1[] = { 'a', 'b', 'c', c }; + +int len1 () +{ + return __builtin_strlen (a1); +} + +const wchar_t ws4[] = { 1, 2, 3, 4 }; +const wchar_t ws7[] = { 1, 2, 3, 4, 0, 0, 0 }; +const wchar_t ws9[9] = { 1, 2, 3, 4, 0 }; + +void wsize () +{ + A (sizeof ws4 == 4 * sizeof *ws4); + A (ws4[0] == 1 && ws4[1] == 2 && ws4[2] == 3 && ws4[3] == 4); + + A (sizeof ws7 == 7 * sizeof *ws7); + A (ws7[0] == 1 && ws7[1] == 2 && ws7[2] == 3 && ws7[4] == 4 + && !ws7[5] && !ws7[6]); + + A (sizeof ws9 == 9 * sizeof *ws9); + A (ws9[0] == 1 && ws9[1] == 2 && ws9[2] == 3 && ws9[4] == 4 + && !ws9[5] && !ws9[6] && !ws9[7] && !ws9[8]); +} + +#if 0 + +// The following aren't handled. + +const char &cref = c; +const char a2[] = { 'a', 'b', 'c', cref }; + +int len2 () +{ + return __builtin_strlen (a2); +} + + +const char* const cptr = &cref; +const char a3[] = { 'a', 'b', 'c', *cptr }; + +int len3 () +{ + return __builtin_strlen (a3); +} + +#endif + +// { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } Index: gcc/testsuite/g++.dg/init/string3.C =================================================================== --- gcc/testsuite/g++.dg/init/string3.C (nonexistent) +++ gcc/testsuite/g++.dg/init/string3.C (working copy) @@ -0,0 +1,36 @@ +// PR tree-optimization/71625 - missing strlen optimization on different +// array initialization style +// +// Verify that strlen() call with a constant character array argument +// initialized with non-constant elements isn't folded. (This is a small +// subset of pr63989). +// +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-optimized" } + + +extern const char c; +const char a0[] = { 'a', 'b', 'c', c }; + +int len0 () +{ + return __builtin_strlen (a0); +} + +const char &ref = c; +const char a1[] = { 'a', 'b', 'c', ref }; + +int len1 () +{ + return __builtin_strlen (a1); +} + +const char* const ptr = &c; +const char a2[] = { 'a', 'b', 'c', *ptr }; + +int len2 () +{ + return __builtin_strlen (a2); +} + +// { dg-final { scan-tree-dump-times "strlen" 3 "optimized" } } Index: gcc/testsuite/gcc.dg/strlenopt-55.c =================================================================== --- gcc/testsuite/gcc.dg/strlenopt-55.c (nonexistent) +++ gcc/testsuite/gcc.dg/strlenopt-55.c (working copy) @@ -0,0 +1,230 @@ +/* PR tree-optimization/71625 - missing strlen optimization on different + array initialization style + + Verify that strlen() of braced initialized array is folded + { dg-do compile } + { dg-options "-O1 -Wall -fdump-tree-gimple -fdump-tree-optimized" } */ + +#include "strlenopt.h" + +#define S \ + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" \ + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \ + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \ + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" \ + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \ + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" \ + "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \ + "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \ + "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \ + "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \ + "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" \ + "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \ + "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" \ + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" + +/* Arrays of char, signed char, and unsigned char to verify that + the length and contents of all are the same as that of the string + literal above. */ + +const char c256[] = { + S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[8], S[9], S[10], + S[11], S[12], S[13], S[14], S[15], S[16], S[17], S[18], S[19], S[20], + S[21], S[22], S[23], S[24], S[25], S[26], S[27], S[28], S[29], S[30], + S[31], S[32], S[33], S[34], S[35], S[36], S[37], S[38], S[39], S[40], + S[41], S[42], S[43], S[44], S[45], S[46], S[47], S[48], S[49], S[50], + S[51], S[52], S[53], S[54], S[55], S[56], S[57], S[58], S[59], S[60], + S[61], S[62], S[63], S[64], S[65], S[66], S[67], S[68], S[69], S[70], + S[71], S[72], S[73], S[74], S[75], S[76], S[77], S[78], S[79], S[80], + S[81], S[82], S[83], S[84], S[85], S[86], S[87], S[88], S[89], S[90], + S[91], S[92], S[93], S[94], S[95], S[96], S[97], S[98], S[99], S[100], + S[101], S[102], S[103], S[104], S[105], S[106], S[107], S[108], S[109], + S[110], S[111], S[112], S[113], S[114], S[115], S[116], S[117], S[118], + S[119], S[120], S[121], S[122], S[123], S[124], S[125], S[126], S[127], + S[128], S[129], S[130], S[131], S[132], S[133], S[134], S[135], S[136], + S[137], S[138], S[139], S[140], S[141], S[142], S[143], S[144], S[145], + S[146], S[147], S[148], S[149], S[150], S[151], S[152], S[153], S[154], + S[155], S[156], S[157], S[158], S[159], S[160], S[161], S[162], S[163], + S[164], S[165], S[166], S[167], S[168], S[169], S[170], S[171], S[172], + S[173], S[174], S[175], S[176], S[177], S[178], S[179], S[180], S[181], + S[182], S[183], S[184], S[185], S[186], S[187], S[188], S[189], S[190], + S[191], S[192], S[193], S[194], S[195], S[196], S[197], S[198], S[199], + S[200], S[201], S[202], S[203], S[204], S[205], S[206], S[207], S[208], + S[209], S[210], S[211], S[212], S[213], S[214], S[215], S[216], S[217], + S[218], S[219], S[220], S[221], S[222], S[223], S[224], S[225], S[226], + S[227], S[228], S[229], S[230], S[231], S[232], S[233], S[234], S[235], + S[236], S[237], S[238], S[239], S[240], S[241], S[242], S[243], S[244], + S[245], S[246], S[247], S[248], S[249], S[250], S[251], S[252], S[253], + S[254], S[255] /* = NUL */ +}; + +const signed char sc256[] = { + S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[8], S[9], S[10], + S[11], S[12], S[13], S[14], S[15], S[16], S[17], S[18], S[19], S[20], + S[21], S[22], S[23], S[24], S[25], S[26], S[27], S[28], S[29], S[30], + S[31], S[32], S[33], S[34], S[35], S[36], S[37], S[38], S[39], S[40], + S[41], S[42], S[43], S[44], S[45], S[46], S[47], S[48], S[49], S[50], + S[51], S[52], S[53], S[54], S[55], S[56], S[57], S[58], S[59], S[60], + S[61], S[62], S[63], S[64], S[65], S[66], S[67], S[68], S[69], S[70], + S[71], S[72], S[73], S[74], S[75], S[76], S[77], S[78], S[79], S[80], + S[81], S[82], S[83], S[84], S[85], S[86], S[87], S[88], S[89], S[90], + S[91], S[92], S[93], S[94], S[95], S[96], S[97], S[98], S[99], S[100], + S[101], S[102], S[103], S[104], S[105], S[106], S[107], S[108], S[109], + S[110], S[111], S[112], S[113], S[114], S[115], S[116], S[117], S[118], + S[119], S[120], S[121], S[122], S[123], S[124], S[125], S[126], S[127], + S[128], S[129], S[130], S[131], S[132], S[133], S[134], S[135], S[136], + S[137], S[138], S[139], S[140], S[141], S[142], S[143], S[144], S[145], + S[146], S[147], S[148], S[149], S[150], S[151], S[152], S[153], S[154], + S[155], S[156], S[157], S[158], S[159], S[160], S[161], S[162], S[163], + S[164], S[165], S[166], S[167], S[168], S[169], S[170], S[171], S[172], + S[173], S[174], S[175], S[176], S[177], S[178], S[179], S[180], S[181], + S[182], S[183], S[184], S[185], S[186], S[187], S[188], S[189], S[190], + S[191], S[192], S[193], S[194], S[195], S[196], S[197], S[198], S[199], + S[200], S[201], S[202], S[203], S[204], S[205], S[206], S[207], S[208], + S[209], S[210], S[211], S[212], S[213], S[214], S[215], S[216], S[217], + S[218], S[219], S[220], S[221], S[222], S[223], S[224], S[225], S[226], + S[227], S[228], S[229], S[230], S[231], S[232], S[233], S[234], S[235], + S[236], S[237], S[238], S[239], S[240], S[241], S[242], S[243], S[244], + S[245], S[246], S[247], S[248], S[249], S[250], S[251], S[252], S[253], + S[254], S[255] /* = NUL */ +}; + +const unsigned char uc256[] = { + S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[8], S[9], S[10], + S[11], S[12], S[13], S[14], S[15], S[16], S[17], S[18], S[19], S[20], + S[21], S[22], S[23], S[24], S[25], S[26], S[27], S[28], S[29], S[30], + S[31], S[32], S[33], S[34], S[35], S[36], S[37], S[38], S[39], S[40], + S[41], S[42], S[43], S[44], S[45], S[46], S[47], S[48], S[49], S[50], + S[51], S[52], S[53], S[54], S[55], S[56], S[57], S[58], S[59], S[60], + S[61], S[62], S[63], S[64], S[65], S[66], S[67], S[68], S[69], S[70], + S[71], S[72], S[73], S[74], S[75], S[76], S[77], S[78], S[79], S[80], + S[81], S[82], S[83], S[84], S[85], S[86], S[87], S[88], S[89], S[90], + S[91], S[92], S[93], S[94], S[95], S[96], S[97], S[98], S[99], S[100], + S[101], S[102], S[103], S[104], S[105], S[106], S[107], S[108], S[109], + S[110], S[111], S[112], S[113], S[114], S[115], S[116], S[117], S[118], + S[119], S[120], S[121], S[122], S[123], S[124], S[125], S[126], S[127], + S[128], S[129], S[130], S[131], S[132], S[133], S[134], S[135], S[136], + S[137], S[138], S[139], S[140], S[141], S[142], S[143], S[144], S[145], + S[146], S[147], S[148], S[149], S[150], S[151], S[152], S[153], S[154], + S[155], S[156], S[157], S[158], S[159], S[160], S[161], S[162], S[163], + S[164], S[165], S[166], S[167], S[168], S[169], S[170], S[171], S[172], + S[173], S[174], S[175], S[176], S[177], S[178], S[179], S[180], S[181], + S[182], S[183], S[184], S[185], S[186], S[187], S[188], S[189], S[190], + S[191], S[192], S[193], S[194], S[195], S[196], S[197], S[198], S[199], + S[200], S[201], S[202], S[203], S[204], S[205], S[206], S[207], S[208], + S[209], S[210], S[211], S[212], S[213], S[214], S[215], S[216], S[217], + S[218], S[219], S[220], S[221], S[222], S[223], S[224], S[225], S[226], + S[227], S[228], S[229], S[230], S[231], S[232], S[233], S[234], S[235], + S[236], S[237], S[238], S[239], S[240], S[241], S[242], S[243], S[244], + S[245], S[246], S[247], S[248], S[249], S[250], S[251], S[252], S[253], + S[254], S[255] /* = NUL */ +}; + +const __CHAR16_TYPE__ c16_4[] = { + 1, 0x7fff, 0x8000, 0xffff, + 0x10000 /* { dg-warning "\\\[-Woverflow]" } */ +}; + +const char a2_implicit[2] = { }; +const char a3_implicit[3] = { }; + +const char a3_nul[3] = { 0 }; +const char a5_nul1[3] = { [1] = 0 }; +const char a7_nul2[3] = { [2] = 0 }; + +const char ax_2_nul[] = { '1', '2', '\0' }; +const char ax_3_nul[] = { '1', '2', '3', '\0' }; + +const char ax_3_des_nul[] = { [3] = 0, [2] = '3', [1] = '2', [0] = '1' }; + +const char ax_3[] = { '1', '2', '3' }; +const char a3_3[3] = { '1', '2', '3' }; + +const char ax_100_3[] = { '1', '2', '3', [100] = '\0' }; + +#define CONCAT(x, y) x ## y +#define CAT(x, y) CONCAT (x, y) +#define FAILNAME(name) CAT (call_ ## name ##_on_line_, __LINE__) + +#define FAIL(name) do { \ + extern void FAILNAME (name) (void); \ + FAILNAME (name)(); \ + } while (0) + +/* Macro to emit a call to funcation named + call_in_true_branch_not_eliminated_on_line_NNN() + for each call that's expected to be eliminated. The dg-final + scan-tree-dump-time directive at the bottom of the test verifies + that no such call appears in output. */ +#define ELIM(expr) \ + if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0 + +#define T(s, n) ELIM (strlen (s) == n) + +void test_nulstring (void) +{ + T (a2_implicit, 0); + T (a3_implicit, 0); + + T (a3_nul, 0); + T (a5_nul1, 0); + T (a7_nul2, 0); + + T (ax_2_nul, 2); + T (ax_3_nul, 3); + T (ax_3_des_nul, 3); + + T (ax_100_3, 3); + T (ax_100_3 + 4, 0); + ELIM (101 == sizeof ax_100_3); + ELIM ('\0' == ax_100_3[100]); + + /* Verify that all three character arrays have the same length + as the string literal they are initialized with. */ + T (S, 255); + T (c256, 255); + T ((const char*)sc256, 255); + T ((const char*)uc256, 255); + + /* Verify that all three character arrays have the same contents + as the string literal they are initialized with. */ + ELIM (0 == memcmp (c256, S, sizeof c256)); + ELIM (0 == memcmp (c256, (const char*)sc256, sizeof c256)); + ELIM (0 == memcmp (c256, (const char*)uc256, sizeof c256)); + + ELIM (0 == strcmp (c256, (const char*)sc256)); + ELIM (0 == strcmp (c256, (const char*)uc256)); + + /* Verify that the char16_t array has the expected contents. */ + ELIM (c16_4[0] == 1 && c16_4[1] == 0x7fff + && c16_4[2] == 0x8000 && c16_4[3] == 0xffff + && c16_4[4] == 0); +} + +/* Verify that excessively large initializers don't run out of + memory. Also verify that the they have the expected size and + contents. */ + +#define MAX (__PTRDIFF_MAX__ - 1) + +const char large_string[] = { 'a', [1234] = 'b', [MAX] = '\0' }; + +const void test_large_string_size (void) +{ + ELIM (sizeof large_string == MAX + 1); + + /* The following expressions are not folded without optimization. */ + ELIM ('a' == large_string[0]); + ELIM ('\0' == large_string[1233]); + ELIM ('b' == large_string[1234]); + ELIM ('\0' == large_string[1235]); + ELIM ('\0' == large_string[MAX - 1]); +} + + +/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } + { dg-final { scan-tree-dump-times "memcmp" 0 "gimple" } } + { dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } } + { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */ Index: gcc/testsuite/gcc.dg/strlenopt-56.c =================================================================== --- gcc/testsuite/gcc.dg/strlenopt-56.c (nonexistent) +++ gcc/testsuite/gcc.dg/strlenopt-56.c (working copy) @@ -0,0 +1,50 @@ +/* PR tree-optimization/71625 - conversion of braced initializers to strings + Verify that array elements have the expected values regardless of sign + and non-ASCII execution character set. + { dg-do compile } + { dg-require-iconv "IBM1047" } + { dg-options "-O -Wall -fexec-charset=IBM1047 -fdump-tree-gimple -fdump-tree-optimized" } */ + +#include "strlenopt.h" + +const char a[] = { 'a', 129, 0 }; +const signed char b[] = { 'b', 130, 0 }; +const unsigned char c[] = { 'c', 131, 0 }; + +const char s[] = "a\201"; +const signed char ss[] = "b\202"; +const unsigned char us[] = "c\203"; + + +#define A(expr) ((expr) ? (void)0 : __builtin_abort ()) + +void test_values (void) +{ + A (a[0] == a[1]); + A (a[1] == 'a'); + + A (b[0] == b[1]); + A (b[1] == (signed char)'b'); + + A (c[0] == c[1]); + A (c[1] == (unsigned char)'c'); +} + +void test_lengths (void) +{ + A (2 == strlen (a)); + A (2 == strlen ((const char*)b)); + A (2 == strlen ((const char*)c)); +} + +void test_contents (void) +{ + A (0 == strcmp (a, s)); + A (0 == strcmp ((const char*)b, (const char*)ss)); + A (0 == strcmp ((const char*)c, (const char*)us)); +} + + +/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } + { dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } } + { dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */ ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-07 23:04 ` Martin Sebor @ 2018-08-08 11:09 ` Jason Merrill 2018-08-09 0:17 ` Martin Sebor 0 siblings, 1 reply; 43+ messages in thread From: Jason Merrill @ 2018-08-08 11:09 UTC (permalink / raw) To: Martin Sebor; +Cc: Gcc Patch List, Joseph Myers On Wed, Aug 8, 2018 at 9:04 AM, Martin Sebor <msebor@gmail.com> wrote: > On 08/07/2018 02:57 AM, Jason Merrill wrote: >> >> On Wed, Aug 1, 2018 at 12:49 AM, Martin Sebor <msebor@gmail.com> wrote: >>> >>> On 07/31/2018 07:38 AM, Jason Merrill wrote: >>>> >>>> >>>> On Tue, Jul 31, 2018 at 9:51 AM, Martin Sebor <msebor@gmail.com> wrote: >>>>> >>>>> >>>>> The middle-end contains code to determine the lengths of constant >>>>> character arrays initialized by string literals. The code is used >>>>> in a number of optimizations and warnings. >>>>> >>>>> However, the code is unable to deal with constant arrays initialized >>>>> using the braced initializer syntax, as in >>>>> >>>>> const char a[] = { '1', '2', '\0' }; >>>>> >>>>> The attached patch extends the C and C++ front-ends to convert such >>>>> initializers into a STRING_CST form. >>>>> >>>>> The goal of this work is to both enable existing optimizations for >>>>> such arrays, and to help detect bugs due to using non-nul terminated >>>>> arrays where nul-terminated strings are expected. The latter is >>>>> an extension of the GCC 8 _Wstringop-overflow and >>>>> -Wstringop-truncation warnings that help detect or prevent reading >>>>> past the end of dynamically created character arrays. Future work >>>>> includes detecting potential past-the-end reads from uninitialized >>>>> local character arrays. >>>> >>>> >>>> >>>>> && TYPE_MAIN_VARIANT (TREE_TYPE (valtype)) == char_type_node) >>>> >>>> >>>> >>>> Why? Don't we want this for other character types as well? >>> >>> >>> It suppresses narrowing warnings for things like >>> >>> signed char a[] = { 0xff }; >>> >>> (there are a couple of tests that exercise this). >> >> >> Why is plain char different in this respect? Presumably one of >> >> char a[] = { -1 }; >> char b[] = { 0xff }; >> >> should give the same narrowing warning, depending on whether char is >> signed. > > > Right. I've added more tests to verify that it does. > >>> At the same time, STRING_CST is supposed to be able to represent >>> strings of any integer type so there should be a way to make it >>> work. On the flip side, recent discussions of changes in this >>> area suggest there may be bugs in the wide character handling of >>> STRING_CST so those would need to be fixed before relying on it >>> for robust support. >>> >>> In any case, if you have a suggestion for how to make it work for >>> at least the narrow character types I'll adjust the patch. >> >> >> I suppose braced_list_to_string should call check_narrowing for C++. > > > I see. I've made that change. That has made it possible to > convert arrays of all character types. Thanks! > >> Currently it uses tree_fits_shwi_p (signed host_wide_int) and then >> stores the extracted value in a host unsigned int, which is then >> converted to host char. Does the right thing happen for -fsigned-char >> or targets with a different character set? > > I believe so. I've added tests for these too (ASCII and EBCDIC) > and also changed the type of the extracted value to HWI to match > (it doesn't change the results of the tests). > > Attached is an updated patch with these changes plus more tests > as suggested by Joseph. Great. Can we also move the call to braced_list_to_string into check_initializer, so it works for templates as well? As a case just before the block that calls reshape_init seems appropriate. Jason ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-08 11:09 ` Jason Merrill @ 2018-08-09 0:17 ` Martin Sebor 2018-08-09 22:07 ` Joseph Myers ` (2 more replies) 0 siblings, 3 replies; 43+ messages in thread From: Martin Sebor @ 2018-08-09 0:17 UTC (permalink / raw) To: Jason Merrill; +Cc: Gcc Patch List, Joseph Myers [-- Attachment #1: Type: text/plain, Size: 4313 bytes --] On 08/08/2018 05:08 AM, Jason Merrill wrote: > On Wed, Aug 8, 2018 at 9:04 AM, Martin Sebor <msebor@gmail.com> wrote: >> On 08/07/2018 02:57 AM, Jason Merrill wrote: >>> >>> On Wed, Aug 1, 2018 at 12:49 AM, Martin Sebor <msebor@gmail.com> wrote: >>>> >>>> On 07/31/2018 07:38 AM, Jason Merrill wrote: >>>>> >>>>> >>>>> On Tue, Jul 31, 2018 at 9:51 AM, Martin Sebor <msebor@gmail.com> wrote: >>>>>> >>>>>> >>>>>> The middle-end contains code to determine the lengths of constant >>>>>> character arrays initialized by string literals. The code is used >>>>>> in a number of optimizations and warnings. >>>>>> >>>>>> However, the code is unable to deal with constant arrays initialized >>>>>> using the braced initializer syntax, as in >>>>>> >>>>>> const char a[] = { '1', '2', '\0' }; >>>>>> >>>>>> The attached patch extends the C and C++ front-ends to convert such >>>>>> initializers into a STRING_CST form. >>>>>> >>>>>> The goal of this work is to both enable existing optimizations for >>>>>> such arrays, and to help detect bugs due to using non-nul terminated >>>>>> arrays where nul-terminated strings are expected. The latter is >>>>>> an extension of the GCC 8 _Wstringop-overflow and >>>>>> -Wstringop-truncation warnings that help detect or prevent reading >>>>>> past the end of dynamically created character arrays. Future work >>>>>> includes detecting potential past-the-end reads from uninitialized >>>>>> local character arrays. >>>>> >>>>> >>>>> >>>>>> && TYPE_MAIN_VARIANT (TREE_TYPE (valtype)) == char_type_node) >>>>> >>>>> >>>>> >>>>> Why? Don't we want this for other character types as well? >>>> >>>> >>>> It suppresses narrowing warnings for things like >>>> >>>> signed char a[] = { 0xff }; >>>> >>>> (there are a couple of tests that exercise this). >>> >>> >>> Why is plain char different in this respect? Presumably one of >>> >>> char a[] = { -1 }; >>> char b[] = { 0xff }; >>> >>> should give the same narrowing warning, depending on whether char is >>> signed. >> >> >> Right. I've added more tests to verify that it does. >> >>>> At the same time, STRING_CST is supposed to be able to represent >>>> strings of any integer type so there should be a way to make it >>>> work. On the flip side, recent discussions of changes in this >>>> area suggest there may be bugs in the wide character handling of >>>> STRING_CST so those would need to be fixed before relying on it >>>> for robust support. >>>> >>>> In any case, if you have a suggestion for how to make it work for >>>> at least the narrow character types I'll adjust the patch. >>> >>> >>> I suppose braced_list_to_string should call check_narrowing for C++. >> >> >> I see. I've made that change. That has made it possible to >> convert arrays of all character types. Thanks! >> >>> Currently it uses tree_fits_shwi_p (signed host_wide_int) and then >>> stores the extracted value in a host unsigned int, which is then >>> converted to host char. Does the right thing happen for -fsigned-char >>> or targets with a different character set? >> >> I believe so. I've added tests for these too (ASCII and EBCDIC) >> and also changed the type of the extracted value to HWI to match >> (it doesn't change the results of the tests). >> >> Attached is an updated patch with these changes plus more tests >> as suggested by Joseph. > > Great. Can we also move the call to braced_list_to_string into > check_initializer, so it works for templates as well? As a case just > before the block that calls reshape_init seems appropriate. Done in the attached patch. I've also avoided dealing with zero-length arrays and added tests to make sure their size stays is regardless of the form of their initializer and the appropriate warnings are issued. Using build_string() rather than build_string_literal() needed a tweak in digest_init_r(). It didn't break anything but since the array type may not have a domain yet, neither will the string. It looks like that may get adjusted later on but I've temporarily guarded the code with #if 1. If the change is fine I'll remove the #if before committing. This initial patch only handles narrow character initializers (i.e., those with TYPE_STRING_FLAG set). Once this gets some exposure I'd like to extend it to other character types, including wchar_t. Martin [-- Attachment #2: gcc-71625.diff --] [-- Type: text/x-patch, Size: 27489 bytes --] PR tree-optimization/71625 - missing strlen optimization on different array initialization style gcc/c/ChangeLog: PR tree-optimization/71625 * c-parser.c (c_parser_declaration_or_fndef): Call braced_list_to_string. gcc/c-family/ChangeLog: PR tree-optimization/71625 * c-common.c (braced_list_to_string): New function. * c-common.h (braced_list_to_string): Declare it. gcc/cp/ChangeLog: PR tree-optimization/71625 * decl.c (check_initializer): Call braced_list_to_string. (eval_check_narrowing): New function. * gcc/cp/typeck2.c (digest_init_r): Accept strings literals as initilizers for all narrow character types. gcc/testsuite/ChangeLog: PR tree-optimization/71625 * g++.dg/init/string2.C: New test. * g++.dg/init/string3.C: New test. * g++.dg/init/string4.C: New test. * gcc.dg/init-string-3.c: New test. * gcc.dg/strlenopt-55.c: New test. * gcc.dg/strlenopt-56.c: New test. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index d919605..b10d9c9 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -8509,4 +8509,102 @@ maybe_add_include_fixit (rich_location *richloc, const char *header) free (text); } +/* Attempt to convert a braced array initializer list CTOR for array + TYPE into a STRING_CST for convenience and efficiency. When non-null, + use EVAL to attempt to evalue constants (used by C++). Return + the converted string on success or null on failure. */ + +tree +braced_list_to_string (tree type, tree ctor, tree (*eval)(tree, tree)) +{ + unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (ctor); + + /* If the array has an explicit bound, use it to constrain the size + of the string. If it doesn't, be sure to create a string that's + as long as implied by the index of the last zero specified via + a designator, as in: + const char a[] = { [7] = 0 }; */ + unsigned HOST_WIDE_INT maxelts = HOST_WIDE_INT_M1U; + if (tree size = TYPE_SIZE_UNIT (type)) + { + if (tree_fits_uhwi_p (size)) + { + maxelts = tree_to_uhwi (size); + maxelts /= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type))); + + /* Avoid converting initializers for zero-length arrays. */ + if (!maxelts) + return NULL_TREE; + } + } + else if (!nelts) + /* Avoid handling the undefined/erroneous case of an empty + initializer for an arrays with unspecified bound. */ + return NULL_TREE; + + tree eltype = TREE_TYPE (type); + + auto_vec<char> str; + str.reserve (nelts + 1); + + unsigned HOST_WIDE_INT i; + tree index, value; + + FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, index, value) + { + unsigned HOST_WIDE_INT idx = index ? tree_to_uhwi (index) : i; + + /* auto_vec is limited to UINT_MAX elements. */ + if (idx > UINT_MAX) + return NULL_TREE; + + /* Attempt to evaluate constants. */ + if (eval) + value = eval (eltype, value); + + /* Avoid non-constant initializers. */ + if (!tree_fits_shwi_p (value)) + return NULL_TREE; + + /* Skip over embedded nuls except the last one (initializer + elements are in ascending order of indices). */ + HOST_WIDE_INT val = tree_to_shwi (value); + if (!val && i + 1 < nelts) + continue; + + /* Bail if the CTOR has a block of more than 256 embedded nuls + due to implicitly initialized elements. */ + unsigned nchars = (idx - str.length ()) + 1; + if (nchars > 256) + return NULL_TREE; + + if (nchars > 1) + { + str.reserve (idx); + str.quick_grow_cleared (idx); + } + + if (idx > maxelts) + return NULL_TREE; + + str.safe_insert (idx, val); + } + + if (!nelts) + /* Append a nul for the empty initializer { }. */ + str.safe_push (0); + +#if 1 + /* Build a STRING_CST with the same type as the array, which + may be an array of unknown bound. */ + tree res = build_string (str.length (), str.begin ()); + TREE_TYPE (res) = type; +#else + /* Build a string literal but return the embedded STRING_CST. */ + tree res = build_string_literal (str.length (), str.begin (), eltype); + res = TREE_OPERAND (TREE_OPERAND (res, 0), 0); +#endif + return res; +} + #include "gt-c-family-c-common.h" diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index fcec95b..8a802bb 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1331,6 +1331,7 @@ extern void maybe_add_include_fixit (rich_location *, const char *); extern void maybe_suggest_missing_token_insertion (rich_location *richloc, enum cpp_ttype token_type, location_t prev_token_loc); +extern tree braced_list_to_string (tree, tree, tree (*)(tree, tree) = NULL); #if CHECKING_P namespace selftest { diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 7a92628..5ad4f57 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -2126,6 +2126,15 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, if (d != error_mark_node) { maybe_warn_string_init (init_loc, TREE_TYPE (d), init); + + /* Try to convert a string CONSTRUCTOR into a STRING_CST. */ + tree valtype = TREE_TYPE (init.value); + if (TREE_CODE (init.value) == CONSTRUCTOR + && TREE_CODE (valtype) == ARRAY_TYPE + && TYPE_STRING_FLAG (TREE_TYPE (valtype))) + if (tree str = braced_list_to_string (valtype, init.value)) + init.value = str; + finish_decl (d, init_loc, init.value, init.original_type, asm_name); } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 78ebbde..d2c5b5d 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6282,6 +6282,30 @@ build_aggr_init_full_exprs (tree decl, tree init, int flags) return build_aggr_init (decl, init, flags, tf_warning_or_error); } +/* Attempt to determine the constant VALUE of integral type and convert + it to TYPE, issuing narrowing warnings/errors as necessary. Return + the constant result or null on failure. Callback for + braced_list_to_string. */ + +static tree +eval_check_narrowing (tree type, tree value) +{ + if (tree valtype = TREE_TYPE (value)) + { + if (TREE_CODE (valtype) != INTEGER_TYPE) + return NULL_TREE; + } + else + return NULL_TREE; + + value = scalar_constant_value (value); + if (!value) + return NULL_TREE; + + check_narrowing (type, value, tf_warning_or_error); + return value; +} + /* Verify INIT (the initializer for DECL), and record the initialization in DECL_INITIAL, if appropriate. CLEANUP is as for grok_reference_init. @@ -6397,7 +6421,18 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups) } else { - init = reshape_init (type, init, tf_warning_or_error); + /* Try to convert a string CONSTRUCTOR into a STRING_CST. */ + tree valtype = TREE_TYPE (decl); + if (TREE_CODE (valtype) == ARRAY_TYPE + && TYPE_STRING_FLAG (TREE_TYPE (valtype)) + && TREE_CODE (init) == CONSTRUCTOR + && TREE_TYPE (init) == init_list_type_node) + if (tree str = braced_list_to_string (valtype, init, + eval_check_narrowing)) + init = str; + + if (TREE_CODE (init) != STRING_CST) + init = reshape_init (type, init, tf_warning_or_error); flags |= LOOKUP_NO_NARROWING; } } diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 7763d53..72515d9 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1056,7 +1056,9 @@ digest_init_r (tree type, tree init, int nested, int flags, if (TYPE_PRECISION (typ1) == BITS_PER_UNIT) { - if (char_type != char_type_node) + if (char_type != char_type_node + && char_type != signed_char_type_node + && char_type != unsigned_char_type_node) { if (complain & tf_error) error_at (loc, "char-array initialized from wide string"); diff --git a/gcc/testsuite/g++.dg/init/string2.C b/gcc/testsuite/g++.dg/init/string2.C new file mode 100644 index 0000000..5da13bd --- /dev/null +++ b/gcc/testsuite/g++.dg/init/string2.C @@ -0,0 +1,104 @@ +// PR tree-optimization/71625 - missing strlen optimization on different +// array initialization style +// +// Verify that strlen() calls with constant character array arguments +// initialized with string constants are folded. (This is a small +// subset of pr71625). +// { dg-do compile } +// { dg-options "-O0 -Wno-error=narrowing -fdump-tree-gimple" } + +#define A(expr) do { typedef char A[-1 + 2 * !!(expr)]; } while (0) + +/* This is undefined but accepted without -Wpedantic. Verify that + the size is zero. */ +const char ax[] = { }; + +void size0 () +{ + A (sizeof ax == 0); +} + +const char a0[] = { 'a', 'b', 'c', '\0' }; + +int len0 () +{ + return __builtin_strlen (a0); +} + +// Verify that narrowing warnings are preserved. +const signed char +sa0[] = { 'a', 'b', 255, '\0' }; // { dg-warning "\\\[\(-Wnarrowing|-Woverflow\)" "" { target { ! c++98_only } } } + +int lens0 () +{ + return __builtin_strlen ((const char*)sa0); +} + +const unsigned char +ua0[] = { 'a', 'b', -1, '\0' }; // { dg-warning "\\\[\(-Wnarrowing|-Woverflow\)" "" { target { ! c++98_only } } } + +int lenu0 () +{ + return __builtin_strlen ((const char*)ua0); +} + +const char c = 0; +const char a1[] = { 'a', 'b', 'c', c }; + +int len1 () +{ + return __builtin_strlen (a1); +} + +template <class T> +int tmplen () +{ + static const T + a[] = { 1, 2, 333, 0 }; // { dg-warning "\\\[\(-Wnarrowing|-Woverflow\)" "" { target { ! c++98_only } } } + return __builtin_strlen (a); +} + +template int tmplen<char>(); + +const wchar_t ws4[] = { 1, 2, 3, 4 }; +const wchar_t ws7[] = { 1, 2, 3, 4, 0, 0, 0 }; +const wchar_t ws9[9] = { 1, 2, 3, 4, 0 }; + +void wsize () +{ + A (sizeof ws4 == 4 * sizeof *ws4); + A (ws4[0] == 1 && ws4[1] == 2 && ws4[2] == 3 && ws4[3] == 4); + + A (sizeof ws7 == 7 * sizeof *ws7); + A (ws7[0] == 1 && ws7[1] == 2 && ws7[2] == 3 && ws7[4] == 4 + && !ws7[5] && !ws7[6]); + + A (sizeof ws9 == 9 * sizeof *ws9); + A (ws9[0] == 1 && ws9[1] == 2 && ws9[2] == 3 && ws9[4] == 4 + && !ws9[5] && !ws9[6] && !ws9[7] && !ws9[8]); +} + +#if 0 + +// The following aren't handled. + +const char &cref = c; +const char a2[] = { 'a', 'b', 'c', cref }; + +int len2 () +{ + return __builtin_strlen (a2); +} + + +const char* const cptr = &cref; +const char a3[] = { 'a', 'b', 'c', *cptr }; + +int len3 () +{ + return __builtin_strlen (a3); +} + +#endif + +// { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } diff --git a/gcc/testsuite/g++.dg/init/string3.C b/gcc/testsuite/g++.dg/init/string3.C new file mode 100644 index 0000000..8212e81 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/string3.C @@ -0,0 +1,35 @@ +// PR tree-optimization/71625 - missing strlen optimization on different +// array initialization style +// +// Verify that strlen() call with a constant character array argument +// initialized with non-constant elements isn't folded. +// +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-optimized" } + + +extern const char c; +const char a0[] = { 'a', 'b', 'c', c }; + +int len0 () +{ + return __builtin_strlen (a0); +} + +const char &ref = c; +const char a1[] = { 'a', 'b', 'c', ref }; + +int len1 () +{ + return __builtin_strlen (a1); +} + +const char* const ptr = &c; +const char a2[] = { 'a', 'b', 'c', *ptr }; + +int len2 () +{ + return __builtin_strlen (a2); +} + +// { dg-final { scan-tree-dump-times "strlen" 3 "optimized" } } diff --git a/gcc/testsuite/g++.dg/init/string4.C b/gcc/testsuite/g++.dg/init/string4.C new file mode 100644 index 0000000..5df4176 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/string4.C @@ -0,0 +1,60 @@ +// PR tree-optimization/71625 - missing strlen optimization on different +// array initialization style + +// Verify that zero-length array initialization results in the expected +// array sizes and in the expected diagnostics. See init-string-3.c +// for the corresponding C test. + +// { dg-do compile } +// { dg-options "-Wall -Wno-unused-local-typedefs -fpermissive" } + +#define A(expr) typedef char A[-1 + 2 * !!(expr)]; + +const char a[] = { }; + +A (sizeof a == 0); + + +const char b[0] = { }; + +A (sizeof b == 0); + +// Also verify that the error is "too many initializers for +// 'const char [0]'" and not "initializer-string is too long." +const char c[0] = { 1 }; // { dg-error "too many initializers for .const char \\\[0]" } + +A (sizeof c == 0); + + +void test_auto_empty (void) +{ + const char a[] = { }; + + A (sizeof a == 0); +} + +void test_auto_zero_length (void) +{ + const char a[0] = { }; + + A (sizeof a == 0); + + const char b[0] = { 0 }; // { dg-error "too many initializers" } + + A (sizeof b == 0); + + const char c[0] = ""; // { dg-warning "too long" } + + A (sizeof c == 0); +} + + +void test_compound_zero_length (void) +{ + A (sizeof (const char[]){ } == 0); + A (sizeof (const char[0]){ } == 0); + A (sizeof (const char[0]){ 0 } == 0); // { dg-error "too many" } + A (sizeof (const char[0]){ 1 } == 0); // { dg-error "too many" } + A (sizeof (const char[0]){ "" } == 0); // { dg-warning "too long" } + A (sizeof (const char[0]){ "1" } == 0); // { dg-warning "too long" } +} diff --git a/gcc/testsuite/gcc.dg/init-string-3.c b/gcc/testsuite/gcc.dg/init-string-3.c new file mode 100644 index 0000000..e955f2e --- /dev/null +++ b/gcc/testsuite/gcc.dg/init-string-3.c @@ -0,0 +1,58 @@ +/* PR tree-optimization/71625 - missing strlen optimization on different + array initialization style + + Verify that zero-length array initialization results in the expected + array sizes. + + { dg-do compile } + { dg-options "-Wall -Wno-unused-local-typedefs" } */ + +#define A(expr) typedef char A[-1 + 2 * !!(expr)]; + +const char a[] = { }; + +A (sizeof a == 0); + + +const char b[0] = { }; + +A (sizeof b == 0); + + +const char c[0] = { 1 }; /* { dg-warning "excess elements" } */ + +A (sizeof c == 0); + + +void test_auto_empty (void) +{ + const char a[] = { }; + + A (sizeof a == 0); +} + +void test_auto_zero_length (void) +{ + const char a[0] = { }; + + A (sizeof a == 0); + + const char b[0] = { 0 }; /* { dg-warning "excess elements" } */ + + A (sizeof b == 0); + + const char c[0] = ""; + + A (sizeof c == 0); +} + + +void test_compound_zero_length (void) +{ + A (sizeof (const char[]){ } == 0); + A (sizeof (const char[0]){ } == 0); + A (sizeof (const char[0]){ 0 } == 0); /* { dg-warning "excess elements" } */ + A (sizeof (const char[0]){ 1 } == 0); /* { dg-warning "excess elements" } */ + A (sizeof (const char[0]){ "" } == 0); + A (sizeof (const char[0]){ "1" } == 0); /* { dg-warning "too long" } */ +} diff --git a/gcc/testsuite/gcc.dg/strlenopt-55.c b/gcc/testsuite/gcc.dg/strlenopt-55.c new file mode 100644 index 0000000..d5a0295 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-55.c @@ -0,0 +1,230 @@ +/* PR tree-optimization/71625 - missing strlen optimization on different + array initialization style + + Verify that strlen() of braced initialized array is folded + { dg-do compile } + { dg-options "-O1 -Wall -fdump-tree-gimple -fdump-tree-optimized" } */ + +#include "strlenopt.h" + +#define S \ + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" \ + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \ + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \ + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" \ + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \ + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" \ + "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \ + "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \ + "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \ + "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \ + "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" \ + "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \ + "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" \ + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" + +/* Arrays of char, signed char, and unsigned char to verify that + the length and contents of all are the same as that of the string + literal above. */ + +const char c256[] = { + S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[8], S[9], S[10], + S[11], S[12], S[13], S[14], S[15], S[16], S[17], S[18], S[19], S[20], + S[21], S[22], S[23], S[24], S[25], S[26], S[27], S[28], S[29], S[30], + S[31], S[32], S[33], S[34], S[35], S[36], S[37], S[38], S[39], S[40], + S[41], S[42], S[43], S[44], S[45], S[46], S[47], S[48], S[49], S[50], + S[51], S[52], S[53], S[54], S[55], S[56], S[57], S[58], S[59], S[60], + S[61], S[62], S[63], S[64], S[65], S[66], S[67], S[68], S[69], S[70], + S[71], S[72], S[73], S[74], S[75], S[76], S[77], S[78], S[79], S[80], + S[81], S[82], S[83], S[84], S[85], S[86], S[87], S[88], S[89], S[90], + S[91], S[92], S[93], S[94], S[95], S[96], S[97], S[98], S[99], S[100], + S[101], S[102], S[103], S[104], S[105], S[106], S[107], S[108], S[109], + S[110], S[111], S[112], S[113], S[114], S[115], S[116], S[117], S[118], + S[119], S[120], S[121], S[122], S[123], S[124], S[125], S[126], S[127], + S[128], S[129], S[130], S[131], S[132], S[133], S[134], S[135], S[136], + S[137], S[138], S[139], S[140], S[141], S[142], S[143], S[144], S[145], + S[146], S[147], S[148], S[149], S[150], S[151], S[152], S[153], S[154], + S[155], S[156], S[157], S[158], S[159], S[160], S[161], S[162], S[163], + S[164], S[165], S[166], S[167], S[168], S[169], S[170], S[171], S[172], + S[173], S[174], S[175], S[176], S[177], S[178], S[179], S[180], S[181], + S[182], S[183], S[184], S[185], S[186], S[187], S[188], S[189], S[190], + S[191], S[192], S[193], S[194], S[195], S[196], S[197], S[198], S[199], + S[200], S[201], S[202], S[203], S[204], S[205], S[206], S[207], S[208], + S[209], S[210], S[211], S[212], S[213], S[214], S[215], S[216], S[217], + S[218], S[219], S[220], S[221], S[222], S[223], S[224], S[225], S[226], + S[227], S[228], S[229], S[230], S[231], S[232], S[233], S[234], S[235], + S[236], S[237], S[238], S[239], S[240], S[241], S[242], S[243], S[244], + S[245], S[246], S[247], S[248], S[249], S[250], S[251], S[252], S[253], + S[254], S[255] /* = NUL */ +}; + +const signed char sc256[] = { + S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[8], S[9], S[10], + S[11], S[12], S[13], S[14], S[15], S[16], S[17], S[18], S[19], S[20], + S[21], S[22], S[23], S[24], S[25], S[26], S[27], S[28], S[29], S[30], + S[31], S[32], S[33], S[34], S[35], S[36], S[37], S[38], S[39], S[40], + S[41], S[42], S[43], S[44], S[45], S[46], S[47], S[48], S[49], S[50], + S[51], S[52], S[53], S[54], S[55], S[56], S[57], S[58], S[59], S[60], + S[61], S[62], S[63], S[64], S[65], S[66], S[67], S[68], S[69], S[70], + S[71], S[72], S[73], S[74], S[75], S[76], S[77], S[78], S[79], S[80], + S[81], S[82], S[83], S[84], S[85], S[86], S[87], S[88], S[89], S[90], + S[91], S[92], S[93], S[94], S[95], S[96], S[97], S[98], S[99], S[100], + S[101], S[102], S[103], S[104], S[105], S[106], S[107], S[108], S[109], + S[110], S[111], S[112], S[113], S[114], S[115], S[116], S[117], S[118], + S[119], S[120], S[121], S[122], S[123], S[124], S[125], S[126], S[127], + S[128], S[129], S[130], S[131], S[132], S[133], S[134], S[135], S[136], + S[137], S[138], S[139], S[140], S[141], S[142], S[143], S[144], S[145], + S[146], S[147], S[148], S[149], S[150], S[151], S[152], S[153], S[154], + S[155], S[156], S[157], S[158], S[159], S[160], S[161], S[162], S[163], + S[164], S[165], S[166], S[167], S[168], S[169], S[170], S[171], S[172], + S[173], S[174], S[175], S[176], S[177], S[178], S[179], S[180], S[181], + S[182], S[183], S[184], S[185], S[186], S[187], S[188], S[189], S[190], + S[191], S[192], S[193], S[194], S[195], S[196], S[197], S[198], S[199], + S[200], S[201], S[202], S[203], S[204], S[205], S[206], S[207], S[208], + S[209], S[210], S[211], S[212], S[213], S[214], S[215], S[216], S[217], + S[218], S[219], S[220], S[221], S[222], S[223], S[224], S[225], S[226], + S[227], S[228], S[229], S[230], S[231], S[232], S[233], S[234], S[235], + S[236], S[237], S[238], S[239], S[240], S[241], S[242], S[243], S[244], + S[245], S[246], S[247], S[248], S[249], S[250], S[251], S[252], S[253], + S[254], S[255] /* = NUL */ +}; + +const unsigned char uc256[] = { + S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[8], S[9], S[10], + S[11], S[12], S[13], S[14], S[15], S[16], S[17], S[18], S[19], S[20], + S[21], S[22], S[23], S[24], S[25], S[26], S[27], S[28], S[29], S[30], + S[31], S[32], S[33], S[34], S[35], S[36], S[37], S[38], S[39], S[40], + S[41], S[42], S[43], S[44], S[45], S[46], S[47], S[48], S[49], S[50], + S[51], S[52], S[53], S[54], S[55], S[56], S[57], S[58], S[59], S[60], + S[61], S[62], S[63], S[64], S[65], S[66], S[67], S[68], S[69], S[70], + S[71], S[72], S[73], S[74], S[75], S[76], S[77], S[78], S[79], S[80], + S[81], S[82], S[83], S[84], S[85], S[86], S[87], S[88], S[89], S[90], + S[91], S[92], S[93], S[94], S[95], S[96], S[97], S[98], S[99], S[100], + S[101], S[102], S[103], S[104], S[105], S[106], S[107], S[108], S[109], + S[110], S[111], S[112], S[113], S[114], S[115], S[116], S[117], S[118], + S[119], S[120], S[121], S[122], S[123], S[124], S[125], S[126], S[127], + S[128], S[129], S[130], S[131], S[132], S[133], S[134], S[135], S[136], + S[137], S[138], S[139], S[140], S[141], S[142], S[143], S[144], S[145], + S[146], S[147], S[148], S[149], S[150], S[151], S[152], S[153], S[154], + S[155], S[156], S[157], S[158], S[159], S[160], S[161], S[162], S[163], + S[164], S[165], S[166], S[167], S[168], S[169], S[170], S[171], S[172], + S[173], S[174], S[175], S[176], S[177], S[178], S[179], S[180], S[181], + S[182], S[183], S[184], S[185], S[186], S[187], S[188], S[189], S[190], + S[191], S[192], S[193], S[194], S[195], S[196], S[197], S[198], S[199], + S[200], S[201], S[202], S[203], S[204], S[205], S[206], S[207], S[208], + S[209], S[210], S[211], S[212], S[213], S[214], S[215], S[216], S[217], + S[218], S[219], S[220], S[221], S[222], S[223], S[224], S[225], S[226], + S[227], S[228], S[229], S[230], S[231], S[232], S[233], S[234], S[235], + S[236], S[237], S[238], S[239], S[240], S[241], S[242], S[243], S[244], + S[245], S[246], S[247], S[248], S[249], S[250], S[251], S[252], S[253], + S[254], S[255] /* = NUL */ +}; + +const __CHAR16_TYPE__ c16_4[] = { + 1, 0x7fff, 0x8000, 0xffff, + 0x10000 /* { dg-warning "\\\[-Woverflow]" } */ +}; + +const char a2_implicit[2] = { }; +const char a3_implicit[3] = { }; + +const char a3_nul[3] = { 0 }; +const char a5_nul1[3] = { [1] = 0 }; +const char a7_nul2[3] = { [2] = 0 }; + +const char ax_2_nul[] = { '1', '2', '\0' }; +const char ax_3_nul[] = { '1', '2', '3', '\0' }; + +const char ax_3_des_nul[] = { [3] = 0, [2] = '3', [1] = '2', [0] = '1' }; + +const char ax_3[] = { '1', '2', '3' }; +const char a3_3[3] = { '1', '2', '3' }; + +const char ax_100_3[] = { '1', '2', '3', [100] = '\0' }; + +#define CONCAT(x, y) x ## y +#define CAT(x, y) CONCAT (x, y) +#define FAILNAME(name) CAT (call_ ## name ##_on_line_, __LINE__) + +#define FAIL(name) do { \ + extern void FAILNAME (name) (void); \ + FAILNAME (name)(); \ + } while (0) + +/* Macro to emit a call to funcation named + call_in_true_branch_not_eliminated_on_line_NNN() + for each call that's expected to be eliminated. The dg-final + scan-tree-dump-time directive at the bottom of the test verifies + that no such call appears in output. */ +#define ELIM(expr) \ + if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0 + +#define T(s, n) ELIM (strlen (s) == n) + +void test_nulstring (void) +{ + T (a2_implicit, 0); + T (a3_implicit, 0); + + T (a3_nul, 0); + T (a5_nul1, 0); + T (a7_nul2, 0); + + T (ax_2_nul, 2); + T (ax_3_nul, 3); + T (ax_3_des_nul, 3); + + T (ax_100_3, 3); + T (ax_100_3 + 4, 0); + ELIM (101 == sizeof ax_100_3); + ELIM ('\0' == ax_100_3[100]); + + /* Verify that all three character arrays have the same length + as the string literal they are initialized with. */ + T (S, 255); + T (c256, 255); + T ((const char*)sc256, 255); + T ((const char*)uc256, 255); + + /* Verify that all three character arrays have the same contents + as the string literal they are initialized with. */ + ELIM (0 == memcmp (c256, S, sizeof c256)); + ELIM (0 == memcmp (c256, (const char*)sc256, sizeof c256)); + ELIM (0 == memcmp (c256, (const char*)uc256, sizeof c256)); + + ELIM (0 == strcmp (c256, (const char*)sc256)); + ELIM (0 == strcmp (c256, (const char*)uc256)); + + /* Verify that the char16_t array has the expected contents. */ + ELIM (c16_4[0] == 1 && c16_4[1] == 0x7fff + && c16_4[2] == 0x8000 && c16_4[3] == 0xffff + && c16_4[4] == 0); +} + +/* Verify that excessively large initializers don't run out of + memory. Also verify that the they have the expected size and + contents. */ + +#define MAX (__PTRDIFF_MAX__ - 1) + +const char large_string[] = { 'a', [1234] = 'b', [MAX] = '\0' }; + +const void test_large_string_size (void) +{ + ELIM (sizeof large_string == MAX + 1); + + /* The following expressions are not folded without optimization. */ + ELIM ('a' == large_string[0]); + ELIM ('\0' == large_string[1233]); + ELIM ('b' == large_string[1234]); + ELIM ('\0' == large_string[1235]); + ELIM ('\0' == large_string[MAX - 1]); +} + + +/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } + { dg-final { scan-tree-dump-times "memcmp" 0 "gimple" } } + { dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } } + { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-56.c b/gcc/testsuite/gcc.dg/strlenopt-56.c new file mode 100644 index 0000000..39a532b --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-56.c @@ -0,0 +1,50 @@ +/* PR tree-optimization/71625 - conversion of braced initializers to strings + Verify that array elements have the expected values regardless of sign + and non-ASCII execution character set. + { dg-do compile } + { dg-require-iconv "IBM1047" } + { dg-options "-O -Wall -fexec-charset=IBM1047 -fdump-tree-gimple -fdump-tree-optimized" } */ + +#include "strlenopt.h" + +const char a[] = { 'a', 129, 0 }; +const signed char b[] = { 'b', 130, 0 }; +const unsigned char c[] = { 'c', 131, 0 }; + +const char s[] = "a\201"; +const signed char ss[] = "b\202"; +const unsigned char us[] = "c\203"; + + +#define A(expr) ((expr) ? (void)0 : __builtin_abort ()) + +void test_values (void) +{ + A (a[0] == a[1]); + A (a[1] == 'a'); + + A (b[0] == b[1]); + A (b[1] == (signed char)'b'); + + A (c[0] == c[1]); + A (c[1] == (unsigned char)'c'); +} + +void test_lengths (void) +{ + A (2 == strlen (a)); + A (2 == strlen ((const char*)b)); + A (2 == strlen ((const char*)c)); +} + +void test_contents (void) +{ + A (0 == strcmp (a, s)); + A (0 == strcmp ((const char*)b, (const char*)ss)); + A (0 == strcmp ((const char*)c, (const char*)us)); +} + + +/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } + { dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } } + { dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */ ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-09 0:17 ` Martin Sebor @ 2018-08-09 22:07 ` Joseph Myers 2018-08-13 10:36 ` Jason Merrill 2018-08-14 13:27 ` James Greenhalgh 2 siblings, 0 replies; 43+ messages in thread From: Joseph Myers @ 2018-08-09 22:07 UTC (permalink / raw) To: Martin Sebor; +Cc: Jason Merrill, Gcc Patch List On Wed, 8 Aug 2018, Martin Sebor wrote: > Done in the attached patch. I've also avoided dealing with > zero-length arrays and added tests to make sure their size > stays is regardless of the form of their initializer and > the appropriate warnings are issued. The C front-end changes in this patch version are OK. -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-09 0:17 ` Martin Sebor 2018-08-09 22:07 ` Joseph Myers @ 2018-08-13 10:36 ` Jason Merrill 2018-08-14 13:27 ` James Greenhalgh 2 siblings, 0 replies; 43+ messages in thread From: Jason Merrill @ 2018-08-13 10:36 UTC (permalink / raw) To: Martin Sebor; +Cc: Gcc Patch List, Joseph Myers On 08/09/2018 12:17 PM, Martin Sebor wrote: > Using build_string() rather than build_string_literal() needed > a tweak in digest_init_r(). It didn't break anything but since > the array type may not have a domain yet, neither will the > string. It looks like that may get adjusted later on but I've > temporarily guarded the code with #if 1. If the change is > fine I'll remove the #if before committing. The digest_init_r change seems to follow from allowing STRING_CST of signed char, so yes, it's fine. > + && TREE_CODE (init) == CONSTRUCTOR > + && TREE_TYPE (init) == init_list_type_node) This is BRACE_ENCLOSED_INITIALIZER_P. OK with that change. Jason ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-09 0:17 ` Martin Sebor 2018-08-09 22:07 ` Joseph Myers 2018-08-13 10:36 ` Jason Merrill @ 2018-08-14 13:27 ` James Greenhalgh 2018-08-14 15:08 ` Martin Sebor 2018-08-14 21:14 ` Joseph Myers 2 siblings, 2 replies; 43+ messages in thread From: James Greenhalgh @ 2018-08-14 13:27 UTC (permalink / raw) To: Martin Sebor; +Cc: Jason Merrill, Gcc Patch List, Joseph Myers, nd On Wed, Aug 08, 2018 at 07:17:07PM -0500, Martin Sebor wrote: > On 08/08/2018 05:08 AM, Jason Merrill wrote: > > On Wed, Aug 8, 2018 at 9:04 AM, Martin Sebor <msebor@gmail.com> wrote: > >> On 08/07/2018 02:57 AM, Jason Merrill wrote: > >>> > >>> On Wed, Aug 1, 2018 at 12:49 AM, Martin Sebor <msebor@gmail.com> wrote: > >>>> > >>>> On 07/31/2018 07:38 AM, Jason Merrill wrote: <snip> > Done in the attached patch. I've also avoided dealing with > zero-length arrays and added tests to make sure their size > stays is regardless of the form of their initializer and > the appropriate warnings are issued. > > Using build_string() rather than build_string_literal() needed > a tweak in digest_init_r(). It didn't break anything but since > the array type may not have a domain yet, neither will the > string. It looks like that may get adjusted later on but I've > temporarily guarded the code with #if 1. If the change is > fine I'll remove the #if before committing. > > This initial patch only handles narrow character initializers > (i.e., those with TYPE_STRING_FLAG set). Once this gets some > exposure I'd like to extend it to other character types, > including wchar_t. Hi Martin, This causes issues for the AArch64 tests (full list below). I see an error message on the following construct: void foo (void) { __Poly8_t x[4] = { 1, 2, 3, 4 }; } init.c:3:20: error: array of inappropriate type initialized from string constant 3 | __Poly8_t x[4] = { 1, 2, 3, 4 }; | __Poly8_t is a type we define in our backend, through a convoluted set of functions, which operates a lot like an unsigned, QI mode type. A second set of tests fail due to changed inlining behaviour for functions with char array initialization: gcc.target/aarch64/vset_lane_1.c gcc.target/aarch64/vneg_s.c gcc.target/aarch64/vclz.c Thanks, James ----- New failures in: gcc.target/aarch64/advsimd-intrinsics/vmax.c gcc.target/aarch64/simd/vzipqp8_1.c gcc.target/aarch64/vldN_dup_1.c gcc.target/aarch64/advsimd-intrinsics/vcle.c gcc.target/aarch64/advsimd-intrinsics/vadd.c gcc.target/aarch64/advsimd-intrinsics/vhadd.c gcc.target/aarch64/advsimd-intrinsics/vmull_n.c gcc.target/aarch64/advsimd-intrinsics/vrndn.c gcc.target/aarch64/simd/vtrnqp8_1.c gcc.target/aarch64/advsimd-intrinsics/vpadal.c gcc.target/aarch64/advsimd-intrinsics/vtrn_half.c gcc.target/aarch64/advsimd-intrinsics/vqdmlal_n.c gcc.target/aarch64/advsimd-intrinsics/vqdmulh.c gcc.target/aarch64/advsimd-intrinsics/vqsub.c gcc.target/aarch64/advsimd-intrinsics/vqdmlal_lane.c gcc.target/aarch64/advsimd-intrinsics/vqdmlsl_n.c gcc.target/aarch64/advsimd-intrinsics/vuzp_half.c gcc.target/aarch64/advsimd-intrinsics/vst1_lane.c gcc.target/aarch64/advsimd-intrinsics/vmla_lane.c gcc.target/aarch64/advsimd-intrinsics/vqdmulh_lane.c gcc.target/aarch64/advsimd-intrinsics/vrsqrte.c gcc.target/aarch64/advsimd-intrinsics/vneg.c gcc.target/aarch64/simd/vuzpqp8_1.c gcc.target/aarch64/advsimd-intrinsics/vcale.c gcc.target/aarch64/advsimd-intrinsics/vmla_n.c gcc.target/aarch64/advsimd-intrinsics/vsub.c gcc.target/aarch64/advsimd-intrinsics/vrev.c gcc.target/aarch64/advsimd-intrinsics/vmul.c gcc.target/aarch64/advsimd-intrinsics/vldX.c gcc.target/aarch64/advsimd-intrinsics/vsubl.c gcc.target/aarch64/advsimd-intrinsics/vfms.c gcc.target/aarch64/advsimd-intrinsics/vmlsl.c gcc.target/aarch64/advsimd-intrinsics/vsli_n.c gcc.target/aarch64/advsimd-intrinsics/vcombine.c gcc.target/aarch64/advsimd-intrinsics/vmul_n.c gcc.target/aarch64/advsimd-intrinsics/vldX_dup.c gcc.target/aarch64/advsimd-intrinsics/vpaddl.c gcc.target/aarch64/advsimd-intrinsics/vqshrn_n.c gcc.target/aarch64/advsimd-intrinsics/vstX_lane.c gcc.target/aarch64/advsimd-intrinsics/vqtbX.c gcc.target/aarch64/advsimd-intrinsics/vext.c gcc.target/aarch64/advsimd-intrinsics/vtrn.c gcc.target/aarch64/advsimd-intrinsics/vtst.c gcc.target/aarch64/advsimd-intrinsics/vbic.c gcc.target/aarch64/advsimd-intrinsics/vqdmlsl.c gcc.target/aarch64/advsimd-intrinsics/vqshl.c gcc.target/aarch64/advsimd-intrinsics/vrsqrts.c gcc.target/aarch64/advsimd-intrinsics/vqdmull_n.c gcc.target/aarch64/advsimd-intrinsics/vqdmlsl_lane.c gcc.target/aarch64/advsimd-intrinsics/vqdmulh_n.c gcc.target/aarch64/advsimd-intrinsics/vsubw.c gcc.target/aarch64/advsimd-intrinsics/vdup_lane.c gcc.target/aarch64/advsimd-intrinsics/vget_high.c gcc.target/aarch64/advsimd-intrinsics/vuzp.c gcc.target/aarch64/advsimd-intrinsics/vqshl_n.c gcc.target/aarch64/advsimd-intrinsics/vrsra_n.c gcc.target/aarch64/advsimd-intrinsics/vcgt.c gcc.target/aarch64/advsimd-intrinsics/vld1_dup.c gcc.target/aarch64/advsimd-intrinsics/vaddhn.c gcc.target/aarch64/advsimd-intrinsics/vqshlu_n.c gcc.target/aarch64/advsimd-intrinsics/vabs.c gcc.target/aarch64/advsimd-intrinsics/vshll_n.c gcc.target/aarch64/advsimd-intrinsics/vsubhn.c gcc.target/aarch64/advsimd-intrinsics/vmlal.c gcc.target/aarch64/advsimd-intrinsics/vqdmlal.c gcc.target/aarch64/advsimd-intrinsics/vrecpe.c gcc.target/aarch64/advsimd-intrinsics/vqneg.c gcc.target/aarch64/advsimd-intrinsics/veor.c gcc.target/aarch64/simd/extq_p8_1.c gcc.target/aarch64/advsimd-intrinsics/vclz.c gcc.target/aarch64/simd/ext_p8_1.c gcc.target/aarch64/advsimd-intrinsics/vqrdmulh_lane.c gcc.target/aarch64/advsimd-intrinsics/vqrshl.c gcc.target/aarch64/advsimd-intrinsics/vqrshrun_n.c gcc.target/aarch64/advsimd-intrinsics/vqrshrn_n.c gcc.target/aarch64/advsimd-intrinsics/vceq.c gcc.target/aarch64/advsimd-intrinsics/vrndm.c gcc.target/aarch64/advsimd-intrinsics/vmlsl_n.c gcc.target/aarch64/advsimd-intrinsics/vmlal_n.c gcc.target/aarch64/advsimd-intrinsics/vqmovun.c gcc.target/aarch64/advsimd-intrinsics/vrshr_n.c gcc.target/aarch64/advsimd-intrinsics/vmls_n.c gcc.target/aarch64/advsimd-intrinsics/vmlsl_lane.c gcc.target/aarch64/advsimd-intrinsics/vqdmull_lane.c gcc.target/aarch64/advsimd-intrinsics/vfms_vfma_n.c gcc.target/aarch64/advsimd-intrinsics/vorr.c gcc.target/aarch64/advsimd-intrinsics/vaddl.c gcc.target/aarch64/advsimd-intrinsics/vmovl.c gcc.target/aarch64/advsimd-intrinsics/vbsl.c gcc.target/aarch64/advsimd-intrinsics/vld1_lane.c gcc.target/aarch64/advsimd-intrinsics/vqmovn.c gcc.target/aarch64/advsimd-intrinsics/vcalt.c gcc.target/aarch64/advsimd-intrinsics/vmul_lane.c gcc.target/aarch64/advsimd-intrinsics/vqshrun_n.c gcc.target/aarch64/advsimd-intrinsics/vset_lane.c gcc.target/aarch64/advsimd-intrinsics/vrsubhn.c gcc.target/aarch64/advsimd-intrinsics/vshl_n.c gcc.target/aarch64/advsimd-intrinsics/vmovn.c gcc.target/aarch64/advsimd-intrinsics/vcls.c gcc.target/aarch64/advsimd-intrinsics/vcage.c gcc.target/aarch64/advsimd-intrinsics/vcnt.c gcc.target/aarch64/advsimd-intrinsics/vmull.c gcc.target/aarch64/simd/vuzpp8_1.c gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p64.c gcc.target/aarch64/advsimd-intrinsics/vfma.c gcc.target/aarch64/advsimd-intrinsics/vld1.c gcc.target/aarch64/advsimd-intrinsics/vhsub.c gcc.target/aarch64/advsimd-intrinsics/vget_low.c gcc.target/aarch64/advsimd-intrinsics/p64_p128.c gcc.target/aarch64/advsimd-intrinsics/vcvt.c gcc.target/aarch64/advsimd-intrinsics/vqdmull.c gcc.target/aarch64/advsimd-intrinsics/vmvn.c gcc.target/aarch64/advsimd-intrinsics/vmin.c gcc.target/aarch64/advsimd-intrinsics/vaba.c gcc.target/aarch64/advsimd-intrinsics/vqrdmulh_n.c gcc.target/aarch64/simd/vtrnp8_1.c gcc.target/aarch64/advsimd-intrinsics/vcagt.c gcc.target/aarch64/advsimd-intrinsics/vdup-vmov.c gcc.target/aarch64/advsimd-intrinsics/vrhadd.c gcc.target/aarch64/advsimd-intrinsics/vabal.c gcc.target/aarch64/advsimd-intrinsics/vrshrn_n.c gcc.target/aarch64/advsimd-intrinsics/vpmax.c gcc.target/aarch64/advsimd-intrinsics/vmls.c gcc.target/aarch64/advsimd-intrinsics/vshrn_n.c gcc.target/aarch64/advsimd-intrinsics/vrnd.c gcc.target/aarch64/advsimd-intrinsics/vabd.c gcc.target/aarch64/simd/vzipp8_1.c gcc.target/aarch64/advsimd-intrinsics/vduph_lane.c gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p128.c gcc.target/aarch64/advsimd-intrinsics/vrshl.c gcc.target/aarch64/advsimd-intrinsics/vcreate.c gcc.target/aarch64/advsimd-intrinsics/vqabs.c gcc.target/aarch64/advsimd-intrinsics/vmull_lane.c gcc.target/aarch64/advsimd-intrinsics/vreinterpret.c gcc.target/aarch64/advsimd-intrinsics/vmlal_lane.c gcc.target/aarch64/advsimd-intrinsics/vshr_n.c gcc.target/aarch64/advsimd-intrinsics/vzip.c gcc.target/aarch64/vldN_lane_1.c gcc.target/aarch64/advsimd-intrinsics/vabdl.c gcc.target/aarch64/advsimd-intrinsics/vpmin.c gcc.target/aarch64/advsimd-intrinsics/vqadd.c gcc.target/aarch64/advsimd-intrinsics/vzip_half.c gcc.target/aarch64/advsimd-intrinsics/vand.c gcc.target/aarch64/advsimd-intrinsics/vpadd.c gcc.target/aarch64/advsimd-intrinsics/vrndx.c gcc.target/aarch64/advsimd-intrinsics/vmla.c gcc.target/aarch64/advsimd-intrinsics/vsra_n.c gcc.target/aarch64/advsimd-intrinsics/vget_lane.c gcc.target/aarch64/advsimd-intrinsics/vqrdmulh.c gcc.target/aarch64/advsimd-intrinsics/vrndp.c gcc.target/aarch64/advsimd-intrinsics/vmls_lane.c gcc.target/aarch64/advsimd-intrinsics/vclt.c gcc.target/aarch64/advsimd-intrinsics/vfma_n.c gcc.target/aarch64/advsimd-intrinsics/vaddw.c gcc.target/aarch64/advsimd-intrinsics/vsri_n.c gcc.target/aarch64/advsimd-intrinsics/vorn.c gcc.target/aarch64/advsimd-intrinsics/vcvt_f16.c gcc.target/aarch64/advsimd-intrinsics/vldX_lane.c gcc.target/aarch64/advsimd-intrinsics/vcge.c gcc.target/aarch64/advsimd-intrinsics/vshl.c gcc.target/aarch64/advsimd-intrinsics/vtbX.c gcc.target/aarch64/advsimd-intrinsics/vraddhn.c gcc.target/aarch64/advsimd-intrinsics/vrnda.c gcc.target/aarch64/advsimd-intrinsics/vrecps.c > > Martin > PR tree-optimization/71625 - missing strlen optimization on different array initialization style > > gcc/c/ChangeLog: > > PR tree-optimization/71625 > * c-parser.c (c_parser_declaration_or_fndef): Call > braced_list_to_string. > > gcc/c-family/ChangeLog: > > PR tree-optimization/71625 > * c-common.c (braced_list_to_string): New function. > * c-common.h (braced_list_to_string): Declare it. > > gcc/cp/ChangeLog: > > PR tree-optimization/71625 > * decl.c (check_initializer): Call braced_list_to_string. > (eval_check_narrowing): New function. > * gcc/cp/typeck2.c (digest_init_r): Accept strings literals > as initilizers for all narrow character types. > > gcc/testsuite/ChangeLog: > > PR tree-optimization/71625 > * g++.dg/init/string2.C: New test. > * g++.dg/init/string3.C: New test. > * g++.dg/init/string4.C: New test. > * gcc.dg/init-string-3.c: New test. > * gcc.dg/strlenopt-55.c: New test. > * gcc.dg/strlenopt-56.c: New test. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-14 13:27 ` James Greenhalgh @ 2018-08-14 15:08 ` Martin Sebor 2018-08-14 15:24 ` Martin Sebor 2018-08-14 21:14 ` Joseph Myers 1 sibling, 1 reply; 43+ messages in thread From: Martin Sebor @ 2018-08-14 15:08 UTC (permalink / raw) To: James Greenhalgh; +Cc: Jason Merrill, Gcc Patch List, Joseph Myers, nd On 08/14/2018 07:27 AM, James Greenhalgh wrote: > On Wed, Aug 08, 2018 at 07:17:07PM -0500, Martin Sebor wrote: >> On 08/08/2018 05:08 AM, Jason Merrill wrote: >>> On Wed, Aug 8, 2018 at 9:04 AM, Martin Sebor <msebor@gmail.com> wrote: >>>> On 08/07/2018 02:57 AM, Jason Merrill wrote: >>>>> >>>>> On Wed, Aug 1, 2018 at 12:49 AM, Martin Sebor <msebor@gmail.com> wrote: >>>>>> >>>>>> On 07/31/2018 07:38 AM, Jason Merrill wrote: > > <snip> > >> Done in the attached patch. I've also avoided dealing with >> zero-length arrays and added tests to make sure their size >> stays is regardless of the form of their initializer and >> the appropriate warnings are issued. >> >> Using build_string() rather than build_string_literal() needed >> a tweak in digest_init_r(). It didn't break anything but since >> the array type may not have a domain yet, neither will the >> string. It looks like that may get adjusted later on but I've >> temporarily guarded the code with #if 1. If the change is >> fine I'll remove the #if before committing. >> >> This initial patch only handles narrow character initializers >> (i.e., those with TYPE_STRING_FLAG set). Once this gets some >> exposure I'd like to extend it to other character types, >> including wchar_t. > > Hi Martin, > > This causes issues for the AArch64 tests (full list below). > > I see an error message on the following construct: > > void foo (void) > { > __Poly8_t x[4] = { 1, 2, 3, 4 }; > } > > init.c:3:20: error: array of inappropriate type initialized from string constant > 3 | __Poly8_t x[4] = { 1, 2, 3, 4 }; > | > > __Poly8_t is a type we define in our backend, through a convoluted set of > functions, which operates a lot like an unsigned, QI mode type. I see the error with my aarch64 cross-compiler . The new code that does the conversion of array initializers to STRING_CSTs looks for the TYPE_STRING_FLAG() to be set on the type of the array elements. Perhaps __Poly8_t should not have the flag set? (If it needs it then I think we'd have to only consider named character types.) > A second set of tests fail due to changed inlining behaviour for functions > with char array initialization: > > gcc.target/aarch64/vset_lane_1.c > gcc.target/aarch64/vneg_s.c > gcc.target/aarch64/vclz.c I'm not sure what's going on here. The tests are very big and take forever to compile with an aarch64 cross-compiler, and I'm not sure what to look for. Can you provide a smaller test case that shows the issue? Martin > > Thanks, > James > > ----- > > New failures in: > > > gcc.target/aarch64/advsimd-intrinsics/vmax.c > gcc.target/aarch64/simd/vzipqp8_1.c > gcc.target/aarch64/vldN_dup_1.c > gcc.target/aarch64/advsimd-intrinsics/vcle.c > gcc.target/aarch64/advsimd-intrinsics/vadd.c > gcc.target/aarch64/advsimd-intrinsics/vhadd.c > gcc.target/aarch64/advsimd-intrinsics/vmull_n.c > gcc.target/aarch64/advsimd-intrinsics/vrndn.c > gcc.target/aarch64/simd/vtrnqp8_1.c > gcc.target/aarch64/advsimd-intrinsics/vpadal.c > gcc.target/aarch64/advsimd-intrinsics/vtrn_half.c > gcc.target/aarch64/advsimd-intrinsics/vqdmlal_n.c > gcc.target/aarch64/advsimd-intrinsics/vqdmulh.c > gcc.target/aarch64/advsimd-intrinsics/vqsub.c > gcc.target/aarch64/advsimd-intrinsics/vqdmlal_lane.c > gcc.target/aarch64/advsimd-intrinsics/vqdmlsl_n.c > gcc.target/aarch64/advsimd-intrinsics/vuzp_half.c > gcc.target/aarch64/advsimd-intrinsics/vst1_lane.c > gcc.target/aarch64/advsimd-intrinsics/vmla_lane.c > gcc.target/aarch64/advsimd-intrinsics/vqdmulh_lane.c > gcc.target/aarch64/advsimd-intrinsics/vrsqrte.c > gcc.target/aarch64/advsimd-intrinsics/vneg.c > gcc.target/aarch64/simd/vuzpqp8_1.c > gcc.target/aarch64/advsimd-intrinsics/vcale.c > gcc.target/aarch64/advsimd-intrinsics/vmla_n.c > gcc.target/aarch64/advsimd-intrinsics/vsub.c > gcc.target/aarch64/advsimd-intrinsics/vrev.c > gcc.target/aarch64/advsimd-intrinsics/vmul.c > gcc.target/aarch64/advsimd-intrinsics/vldX.c > gcc.target/aarch64/advsimd-intrinsics/vsubl.c > gcc.target/aarch64/advsimd-intrinsics/vfms.c > gcc.target/aarch64/advsimd-intrinsics/vmlsl.c > gcc.target/aarch64/advsimd-intrinsics/vsli_n.c > gcc.target/aarch64/advsimd-intrinsics/vcombine.c > gcc.target/aarch64/advsimd-intrinsics/vmul_n.c > gcc.target/aarch64/advsimd-intrinsics/vldX_dup.c > gcc.target/aarch64/advsimd-intrinsics/vpaddl.c > gcc.target/aarch64/advsimd-intrinsics/vqshrn_n.c > gcc.target/aarch64/advsimd-intrinsics/vstX_lane.c > gcc.target/aarch64/advsimd-intrinsics/vqtbX.c > gcc.target/aarch64/advsimd-intrinsics/vext.c > gcc.target/aarch64/advsimd-intrinsics/vtrn.c > gcc.target/aarch64/advsimd-intrinsics/vtst.c > gcc.target/aarch64/advsimd-intrinsics/vbic.c > gcc.target/aarch64/advsimd-intrinsics/vqdmlsl.c > gcc.target/aarch64/advsimd-intrinsics/vqshl.c > gcc.target/aarch64/advsimd-intrinsics/vrsqrts.c > gcc.target/aarch64/advsimd-intrinsics/vqdmull_n.c > gcc.target/aarch64/advsimd-intrinsics/vqdmlsl_lane.c > gcc.target/aarch64/advsimd-intrinsics/vqdmulh_n.c > gcc.target/aarch64/advsimd-intrinsics/vsubw.c > gcc.target/aarch64/advsimd-intrinsics/vdup_lane.c > gcc.target/aarch64/advsimd-intrinsics/vget_high.c > gcc.target/aarch64/advsimd-intrinsics/vuzp.c > gcc.target/aarch64/advsimd-intrinsics/vqshl_n.c > gcc.target/aarch64/advsimd-intrinsics/vrsra_n.c > gcc.target/aarch64/advsimd-intrinsics/vcgt.c > gcc.target/aarch64/advsimd-intrinsics/vld1_dup.c > gcc.target/aarch64/advsimd-intrinsics/vaddhn.c > gcc.target/aarch64/advsimd-intrinsics/vqshlu_n.c > gcc.target/aarch64/advsimd-intrinsics/vabs.c > gcc.target/aarch64/advsimd-intrinsics/vshll_n.c > gcc.target/aarch64/advsimd-intrinsics/vsubhn.c > gcc.target/aarch64/advsimd-intrinsics/vmlal.c > gcc.target/aarch64/advsimd-intrinsics/vqdmlal.c > gcc.target/aarch64/advsimd-intrinsics/vrecpe.c > gcc.target/aarch64/advsimd-intrinsics/vqneg.c > gcc.target/aarch64/advsimd-intrinsics/veor.c > gcc.target/aarch64/simd/extq_p8_1.c > gcc.target/aarch64/advsimd-intrinsics/vclz.c > gcc.target/aarch64/simd/ext_p8_1.c > gcc.target/aarch64/advsimd-intrinsics/vqrdmulh_lane.c > gcc.target/aarch64/advsimd-intrinsics/vqrshl.c > gcc.target/aarch64/advsimd-intrinsics/vqrshrun_n.c > gcc.target/aarch64/advsimd-intrinsics/vqrshrn_n.c > gcc.target/aarch64/advsimd-intrinsics/vceq.c > gcc.target/aarch64/advsimd-intrinsics/vrndm.c > gcc.target/aarch64/advsimd-intrinsics/vmlsl_n.c > gcc.target/aarch64/advsimd-intrinsics/vmlal_n.c > gcc.target/aarch64/advsimd-intrinsics/vqmovun.c > gcc.target/aarch64/advsimd-intrinsics/vrshr_n.c > gcc.target/aarch64/advsimd-intrinsics/vmls_n.c > gcc.target/aarch64/advsimd-intrinsics/vmlsl_lane.c > gcc.target/aarch64/advsimd-intrinsics/vqdmull_lane.c > gcc.target/aarch64/advsimd-intrinsics/vfms_vfma_n.c > gcc.target/aarch64/advsimd-intrinsics/vorr.c > gcc.target/aarch64/advsimd-intrinsics/vaddl.c > gcc.target/aarch64/advsimd-intrinsics/vmovl.c > gcc.target/aarch64/advsimd-intrinsics/vbsl.c > gcc.target/aarch64/advsimd-intrinsics/vld1_lane.c > gcc.target/aarch64/advsimd-intrinsics/vqmovn.c > gcc.target/aarch64/advsimd-intrinsics/vcalt.c > gcc.target/aarch64/advsimd-intrinsics/vmul_lane.c > gcc.target/aarch64/advsimd-intrinsics/vqshrun_n.c > gcc.target/aarch64/advsimd-intrinsics/vset_lane.c > gcc.target/aarch64/advsimd-intrinsics/vrsubhn.c > gcc.target/aarch64/advsimd-intrinsics/vshl_n.c > gcc.target/aarch64/advsimd-intrinsics/vmovn.c > gcc.target/aarch64/advsimd-intrinsics/vcls.c > gcc.target/aarch64/advsimd-intrinsics/vcage.c > gcc.target/aarch64/advsimd-intrinsics/vcnt.c > gcc.target/aarch64/advsimd-intrinsics/vmull.c > gcc.target/aarch64/simd/vuzpp8_1.c > gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p64.c > gcc.target/aarch64/advsimd-intrinsics/vfma.c > gcc.target/aarch64/advsimd-intrinsics/vld1.c > gcc.target/aarch64/advsimd-intrinsics/vhsub.c > gcc.target/aarch64/advsimd-intrinsics/vget_low.c > gcc.target/aarch64/advsimd-intrinsics/p64_p128.c > gcc.target/aarch64/advsimd-intrinsics/vcvt.c > gcc.target/aarch64/advsimd-intrinsics/vqdmull.c > gcc.target/aarch64/advsimd-intrinsics/vmvn.c > gcc.target/aarch64/advsimd-intrinsics/vmin.c > gcc.target/aarch64/advsimd-intrinsics/vaba.c > gcc.target/aarch64/advsimd-intrinsics/vqrdmulh_n.c > gcc.target/aarch64/simd/vtrnp8_1.c > gcc.target/aarch64/advsimd-intrinsics/vcagt.c > gcc.target/aarch64/advsimd-intrinsics/vdup-vmov.c > gcc.target/aarch64/advsimd-intrinsics/vrhadd.c > gcc.target/aarch64/advsimd-intrinsics/vabal.c > gcc.target/aarch64/advsimd-intrinsics/vrshrn_n.c > gcc.target/aarch64/advsimd-intrinsics/vpmax.c > gcc.target/aarch64/advsimd-intrinsics/vmls.c > gcc.target/aarch64/advsimd-intrinsics/vshrn_n.c > gcc.target/aarch64/advsimd-intrinsics/vrnd.c > gcc.target/aarch64/advsimd-intrinsics/vabd.c > gcc.target/aarch64/simd/vzipp8_1.c > gcc.target/aarch64/advsimd-intrinsics/vduph_lane.c > gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p128.c > gcc.target/aarch64/advsimd-intrinsics/vrshl.c > gcc.target/aarch64/advsimd-intrinsics/vcreate.c > gcc.target/aarch64/advsimd-intrinsics/vqabs.c > gcc.target/aarch64/advsimd-intrinsics/vmull_lane.c > gcc.target/aarch64/advsimd-intrinsics/vreinterpret.c > gcc.target/aarch64/advsimd-intrinsics/vmlal_lane.c > gcc.target/aarch64/advsimd-intrinsics/vshr_n.c > gcc.target/aarch64/advsimd-intrinsics/vzip.c > gcc.target/aarch64/vldN_lane_1.c > gcc.target/aarch64/advsimd-intrinsics/vabdl.c > gcc.target/aarch64/advsimd-intrinsics/vpmin.c > gcc.target/aarch64/advsimd-intrinsics/vqadd.c > gcc.target/aarch64/advsimd-intrinsics/vzip_half.c > gcc.target/aarch64/advsimd-intrinsics/vand.c > gcc.target/aarch64/advsimd-intrinsics/vpadd.c > gcc.target/aarch64/advsimd-intrinsics/vrndx.c > gcc.target/aarch64/advsimd-intrinsics/vmla.c > gcc.target/aarch64/advsimd-intrinsics/vsra_n.c > gcc.target/aarch64/advsimd-intrinsics/vget_lane.c > gcc.target/aarch64/advsimd-intrinsics/vqrdmulh.c > gcc.target/aarch64/advsimd-intrinsics/vrndp.c > gcc.target/aarch64/advsimd-intrinsics/vmls_lane.c > gcc.target/aarch64/advsimd-intrinsics/vclt.c > gcc.target/aarch64/advsimd-intrinsics/vfma_n.c > gcc.target/aarch64/advsimd-intrinsics/vaddw.c > gcc.target/aarch64/advsimd-intrinsics/vsri_n.c > gcc.target/aarch64/advsimd-intrinsics/vorn.c > gcc.target/aarch64/advsimd-intrinsics/vcvt_f16.c > gcc.target/aarch64/advsimd-intrinsics/vldX_lane.c > gcc.target/aarch64/advsimd-intrinsics/vcge.c > gcc.target/aarch64/advsimd-intrinsics/vshl.c > gcc.target/aarch64/advsimd-intrinsics/vtbX.c > gcc.target/aarch64/advsimd-intrinsics/vraddhn.c > gcc.target/aarch64/advsimd-intrinsics/vrnda.c > gcc.target/aarch64/advsimd-intrinsics/vrecps.c > > > > > >> >> Martin > >> PR tree-optimization/71625 - missing strlen optimization on different array initialization style >> >> gcc/c/ChangeLog: >> >> PR tree-optimization/71625 >> * c-parser.c (c_parser_declaration_or_fndef): Call >> braced_list_to_string. >> >> gcc/c-family/ChangeLog: >> >> PR tree-optimization/71625 >> * c-common.c (braced_list_to_string): New function. >> * c-common.h (braced_list_to_string): Declare it. >> >> gcc/cp/ChangeLog: >> >> PR tree-optimization/71625 >> * decl.c (check_initializer): Call braced_list_to_string. >> (eval_check_narrowing): New function. >> * gcc/cp/typeck2.c (digest_init_r): Accept strings literals >> as initilizers for all narrow character types. >> >> gcc/testsuite/ChangeLog: >> >> PR tree-optimization/71625 >> * g++.dg/init/string2.C: New test. >> * g++.dg/init/string3.C: New test. >> * g++.dg/init/string4.C: New test. >> * gcc.dg/init-string-3.c: New test. >> * gcc.dg/strlenopt-55.c: New test. >> * gcc.dg/strlenopt-56.c: New test. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-14 15:08 ` Martin Sebor @ 2018-08-14 15:24 ` Martin Sebor 2018-08-15 2:34 ` Martin Sebor 0 siblings, 1 reply; 43+ messages in thread From: Martin Sebor @ 2018-08-14 15:24 UTC (permalink / raw) To: James Greenhalgh; +Cc: Jason Merrill, Gcc Patch List, Joseph Myers, nd On 08/14/2018 09:08 AM, Martin Sebor wrote: > On 08/14/2018 07:27 AM, James Greenhalgh wrote: >> On Wed, Aug 08, 2018 at 07:17:07PM -0500, Martin Sebor wrote: >>> On 08/08/2018 05:08 AM, Jason Merrill wrote: >>>> On Wed, Aug 8, 2018 at 9:04 AM, Martin Sebor <msebor@gmail.com> wrote: >>>>> On 08/07/2018 02:57 AM, Jason Merrill wrote: >>>>>> >>>>>> On Wed, Aug 1, 2018 at 12:49 AM, Martin Sebor <msebor@gmail.com> >>>>>> wrote: >>>>>>> >>>>>>> On 07/31/2018 07:38 AM, Jason Merrill wrote: >> >> <snip> >> >>> Done in the attached patch. I've also avoided dealing with >>> zero-length arrays and added tests to make sure their size >>> stays is regardless of the form of their initializer and >>> the appropriate warnings are issued. >>> >>> Using build_string() rather than build_string_literal() needed >>> a tweak in digest_init_r(). It didn't break anything but since >>> the array type may not have a domain yet, neither will the >>> string. It looks like that may get adjusted later on but I've >>> temporarily guarded the code with #if 1. If the change is >>> fine I'll remove the #if before committing. >>> >>> This initial patch only handles narrow character initializers >>> (i.e., those with TYPE_STRING_FLAG set). Once this gets some >>> exposure I'd like to extend it to other character types, >>> including wchar_t. >> >> Hi Martin, >> >> This causes issues for the AArch64 tests (full list below). >> >> I see an error message on the following construct: >> >> void foo (void) >> { >> __Poly8_t x[4] = { 1, 2, 3, 4 }; >> } >> >> init.c:3:20: error: array of inappropriate type initialized from >> string constant >> 3 | __Poly8_t x[4] = { 1, 2, 3, 4 }; >> | >> >> __Poly8_t is a type we define in our backend, through a convoluted set of >> functions, which operates a lot like an unsigned, QI mode type. > > I see the error with my aarch64 cross-compiler . The new code > that does the conversion of array initializers to STRING_CSTs > looks for the TYPE_STRING_FLAG() to be set on the type of > the array elements. Perhaps __Poly8_t should not have the flag > set? (If it needs it then I think we'd have to only consider > named character types.) The change below gets rid of the compilation error. I don't know if it's appropriate for the aarch64 back end: Index: gcc/config/aarch64/aarch64-builtins.c =================================================================== --- gcc/config/aarch64/aarch64-builtins.c (revision 263537) +++ gcc/config/aarch64/aarch64-builtins.c (working copy) @@ -643,6 +643,7 @@ aarch64_init_simd_builtin_types (void) /* Poly types are a world of their own. */ aarch64_simd_types[Poly8_t].eltype = aarch64_simd_types[Poly8_t].itype = build_distinct_type_copy (unsigned_intQI_type_node); + TYPE_STRING_FLAG (aarch64_simd_types[Poly8_t].eltype) = false; aarch64_simd_types[Poly16_t].eltype = aarch64_simd_types[Poly16_t].itype = build_distinct_type_copy (unsigned_intHI_type_node); aarch64_simd_types[Poly64_t].eltype = aarch64_simd_types[Poly64_t].itype = >> A second set of tests fail due to changed inlining behaviour for >> functions >> with char array initialization: >> >> gcc.target/aarch64/vset_lane_1.c >> gcc.target/aarch64/vneg_s.c >> gcc.target/aarch64/vclz.c > > I'm not sure what's going on here. The tests are very big and > take forever to compile with an aarch64 cross-compiler, and I'm > not sure what to look for. Can you provide a smaller test case > that shows the issue? > > Martin > >> >> Thanks, >> James >> >> ----- >> >> New failures in: >> >> >> gcc.target/aarch64/advsimd-intrinsics/vmax.c >> gcc.target/aarch64/simd/vzipqp8_1.c >> gcc.target/aarch64/vldN_dup_1.c >> gcc.target/aarch64/advsimd-intrinsics/vcle.c >> gcc.target/aarch64/advsimd-intrinsics/vadd.c >> gcc.target/aarch64/advsimd-intrinsics/vhadd.c >> gcc.target/aarch64/advsimd-intrinsics/vmull_n.c >> gcc.target/aarch64/advsimd-intrinsics/vrndn.c >> gcc.target/aarch64/simd/vtrnqp8_1.c >> gcc.target/aarch64/advsimd-intrinsics/vpadal.c >> gcc.target/aarch64/advsimd-intrinsics/vtrn_half.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmlal_n.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmulh.c >> gcc.target/aarch64/advsimd-intrinsics/vqsub.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmlal_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmlsl_n.c >> gcc.target/aarch64/advsimd-intrinsics/vuzp_half.c >> gcc.target/aarch64/advsimd-intrinsics/vst1_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vmla_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmulh_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vrsqrte.c >> gcc.target/aarch64/advsimd-intrinsics/vneg.c >> gcc.target/aarch64/simd/vuzpqp8_1.c >> gcc.target/aarch64/advsimd-intrinsics/vcale.c >> gcc.target/aarch64/advsimd-intrinsics/vmla_n.c >> gcc.target/aarch64/advsimd-intrinsics/vsub.c >> gcc.target/aarch64/advsimd-intrinsics/vrev.c >> gcc.target/aarch64/advsimd-intrinsics/vmul.c >> gcc.target/aarch64/advsimd-intrinsics/vldX.c >> gcc.target/aarch64/advsimd-intrinsics/vsubl.c >> gcc.target/aarch64/advsimd-intrinsics/vfms.c >> gcc.target/aarch64/advsimd-intrinsics/vmlsl.c >> gcc.target/aarch64/advsimd-intrinsics/vsli_n.c >> gcc.target/aarch64/advsimd-intrinsics/vcombine.c >> gcc.target/aarch64/advsimd-intrinsics/vmul_n.c >> gcc.target/aarch64/advsimd-intrinsics/vldX_dup.c >> gcc.target/aarch64/advsimd-intrinsics/vpaddl.c >> gcc.target/aarch64/advsimd-intrinsics/vqshrn_n.c >> gcc.target/aarch64/advsimd-intrinsics/vstX_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vqtbX.c >> gcc.target/aarch64/advsimd-intrinsics/vext.c >> gcc.target/aarch64/advsimd-intrinsics/vtrn.c >> gcc.target/aarch64/advsimd-intrinsics/vtst.c >> gcc.target/aarch64/advsimd-intrinsics/vbic.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmlsl.c >> gcc.target/aarch64/advsimd-intrinsics/vqshl.c >> gcc.target/aarch64/advsimd-intrinsics/vrsqrts.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmull_n.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmlsl_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmulh_n.c >> gcc.target/aarch64/advsimd-intrinsics/vsubw.c >> gcc.target/aarch64/advsimd-intrinsics/vdup_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vget_high.c >> gcc.target/aarch64/advsimd-intrinsics/vuzp.c >> gcc.target/aarch64/advsimd-intrinsics/vqshl_n.c >> gcc.target/aarch64/advsimd-intrinsics/vrsra_n.c >> gcc.target/aarch64/advsimd-intrinsics/vcgt.c >> gcc.target/aarch64/advsimd-intrinsics/vld1_dup.c >> gcc.target/aarch64/advsimd-intrinsics/vaddhn.c >> gcc.target/aarch64/advsimd-intrinsics/vqshlu_n.c >> gcc.target/aarch64/advsimd-intrinsics/vabs.c >> gcc.target/aarch64/advsimd-intrinsics/vshll_n.c >> gcc.target/aarch64/advsimd-intrinsics/vsubhn.c >> gcc.target/aarch64/advsimd-intrinsics/vmlal.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmlal.c >> gcc.target/aarch64/advsimd-intrinsics/vrecpe.c >> gcc.target/aarch64/advsimd-intrinsics/vqneg.c >> gcc.target/aarch64/advsimd-intrinsics/veor.c >> gcc.target/aarch64/simd/extq_p8_1.c >> gcc.target/aarch64/advsimd-intrinsics/vclz.c >> gcc.target/aarch64/simd/ext_p8_1.c >> gcc.target/aarch64/advsimd-intrinsics/vqrdmulh_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vqrshl.c >> gcc.target/aarch64/advsimd-intrinsics/vqrshrun_n.c >> gcc.target/aarch64/advsimd-intrinsics/vqrshrn_n.c >> gcc.target/aarch64/advsimd-intrinsics/vceq.c >> gcc.target/aarch64/advsimd-intrinsics/vrndm.c >> gcc.target/aarch64/advsimd-intrinsics/vmlsl_n.c >> gcc.target/aarch64/advsimd-intrinsics/vmlal_n.c >> gcc.target/aarch64/advsimd-intrinsics/vqmovun.c >> gcc.target/aarch64/advsimd-intrinsics/vrshr_n.c >> gcc.target/aarch64/advsimd-intrinsics/vmls_n.c >> gcc.target/aarch64/advsimd-intrinsics/vmlsl_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmull_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vfms_vfma_n.c >> gcc.target/aarch64/advsimd-intrinsics/vorr.c >> gcc.target/aarch64/advsimd-intrinsics/vaddl.c >> gcc.target/aarch64/advsimd-intrinsics/vmovl.c >> gcc.target/aarch64/advsimd-intrinsics/vbsl.c >> gcc.target/aarch64/advsimd-intrinsics/vld1_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vqmovn.c >> gcc.target/aarch64/advsimd-intrinsics/vcalt.c >> gcc.target/aarch64/advsimd-intrinsics/vmul_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vqshrun_n.c >> gcc.target/aarch64/advsimd-intrinsics/vset_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vrsubhn.c >> gcc.target/aarch64/advsimd-intrinsics/vshl_n.c >> gcc.target/aarch64/advsimd-intrinsics/vmovn.c >> gcc.target/aarch64/advsimd-intrinsics/vcls.c >> gcc.target/aarch64/advsimd-intrinsics/vcage.c >> gcc.target/aarch64/advsimd-intrinsics/vcnt.c >> gcc.target/aarch64/advsimd-intrinsics/vmull.c >> gcc.target/aarch64/simd/vuzpp8_1.c >> gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p64.c >> gcc.target/aarch64/advsimd-intrinsics/vfma.c >> gcc.target/aarch64/advsimd-intrinsics/vld1.c >> gcc.target/aarch64/advsimd-intrinsics/vhsub.c >> gcc.target/aarch64/advsimd-intrinsics/vget_low.c >> gcc.target/aarch64/advsimd-intrinsics/p64_p128.c >> gcc.target/aarch64/advsimd-intrinsics/vcvt.c >> gcc.target/aarch64/advsimd-intrinsics/vqdmull.c >> gcc.target/aarch64/advsimd-intrinsics/vmvn.c >> gcc.target/aarch64/advsimd-intrinsics/vmin.c >> gcc.target/aarch64/advsimd-intrinsics/vaba.c >> gcc.target/aarch64/advsimd-intrinsics/vqrdmulh_n.c >> gcc.target/aarch64/simd/vtrnp8_1.c >> gcc.target/aarch64/advsimd-intrinsics/vcagt.c >> gcc.target/aarch64/advsimd-intrinsics/vdup-vmov.c >> gcc.target/aarch64/advsimd-intrinsics/vrhadd.c >> gcc.target/aarch64/advsimd-intrinsics/vabal.c >> gcc.target/aarch64/advsimd-intrinsics/vrshrn_n.c >> gcc.target/aarch64/advsimd-intrinsics/vpmax.c >> gcc.target/aarch64/advsimd-intrinsics/vmls.c >> gcc.target/aarch64/advsimd-intrinsics/vshrn_n.c >> gcc.target/aarch64/advsimd-intrinsics/vrnd.c >> gcc.target/aarch64/advsimd-intrinsics/vabd.c >> gcc.target/aarch64/simd/vzipp8_1.c >> gcc.target/aarch64/advsimd-intrinsics/vduph_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p128.c >> gcc.target/aarch64/advsimd-intrinsics/vrshl.c >> gcc.target/aarch64/advsimd-intrinsics/vcreate.c >> gcc.target/aarch64/advsimd-intrinsics/vqabs.c >> gcc.target/aarch64/advsimd-intrinsics/vmull_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vreinterpret.c >> gcc.target/aarch64/advsimd-intrinsics/vmlal_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vshr_n.c >> gcc.target/aarch64/advsimd-intrinsics/vzip.c >> gcc.target/aarch64/vldN_lane_1.c >> gcc.target/aarch64/advsimd-intrinsics/vabdl.c >> gcc.target/aarch64/advsimd-intrinsics/vpmin.c >> gcc.target/aarch64/advsimd-intrinsics/vqadd.c >> gcc.target/aarch64/advsimd-intrinsics/vzip_half.c >> gcc.target/aarch64/advsimd-intrinsics/vand.c >> gcc.target/aarch64/advsimd-intrinsics/vpadd.c >> gcc.target/aarch64/advsimd-intrinsics/vrndx.c >> gcc.target/aarch64/advsimd-intrinsics/vmla.c >> gcc.target/aarch64/advsimd-intrinsics/vsra_n.c >> gcc.target/aarch64/advsimd-intrinsics/vget_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vqrdmulh.c >> gcc.target/aarch64/advsimd-intrinsics/vrndp.c >> gcc.target/aarch64/advsimd-intrinsics/vmls_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vclt.c >> gcc.target/aarch64/advsimd-intrinsics/vfma_n.c >> gcc.target/aarch64/advsimd-intrinsics/vaddw.c >> gcc.target/aarch64/advsimd-intrinsics/vsri_n.c >> gcc.target/aarch64/advsimd-intrinsics/vorn.c >> gcc.target/aarch64/advsimd-intrinsics/vcvt_f16.c >> gcc.target/aarch64/advsimd-intrinsics/vldX_lane.c >> gcc.target/aarch64/advsimd-intrinsics/vcge.c >> gcc.target/aarch64/advsimd-intrinsics/vshl.c >> gcc.target/aarch64/advsimd-intrinsics/vtbX.c >> gcc.target/aarch64/advsimd-intrinsics/vraddhn.c >> gcc.target/aarch64/advsimd-intrinsics/vrnda.c >> gcc.target/aarch64/advsimd-intrinsics/vrecps.c >> >> >> >> >> >>> >>> Martin >> >>> PR tree-optimization/71625 - missing strlen optimization on different >>> array initialization style >>> >>> gcc/c/ChangeLog: >>> >>> PR tree-optimization/71625 >>> * c-parser.c (c_parser_declaration_or_fndef): Call >>> braced_list_to_string. >>> >>> gcc/c-family/ChangeLog: >>> >>> PR tree-optimization/71625 >>> * c-common.c (braced_list_to_string): New function. >>> * c-common.h (braced_list_to_string): Declare it. >>> >>> gcc/cp/ChangeLog: >>> >>> PR tree-optimization/71625 >>> * decl.c (check_initializer): Call braced_list_to_string. >>> (eval_check_narrowing): New function. >>> * gcc/cp/typeck2.c (digest_init_r): Accept strings literals >>> as initilizers for all narrow character types. >>> >>> gcc/testsuite/ChangeLog: >>> >>> PR tree-optimization/71625 >>> * g++.dg/init/string2.C: New test. >>> * g++.dg/init/string3.C: New test. >>> * g++.dg/init/string4.C: New test. >>> * gcc.dg/init-string-3.c: New test. >>> * gcc.dg/strlenopt-55.c: New test. >>> * gcc.dg/strlenopt-56.c: New test. > ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-14 15:24 ` Martin Sebor @ 2018-08-15 2:34 ` Martin Sebor 2018-08-15 10:29 ` James Greenhalgh 0 siblings, 1 reply; 43+ messages in thread From: Martin Sebor @ 2018-08-15 2:34 UTC (permalink / raw) To: James Greenhalgh; +Cc: Jason Merrill, Gcc Patch List, Joseph Myers, nd On 08/14/2018 09:24 AM, Martin Sebor wrote: > On 08/14/2018 09:08 AM, Martin Sebor wrote: >> On 08/14/2018 07:27 AM, James Greenhalgh wrote: >>> On Wed, Aug 08, 2018 at 07:17:07PM -0500, Martin Sebor wrote: >>>> On 08/08/2018 05:08 AM, Jason Merrill wrote: >>>>> On Wed, Aug 8, 2018 at 9:04 AM, Martin Sebor <msebor@gmail.com> wrote: >>>>>> On 08/07/2018 02:57 AM, Jason Merrill wrote: >>>>>>> >>>>>>> On Wed, Aug 1, 2018 at 12:49 AM, Martin Sebor <msebor@gmail.com> >>>>>>> wrote: >>>>>>>> >>>>>>>> On 07/31/2018 07:38 AM, Jason Merrill wrote: >>> >>> <snip> >>> >>>> Done in the attached patch. I've also avoided dealing with >>>> zero-length arrays and added tests to make sure their size >>>> stays is regardless of the form of their initializer and >>>> the appropriate warnings are issued. >>>> >>>> Using build_string() rather than build_string_literal() needed >>>> a tweak in digest_init_r(). It didn't break anything but since >>>> the array type may not have a domain yet, neither will the >>>> string. It looks like that may get adjusted later on but I've >>>> temporarily guarded the code with #if 1. If the change is >>>> fine I'll remove the #if before committing. >>>> >>>> This initial patch only handles narrow character initializers >>>> (i.e., those with TYPE_STRING_FLAG set). Once this gets some >>>> exposure I'd like to extend it to other character types, >>>> including wchar_t. >>> >>> Hi Martin, >>> >>> This causes issues for the AArch64 tests (full list below). >>> >>> I see an error message on the following construct: >>> >>> void foo (void) >>> { >>> __Poly8_t x[4] = { 1, 2, 3, 4 }; >>> } >>> >>> init.c:3:20: error: array of inappropriate type initialized from >>> string constant >>> 3 | __Poly8_t x[4] = { 1, 2, 3, 4 }; >>> | >>> >>> __Poly8_t is a type we define in our backend, through a convoluted >>> set of >>> functions, which operates a lot like an unsigned, QI mode type. >> >> I see the error with my aarch64 cross-compiler . The new code >> that does the conversion of array initializers to STRING_CSTs >> looks for the TYPE_STRING_FLAG() to be set on the type of >> the array elements. Perhaps __Poly8_t should not have the flag >> set? (If it needs it then I think we'd have to only consider >> named character types.) > > The change below gets rid of the compilation error. I don't > know if it's appropriate for the aarch64 back end: > > Index: gcc/config/aarch64/aarch64-builtins.c > =================================================================== > --- gcc/config/aarch64/aarch64-builtins.c (revision 263537) > +++ gcc/config/aarch64/aarch64-builtins.c (working copy) > @@ -643,6 +643,7 @@ aarch64_init_simd_builtin_types (void) > /* Poly types are a world of their own. */ > aarch64_simd_types[Poly8_t].eltype = aarch64_simd_types[Poly8_t].itype = > build_distinct_type_copy (unsigned_intQI_type_node); > + TYPE_STRING_FLAG (aarch64_simd_types[Poly8_t].eltype) = false; > aarch64_simd_types[Poly16_t].eltype = > aarch64_simd_types[Poly16_t].itype = > build_distinct_type_copy (unsigned_intHI_type_node); > aarch64_simd_types[Poly64_t].eltype = > aarch64_simd_types[Poly64_t].itype = > > >>> A second set of tests fail due to changed inlining behaviour for >>> functions >>> with char array initialization: >>> >>> gcc.target/aarch64/vset_lane_1.c >>> gcc.target/aarch64/vneg_s.c >>> gcc.target/aarch64/vclz.c >> >> I'm not sure what's going on here. The tests are very big and >> take forever to compile with an aarch64 cross-compiler, and I'm >> not sure what to look for. Can you provide a smaller test case >> that shows the issue? I wonder if these changes might be due to the same problem: the tests define and initialize arrays of the Int8x16_t type which is initialized to intQI_type_node, i.e., the signed form of Poly8_t. Does the conversion to STRING_CST cause a performance degradation or is it just that the tests end up with equivalent but slightly different assembly? The tests also use int8_t and uint8_t for the expected results. Those are typedefs for signed and unsigned char, respectively. Is the conversion to strings for those fine? Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-15 2:34 ` Martin Sebor @ 2018-08-15 10:29 ` James Greenhalgh 2018-08-15 15:04 ` Richard Biener 2018-08-15 15:51 ` Martin Sebor 0 siblings, 2 replies; 43+ messages in thread From: James Greenhalgh @ 2018-08-15 10:29 UTC (permalink / raw) To: Martin Sebor; +Cc: Jason Merrill, Gcc Patch List, Joseph Myers, nd On Tue, Aug 14, 2018 at 09:34:08PM -0500, Martin Sebor wrote: > On 08/14/2018 09:24 AM, Martin Sebor wrote: > > On 08/14/2018 09:08 AM, Martin Sebor wrote: > >> On 08/14/2018 07:27 AM, James Greenhalgh wrote: > >>> On Wed, Aug 08, 2018 at 07:17:07PM -0500, Martin Sebor wrote: > >>>> On 08/08/2018 05:08 AM, Jason Merrill wrote: > >>>>> On Wed, Aug 8, 2018 at 9:04 AM, Martin Sebor <msebor@gmail.com> wrote: > >>>>>> On 08/07/2018 02:57 AM, Jason Merrill wrote: > >>>>>>> > >>>>>>> On Wed, Aug 1, 2018 at 12:49 AM, Martin Sebor <msebor@gmail.com> > >>>>>>> wrote: > >>>>>>>> > >>>>>>>> On 07/31/2018 07:38 AM, Jason Merrill wrote: > >>> > >>> <snip> > >>> > >>>> Done in the attached patch. I've also avoided dealing with > >>>> zero-length arrays and added tests to make sure their size > >>>> stays is regardless of the form of their initializer and > >>>> the appropriate warnings are issued. > >>>> > >>>> Using build_string() rather than build_string_literal() needed > >>>> a tweak in digest_init_r(). It didn't break anything but since > >>>> the array type may not have a domain yet, neither will the > >>>> string. It looks like that may get adjusted later on but I've > >>>> temporarily guarded the code with #if 1. If the change is > >>>> fine I'll remove the #if before committing. > >>>> > >>>> This initial patch only handles narrow character initializers > >>>> (i.e., those with TYPE_STRING_FLAG set). Once this gets some > >>>> exposure I'd like to extend it to other character types, > >>>> including wchar_t. > >>> > >>> Hi Martin, > >>> > >>> This causes issues for the AArch64 tests (full list below). > >>> > >>> I see an error message on the following construct: > >>> > >>> void foo (void) > >>> { > >>> __Poly8_t x[4] = { 1, 2, 3, 4 }; > >>> } > >>> > >>> init.c:3:20: error: array of inappropriate type initialized from > >>> string constant > >>> 3 | __Poly8_t x[4] = { 1, 2, 3, 4 }; > >>> | > >>> > >>> __Poly8_t is a type we define in our backend, through a convoluted > >>> set of > >>> functions, which operates a lot like an unsigned, QI mode type. > >> > >> I see the error with my aarch64 cross-compiler . The new code > >> that does the conversion of array initializers to STRING_CSTs > >> looks for the TYPE_STRING_FLAG() to be set on the type of > >> the array elements. Perhaps __Poly8_t should not have the flag > >> set? (If it needs it then I think we'd have to only consider > >> named character types.) > > > > The change below gets rid of the compilation error. I don't > > know if it's appropriate for the aarch64 back end: > > > > Index: gcc/config/aarch64/aarch64-builtins.c > > =================================================================== > > --- gcc/config/aarch64/aarch64-builtins.c (revision 263537) > > +++ gcc/config/aarch64/aarch64-builtins.c (working copy) > > @@ -643,6 +643,7 @@ aarch64_init_simd_builtin_types (void) > > /* Poly types are a world of their own. */ > > aarch64_simd_types[Poly8_t].eltype = aarch64_simd_types[Poly8_t].itype = > > build_distinct_type_copy (unsigned_intQI_type_node); > > + TYPE_STRING_FLAG (aarch64_simd_types[Poly8_t].eltype) = false; > > aarch64_simd_types[Poly16_t].eltype = > > aarch64_simd_types[Poly16_t].itype = > > build_distinct_type_copy (unsigned_intHI_type_node); > > aarch64_simd_types[Poly64_t].eltype = > > aarch64_simd_types[Poly64_t].itype = This fix seems correct to me, the poly types are not strings. Looking at other uses of TYPE_STRING_FLAG this change doesn't seem like it would have impact on parsing or code generation. OK for trunk. > >>> A second set of tests fail due to changed inlining behaviour for > >>> functions > >>> with char array initialization: > >>> > >>> gcc.target/aarch64/vset_lane_1.c > >>> gcc.target/aarch64/vneg_s.c > >>> gcc.target/aarch64/vclz.c > >> > >> I'm not sure what's going on here. The tests are very big and > >> take forever to compile with an aarch64 cross-compiler, and I'm > >> not sure what to look for. Can you provide a smaller test case > >> that shows the issue? > > I wonder if these changes might be due to the same problem: > the tests define and initialize arrays of the Int8x16_t type > which is initialized to intQI_type_node, i.e., the signed > form of Poly8_t. Does the conversion to STRING_CST cause > a performance degradation or is it just that the tests end > up with equivalent but slightly different assembly? These tests aren't looking at performance, just expecting to see certain instructions emitted. The only change is that now the int8x16_t forms are inlined (so the scan-assembler-times fails with two matches, one expected, one in the inlined function body copy). The difference seems to be in the initialization cost of the input data set. Before your patch: int8_tD.3359 test_set0D.21541[8]; int8_tD.3359 answ_set0D.21542[8]; test_set0D.21541[0] = 0; test_set0D.21541[1] = 1; test_set0D.21541[2] = -1; test_set0D.21541[3] = 10; test_set0D.21541[4] = -10; test_set0D.21541[5] = 0; test_set0D.21541[6] = 127; test_set0D.21541[7] = -128; answ_set0D.21542[0] = 0; answ_set0D.21542[1] = -1; answ_set0D.21542[2] = 1; answ_set0D.21542[3] = -10; answ_set0D.21542[4] = 10; answ_set0D.21542[5] = 0; answ_set0D.21542[6] = -127; answ_set0D.21542[7] = -128; After your patch: int8_tD.3357 test_set0D.21539[8]; int8_tD.3357 answ_set0D.21540[8]; test_set0D.21539 = ""; answ_set0D.21540 = ""; I think that is probably what you expected to happen; but the impact on inlining might not have been. Probably, we want to just change these tests to explicitly disable inlining. The tests appear to execute correctly. The print in the dump file is a bit unusual; presumably the impact of having non-printing characters in my initializer list - but less helpful output for it. Off topic; these tests are quick to copmpile on my cross and native compilers. Do you have additional checking enabled? Thanks, James > > The tests also use int8_t and uint8_t for the expected results. > Those are typedefs for signed and unsigned char, respectively. > Is the conversion to strings for those fine? > > Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-15 10:29 ` James Greenhalgh @ 2018-08-15 15:04 ` Richard Biener 2018-08-15 15:51 ` Martin Sebor 1 sibling, 0 replies; 43+ messages in thread From: Richard Biener @ 2018-08-15 15:04 UTC (permalink / raw) To: gcc-patches, James Greenhalgh, Martin Sebor Cc: Jason Merrill, Gcc Patch List, Joseph Myers, nd On August 15, 2018 12:28:55 PM GMT+02:00, James Greenhalgh <James.Greenhalgh@arm.com> wrote: >On Tue, Aug 14, 2018 at 09:34:08PM -0500, Martin Sebor wrote: >> On 08/14/2018 09:24 AM, Martin Sebor wrote: >> > On 08/14/2018 09:08 AM, Martin Sebor wrote: >> >> On 08/14/2018 07:27 AM, James Greenhalgh wrote: >> >>> On Wed, Aug 08, 2018 at 07:17:07PM -0500, Martin Sebor wrote: >> >>>> On 08/08/2018 05:08 AM, Jason Merrill wrote: >> >>>>> On Wed, Aug 8, 2018 at 9:04 AM, Martin Sebor <msebor@gmail.com> >wrote: >> >>>>>> On 08/07/2018 02:57 AM, Jason Merrill wrote: >> >>>>>>> >> >>>>>>> On Wed, Aug 1, 2018 at 12:49 AM, Martin Sebor ><msebor@gmail.com> >> >>>>>>> wrote: >> >>>>>>>> >> >>>>>>>> On 07/31/2018 07:38 AM, Jason Merrill wrote: >> >>> >> >>> <snip> >> >>> >> >>>> Done in the attached patch. I've also avoided dealing with >> >>>> zero-length arrays and added tests to make sure their size >> >>>> stays is regardless of the form of their initializer and >> >>>> the appropriate warnings are issued. >> >>>> >> >>>> Using build_string() rather than build_string_literal() needed >> >>>> a tweak in digest_init_r(). It didn't break anything but since >> >>>> the array type may not have a domain yet, neither will the >> >>>> string. It looks like that may get adjusted later on but I've >> >>>> temporarily guarded the code with #if 1. If the change is >> >>>> fine I'll remove the #if before committing. >> >>>> >> >>>> This initial patch only handles narrow character initializers >> >>>> (i.e., those with TYPE_STRING_FLAG set). Once this gets some >> >>>> exposure I'd like to extend it to other character types, >> >>>> including wchar_t. >> >>> >> >>> Hi Martin, >> >>> >> >>> This causes issues for the AArch64 tests (full list below). >> >>> >> >>> I see an error message on the following construct: >> >>> >> >>> void foo (void) >> >>> { >> >>> __Poly8_t x[4] = { 1, 2, 3, 4 }; >> >>> } >> >>> >> >>> init.c:3:20: error: array of inappropriate type initialized >from >> >>> string constant >> >>> 3 | __Poly8_t x[4] = { 1, 2, 3, 4 }; >> >>> | >> >>> >> >>> __Poly8_t is a type we define in our backend, through a >convoluted >> >>> set of >> >>> functions, which operates a lot like an unsigned, QI mode type. >> >> >> >> I see the error with my aarch64 cross-compiler . The new code >> >> that does the conversion of array initializers to STRING_CSTs >> >> looks for the TYPE_STRING_FLAG() to be set on the type of >> >> the array elements. Perhaps __Poly8_t should not have the flag >> >> set? (If it needs it then I think we'd have to only consider >> >> named character types.) >> > >> > The change below gets rid of the compilation error. I don't >> > know if it's appropriate for the aarch64 back end: >> > >> > Index: gcc/config/aarch64/aarch64-builtins.c >> > =================================================================== >> > --- gcc/config/aarch64/aarch64-builtins.c (revision 263537) >> > +++ gcc/config/aarch64/aarch64-builtins.c (working copy) >> > @@ -643,6 +643,7 @@ aarch64_init_simd_builtin_types (void) >> > /* Poly types are a world of their own. */ >> > aarch64_simd_types[Poly8_t].eltype = >aarch64_simd_types[Poly8_t].itype = >> > build_distinct_type_copy (unsigned_intQI_type_node); >> > + TYPE_STRING_FLAG (aarch64_simd_types[Poly8_t].eltype) = false; >> > aarch64_simd_types[Poly16_t].eltype = >> > aarch64_simd_types[Poly16_t].itype = >> > build_distinct_type_copy (unsigned_intHI_type_node); >> > aarch64_simd_types[Poly64_t].eltype = >> > aarch64_simd_types[Poly64_t].itype = > >This fix seems correct to me, the poly types are not strings. Looking >at >other uses of TYPE_STRING_FLAG this change doesn't seem like it would >have >impact on parsing or code generation. > >OK for trunk. > >> >>> A second set of tests fail due to changed inlining behaviour for >> >>> functions >> >>> with char array initialization: >> >>> >> >>> gcc.target/aarch64/vset_lane_1.c >> >>> gcc.target/aarch64/vneg_s.c >> >>> gcc.target/aarch64/vclz.c >> >> >> >> I'm not sure what's going on here. The tests are very big and >> >> take forever to compile with an aarch64 cross-compiler, and I'm >> >> not sure what to look for. Can you provide a smaller test case >> >> that shows the issue? >> >> I wonder if these changes might be due to the same problem: >> the tests define and initialize arrays of the Int8x16_t type >> which is initialized to intQI_type_node, i.e., the signed >> form of Poly8_t. Does the conversion to STRING_CST cause >> a performance degradation or is it just that the tests end >> up with equivalent but slightly different assembly? > >These tests aren't looking at performance, just expecting to see >certain >instructions emitted. The only change is that now the int8x16_t forms >are >inlined (so the scan-assembler-times fails with two matches, one >expected, >one in the inlined function body copy). > >The difference seems to be in the initialization cost of the input data >set. > >Before your patch: > > int8_tD.3359 test_set0D.21541[8]; > int8_tD.3359 answ_set0D.21542[8]; > > test_set0D.21541[0] = 0; > test_set0D.21541[1] = 1; > test_set0D.21541[2] = -1; > test_set0D.21541[3] = 10; > test_set0D.21541[4] = -10; > test_set0D.21541[5] = 0; > test_set0D.21541[6] = 127; > test_set0D.21541[7] = -128; > answ_set0D.21542[0] = 0; > answ_set0D.21542[1] = -1; > answ_set0D.21542[2] = 1; > answ_set0D.21542[3] = -10; > answ_set0D.21542[4] = 10; > answ_set0D.21542[5] = 0; > answ_set0D.21542[6] = -127; > answ_set0D.21542[7] = -128; > >After your patch: > > int8_tD.3357 test_set0D.21539[8]; > int8_tD.3357 answ_set0D.21540[8]; > > test_set0D.21539 = ""; > answ_set0D.21540 = ""; Can we fix printing of string literals to include non-printable chars please? The above looks like wrong-code though it probably isn't. When Martin L. proposed a similar patch I was suggesting to restrict conversion to initializes with only printable characters. >I think that is probably what you expected to happen; but the impact on >inlining might not have been. It's more the effect of changed gimplification that shows, the inlining is a 2nd order effect. Richard. Probably, we want to just change these >tests >to explicitly disable inlining. The tests appear to execute correctly. > >The print in the dump file is a bit unusual; presumably the impact of >having >non-printing characters in my initializer list - but less helpful >output for >it. > >Off topic; these tests are quick to copmpile on my cross and native >compilers. Do you have additional checking enabled? > >Thanks, >James > >> >> The tests also use int8_t and uint8_t for the expected results. >> Those are typedefs for signed and unsigned char, respectively. >> Is the conversion to strings for those fine? >> >> Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-15 10:29 ` James Greenhalgh 2018-08-15 15:04 ` Richard Biener @ 2018-08-15 15:51 ` Martin Sebor 1 sibling, 0 replies; 43+ messages in thread From: Martin Sebor @ 2018-08-15 15:51 UTC (permalink / raw) To: James Greenhalgh; +Cc: Jason Merrill, Gcc Patch List, Joseph Myers, nd On 08/15/2018 04:28 AM, James Greenhalgh wrote: > On Tue, Aug 14, 2018 at 09:34:08PM -0500, Martin Sebor wrote: >> On 08/14/2018 09:24 AM, Martin Sebor wrote: >>> On 08/14/2018 09:08 AM, Martin Sebor wrote: >>>> On 08/14/2018 07:27 AM, James Greenhalgh wrote: >>>>> On Wed, Aug 08, 2018 at 07:17:07PM -0500, Martin Sebor wrote: >>>>>> On 08/08/2018 05:08 AM, Jason Merrill wrote: >>>>>>> On Wed, Aug 8, 2018 at 9:04 AM, Martin Sebor <msebor@gmail.com> wrote: >>>>>>>> On 08/07/2018 02:57 AM, Jason Merrill wrote: >>>>>>>>> >>>>>>>>> On Wed, Aug 1, 2018 at 12:49 AM, Martin Sebor <msebor@gmail.com> >>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> On 07/31/2018 07:38 AM, Jason Merrill wrote: >>>>> >>>>> <snip> >>>>> >>>>>> Done in the attached patch. I've also avoided dealing with >>>>>> zero-length arrays and added tests to make sure their size >>>>>> stays is regardless of the form of their initializer and >>>>>> the appropriate warnings are issued. >>>>>> >>>>>> Using build_string() rather than build_string_literal() needed >>>>>> a tweak in digest_init_r(). It didn't break anything but since >>>>>> the array type may not have a domain yet, neither will the >>>>>> string. It looks like that may get adjusted later on but I've >>>>>> temporarily guarded the code with #if 1. If the change is >>>>>> fine I'll remove the #if before committing. >>>>>> >>>>>> This initial patch only handles narrow character initializers >>>>>> (i.e., those with TYPE_STRING_FLAG set). Once this gets some >>>>>> exposure I'd like to extend it to other character types, >>>>>> including wchar_t. >>>>> >>>>> Hi Martin, >>>>> >>>>> This causes issues for the AArch64 tests (full list below). >>>>> >>>>> I see an error message on the following construct: >>>>> >>>>> void foo (void) >>>>> { >>>>> __Poly8_t x[4] = { 1, 2, 3, 4 }; >>>>> } >>>>> >>>>> init.c:3:20: error: array of inappropriate type initialized from >>>>> string constant >>>>> 3 | __Poly8_t x[4] = { 1, 2, 3, 4 }; >>>>> | >>>>> >>>>> __Poly8_t is a type we define in our backend, through a convoluted >>>>> set of >>>>> functions, which operates a lot like an unsigned, QI mode type. >>>> >>>> I see the error with my aarch64 cross-compiler . The new code >>>> that does the conversion of array initializers to STRING_CSTs >>>> looks for the TYPE_STRING_FLAG() to be set on the type of >>>> the array elements. Perhaps __Poly8_t should not have the flag >>>> set? (If it needs it then I think we'd have to only consider >>>> named character types.) >>> >>> The change below gets rid of the compilation error. I don't >>> know if it's appropriate for the aarch64 back end: >>> >>> Index: gcc/config/aarch64/aarch64-builtins.c >>> =================================================================== >>> --- gcc/config/aarch64/aarch64-builtins.c (revision 263537) >>> +++ gcc/config/aarch64/aarch64-builtins.c (working copy) >>> @@ -643,6 +643,7 @@ aarch64_init_simd_builtin_types (void) >>> /* Poly types are a world of their own. */ >>> aarch64_simd_types[Poly8_t].eltype = aarch64_simd_types[Poly8_t].itype = >>> build_distinct_type_copy (unsigned_intQI_type_node); >>> + TYPE_STRING_FLAG (aarch64_simd_types[Poly8_t].eltype) = false; >>> aarch64_simd_types[Poly16_t].eltype = >>> aarch64_simd_types[Poly16_t].itype = >>> build_distinct_type_copy (unsigned_intHI_type_node); >>> aarch64_simd_types[Poly64_t].eltype = >>> aarch64_simd_types[Poly64_t].itype = > > This fix seems correct to me, the poly types are not strings. Looking at > other uses of TYPE_STRING_FLAG this change doesn't seem like it would have > impact on parsing or code generation. > > OK for trunk. I committed this in r263561. >>>>> A second set of tests fail due to changed inlining behaviour for >>>>> functions >>>>> with char array initialization: >>>>> >>>>> gcc.target/aarch64/vset_lane_1.c >>>>> gcc.target/aarch64/vneg_s.c >>>>> gcc.target/aarch64/vclz.c >>>> >>>> I'm not sure what's going on here. The tests are very big and >>>> take forever to compile with an aarch64 cross-compiler, and I'm >>>> not sure what to look for. Can you provide a smaller test case >>>> that shows the issue? >> >> I wonder if these changes might be due to the same problem: >> the tests define and initialize arrays of the Int8x16_t type >> which is initialized to intQI_type_node, i.e., the signed >> form of Poly8_t. Does the conversion to STRING_CST cause >> a performance degradation or is it just that the tests end >> up with equivalent but slightly different assembly? > > These tests aren't looking at performance, just expecting to see certain > instructions emitted. The only change is that now the int8x16_t forms are > inlined (so the scan-assembler-times fails with two matches, one expected, > one in the inlined function body copy). > > The difference seems to be in the initialization cost of the input data set. > > Before your patch: > > int8_tD.3359 test_set0D.21541[8]; > int8_tD.3359 answ_set0D.21542[8]; > > test_set0D.21541[0] = 0; > test_set0D.21541[1] = 1; > test_set0D.21541[2] = -1; > test_set0D.21541[3] = 10; > test_set0D.21541[4] = -10; > test_set0D.21541[5] = 0; > test_set0D.21541[6] = 127; > test_set0D.21541[7] = -128; > answ_set0D.21542[0] = 0; > answ_set0D.21542[1] = -1; > answ_set0D.21542[2] = 1; > answ_set0D.21542[3] = -10; > answ_set0D.21542[4] = 10; > answ_set0D.21542[5] = 0; > answ_set0D.21542[6] = -127; > answ_set0D.21542[7] = -128; > > After your patch: > > int8_tD.3357 test_set0D.21539[8]; > int8_tD.3357 answ_set0D.21540[8]; > > test_set0D.21539 = ""; > answ_set0D.21540 = ""; > > I think that is probably what you expected to happen; but the impact on > inlining might not have been. Probably, we want to just change these tests > to explicitly disable inlining. The tests appear to execute correctly. > > The print in the dump file is a bit unusual; presumably the impact of having > non-printing characters in my initializer list - but less helpful output for > it. I agree it's less than helpful. It's not the result of this change. The output is the same for string literals. E.g., for this: void f (void*, ...); void g (void) { char a[] = { 0, 1, 2, 3 }; char b[] = "\000\001\002\003"; f (a, b); } we get the following on trunk: <bb 2> [local count: 1073741825]: a = ""; b = ""; f (&a, &b); and the following with GCC 8: MEM[(char[4] *)&a] = 50462976; b = ""; f (&a, &b); I'll see if I can quickly tweak things to include all characters in the output. > Off topic; these tests are quick to copmpile on my cross and native > compilers. Do you have additional checking enabled? Yes, I did have --enable-checking=all set that I forgot about. With it, gcc.target/aarch64/advsimd-intrinsics/vmax.c takes 2m 21sec to compile without optimization. The gcc.target/aarch64/vclz.c test takes 1m 45sec at -O3. Removing --enable-checking=all reduced the compile times for the two tests to just over a second. Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-14 13:27 ` James Greenhalgh 2018-08-14 15:08 ` Martin Sebor @ 2018-08-14 21:14 ` Joseph Myers 2018-08-14 22:18 ` Martin Sebor 1 sibling, 1 reply; 43+ messages in thread From: Joseph Myers @ 2018-08-14 21:14 UTC (permalink / raw) To: James Greenhalgh; +Cc: Martin Sebor, Jason Merrill, Gcc Patch List, nd On Tue, 14 Aug 2018, James Greenhalgh wrote: > Hi Martin, > > This causes issues for the AArch64 tests (full list below). This change (r263511) also breaks the glibc build for alpha-linux-gnu with build-many-glibcs.py (using mainline GCC and binutils). The error I see is: /scratch/jmyers/glibc-bot/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/../../../../alpha-glibc-linux-gnu/bin/ld: /scratch/jmyers/glibc-bot/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/libc.a(plural.o): in function `__gettextparse': /scratch/jmyers/glibc-bot/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:1108:(.text+0x218): relocation truncated to fit: GPRELHIGH against `.sdata' /scratch/jmyers/glibc-bot/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/../../../../alpha-glibc-linux-gnu/bin/ld: /scratch/jmyers/glibc-bot/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:1348:(.text+0x300): relocation truncated to fit: GPRELHIGH against `.sdata' collect2: error: ld returned 1 exit status ../Rules:224: recipe for target '/scratch/jmyers/glibc-bot/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/elf/sln' failed make[3]: *** [/scratch/jmyers/glibc-bot/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/elf/sln] Error 1 This is with Bison 3.0.4, should the version used to produce intl/plural.c prove relevant. -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-14 21:14 ` Joseph Myers @ 2018-08-14 22:18 ` Martin Sebor 2018-08-15 12:07 ` Joseph Myers 0 siblings, 1 reply; 43+ messages in thread From: Martin Sebor @ 2018-08-14 22:18 UTC (permalink / raw) To: Joseph Myers, James Greenhalgh; +Cc: Jason Merrill, Gcc Patch List, nd On 08/14/2018 03:14 PM, Joseph Myers wrote: > On Tue, 14 Aug 2018, James Greenhalgh wrote: > >> Hi Martin, >> >> This causes issues for the AArch64 tests (full list below). > > This change (r263511) also breaks the glibc build for alpha-linux-gnu with > build-many-glibcs.py (using mainline GCC and binutils). The error I see > is: > > /scratch/jmyers/glibc-bot/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/../../../../alpha-glibc-linux-gnu/bin/ld: > /scratch/jmyers/glibc-bot/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/libc.a(plural.o): > in function `__gettextparse': > /scratch/jmyers/glibc-bot/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:1108:(.text+0x218): > relocation truncated to fit: GPRELHIGH against `.sdata' > /scratch/jmyers/glibc-bot/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/../../../../alpha-glibc-linux-gnu/bin/ld: > /scratch/jmyers/glibc-bot/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:1348:(.text+0x300): > relocation truncated to fit: GPRELHIGH against `.sdata' > collect2: error: ld returned 1 exit status > ../Rules:224: recipe for target > '/scratch/jmyers/glibc-bot/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/elf/sln' > failed > make[3]: *** > [/scratch/jmyers/glibc-bot/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/elf/sln] > Error 1 > > This is with Bison 3.0.4, should the version used to produce intl/plural.c > prove relevant. Can you send me the translation unit and the options it was compiled with that triggered the errors? Thanks Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-14 22:18 ` Martin Sebor @ 2018-08-15 12:07 ` Joseph Myers 2018-08-15 21:02 ` Martin Sebor 0 siblings, 1 reply; 43+ messages in thread From: Joseph Myers @ 2018-08-15 12:07 UTC (permalink / raw) To: Martin Sebor; +Cc: James Greenhalgh, Jason Merrill, Gcc Patch List, nd [-- Attachment #1: Type: text/plain, Size: 2549 bytes --] On Tue, 14 Aug 2018, Martin Sebor wrote: > > This is with Bison 3.0.4, should the version used to produce intl/plural.c > > prove relevant. > > Can you send me the translation unit and the options it was compiled > with that triggered the errors? I've attached plural.i. The error is a static link error linking sln, but maybe comparing results of compiling plural.i before and after the changes may be enlightening (unless it's actually a difference in code elsewhere in glibc causing a link error reported in plural.o). Compiled with: alpha-glibc-linux-gnu-gcc /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c -c -std=gnu11 -fgnu89-inline -O2 -Wall -Werror -Wundef -Wwrite-strings -fmerge-all-constants -fno-stack-protector -frounding-math -g -Wstrict-prototypes -Wold-style-definition -fno-math-errno -mlong-double-128 -mieee -mfp-rounding-mode=d -ftls-model=initial-exec -I../include -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu -I../sysdeps/unix/sysv/linux/alpha/alpha -I../sysdeps/unix/sysv/linux/alpha/fpu -I../sysdeps/alpha/fpu -I../sysdeps/unix/sysv/linux/alpha -I../sysdeps/alpha/nptl -I../sysdeps/unix/sysv/linux/wordsize-64 -I../sysdeps/ieee754/ldbl-64-128 -I../sysdeps/ieee754/ldbl-opt -I../sysdeps/unix/sysv/linux/include -I../sysdeps/unix/sysv/linux -I../sysdeps/nptl -I../sysdeps/pthread -I../sysdeps/gnu -I../sysdeps/unix/inet -I../sysdeps/unix/sysv -I../sysdeps/unix/alpha -I../sysdeps/unix -I../sysdeps/posix -I../sysdeps/alpha -I../sysdeps/wordsize-64 -I../sysdeps/ieee754/ldbl-128 -I../sysdeps/ieee754/dbl-64/wordsize-64 -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 -I../sysdeps/ieee754 -I../sysdeps/generic -I.. -I../libio -I. -D_LIBC_REENTRANT -include /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/libc-modules.h -DMODULE_NAME=libc -include ../include/libc-symbols.h -DTOP_NAMESPACE=glibc -D'LOCALEDIR="/usr/share/locale"' -D'LOCALE_ALIAS_PATH="/usr/share/locale"' -o /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o -MD -MP -MF /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o.dt -MT /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o -- Joseph S. Myers joseph@codesourcery.com [-- Attachment #2: Type: text/plain, Size: 111776 bytes --] # 1 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" # 1 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc-src/alpha-linux-gnu/intl//" # 1 "<built-in>" # 1 "<command-line>" # 1 "../include/stdc-predef.h" 1 # 1 "<command-line>" 2 # 1 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/libc-modules.h" 1 # 1 "<command-line>" 2 # 1 "./../include/libc-symbols.h" 1 # 85 "./../include/libc-symbols.h" # 1 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/config.h" 1 # 86 "./../include/libc-symbols.h" 2 # 847 "./../include/libc-symbols.h" # 1 "../sysdeps/generic/symbol-hacks.h" 1 # 848 "./../include/libc-symbols.h" 2 # 1 "<command-line>" 2 # 1 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" # 1 "plural.y" # 29 "plural.y" # 1 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/config.h" 1 # 30 "plural.y" 2 # 1 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 1 3 4 # 143 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 3 4 # 143 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 3 4 typedef long int ptrdiff_t; # 209 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 3 4 typedef long unsigned int size_t; # 321 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 3 4 typedef int wchar_t; # 415 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 3 4 typedef struct { long long __max_align_ll __attribute__((__aligned__(__alignof__(long long)))); long double __max_align_ld __attribute__((__aligned__(__alignof__(long double)))); # 426 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 3 4 } max_align_t; # 33 "plural.y" 2 # 1 "../include/stdlib.h" 1 # 1 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 1 3 4 # 5 "../include/stdlib.h" 2 # 1 "../stdlib/stdlib.h" 1 # 25 "../stdlib/stdlib.h" # 1 "../bits/libc-header-start.h" 1 # 33 "../bits/libc-header-start.h" # 1 "../include/features.h" 1 # 428 "../include/features.h" # 1 "../include/sys/cdefs.h" 1 # 1 "../misc/sys/cdefs.h" 1 # 442 "../misc/sys/cdefs.h" # 1 "../sysdeps/unix/sysv/linux/alpha/bits/wordsize.h" 1 # 443 "../misc/sys/cdefs.h" 2 # 1 "../sysdeps/ieee754/ldbl-opt/bits/long-double.h" 1 # 444 "../misc/sys/cdefs.h" 2 # 4 "../include/sys/cdefs.h" 2 # 12 "../include/sys/cdefs.h" # 12 "../include/sys/cdefs.h" extern void __chk_fail (void) __attribute__ ((__noreturn__)); extern __typeof (__chk_fail) __chk_fail __attribute__ ((visibility ("hidden"))); # 429 "../include/features.h" 2 # 452 "../include/features.h" # 1 "../include/gnu/stubs.h" 1 # 453 "../include/features.h" 2 # 34 "../bits/libc-header-start.h" 2 # 26 "../stdlib/stdlib.h" 2 # 1 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 1 3 4 # 32 "../stdlib/stdlib.h" 2 # 1 "../sysdeps/unix/sysv/linux/bits/waitflags.h" 1 # 40 "../stdlib/stdlib.h" 2 # 1 "../bits/waitstatus.h" 1 # 41 "../stdlib/stdlib.h" 2 # 55 "../stdlib/stdlib.h" # 1 "../sysdeps/ieee754/ldbl-128/bits/floatn.h" 1 # 23 "../sysdeps/ieee754/ldbl-128/bits/floatn.h" # 1 "../sysdeps/ieee754/ldbl-opt/bits/long-double.h" 1 # 24 "../sysdeps/ieee754/ldbl-128/bits/floatn.h" 2 # 95 "../sysdeps/ieee754/ldbl-128/bits/floatn.h" # 1 "../bits/floatn-common.h" 1 # 24 "../bits/floatn-common.h" # 1 "../sysdeps/ieee754/ldbl-opt/bits/long-double.h" 1 # 25 "../bits/floatn-common.h" 2 # 96 "../sysdeps/ieee754/ldbl-128/bits/floatn.h" 2 # 56 "../stdlib/stdlib.h" 2 typedef struct { int quot; int rem; } div_t; typedef struct { long int quot; long int rem; } ldiv_t; __extension__ typedef struct { long long int quot; long long int rem; } lldiv_t; # 97 "../stdlib/stdlib.h" extern size_t __ctype_get_mb_cur_max (void) __attribute__ ((__nothrow__ )) ; extern double atof (const char *__nptr) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern int atoi (const char *__nptr) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern long int atol (const char *__nptr) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; __extension__ extern long long int atoll (const char *__nptr) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern double strtod (const char *__restrict __nptr, char **__restrict __endptr) __attribute__ ((__nothrow__ )) ; extern float strtof (const char *__restrict __nptr, char **__restrict __endptr) __attribute__ ((__nothrow__ )) ; extern long double strtold (const char *__restrict __nptr, char **__restrict __endptr) __attribute__ ((__nothrow__ )) ; # 140 "../stdlib/stdlib.h" extern _Float32 strtof32 (const char *__restrict __nptr, char **__restrict __endptr) __attribute__ ((__nothrow__ )) ; extern _Float64 strtof64 (const char *__restrict __nptr, char **__restrict __endptr) __attribute__ ((__nothrow__ )) ; extern _Float128 strtof128 (const char *__restrict __nptr, char **__restrict __endptr) __attribute__ ((__nothrow__ )) ; extern _Float32x strtof32x (const char *__restrict __nptr, char **__restrict __endptr) __attribute__ ((__nothrow__ )) ; extern _Float64x strtof64x (const char *__restrict __nptr, char **__restrict __endptr) __attribute__ ((__nothrow__ )) ; # 176 "../stdlib/stdlib.h" extern long int strtol (const char *__restrict __nptr, char **__restrict __endptr, int __base) __attribute__ ((__nothrow__ )) ; extern unsigned long int strtoul (const char *__restrict __nptr, char **__restrict __endptr, int __base) __attribute__ ((__nothrow__ )) ; __extension__ extern long long int strtoq (const char *__restrict __nptr, char **__restrict __endptr, int __base) __attribute__ ((__nothrow__ )) ; __extension__ extern unsigned long long int strtouq (const char *__restrict __nptr, char **__restrict __endptr, int __base) __attribute__ ((__nothrow__ )) ; __extension__ extern long long int strtoll (const char *__restrict __nptr, char **__restrict __endptr, int __base) __attribute__ ((__nothrow__ )) ; __extension__ extern unsigned long long int strtoull (const char *__restrict __nptr, char **__restrict __endptr, int __base) __attribute__ ((__nothrow__ )) ; extern int strfromd (char *__dest, size_t __size, const char *__format, double __f) __attribute__ ((__nothrow__ )) ; extern int strfromf (char *__dest, size_t __size, const char *__format, float __f) __attribute__ ((__nothrow__ )) ; extern int strfroml (char *__dest, size_t __size, const char *__format, long double __f) __attribute__ ((__nothrow__ )) ; # 232 "../stdlib/stdlib.h" extern int strfromf32 (char *__dest, size_t __size, const char * __format, _Float32 __f) __attribute__ ((__nothrow__ )) ; extern int strfromf64 (char *__dest, size_t __size, const char * __format, _Float64 __f) __attribute__ ((__nothrow__ )) ; extern int strfromf128 (char *__dest, size_t __size, const char * __format, _Float128 __f) __attribute__ ((__nothrow__ )) ; extern int strfromf32x (char *__dest, size_t __size, const char * __format, _Float32x __f) __attribute__ ((__nothrow__ )) ; extern int strfromf64x (char *__dest, size_t __size, const char * __format, _Float64x __f) __attribute__ ((__nothrow__ )) ; # 272 "../stdlib/stdlib.h" # 1 "../include/bits/types/locale_t.h" 1 # 1 "../locale/bits/types/locale_t.h" 1 # 22 "../locale/bits/types/locale_t.h" # 1 "../include/bits/types/__locale_t.h" 1 # 1 "../locale/bits/types/__locale_t.h" 1 # 28 "../locale/bits/types/__locale_t.h" struct __locale_struct { struct __locale_data *__locales[13]; const unsigned short int *__ctype_b; const int *__ctype_tolower; const int *__ctype_toupper; const char *__names[13]; }; typedef struct __locale_struct *__locale_t; # 1 "../include/bits/types/__locale_t.h" 2 # 23 "../locale/bits/types/locale_t.h" 2 typedef __locale_t locale_t; # 1 "../include/bits/types/locale_t.h" 2 # 273 "../stdlib/stdlib.h" 2 extern long int strtol_l (const char *__restrict __nptr, char **__restrict __endptr, int __base, locale_t __loc) __attribute__ ((__nothrow__ )) ; extern unsigned long int strtoul_l (const char *__restrict __nptr, char **__restrict __endptr, int __base, locale_t __loc) __attribute__ ((__nothrow__ )) ; __extension__ extern long long int strtoll_l (const char *__restrict __nptr, char **__restrict __endptr, int __base, locale_t __loc) __attribute__ ((__nothrow__ )) ; __extension__ extern unsigned long long int strtoull_l (const char *__restrict __nptr, char **__restrict __endptr, int __base, locale_t __loc) __attribute__ ((__nothrow__ )) ; extern double strtod_l (const char *__restrict __nptr, char **__restrict __endptr, locale_t __loc) __attribute__ ((__nothrow__ )) ; extern float strtof_l (const char *__restrict __nptr, char **__restrict __endptr, locale_t __loc) __attribute__ ((__nothrow__ )) ; extern long double strtold_l (const char *__restrict __nptr, char **__restrict __endptr, locale_t __loc) __attribute__ ((__nothrow__ )) ; # 316 "../stdlib/stdlib.h" extern _Float32 strtof32_l (const char *__restrict __nptr, char **__restrict __endptr, locale_t __loc) __attribute__ ((__nothrow__ )) ; extern _Float64 strtof64_l (const char *__restrict __nptr, char **__restrict __endptr, locale_t __loc) __attribute__ ((__nothrow__ )) ; extern _Float128 strtof128_l (const char *__restrict __nptr, char **__restrict __endptr, locale_t __loc) __attribute__ ((__nothrow__ )) ; extern _Float32x strtof32x_l (const char *__restrict __nptr, char **__restrict __endptr, locale_t __loc) __attribute__ ((__nothrow__ )) ; extern _Float64x strtof64x_l (const char *__restrict __nptr, char **__restrict __endptr, locale_t __loc) __attribute__ ((__nothrow__ )) ; # 360 "../stdlib/stdlib.h" extern __inline int __attribute__ ((__nothrow__ )) atoi (const char *__nptr) { return (int) strtol (__nptr, (char **) # 363 "../stdlib/stdlib.h" 3 4 ((void *)0) # 363 "../stdlib/stdlib.h" , 10); } extern __inline long int __attribute__ ((__nothrow__ )) atol (const char *__nptr) { return strtol (__nptr, (char **) # 368 "../stdlib/stdlib.h" 3 4 ((void *)0) # 368 "../stdlib/stdlib.h" , 10); } __extension__ extern __inline long long int __attribute__ ((__nothrow__ )) atoll (const char *__nptr) { return strtoll (__nptr, (char **) # 375 "../stdlib/stdlib.h" 3 4 ((void *)0) # 375 "../stdlib/stdlib.h" , 10); } # 385 "../stdlib/stdlib.h" extern char *l64a (long int __n) __attribute__ ((__nothrow__ )) ; extern long int a64l (const char *__s) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; # 1 "../include/sys/types.h" 1 # 1 "../posix/sys/types.h" 1 # 27 "../posix/sys/types.h" # 1 "../include/bits/types.h" 1 # 1 "../posix/bits/types.h" 1 # 27 "../posix/bits/types.h" # 1 "../sysdeps/unix/sysv/linux/alpha/bits/wordsize.h" 1 # 28 "../posix/bits/types.h" 2 typedef unsigned char __u_char; typedef unsigned short int __u_short; typedef unsigned int __u_int; typedef unsigned long int __u_long; typedef signed char __int8_t; typedef unsigned char __uint8_t; typedef signed short int __int16_t; typedef unsigned short int __uint16_t; typedef signed int __int32_t; typedef unsigned int __uint32_t; typedef signed long int __int64_t; typedef unsigned long int __uint64_t; typedef __int8_t __int_least8_t; typedef __uint8_t __uint_least8_t; typedef __int16_t __int_least16_t; typedef __uint16_t __uint_least16_t; typedef __int32_t __int_least32_t; typedef __uint32_t __uint_least32_t; typedef __int64_t __int_least64_t; typedef __uint64_t __uint_least64_t; typedef long int __quad_t; typedef unsigned long int __u_quad_t; typedef long int __intmax_t; typedef unsigned long int __uintmax_t; # 140 "../posix/bits/types.h" # 1 "../sysdeps/unix/sysv/linux/alpha/bits/typesizes.h" 1 # 141 "../posix/bits/types.h" 2 typedef unsigned long int __dev_t; typedef unsigned int __uid_t; typedef unsigned int __gid_t; typedef unsigned int __ino_t; typedef unsigned long int __ino64_t; typedef unsigned int __mode_t; typedef unsigned int __nlink_t; typedef long int __off_t; typedef long int __off64_t; typedef int __pid_t; typedef struct { int __val[2]; } __fsid_t; typedef long int __clock_t; typedef unsigned long int __rlim_t; typedef unsigned long int __rlim64_t; typedef unsigned int __id_t; typedef long int __time_t; typedef unsigned int __useconds_t; typedef long int __suseconds_t; typedef int __daddr_t; typedef int __key_t; typedef int __clockid_t; typedef void * __timer_t; typedef unsigned int __blksize_t; typedef unsigned int __blkcnt_t; typedef unsigned long int __blkcnt64_t; typedef int __fsblkcnt_t; typedef long int __fsblkcnt64_t; typedef unsigned int __fsfilcnt_t; typedef unsigned long int __fsfilcnt64_t; typedef int __fsword_t; typedef long int __ssize_t; typedef long int __syscall_slong_t; typedef unsigned long int __syscall_ulong_t; typedef __off64_t __loff_t; typedef char *__caddr_t; typedef long int __intptr_t; typedef unsigned int __socklen_t; typedef int __sig_atomic_t; # 1 "../include/bits/types.h" 2 # 30 "../posix/sys/types.h" 2 typedef __u_char u_char; typedef __u_short u_short; typedef __u_int u_int; typedef __u_long u_long; typedef __quad_t quad_t; typedef __u_quad_t u_quad_t; typedef __fsid_t fsid_t; typedef __loff_t loff_t; typedef __ino_t ino_t; typedef __ino64_t ino64_t; typedef __dev_t dev_t; typedef __gid_t gid_t; typedef __mode_t mode_t; typedef __nlink_t nlink_t; typedef __uid_t uid_t; typedef __off_t off_t; typedef __off64_t off64_t; typedef __pid_t pid_t; typedef __id_t id_t; typedef __ssize_t ssize_t; typedef __daddr_t daddr_t; typedef __caddr_t caddr_t; typedef __key_t key_t; # 1 "../include/bits/types/clock_t.h" 1 # 1 "../time/bits/types/clock_t.h" 1 # 1 "../include/bits/types.h" 1 # 5 "../time/bits/types/clock_t.h" 2 typedef __clock_t clock_t; # 1 "../include/bits/types/clock_t.h" 2 # 127 "../posix/sys/types.h" 2 # 1 "../include/bits/types/clockid_t.h" 1 # 1 "../time/bits/types/clockid_t.h" 1 # 1 "../include/bits/types.h" 1 # 5 "../time/bits/types/clockid_t.h" 2 typedef __clockid_t clockid_t; # 1 "../include/bits/types/clockid_t.h" 2 # 129 "../posix/sys/types.h" 2 # 1 "../include/bits/types/time_t.h" 1 # 1 "../time/bits/types/time_t.h" 1 # 1 "../include/bits/types.h" 1 # 5 "../time/bits/types/time_t.h" 2 typedef __time_t time_t; # 1 "../include/bits/types/time_t.h" 2 # 130 "../posix/sys/types.h" 2 # 1 "../include/bits/types/timer_t.h" 1 # 1 "../time/bits/types/timer_t.h" 1 # 1 "../include/bits/types.h" 1 # 5 "../time/bits/types/timer_t.h" 2 typedef __timer_t timer_t; # 1 "../include/bits/types/timer_t.h" 2 # 131 "../posix/sys/types.h" 2 typedef __useconds_t useconds_t; typedef __suseconds_t suseconds_t; # 1 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 1 3 4 # 145 "../posix/sys/types.h" 2 typedef unsigned long int ulong; typedef unsigned short int ushort; typedef unsigned int uint; # 1 "../bits/stdint-intn.h" 1 # 22 "../bits/stdint-intn.h" # 1 "../include/bits/types.h" 1 # 23 "../bits/stdint-intn.h" 2 typedef __int8_t int8_t; typedef __int16_t int16_t; typedef __int32_t int32_t; typedef __int64_t int64_t; # 156 "../posix/sys/types.h" 2 # 177 "../posix/sys/types.h" typedef unsigned int u_int8_t __attribute__ ((__mode__ (__QI__))); typedef unsigned int u_int16_t __attribute__ ((__mode__ (__HI__))); typedef unsigned int u_int32_t __attribute__ ((__mode__ (__SI__))); typedef unsigned int u_int64_t __attribute__ ((__mode__ (__DI__))); typedef int register_t __attribute__ ((__mode__ (__word__))); # 193 "../posix/sys/types.h" # 1 "../include/endian.h" 1 # 1 "../string/endian.h" 1 # 36 "../string/endian.h" # 1 "../sysdeps/alpha/bits/endian.h" 1 # 37 "../string/endian.h" 2 # 60 "../string/endian.h" # 1 "../bits/byteswap.h" 1 # 27 "../bits/byteswap.h" # 1 "../include/bits/types.h" 1 # 28 "../bits/byteswap.h" 2 static __inline __uint16_t __bswap_16 (__uint16_t __bsx) { return __builtin_bswap16 (__bsx); } static __inline __uint32_t __bswap_32 (__uint32_t __bsx) { return __builtin_bswap32 (__bsx); } # 69 "../bits/byteswap.h" __extension__ static __inline __uint64_t __bswap_64 (__uint64_t __bsx) { return __builtin_bswap64 (__bsx); } # 61 "../string/endian.h" 2 # 1 "../bits/uintn-identity.h" 1 # 26 "../bits/uintn-identity.h" # 1 "../include/bits/types.h" 1 # 27 "../bits/uintn-identity.h" 2 static __inline __uint16_t __uint16_identity (__uint16_t __x) { return __x; } static __inline __uint32_t __uint32_identity (__uint32_t __x) { return __x; } static __inline __uint64_t __uint64_identity (__uint64_t __x) { return __x; } # 62 "../string/endian.h" 2 # 2 "../include/endian.h" 2 # 194 "../posix/sys/types.h" 2 # 1 "../include/sys/select.h" 1 # 1 "../misc/sys/select.h" 1 # 27 "../misc/sys/select.h" # 1 "../include/bits/types.h" 1 # 28 "../misc/sys/select.h" 2 # 1 "../bits/select.h" 1 # 31 "../misc/sys/select.h" 2 # 1 "../include/bits/types/sigset_t.h" 1 # 1 "../signal/bits/types/sigset_t.h" 1 # 1 "../sysdeps/unix/sysv/linux/bits/types/__sigset_t.h" 1 typedef struct { unsigned long int __val[(1024 / (8 * sizeof (unsigned long int)))]; } __sigset_t; # 5 "../signal/bits/types/sigset_t.h" 2 typedef __sigset_t sigset_t; # 1 "../include/bits/types/sigset_t.h" 2 # 34 "../misc/sys/select.h" 2 # 1 "../include/bits/types/time_t.h" 1 # 37 "../misc/sys/select.h" 2 # 1 "../include/bits/types/struct_timeval.h" 1 # 1 "../time/bits/types/struct_timeval.h" 1 # 1 "../include/bits/types.h" 1 # 5 "../time/bits/types/struct_timeval.h" 2 struct timeval { __time_t tv_sec; __suseconds_t tv_usec; }; # 1 "../include/bits/types/struct_timeval.h" 2 # 38 "../misc/sys/select.h" 2 # 1 "../include/bits/types/struct_timespec.h" 1 # 1 "../time/bits/types/struct_timespec.h" 1 # 1 "../include/bits/types.h" 1 # 6 "../time/bits/types/struct_timespec.h" 2 struct timespec { __time_t tv_sec; __syscall_slong_t tv_nsec; }; # 1 "../include/bits/types/struct_timespec.h" 2 # 40 "../misc/sys/select.h" 2 # 49 "../misc/sys/select.h" typedef long int __fd_mask; # 59 "../misc/sys/select.h" typedef struct { __fd_mask fds_bits[1024 / (8 * (int) sizeof (__fd_mask))]; } fd_set; typedef __fd_mask fd_mask; # 91 "../misc/sys/select.h" # 101 "../misc/sys/select.h" extern int select (int __nfds, fd_set *__restrict __readfds, fd_set *__restrict __writefds, fd_set *__restrict __exceptfds, struct timeval *__restrict __timeout); # 113 "../misc/sys/select.h" extern int pselect (int __nfds, fd_set *__restrict __readfds, fd_set *__restrict __writefds, fd_set *__restrict __exceptfds, const struct timespec *__restrict __timeout, const __sigset_t *__restrict __sigmask); # 126 "../misc/sys/select.h" # 3 "../include/sys/select.h" 2 extern int __pselect (int __nfds, fd_set *__readfds, fd_set *__writefds, fd_set *__exceptfds, const struct timespec *__timeout, const __sigset_t *__sigmask); extern int __select (int __nfds, fd_set *__restrict __readfds, fd_set *__restrict __writefds, fd_set *__restrict __exceptfds, struct timeval *__restrict __timeout); extern __typeof (__select) __select __attribute__ ((visibility ("hidden"))); # 197 "../posix/sys/types.h" 2 typedef __blksize_t blksize_t; typedef __blkcnt_t blkcnt_t; typedef __fsblkcnt_t fsblkcnt_t; typedef __fsfilcnt_t fsfilcnt_t; # 236 "../posix/sys/types.h" typedef __blkcnt64_t blkcnt64_t; typedef __fsblkcnt64_t fsblkcnt64_t; typedef __fsfilcnt64_t fsfilcnt64_t; # 1 "../sysdeps/nptl/bits/pthreadtypes.h" 1 # 23 "../sysdeps/nptl/bits/pthreadtypes.h" # 1 "../sysdeps/nptl/bits/thread-shared-types.h" 1 # 77 "../sysdeps/nptl/bits/thread-shared-types.h" # 1 "../sysdeps/alpha/nptl/bits/pthreadtypes-arch.h" 1 # 42 "../sysdeps/alpha/nptl/bits/pthreadtypes-arch.h" struct __pthread_rwlock_arch_t { unsigned int __readers; unsigned int __writers; unsigned int __wrphase_futex; unsigned int __writers_futex; unsigned int __pad3; unsigned int __pad4; int __cur_writer; int __shared; unsigned long int __pad1; unsigned long int __pad2; unsigned int __flags; }; # 78 "../sysdeps/nptl/bits/thread-shared-types.h" 2 typedef struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __pthread_list_t; # 118 "../sysdeps/nptl/bits/thread-shared-types.h" struct __pthread_mutex_s { int __lock ; unsigned int __count; int __owner; unsigned int __nusers; int __kind; int __spins; __pthread_list_t __list; # 145 "../sysdeps/nptl/bits/thread-shared-types.h" }; struct __pthread_cond_s { __extension__ union { __extension__ unsigned long long int __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; __extension__ union { __extension__ unsigned long long int __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2] ; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; }; # 24 "../sysdeps/nptl/bits/pthreadtypes.h" 2 typedef unsigned long int pthread_t; typedef union { char __size[4]; int __align; } pthread_mutexattr_t; typedef union { char __size[4]; int __align; } pthread_condattr_t; typedef unsigned int pthread_key_t; typedef int pthread_once_t; union pthread_attr_t { char __size[56]; long int __align; }; typedef union pthread_attr_t pthread_attr_t; typedef union { struct __pthread_mutex_s __data; char __size[40]; long int __align; } pthread_mutex_t; typedef union { struct __pthread_cond_s __data; char __size[48]; __extension__ long long int __align; } pthread_cond_t; typedef union { struct __pthread_rwlock_arch_t __data; char __size[56]; long int __align; } pthread_rwlock_t; typedef union { char __size[8]; long int __align; } pthread_rwlockattr_t; typedef volatile int pthread_spinlock_t; typedef union { char __size[32]; long int __align; } pthread_barrier_t; typedef union { char __size[4]; int __align; } pthread_barrierattr_t; # 245 "../posix/sys/types.h" 2 # 1 "../include/sys/types.h" 2 # 395 "../stdlib/stdlib.h" 2 extern long int random (void) __attribute__ ((__nothrow__ )); extern void srandom (unsigned int __seed) __attribute__ ((__nothrow__ )); extern char *initstate (unsigned int __seed, char *__statebuf, size_t __statelen) __attribute__ ((__nothrow__ )) ; extern char *setstate (char *__statebuf) __attribute__ ((__nothrow__ )) ; struct random_data { int32_t *fptr; int32_t *rptr; int32_t *state; int rand_type; int rand_deg; int rand_sep; int32_t *end_ptr; }; extern int random_r (struct random_data *__restrict __buf, int32_t *__restrict __result) __attribute__ ((__nothrow__ )) ; extern int srandom_r (unsigned int __seed, struct random_data *__buf) __attribute__ ((__nothrow__ )) ; extern int initstate_r (unsigned int __seed, char *__restrict __statebuf, size_t __statelen, struct random_data *__restrict __buf) __attribute__ ((__nothrow__ )) ; extern int setstate_r (char *__restrict __statebuf, struct random_data *__restrict __buf) __attribute__ ((__nothrow__ )) ; extern int rand (void) __attribute__ ((__nothrow__ )); extern void srand (unsigned int __seed) __attribute__ ((__nothrow__ )); extern int rand_r (unsigned int *__seed) __attribute__ ((__nothrow__ )); extern double drand48 (void) __attribute__ ((__nothrow__ )); extern double erand48 (unsigned short int __xsubi[3]) __attribute__ ((__nothrow__ )) ; extern long int lrand48 (void) __attribute__ ((__nothrow__ )); extern long int nrand48 (unsigned short int __xsubi[3]) __attribute__ ((__nothrow__ )) ; extern long int mrand48 (void) __attribute__ ((__nothrow__ )); extern long int jrand48 (unsigned short int __xsubi[3]) __attribute__ ((__nothrow__ )) ; extern void srand48 (long int __seedval) __attribute__ ((__nothrow__ )); extern unsigned short int *seed48 (unsigned short int __seed16v[3]) __attribute__ ((__nothrow__ )) ; extern void lcong48 (unsigned short int __param[7]) __attribute__ ((__nothrow__ )) ; struct drand48_data { unsigned short int __x[3]; unsigned short int __old_x[3]; unsigned short int __c; unsigned short int __init; __extension__ unsigned long long int __a; }; extern int drand48_r (struct drand48_data *__restrict __buffer, double *__restrict __result) __attribute__ ((__nothrow__ )) ; extern int erand48_r (unsigned short int __xsubi[3], struct drand48_data *__restrict __buffer, double *__restrict __result) __attribute__ ((__nothrow__ )) ; extern int lrand48_r (struct drand48_data *__restrict __buffer, long int *__restrict __result) __attribute__ ((__nothrow__ )) ; extern int nrand48_r (unsigned short int __xsubi[3], struct drand48_data *__restrict __buffer, long int *__restrict __result) __attribute__ ((__nothrow__ )) ; extern int mrand48_r (struct drand48_data *__restrict __buffer, long int *__restrict __result) __attribute__ ((__nothrow__ )) ; extern int jrand48_r (unsigned short int __xsubi[3], struct drand48_data *__restrict __buffer, long int *__restrict __result) __attribute__ ((__nothrow__ )) ; extern int srand48_r (long int __seedval, struct drand48_data *__buffer) __attribute__ ((__nothrow__ )) ; extern int seed48_r (unsigned short int __seed16v[3], struct drand48_data *__buffer) __attribute__ ((__nothrow__ )) ; extern int lcong48_r (unsigned short int __param[7], struct drand48_data *__buffer) __attribute__ ((__nothrow__ )) ; extern void *malloc (size_t __size) __attribute__ ((__nothrow__ )) __attribute__ ((__malloc__)) ; extern void *calloc (size_t __nmemb, size_t __size) __attribute__ ((__nothrow__ )) __attribute__ ((__malloc__)) ; extern void *realloc (void *__ptr, size_t __size) __attribute__ ((__nothrow__ )) __attribute__ ((__warn_unused_result__)); extern void *reallocarray (void *__ptr, size_t __nmemb, size_t __size) __attribute__ ((__nothrow__ )) __attribute__ ((__warn_unused_result__)); extern void free (void *__ptr) __attribute__ ((__nothrow__ )); # 1 "../include/alloca.h" 1 # 1 "../stdlib/alloca.h" 1 # 24 "../stdlib/alloca.h" # 1 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 1 3 4 # 25 "../stdlib/alloca.h" 2 extern void *alloca (size_t __size) __attribute__ ((__nothrow__ )); # 4 "../include/alloca.h" 2 # 1 "../include/stackinfo.h" 1 # 24 "../include/stackinfo.h" # 1 "../sysdeps/alpha/stackinfo.h" 1 # 24 "../sysdeps/alpha/stackinfo.h" # 1 "../include/elf.h" 1 # 1 "../elf/elf.h" 1 # 24 "../elf/elf.h" # 1 "../sysdeps/generic/stdint.h" 1 # 26 "../sysdeps/generic/stdint.h" # 1 "../bits/libc-header-start.h" 1 # 27 "../sysdeps/generic/stdint.h" 2 # 1 "../include/bits/types.h" 1 # 28 "../sysdeps/generic/stdint.h" 2 # 1 "../bits/wchar.h" 1 # 29 "../sysdeps/generic/stdint.h" 2 # 1 "../sysdeps/unix/sysv/linux/alpha/bits/wordsize.h" 1 # 30 "../sysdeps/generic/stdint.h" 2 # 1 "../bits/stdint-uintn.h" 1 # 22 "../bits/stdint-uintn.h" # 1 "../include/bits/types.h" 1 # 23 "../bits/stdint-uintn.h" 2 typedef __uint8_t uint8_t; typedef __uint16_t uint16_t; typedef __uint32_t uint32_t; typedef __uint64_t uint64_t; # 38 "../sysdeps/generic/stdint.h" 2 typedef __int_least8_t int_least8_t; typedef __int_least16_t int_least16_t; typedef __int_least32_t int_least32_t; typedef __int_least64_t int_least64_t; typedef __uint_least8_t uint_least8_t; typedef __uint_least16_t uint_least16_t; typedef __uint_least32_t uint_least32_t; typedef __uint_least64_t uint_least64_t; typedef signed char int_fast8_t; typedef long int int_fast16_t; typedef long int int_fast32_t; typedef long int int_fast64_t; # 71 "../sysdeps/generic/stdint.h" typedef unsigned char uint_fast8_t; typedef unsigned long int uint_fast16_t; typedef unsigned long int uint_fast32_t; typedef unsigned long int uint_fast64_t; # 87 "../sysdeps/generic/stdint.h" typedef long int intptr_t; typedef unsigned long int uintptr_t; # 101 "../sysdeps/generic/stdint.h" typedef __intmax_t intmax_t; typedef __uintmax_t uintmax_t; # 29 "../elf/elf.h" 2 typedef uint16_t Elf32_Half; typedef uint16_t Elf64_Half; typedef uint32_t Elf32_Word; typedef int32_t Elf32_Sword; typedef uint32_t Elf64_Word; typedef int32_t Elf64_Sword; typedef uint64_t Elf32_Xword; typedef int64_t Elf32_Sxword; typedef uint64_t Elf64_Xword; typedef int64_t Elf64_Sxword; typedef uint32_t Elf32_Addr; typedef uint64_t Elf64_Addr; typedef uint32_t Elf32_Off; typedef uint64_t Elf64_Off; typedef uint16_t Elf32_Section; typedef uint16_t Elf64_Section; typedef Elf32_Half Elf32_Versym; typedef Elf64_Half Elf64_Versym; typedef struct { unsigned char e_ident[(16)]; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; } Elf32_Ehdr; typedef struct { unsigned char e_ident[(16)]; Elf64_Half e_type; Elf64_Half e_machine; Elf64_Word e_version; Elf64_Addr e_entry; Elf64_Off e_phoff; Elf64_Off e_shoff; Elf64_Word e_flags; Elf64_Half e_ehsize; Elf64_Half e_phentsize; Elf64_Half e_phnum; Elf64_Half e_shentsize; Elf64_Half e_shnum; Elf64_Half e_shstrndx; } Elf64_Ehdr; # 384 "../elf/elf.h" typedef struct { Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; Elf32_Word sh_addralign; Elf32_Word sh_entsize; } Elf32_Shdr; typedef struct { Elf64_Word sh_name; Elf64_Word sh_type; Elf64_Xword sh_flags; Elf64_Addr sh_addr; Elf64_Off sh_offset; Elf64_Xword sh_size; Elf64_Word sh_link; Elf64_Word sh_info; Elf64_Xword sh_addralign; Elf64_Xword sh_entsize; } Elf64_Shdr; # 491 "../elf/elf.h" typedef struct { Elf32_Word ch_type; Elf32_Word ch_size; Elf32_Word ch_addralign; } Elf32_Chdr; typedef struct { Elf64_Word ch_type; Elf64_Word ch_reserved; Elf64_Xword ch_size; Elf64_Xword ch_addralign; } Elf64_Chdr; # 518 "../elf/elf.h" typedef struct { Elf32_Word st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; unsigned char st_other; Elf32_Section st_shndx; } Elf32_Sym; typedef struct { Elf64_Word st_name; unsigned char st_info; unsigned char st_other; Elf64_Section st_shndx; Elf64_Addr st_value; Elf64_Xword st_size; } Elf64_Sym; typedef struct { Elf32_Half si_boundto; Elf32_Half si_flags; } Elf32_Syminfo; typedef struct { Elf64_Half si_boundto; Elf64_Half si_flags; } Elf64_Syminfo; # 633 "../elf/elf.h" typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; } Elf32_Rel; typedef struct { Elf64_Addr r_offset; Elf64_Xword r_info; } Elf64_Rel; typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; Elf32_Sword r_addend; } Elf32_Rela; typedef struct { Elf64_Addr r_offset; Elf64_Xword r_info; Elf64_Sxword r_addend; } Elf64_Rela; # 678 "../elf/elf.h" typedef struct { Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_Phdr; typedef struct { Elf64_Word p_type; Elf64_Word p_flags; Elf64_Off p_offset; Elf64_Addr p_vaddr; Elf64_Addr p_paddr; Elf64_Xword p_filesz; Elf64_Xword p_memsz; Elf64_Xword p_align; } Elf64_Phdr; # 819 "../elf/elf.h" typedef struct { Elf32_Sword d_tag; union { Elf32_Word d_val; Elf32_Addr d_ptr; } d_un; } Elf32_Dyn; typedef struct { Elf64_Sxword d_tag; union { Elf64_Xword d_val; Elf64_Addr d_ptr; } d_un; } Elf64_Dyn; # 998 "../elf/elf.h" typedef struct { Elf32_Half vd_version; Elf32_Half vd_flags; Elf32_Half vd_ndx; Elf32_Half vd_cnt; Elf32_Word vd_hash; Elf32_Word vd_aux; Elf32_Word vd_next; } Elf32_Verdef; typedef struct { Elf64_Half vd_version; Elf64_Half vd_flags; Elf64_Half vd_ndx; Elf64_Half vd_cnt; Elf64_Word vd_hash; Elf64_Word vd_aux; Elf64_Word vd_next; } Elf64_Verdef; # 1040 "../elf/elf.h" typedef struct { Elf32_Word vda_name; Elf32_Word vda_next; } Elf32_Verdaux; typedef struct { Elf64_Word vda_name; Elf64_Word vda_next; } Elf64_Verdaux; typedef struct { Elf32_Half vn_version; Elf32_Half vn_cnt; Elf32_Word vn_file; Elf32_Word vn_aux; Elf32_Word vn_next; } Elf32_Verneed; typedef struct { Elf64_Half vn_version; Elf64_Half vn_cnt; Elf64_Word vn_file; Elf64_Word vn_aux; Elf64_Word vn_next; } Elf64_Verneed; # 1087 "../elf/elf.h" typedef struct { Elf32_Word vna_hash; Elf32_Half vna_flags; Elf32_Half vna_other; Elf32_Word vna_name; Elf32_Word vna_next; } Elf32_Vernaux; typedef struct { Elf64_Word vna_hash; Elf64_Half vna_flags; Elf64_Half vna_other; Elf64_Word vna_name; Elf64_Word vna_next; } Elf64_Vernaux; # 1121 "../elf/elf.h" typedef struct { uint32_t a_type; union { uint32_t a_val; } a_un; } Elf32_auxv_t; typedef struct { uint64_t a_type; union { uint64_t a_val; } a_un; } Elf64_auxv_t; # 1220 "../elf/elf.h" typedef struct { Elf32_Word n_namesz; Elf32_Word n_descsz; Elf32_Word n_type; } Elf32_Nhdr; typedef struct { Elf64_Word n_namesz; Elf64_Word n_descsz; Elf64_Word n_type; } Elf64_Nhdr; # 1340 "../elf/elf.h" typedef struct { Elf32_Xword m_value; Elf32_Word m_info; Elf32_Word m_poffset; Elf32_Half m_repeat; Elf32_Half m_stride; } Elf32_Move; typedef struct { Elf64_Xword m_value; Elf64_Xword m_info; Elf64_Xword m_poffset; Elf64_Half m_repeat; Elf64_Half m_stride; } Elf64_Move; # 1729 "../elf/elf.h" typedef union { struct { Elf32_Word gt_current_g_value; Elf32_Word gt_unused; } gt_header; struct { Elf32_Word gt_g_value; Elf32_Word gt_bytes; } gt_entry; } Elf32_gptab; typedef struct { Elf32_Word ri_gprmask; Elf32_Word ri_cprmask[4]; Elf32_Sword ri_gp_value; } Elf32_RegInfo; typedef struct { unsigned char kind; unsigned char size; Elf32_Section section; Elf32_Word info; } Elf_Options; # 1805 "../elf/elf.h" typedef struct { Elf32_Word hwp_flags1; Elf32_Word hwp_flags2; } Elf_Options_Hw; # 1971 "../elf/elf.h" typedef struct { Elf32_Word l_name; Elf32_Word l_time_stamp; Elf32_Word l_checksum; Elf32_Word l_version; Elf32_Word l_flags; } Elf32_Lib; typedef struct { Elf64_Word l_name; Elf64_Word l_time_stamp; Elf64_Word l_checksum; Elf64_Word l_version; Elf64_Word l_flags; } Elf64_Lib; # 2002 "../elf/elf.h" typedef Elf32_Addr Elf32_Conflict; typedef struct { Elf32_Half version; unsigned char isa_level; unsigned char isa_rev; unsigned char gpr_size; unsigned char cpr1_size; unsigned char cpr2_size; unsigned char fp_abi; Elf32_Word isa_ext; Elf32_Word ases; Elf32_Word flags1; Elf32_Word flags2; } Elf_MIPS_ABIFlags_v0; # 2078 "../elf/elf.h" enum { Val_GNU_MIPS_ABI_FP_ANY = 0, Val_GNU_MIPS_ABI_FP_DOUBLE = 1, Val_GNU_MIPS_ABI_FP_SINGLE = 2, Val_GNU_MIPS_ABI_FP_SOFT = 3, Val_GNU_MIPS_ABI_FP_OLD_64 = 4, Val_GNU_MIPS_ABI_FP_XX = 5, Val_GNU_MIPS_ABI_FP_64 = 6, Val_GNU_MIPS_ABI_FP_64A = 7, Val_GNU_MIPS_ABI_FP_MAX = 7 }; # 3928 "../elf/elf.h" # 3 "../include/elf.h" 2 # 1 "../include/libc-pointer-arith.h" 1 # 7 "../include/elf.h" 2 # 20 "../include/elf.h" # 1 "../sysdeps/alpha/dl-dtprocnum.h" 1 # 21 "../include/elf.h" 2 # 25 "../sysdeps/alpha/stackinfo.h" 2 # 25 "../include/stackinfo.h" 2 # 8 "../include/alloca.h" 2 extern void *__alloca (size_t __size); extern int __libc_use_alloca (size_t size) __attribute__ ((const)); extern int __libc_alloca_cutoff (size_t size) __attribute__ ((const)); extern __typeof (__libc_alloca_cutoff) __libc_alloca_cutoff __attribute__ ((visibility ("hidden"))); # 1 "../sysdeps/pthread/allocalim.h" 1 # 19 "../sysdeps/pthread/allocalim.h" # 1 "../include/alloca.h" 1 # 20 "../sysdeps/pthread/allocalim.h" 2 # 1 "../include/limits.h" 1 # 26 "../include/limits.h" # 1 "../bits/libc-header-start.h" 1 # 27 "../include/limits.h" 2 # 124 "../include/limits.h" # 1 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include-fixed/limits.h" 1 3 4 # 125 "../include/limits.h" 2 # 183 "../include/limits.h" # 1 "../include/bits/posix1_lim.h" 1 # 1 "../posix/bits/posix1_lim.h" 1 # 27 "../posix/bits/posix1_lim.h" # 1 "../sysdeps/unix/sysv/linux/alpha/bits/wordsize.h" 1 # 28 "../posix/bits/posix1_lim.h" 2 # 161 "../posix/bits/posix1_lim.h" # 1 "../sysdeps/unix/sysv/linux/alpha/bits/local_lim.h" 1 # 38 "../sysdeps/unix/sysv/linux/alpha/bits/local_lim.h" # 1 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/sysroot/usr/include/linux/limits.h" 1 3 4 # 39 "../sysdeps/unix/sysv/linux/alpha/bits/local_lim.h" 2 # 162 "../posix/bits/posix1_lim.h" 2 # 1 "../include/bits/posix1_lim.h" 2 # 184 "../include/limits.h" 2 # 1 "../include/bits/posix2_lim.h" 1 # 1 "../posix/bits/posix2_lim.h" 1 # 1 "../include/bits/posix2_lim.h" 2 # 188 "../include/limits.h" 2 # 1 "../include/bits/xopen_lim.h" 1 # 64 "../include/bits/xopen_lim.h" # 1 "../sysdeps/unix/sysv/linux/bits/uio_lim.h" 1 # 65 "../include/bits/xopen_lim.h" 2 # 192 "../include/limits.h" 2 # 21 "../sysdeps/pthread/allocalim.h" 2 extern __inline __attribute__ ((__always_inline__)) int __libc_use_alloca (size_t size) { return (__builtin_expect ((__libc_alloca_cutoff (size)), 1) || __builtin_expect ((size <= 24576 / 4), 1) ); } # 25 "../include/alloca.h" 2 # 567 "../stdlib/stdlib.h" 2 extern void *valloc (size_t __size) __attribute__ ((__nothrow__ )) __attribute__ ((__malloc__)) ; extern int posix_memalign (void **__memptr, size_t __alignment, size_t __size) __attribute__ ((__nothrow__ )) ; extern void *aligned_alloc (size_t __alignment, size_t __size) __attribute__ ((__nothrow__ )) __attribute__ ((__malloc__)) __attribute__ ((__alloc_size__ (2))) ; extern void abort (void) __attribute__ ((__nothrow__ )) __attribute__ ((__noreturn__)); extern int atexit (void (*__func) (void)) __attribute__ ((__nothrow__ )) ; extern int at_quick_exit (void (*__func) (void)) __attribute__ ((__nothrow__ )) ; extern int on_exit (void (*__func) (int __status, void *__arg), void *__arg) __attribute__ ((__nothrow__ )) ; extern void exit (int __status) __attribute__ ((__nothrow__ )) __attribute__ ((__noreturn__)); extern void quick_exit (int __status) __attribute__ ((__nothrow__ )) __attribute__ ((__noreturn__)); extern void _Exit (int __status) __attribute__ ((__nothrow__ )) __attribute__ ((__noreturn__)); extern char *getenv (const char *__name) __attribute__ ((__nothrow__ )) ; extern char *secure_getenv (const char *__name) __attribute__ ((__nothrow__ )) ; extern int putenv (char *__string) __attribute__ ((__nothrow__ )) ; extern int setenv (const char *__name, const char *__value, int __replace) __attribute__ ((__nothrow__ )) ; extern int unsetenv (const char *__name) __attribute__ ((__nothrow__ )) ; extern int clearenv (void) __attribute__ ((__nothrow__ )); # 672 "../stdlib/stdlib.h" extern char *mktemp (char *__template) __attribute__ ((__nothrow__ )) ; # 685 "../stdlib/stdlib.h" extern int mkstemp (char *__template) ; # 695 "../stdlib/stdlib.h" extern int mkstemp64 (char *__template) ; # 707 "../stdlib/stdlib.h" extern int mkstemps (char *__template, int __suffixlen) ; # 717 "../stdlib/stdlib.h" extern int mkstemps64 (char *__template, int __suffixlen) ; # 728 "../stdlib/stdlib.h" extern char *mkdtemp (char *__template) __attribute__ ((__nothrow__ )) ; # 739 "../stdlib/stdlib.h" extern int mkostemp (char *__template, int __flags) ; # 749 "../stdlib/stdlib.h" extern int mkostemp64 (char *__template, int __flags) ; # 759 "../stdlib/stdlib.h" extern int mkostemps (char *__template, int __suffixlen, int __flags) ; # 771 "../stdlib/stdlib.h" extern int mkostemps64 (char *__template, int __suffixlen, int __flags) ; # 781 "../stdlib/stdlib.h" extern int system (const char *__command) ; extern char *canonicalize_file_name (const char *__name) __attribute__ ((__nothrow__ )) ; # 797 "../stdlib/stdlib.h" extern char *realpath (const char *__restrict __name, char *__restrict __resolved) __attribute__ ((__nothrow__ )) ; typedef int (*__compar_fn_t) (const void *, const void *); typedef __compar_fn_t comparison_fn_t; typedef int (*__compar_d_fn_t) (const void *, const void *, void *); extern void *bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size, __compar_fn_t __compar) ; # 1 "../bits/stdlib-bsearch.h" 1 # 19 "../bits/stdlib-bsearch.h" extern __inline void * bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size, __compar_fn_t __compar) { size_t __l, __u, __idx; const void *__p; int __comparison; __l = 0; __u = __nmemb; while (__l < __u) { __idx = (__l + __u) / 2; __p = (void *) (((const char *) __base) + (__idx * __size)); __comparison = (*__compar) (__key, __p); if (__comparison < 0) __u = __idx; else if (__comparison > 0) __l = __idx + 1; else return (void *) __p; } return # 42 "../bits/stdlib-bsearch.h" 3 4 ((void *)0) # 42 "../bits/stdlib-bsearch.h" ; } # 823 "../stdlib/stdlib.h" 2 extern void qsort (void *__base, size_t __nmemb, size_t __size, __compar_fn_t __compar) ; extern void qsort_r (void *__base, size_t __nmemb, size_t __size, __compar_d_fn_t __compar, void *__arg) ; extern int abs (int __x) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)) ; extern long int labs (long int __x) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)) ; __extension__ extern long long int llabs (long long int __x) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)) ; extern div_t div (int __numer, int __denom) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)) ; extern ldiv_t ldiv (long int __numer, long int __denom) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)) ; __extension__ extern lldiv_t lldiv (long long int __numer, long long int __denom) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)) ; # 869 "../stdlib/stdlib.h" extern char *ecvt (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign) __attribute__ ((__nothrow__ )) ; extern char *fcvt (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign) __attribute__ ((__nothrow__ )) ; extern char *gcvt (double __value, int __ndigit, char *__buf) __attribute__ ((__nothrow__ )) ; extern char *qecvt (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign) __attribute__ ((__nothrow__ )) ; extern char *qfcvt (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign) __attribute__ ((__nothrow__ )) ; extern char *qgcvt (long double __value, int __ndigit, char *__buf) __attribute__ ((__nothrow__ )) ; extern int ecvt_r (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len) __attribute__ ((__nothrow__ )) ; extern int fcvt_r (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len) __attribute__ ((__nothrow__ )) ; extern int qecvt_r (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len) __attribute__ ((__nothrow__ )) ; extern int qfcvt_r (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len) __attribute__ ((__nothrow__ )) ; extern int mblen (const char *__s, size_t __n) __attribute__ ((__nothrow__ )); extern int mbtowc (wchar_t *__restrict __pwc, const char *__restrict __s, size_t __n) __attribute__ ((__nothrow__ )); extern int wctomb (char *__s, wchar_t __wchar) __attribute__ ((__nothrow__ )); extern size_t mbstowcs (wchar_t *__restrict __pwcs, const char *__restrict __s, size_t __n) __attribute__ ((__nothrow__ )); extern size_t wcstombs (char *__restrict __s, const wchar_t *__restrict __pwcs, size_t __n) __attribute__ ((__nothrow__ )); extern int rpmatch (const char *__response) __attribute__ ((__nothrow__ )) ; # 954 "../stdlib/stdlib.h" extern int getsubopt (char **__restrict __optionp, char *const *__restrict __tokens, char **__restrict __valuep) __attribute__ ((__nothrow__ )) ; extern int posix_openpt (int __oflag) ; extern int grantpt (int __fd) __attribute__ ((__nothrow__ )); extern int unlockpt (int __fd) __attribute__ ((__nothrow__ )); extern char *ptsname (int __fd) __attribute__ ((__nothrow__ )) ; extern int ptsname_r (int __fd, char *__buf, size_t __buflen) __attribute__ ((__nothrow__ )) ; extern int getpt (void); extern int getloadavg (double __loadavg[], int __nelem) __attribute__ ((__nothrow__ )) ; # 1010 "../stdlib/stdlib.h" # 1 "../include/bits/stdlib-float.h" 1 # 1 "../stdlib/bits/stdlib-float.h" 1 # 24 "../stdlib/bits/stdlib-float.h" extern __inline double __attribute__ ((__nothrow__ )) atof (const char *__nptr) { return strtod (__nptr, (char **) # 27 "../stdlib/bits/stdlib-float.h" 3 4 ((void *)0) # 27 "../stdlib/bits/stdlib-float.h" ); } # 7 "../include/bits/stdlib-float.h" 2 # 1011 "../stdlib/stdlib.h" 2 # 1020 "../stdlib/stdlib.h" # 7 "../include/stdlib.h" 2 # 1 "../include/sys/stat.h" 1 # 1 "../io/sys/stat.h" 1 # 27 "../io/sys/stat.h" # 1 "../include/bits/types.h" 1 # 28 "../io/sys/stat.h" 2 # 1 "../include/bits/types/struct_timespec.h" 1 # 31 "../io/sys/stat.h" 2 # 1 "../include/bits/types/time_t.h" 1 # 38 "../io/sys/stat.h" 2 # 99 "../io/sys/stat.h" # 1 "../sysdeps/unix/sysv/linux/alpha/bits/stat.h" 1 # 69 "../sysdeps/unix/sysv/linux/alpha/bits/stat.h" struct stat { __dev_t st_dev; __ino_t st_ino; int __pad0; __dev_t st_rdev; __off_t st_size; __blkcnt_t st_blocks; int __pad1; __mode_t st_mode; __uid_t st_uid; __gid_t st_gid; __blksize_t st_blksize; __nlink_t st_nlink; int __pad2; __extension__ union { struct timespec st_atim; struct { __time_t st_atime; unsigned long st_atimensec; }; }; __extension__ union { struct timespec st_mtim; struct { __time_t st_mtime; unsigned long st_mtimensec; }; }; __extension__ union { struct timespec st_ctim; struct { __time_t st_ctime; unsigned long st_ctimensec; }; }; long __glibc_reserved[3]; }; struct stat64 { __dev_t st_dev; __ino64_t st_ino; __dev_t st_rdev; __off_t st_size; __blkcnt64_t st_blocks; __mode_t st_mode; __uid_t st_uid; __gid_t st_gid; __blksize_t st_blksize; __nlink_t st_nlink; int __pad0; __extension__ union { struct timespec st_atim; struct { __time_t st_atime; unsigned long st_atimensec; }; }; __extension__ union { struct timespec st_mtim; struct { __time_t st_mtime; unsigned long st_mtimensec; }; }; __extension__ union { struct timespec st_ctim; struct { __time_t st_ctime; unsigned long st_ctimensec; }; }; long __glibc_reserved[3]; }; # 102 "../io/sys/stat.h" 2 # 205 "../io/sys/stat.h" extern int stat (const char *__restrict __file, struct stat *__restrict __buf) __attribute__ ((__nothrow__ )) ; extern int fstat (int __fd, struct stat *__buf) __attribute__ ((__nothrow__ )) ; # 224 "../io/sys/stat.h" extern int stat64 (const char *__restrict __file, struct stat64 *__restrict __buf) __attribute__ ((__nothrow__ )) ; extern int fstat64 (int __fd, struct stat64 *__buf) __attribute__ ((__nothrow__ )) ; extern int fstatat (int __fd, const char *__restrict __file, struct stat *__restrict __buf, int __flag) __attribute__ ((__nothrow__ )) ; # 249 "../io/sys/stat.h" extern int fstatat64 (int __fd, const char *__restrict __file, struct stat64 *__restrict __buf, int __flag) __attribute__ ((__nothrow__ )) ; extern int lstat (const char *__restrict __file, struct stat *__restrict __buf) __attribute__ ((__nothrow__ )) ; # 272 "../io/sys/stat.h" extern int lstat64 (const char *__restrict __file, struct stat64 *__restrict __buf) __attribute__ ((__nothrow__ )) ; extern int chmod (const char *__file, __mode_t __mode) __attribute__ ((__nothrow__ )) ; extern int lchmod (const char *__file, __mode_t __mode) __attribute__ ((__nothrow__ )) ; extern int fchmod (int __fd, __mode_t __mode) __attribute__ ((__nothrow__ )); extern int fchmodat (int __fd, const char *__file, __mode_t __mode, int __flag) __attribute__ ((__nothrow__ )) ; extern __mode_t umask (__mode_t __mask) __attribute__ ((__nothrow__ )); extern __mode_t getumask (void) __attribute__ ((__nothrow__ )); extern int mkdir (const char *__path, __mode_t __mode) __attribute__ ((__nothrow__ )) ; extern int mkdirat (int __fd, const char *__path, __mode_t __mode) __attribute__ ((__nothrow__ )) ; extern int mknod (const char *__path, __mode_t __mode, __dev_t __dev) __attribute__ ((__nothrow__ )) ; extern int mknodat (int __fd, const char *__path, __mode_t __mode, __dev_t __dev) __attribute__ ((__nothrow__ )) ; extern int mkfifo (const char *__path, __mode_t __mode) __attribute__ ((__nothrow__ )) ; extern int mkfifoat (int __fd, const char *__path, __mode_t __mode) __attribute__ ((__nothrow__ )) ; extern int utimensat (int __fd, const char *__path, const struct timespec __times[2], int __flags) __attribute__ ((__nothrow__ )) ; extern int futimens (int __fd, const struct timespec __times[2]) __attribute__ ((__nothrow__ )); # 395 "../io/sys/stat.h" extern int __fxstat (int __ver, int __fildes, struct stat *__stat_buf) __attribute__ ((__nothrow__ )) ; extern int __xstat (int __ver, const char *__filename, struct stat *__stat_buf) __attribute__ ((__nothrow__ )) ; extern int __lxstat (int __ver, const char *__filename, struct stat *__stat_buf) __attribute__ ((__nothrow__ )) ; extern int __fxstatat (int __ver, int __fildes, const char *__filename, struct stat *__stat_buf, int __flag) __attribute__ ((__nothrow__ )) ; # 428 "../io/sys/stat.h" extern int __fxstat64 (int __ver, int __fildes, struct stat64 *__stat_buf) __attribute__ ((__nothrow__ )) ; extern int __xstat64 (int __ver, const char *__filename, struct stat64 *__stat_buf) __attribute__ ((__nothrow__ )) ; extern int __lxstat64 (int __ver, const char *__filename, struct stat64 *__stat_buf) __attribute__ ((__nothrow__ )) ; extern int __fxstatat64 (int __ver, int __fildes, const char *__filename, struct stat64 *__stat_buf, int __flag) __attribute__ ((__nothrow__ )) ; extern int __xmknod (int __ver, const char *__path, __mode_t __mode, __dev_t *__dev) __attribute__ ((__nothrow__ )) ; extern int __xmknodat (int __ver, int __fd, const char *__path, __mode_t __mode, __dev_t *__dev) __attribute__ ((__nothrow__ )) ; # 1 "../include/bits/statx.h" 1 # 1 "../io/bits/statx.h" 1 # 25 "../io/bits/statx.h" struct statx_timestamp { __int64_t tv_sec; __uint32_t tv_nsec; __int32_t __statx_timestamp_pad1[1]; }; struct statx { __uint32_t stx_mask; __uint32_t stx_blksize; __uint64_t stx_attributes; __uint32_t stx_nlink; __uint32_t stx_uid; __uint32_t stx_gid; __uint16_t stx_mode; __uint16_t __statx_pad1[1]; __uint64_t stx_ino; __uint64_t stx_size; __uint64_t stx_blocks; __uint64_t stx_attributes_mask; struct statx_timestamp stx_atime; struct statx_timestamp stx_btime; struct statx_timestamp stx_ctime; struct statx_timestamp stx_mtime; __uint32_t stx_rdev_major; __uint32_t stx_rdev_minor; __uint32_t stx_dev_major; __uint32_t stx_dev_minor; __uint64_t __statx_pad2[14]; }; # 84 "../io/bits/statx.h" int statx (int __dirfd, const char *__restrict __path, int __flags, unsigned int __mask, struct statx *__restrict __buf) __attribute__ ((__nothrow__ )) ; # 1 "../include/bits/statx.h" 2 # 447 "../io/sys/stat.h" 2 extern __inline int __attribute__ ((__nothrow__ )) stat (const char *__path, struct stat *__statbuf) { return __xstat (3, __path, __statbuf); } extern __inline int __attribute__ ((__nothrow__ )) lstat (const char *__path, struct stat *__statbuf) { return __lxstat (3, __path, __statbuf); } extern __inline int __attribute__ ((__nothrow__ )) fstat (int __fd, struct stat *__statbuf) { return __fxstat (3, __fd, __statbuf); } extern __inline int __attribute__ ((__nothrow__ )) fstatat (int __fd, const char *__filename, struct stat *__statbuf, int __flag) { return __fxstatat (3, __fd, __filename, __statbuf, __flag); } extern __inline int __attribute__ ((__nothrow__ )) mknod (const char *__path, __mode_t __mode, __dev_t __dev) { return __xmknod (0, __path, __mode, &__dev); } extern __inline int __attribute__ ((__nothrow__ )) mknodat (int __fd, const char *__path, __mode_t __mode, __dev_t __dev) { return __xmknodat (0, __fd, __path, __mode, &__dev); } extern __inline int __attribute__ ((__nothrow__ )) stat64 (const char *__path, struct stat64 *__statbuf) { return __xstat64 (3, __path, __statbuf); } extern __inline int __attribute__ ((__nothrow__ )) lstat64 (const char *__path, struct stat64 *__statbuf) { return __lxstat64 (3, __path, __statbuf); } extern __inline int __attribute__ ((__nothrow__ )) fstat64 (int __fd, struct stat64 *__statbuf) { return __fxstat64 (3, __fd, __statbuf); } extern __inline int __attribute__ ((__nothrow__ )) fstatat64 (int __fd, const char *__filename, struct stat64 *__statbuf, int __flag) { return __fxstatat64 (3, __fd, __filename, __statbuf, __flag); } # 3 "../include/sys/stat.h" 2 extern int __stat (const char *__file, struct stat *__buf); extern int __fstat (int __fd, struct stat *__buf); extern int __lstat (const char *__file, struct stat *__buf); extern int __chmod (const char *__file, __mode_t __mode); extern __typeof (__chmod) __chmod __attribute__ ((visibility ("hidden"))); extern int __fchmod (int __fd, __mode_t __mode); extern __mode_t __umask (__mode_t __mask); extern int __mkdir (const char *__path, __mode_t __mode); extern __typeof (__mkdir) __mkdir __attribute__ ((visibility ("hidden"))); extern int __mknod (const char *__path, __mode_t __mode, __dev_t __dev); extern __typeof (__fxstat) __fxstat __attribute__ ((visibility ("hidden"))); extern __typeof (__fxstat64) __fxstat64 __attribute__ ((visibility ("hidden"))); extern __typeof (__lxstat) __lxstat __attribute__ ((visibility ("hidden"))); extern __typeof (__lxstat64) __lxstat64 __attribute__ ((visibility ("hidden"))); extern __typeof (__xstat) __xstat __attribute__ ((visibility ("hidden"))); extern __typeof (__xstat64) __xstat64 __attribute__ ((visibility ("hidden"))); extern __inline__ int __stat (const char *__path, struct stat *__statbuf) { return __xstat (3, __path, __statbuf); } extern __typeof (__xmknod) __xmknod __attribute__ ((visibility ("hidden"))); extern __inline__ int __mknod (const char *__path, __mode_t __mode, __dev_t __dev) { return __xmknod (0, __path, __mode, &__dev); } extern __typeof (__xmknodat) __xmknodat __attribute__ ((visibility ("hidden"))); extern __typeof (__fxstatat) __fxstatat __attribute__ ((visibility ("hidden"))); extern __typeof (__fxstatat64) __fxstatat64 __attribute__ ((visibility ("hidden"))); # 11 "../include/stdlib.h" 2 extern __typeof (strtol_l) __strtol_l; extern __typeof (strtoul_l) __strtoul_l; extern __typeof (strtoll_l) __strtoll_l; extern __typeof (strtoull_l) __strtoull_l; extern __typeof (strtod_l) __strtod_l; extern __typeof (strtof_l) __strtof_l; extern __typeof (strtold_l) __strtold_l; extern __typeof (__strtol_l) __strtol_l __attribute__ ((visibility ("hidden"))); extern __typeof (__strtoul_l) __strtoul_l __attribute__ ((visibility ("hidden"))); extern __typeof (__strtoll_l) __strtoll_l __attribute__ ((visibility ("hidden"))); extern __typeof (__strtoull_l) __strtoull_l __attribute__ ((visibility ("hidden"))); extern __typeof (__strtod_l) __strtod_l __attribute__ ((visibility ("hidden"))); extern __typeof (__strtof_l) __strtof_l __attribute__ ((visibility ("hidden"))); extern __typeof (__strtold_l) __strtold_l __attribute__ ((visibility ("hidden"))); extern __typeof (exit) exit __attribute__ ((visibility ("hidden"))); extern __typeof (abort) abort __attribute__ ((visibility ("hidden"))); extern __typeof (getenv) getenv __attribute__ ((visibility ("hidden"))); extern __typeof (secure_getenv) __libc_secure_getenv; extern __typeof (__libc_secure_getenv) __libc_secure_getenv __attribute__ ((visibility ("hidden"))); extern __typeof (bsearch) bsearch __attribute__ ((visibility ("hidden"))); extern __typeof (qsort) qsort __attribute__ ((visibility ("hidden"))); extern __typeof (qsort_r) __qsort_r; extern __typeof (__qsort_r) __qsort_r __attribute__ ((visibility ("hidden"))); extern __typeof (lrand48_r) lrand48_r __attribute__ ((visibility ("hidden"))); extern __typeof (wctomb) wctomb __attribute__ ((visibility ("hidden"))); extern long int __random (void) ; extern void __srandom (unsigned int __seed); extern char *__initstate (unsigned int __seed, char *__statebuf, size_t __statelen); extern char *__setstate (char *__statebuf); extern int __random_r (struct random_data *__buf, int32_t *__result) ; extern int __srandom_r (unsigned int __seed, struct random_data *__buf) ; extern int __initstate_r (unsigned int __seed, char *__statebuf, size_t __statelen, struct random_data *__buf) ; extern int __setstate_r (char *__statebuf, struct random_data *__buf) ; extern int __rand_r (unsigned int *__seed); extern int __erand48_r (unsigned short int __xsubi[3], struct drand48_data *__buffer, double *__result) ; extern int __nrand48_r (unsigned short int __xsubi[3], struct drand48_data *__buffer, long int *__result) ; extern int __jrand48_r (unsigned short int __xsubi[3], struct drand48_data *__buffer, long int *__result) ; extern int __srand48_r (long int __seedval, struct drand48_data *__buffer) ; extern int __seed48_r (unsigned short int __seed16v[3], struct drand48_data *__buffer) ; extern int __lcong48_r (unsigned short int __param[7], struct drand48_data *__buffer) ; extern int __drand48_iterate (unsigned short int __xsubi[3], struct drand48_data *__buffer) ; extern struct drand48_data __libc_drand48_data ; extern int __setenv (const char *__name, const char *__value, int __replace) ; extern int __unsetenv (const char *__name) ; extern int __clearenv (void) ; extern char *__mktemp (char *__template) __attribute__ ((__nothrow__ )) ; extern char *__canonicalize_file_name (const char *__name); extern char *__realpath (const char *__name, char *__resolved); extern __typeof (__realpath) __realpath __attribute__ ((visibility ("hidden"))); extern int __ptsname_r (int __fd, char *__buf, size_t __buflen) ; extern int __ptsname_internal (int fd, char *buf, size_t buflen, struct stat64 *stp) ; extern int __getpt (void); extern int __posix_openpt (int __oflag) ; extern int __add_to_environ (const char *name, const char *value, const char *combines, int replace) ; extern void _quicksort (void *const pbase, size_t total_elems, size_t size, __compar_d_fn_t cmp, void *arg); extern int __on_exit (void (*__func) (int __status, void *__arg), void *__arg); extern int __cxa_atexit (void (*func) (void *), void *arg, void *d); extern __typeof (__cxa_atexit) __cxa_atexit __attribute__ ((visibility ("hidden")));; extern int __cxa_thread_atexit_impl (void (*func) (void *), void *arg, void *d); extern void __call_tls_dtors (void) __attribute__ ((weak)) ; extern __typeof (__call_tls_dtors) __call_tls_dtors __attribute__ ((visibility ("hidden"))); extern void __cxa_finalize (void *d); extern int __posix_memalign (void **memptr, size_t alignment, size_t size); extern void *__libc_memalign (size_t alignment, size_t size) __attribute__ ((__malloc__)); extern void *__libc_reallocarray (void *__ptr, size_t __nmemb, size_t __size) __attribute__ ((__nothrow__ )) __attribute__ ((__warn_unused_result__)); extern __typeof (__libc_reallocarray) __libc_reallocarray __attribute__ ((visibility ("hidden"))); extern int __libc_system (const char *line); extern double __strtod_internal (const char *__restrict __nptr, char **__restrict __endptr, int __group) __attribute__ ((__nothrow__ )) ; extern float __strtof_internal (const char *__restrict __nptr, char **__restrict __endptr, int __group) __attribute__ ((__nothrow__ )) ; extern long double __strtold_internal (const char *__restrict __nptr, char **__restrict __endptr, int __group) __attribute__ ((__nothrow__ )) ; extern long int __strtol_internal (const char *__restrict __nptr, char **__restrict __endptr, int __base, int __group) __attribute__ ((__nothrow__ )) ; extern unsigned long int __strtoul_internal (const char *__restrict __nptr, char **__restrict __endptr, int __base, int __group) __attribute__ ((__nothrow__ )) ; __extension__ extern long long int __strtoll_internal (const char *__restrict __nptr, char **__restrict __endptr, int __base, int __group) __attribute__ ((__nothrow__ )) ; __extension__ extern unsigned long long int __strtoull_internal (const char * __restrict __nptr, char **__restrict __endptr, int __base, int __group) __attribute__ ((__nothrow__ )) ; extern __typeof (__strtof_internal) __strtof_internal __attribute__ ((visibility ("hidden"))); extern __typeof (__strtod_internal) __strtod_internal __attribute__ ((visibility ("hidden"))); extern __typeof (__strtold_internal) __strtold_internal __attribute__ ((visibility ("hidden"))); extern __typeof (__strtol_internal) __strtol_internal __attribute__ ((visibility ("hidden"))); extern __typeof (__strtoll_internal) __strtoll_internal __attribute__ ((visibility ("hidden"))); extern __typeof (__strtoul_internal) __strtoul_internal __attribute__ ((visibility ("hidden"))); extern __typeof (__strtoull_internal) __strtoull_internal __attribute__ ((visibility ("hidden"))); extern double ____strtod_l_internal (const char *__restrict __nptr, char **__restrict __endptr, int __group, locale_t __loc); extern float ____strtof_l_internal (const char *__restrict __nptr, char **__restrict __endptr, int __group, locale_t __loc); extern long double ____strtold_l_internal (const char *__restrict __nptr, char **__restrict __endptr, int __group, locale_t __loc); extern long int ____strtol_l_internal (const char *__restrict __nptr, char **__restrict __endptr, int __base, int __group, locale_t __loc); extern unsigned long int ____strtoul_l_internal (const char * __restrict __nptr, char **__restrict __endptr, int __base, int __group, locale_t __loc); __extension__ extern long long int ____strtoll_l_internal (const char *__restrict __nptr, char **__restrict __endptr, int __base, int __group, locale_t __loc); __extension__ extern unsigned long long int ____strtoull_l_internal (const char * __restrict __nptr, char ** __restrict __endptr, int __base, int __group, locale_t __loc); extern __typeof (____strtof_l_internal) ____strtof_l_internal __attribute__ ((visibility ("hidden"))); extern __typeof (____strtod_l_internal) ____strtod_l_internal __attribute__ ((visibility ("hidden"))); extern __typeof (____strtold_l_internal) ____strtold_l_internal __attribute__ ((visibility ("hidden"))); extern __typeof (____strtol_l_internal) ____strtol_l_internal __attribute__ ((visibility ("hidden"))); extern __typeof (____strtoll_l_internal) ____strtoll_l_internal __attribute__ ((visibility ("hidden"))); extern __typeof (____strtoul_l_internal) ____strtoul_l_internal __attribute__ ((visibility ("hidden"))); extern __typeof (____strtoull_l_internal) ____strtoull_l_internal __attribute__ ((visibility ("hidden"))); extern __typeof (strtof) strtof __attribute__ ((visibility ("hidden"))); extern __typeof (strtod) strtod __attribute__ ((visibility ("hidden"))); extern __typeof (strtold) strtold __attribute__ ((visibility ("hidden"))); extern __typeof (strtol) strtol __attribute__ ((visibility ("hidden"))); extern __typeof (strtoll) strtoll __attribute__ ((visibility ("hidden"))); extern __typeof (strtoul) strtoul __attribute__ ((visibility ("hidden"))); extern __typeof (strtoull) strtoull __attribute__ ((visibility ("hidden"))); extern __typeof (atoi) atoi __attribute__ ((visibility ("hidden"))); extern float __strtof_nan (const char *, char **, char); extern double __strtod_nan (const char *, char **, char); extern long double __strtold_nan (const char *, char **, char); extern float __wcstof_nan (const wchar_t *, wchar_t **, wchar_t); extern double __wcstod_nan (const wchar_t *, wchar_t **, wchar_t); extern long double __wcstold_nan (const wchar_t *, wchar_t **, wchar_t); extern __typeof (__strtof_nan) __strtof_nan __attribute__ ((visibility ("hidden"))); extern __typeof (__strtod_nan) __strtod_nan __attribute__ ((visibility ("hidden"))); extern __typeof (__strtold_nan) __strtold_nan __attribute__ ((visibility ("hidden"))); extern __typeof (__wcstof_nan) __wcstof_nan __attribute__ ((visibility ("hidden"))); extern __typeof (__wcstod_nan) __wcstod_nan __attribute__ ((visibility ("hidden"))); extern __typeof (__wcstold_nan) __wcstold_nan __attribute__ ((visibility ("hidden"))); # 256 "../include/stdlib.h" extern char *__ecvt (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign); extern char *__fcvt (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign); extern char *__gcvt (double __value, int __ndigit, char *__buf); extern int __ecvt_r (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len); extern __typeof (__ecvt_r) __ecvt_r __attribute__ ((visibility ("hidden"))); extern int __fcvt_r (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len); extern __typeof (__fcvt_r) __fcvt_r __attribute__ ((visibility ("hidden"))); extern char *__qecvt (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign); extern char *__qfcvt (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign); extern char *__qgcvt (long double __value, int __ndigit, char *__buf); extern int __qecvt_r (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len); extern __typeof (__qecvt_r) __qecvt_r __attribute__ ((visibility ("hidden"))); extern int __qfcvt_r (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len); extern __typeof (__qfcvt_r) __qfcvt_r __attribute__ ((visibility ("hidden"))); extern void *__default_morecore (ptrdiff_t) __attribute__ ((__nothrow__ )); extern __typeof (__default_morecore) __default_morecore __attribute__ ((visibility ("hidden"))); struct abort_msg_s { unsigned int size; char msg[0]; }; extern struct abort_msg_s *__abort_msg; extern __typeof (__abort_msg) __abort_msg __attribute__ ((visibility ("hidden"))); # 34 "plural.y" 2 # 1 "../include/string.h" 1 # 1 "../include/sys/types.h" 1 # 7 "../include/string.h" 2 extern void *__memccpy (void *__dest, const void *__src, int __c, size_t __n); extern size_t __strnlen (const char *__string, size_t __maxlen) __attribute__ ((__pure__)); extern char *__strsep (char **__stringp, const char *__delim); extern __typeof (__strsep) __strsep __attribute__ ((visibility ("hidden"))); extern int __strverscmp (const char *__s1, const char *__s2) __attribute__ ((__pure__)); extern int __strncasecmp (const char *__s1, const char *__s2, size_t __n) __attribute__ ((__pure__)); extern int __strcasecmp (const char *__s1, const char *__s2) __attribute__ ((__pure__)); extern char *__strcasestr (const char *__haystack, const char *__needle) __attribute__ ((__pure__)); extern char *__strdup (const char *__string) __attribute__ ((__malloc__)); extern char *__strndup (const char *__string, size_t __n) __attribute__ ((__malloc__)); extern void *__rawmemchr (const void *__s, int __c) __attribute__ ((__pure__)); extern char *__strchrnul (const char *__s, int __c) __attribute__ ((__pure__)); extern void *__memrchr (const void *__s, int __c, size_t __n) __attribute__ ((__pure__)); extern void *__memchr (const void *__s, int __c, size_t __n) __attribute__ ((__pure__)); extern void __bzero (void *__s, size_t __n) __attribute__ ((__nothrow__ )) ; extern int __ffs (int __i) __attribute__ ((const)); extern char *__strerror_r (int __errnum, char *__buf, size_t __buflen); void __strerror_thread_freeres (void) ; # 1 "../sysdeps/generic/string_private.h" 1 # 58 "../include/string.h" 2 # 1 "../string/string.h" 1 # 26 "../string/string.h" # 1 "../bits/libc-header-start.h" 1 # 27 "../string/string.h" 2 # 1 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 1 3 4 # 34 "../string/string.h" 2 # 42 "../string/string.h" extern void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n) __attribute__ ((__nothrow__ )) ; extern void *memmove (void *__dest, const void *__src, size_t __n) __attribute__ ((__nothrow__ )) ; extern void *memccpy (void *__restrict __dest, const void *__restrict __src, int __c, size_t __n) __attribute__ ((__nothrow__ )) ; extern void *memset (void *__s, int __c, size_t __n) __attribute__ ((__nothrow__ )) ; extern int memcmp (const void *__s1, const void *__s2, size_t __n) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; # 90 "../string/string.h" extern void *memchr (const void *__s, int __c, size_t __n) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; # 103 "../string/string.h" extern void *rawmemchr (const void *__s, int __c) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; # 114 "../string/string.h" extern void *memrchr (const void *__s, int __c, size_t __n) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern char *strcpy (char *__restrict __dest, const char *__restrict __src) __attribute__ ((__nothrow__ )) ; extern char *strncpy (char *__restrict __dest, const char *__restrict __src, size_t __n) __attribute__ ((__nothrow__ )) ; extern char *strcat (char *__restrict __dest, const char *__restrict __src) __attribute__ ((__nothrow__ )) ; extern char *strncat (char *__restrict __dest, const char *__restrict __src, size_t __n) __attribute__ ((__nothrow__ )) ; extern int strcmp (const char *__s1, const char *__s2) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern int strncmp (const char *__s1, const char *__s2, size_t __n) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern int strcoll (const char *__s1, const char *__s2) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern size_t strxfrm (char *__restrict __dest, const char *__restrict __src, size_t __n) __attribute__ ((__nothrow__ )) ; # 1 "../include/bits/types/locale_t.h" 1 # 153 "../string/string.h" 2 extern int strcoll_l (const char *__s1, const char *__s2, locale_t __l) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern size_t strxfrm_l (char *__dest, const char *__src, size_t __n, locale_t __l) __attribute__ ((__nothrow__ )) ; extern char *strdup (const char *__s) __attribute__ ((__nothrow__ )) __attribute__ ((__malloc__)) ; extern char *strndup (const char *__string, size_t __n) __attribute__ ((__nothrow__ )) __attribute__ ((__malloc__)) ; # 225 "../string/string.h" extern char *strchr (const char *__s, int __c) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; # 252 "../string/string.h" extern char *strrchr (const char *__s, int __c) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; # 265 "../string/string.h" extern char *strchrnul (const char *__s, int __c) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern size_t strcspn (const char *__s, const char *__reject) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern size_t strspn (const char *__s, const char *__accept) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; # 302 "../string/string.h" extern char *strpbrk (const char *__s, const char *__accept) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; # 329 "../string/string.h" extern char *strstr (const char *__haystack, const char *__needle) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern char *strtok (char *__restrict __s, const char *__restrict __delim) __attribute__ ((__nothrow__ )) ; extern char *__strtok_r (char *__restrict __s, const char *__restrict __delim, char **__restrict __save_ptr) __attribute__ ((__nothrow__ )) ; extern char *strtok_r (char *__restrict __s, const char *__restrict __delim, char **__restrict __save_ptr) __attribute__ ((__nothrow__ )) ; # 359 "../string/string.h" extern char *strcasestr (const char *__haystack, const char *__needle) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern void *memmem (const void *__haystack, size_t __haystacklen, const void *__needle, size_t __needlelen) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern void *__mempcpy (void *__restrict __dest, const void *__restrict __src, size_t __n) __attribute__ ((__nothrow__ )) ; extern void *mempcpy (void *__restrict __dest, const void *__restrict __src, size_t __n) __attribute__ ((__nothrow__ )) ; extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern size_t strnlen (const char *__string, size_t __maxlen) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern char *strerror (int __errnum) __attribute__ ((__nothrow__ )); # 420 "../string/string.h" extern char *strerror_r (int __errnum, char *__buf, size_t __buflen) __attribute__ ((__nothrow__ )) ; extern char *strerror_l (int __errnum, locale_t __l) __attribute__ ((__nothrow__ )); # 1 "../include/strings.h" 1 # 1 "../string/strings.h" 1 # 23 "../string/strings.h" # 1 "/scratch/jmyers/glibc/many9/install/compilers/alpha-linux-gnu/lib/gcc/alpha-glibc-linux-gnu/9.0.0/include/stddef.h" 1 3 4 # 24 "../string/strings.h" 2 extern int bcmp (const void *__s1, const void *__s2, size_t __n) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern void bcopy (const void *__src, void *__dest, size_t __n) __attribute__ ((__nothrow__ )) ; extern void bzero (void *__s, size_t __n) __attribute__ ((__nothrow__ )) ; # 68 "../string/strings.h" extern char *index (const char *__s, int __c) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; # 96 "../string/strings.h" extern char *rindex (const char *__s, int __c) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern int ffs (int __i) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)); extern int ffsl (long int __l) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)); __extension__ extern int ffsll (long long int __ll) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)); extern int strcasecmp (const char *__s1, const char *__s2) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern int strncasecmp (const char *__s1, const char *__s2, size_t __n) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; # 1 "../include/bits/types/locale_t.h" 1 # 126 "../string/strings.h" 2 extern int strcasecmp_l (const char *__s1, const char *__s2, locale_t __loc) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern int strncasecmp_l (const char *__s1, const char *__s2, size_t __n, locale_t __loc) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; # 1 "../include/strings.h" 2 # 432 "../string/string.h" 2 extern void explicit_bzero (void *__s, size_t __n) __attribute__ ((__nothrow__ )) ; extern char *strsep (char **__restrict __stringp, const char *__restrict __delim) __attribute__ ((__nothrow__ )) ; extern char *strsignal (int __sig) __attribute__ ((__nothrow__ )); extern char *__stpcpy (char *__restrict __dest, const char *__restrict __src) __attribute__ ((__nothrow__ )) ; extern char *stpcpy (char *__restrict __dest, const char *__restrict __src) __attribute__ ((__nothrow__ )) ; extern char *__stpncpy (char *__restrict __dest, const char *__restrict __src, size_t __n) __attribute__ ((__nothrow__ )) ; extern char *stpncpy (char *__restrict __dest, const char *__restrict __src, size_t __n) __attribute__ ((__nothrow__ )) ; extern int strverscmp (const char *__s1, const char *__s2) __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) ; extern char *strfry (char *__string) __attribute__ ((__nothrow__ )) ; extern void *memfrob (void *__s, size_t __n) __attribute__ ((__nothrow__ )) ; # 486 "../string/string.h" extern char *basename (const char *__filename) __attribute__ ((__nothrow__ )) ; # 498 "../string/string.h" # 61 "../include/string.h" 2 extern __typeof (strcoll_l) __strcoll_l; extern __typeof (strxfrm_l) __strxfrm_l; extern __typeof (strcasecmp_l) __strcasecmp_l; extern __typeof (strncasecmp_l) __strncasecmp_l; # 82 "../include/string.h" extern __typeof (__mempcpy) __mempcpy __attribute__ ((visibility ("hidden"))); extern __typeof (__stpcpy) __stpcpy __attribute__ ((visibility ("hidden"))); extern __typeof (__stpncpy) __stpncpy __attribute__ ((visibility ("hidden"))); extern __typeof (__rawmemchr) __rawmemchr __attribute__ ((visibility ("hidden"))); extern __typeof (__strcasecmp) __strcasecmp __attribute__ ((visibility ("hidden"))); extern __typeof (__strcasecmp_l) __strcasecmp_l __attribute__ ((visibility ("hidden"))); extern __typeof (__strncasecmp_l) __strncasecmp_l __attribute__ ((visibility ("hidden"))); extern __typeof (strncat) __strncat; extern __typeof (__strncat) __strncat __attribute__ ((visibility ("hidden"))); extern __typeof (__strdup) __strdup __attribute__ ((visibility ("hidden"))); extern __typeof (__strndup) __strndup __attribute__ ((visibility ("hidden"))); extern __typeof (__strerror_r) __strerror_r __attribute__ ((visibility ("hidden"))); extern __typeof (__strverscmp) __strverscmp __attribute__ ((visibility ("hidden"))); extern __typeof (basename) basename __attribute__ ((visibility ("hidden"))); extern char *__basename (const char *__filename) __attribute__ ((__nothrow__ )) ; extern __typeof (__basename) __basename __attribute__ ((visibility ("hidden"))); extern __typeof (strcoll) strcoll __attribute__ ((visibility ("hidden"))); extern __typeof (__strcoll_l) __strcoll_l __attribute__ ((visibility ("hidden"))); extern __typeof (__strxfrm_l) __strxfrm_l __attribute__ ((visibility ("hidden"))); extern __typeof (__strtok_r) __strtok_r __attribute__ ((visibility ("hidden"))); extern char *__strsep_g (char **__stringp, const char *__delim); extern __typeof (__strsep_g) __strsep_g __attribute__ ((visibility ("hidden"))); extern __typeof (strnlen) strnlen __attribute__ ((visibility ("hidden"))); extern __typeof (__strnlen) __strnlen __attribute__ ((visibility ("hidden"))); extern __typeof (memmem) memmem __attribute__ ((visibility ("hidden"))); extern __typeof (memmem) __memmem; extern __typeof (__memmem) __memmem __attribute__ ((visibility ("hidden"))); extern __typeof (__ffs) __ffs __attribute__ ((visibility ("hidden"))); void __explicit_bzero_chk_internal (void *, size_t, size_t) __attribute__ ((__nothrow__ )) ; extern __typeof (memchr) memchr __attribute__ ((visibility ("hidden"))); extern __typeof (memcpy) memcpy __attribute__ ((visibility ("hidden"))); extern __typeof (mempcpy) mempcpy __attribute__ ((visibility ("hidden"))); extern __typeof (memcmp) memcmp __attribute__ ((visibility ("hidden"))); extern __typeof (memmove) memmove __attribute__ ((visibility ("hidden"))); extern __typeof (memset) memset __attribute__ ((visibility ("hidden"))); extern __typeof (strcat) strcat __attribute__ ((visibility ("hidden"))); extern __typeof (strchr) strchr __attribute__ ((visibility ("hidden"))); extern __typeof (strcmp) strcmp __attribute__ ((visibility ("hidden"))); extern __typeof (strcpy) strcpy __attribute__ ((visibility ("hidden"))); extern __typeof (strcspn) strcspn __attribute__ ((visibility ("hidden"))); extern __typeof (strlen) strlen __attribute__ ((visibility ("hidden"))); extern __typeof (strncmp) strncmp __attribute__ ((visibility ("hidden"))); extern __typeof (strncpy) strncpy __attribute__ ((visibility ("hidden"))); extern __typeof (strpbrk) strpbrk __attribute__ ((visibility ("hidden"))); extern __typeof (stpcpy) stpcpy __attribute__ ((visibility ("hidden"))); extern __typeof (strrchr) strrchr __attribute__ ((visibility ("hidden"))); extern __typeof (strspn) strspn __attribute__ ((visibility ("hidden"))); extern __typeof (strstr) strstr __attribute__ ((visibility ("hidden"))); extern __typeof (ffs) ffs __attribute__ ((visibility ("hidden"))); # 173 "../include/string.h" extern __typeof (mempcpy) mempcpy __asm__ ("__mempcpy"); extern __typeof (stpcpy) stpcpy __asm__ ("__stpcpy"); extern void *__memcpy_chk (void *__restrict __dest, const void *__restrict __src, size_t __len, size_t __destlen) __attribute__ ((__nothrow__ )); extern void *__memmove_chk (void *__dest, const void *__src, size_t __len, size_t __destlen) __attribute__ ((__nothrow__ )); extern void *__mempcpy_chk (void *__restrict __dest, const void *__restrict __src, size_t __len, size_t __destlen) __attribute__ ((__nothrow__ )); extern void *__memset_chk (void *__dest, int __ch, size_t __len, size_t __destlen) __attribute__ ((__nothrow__ )); extern char *__strcpy_chk (char *__restrict __dest, const char *__restrict __src, size_t __destlen) __attribute__ ((__nothrow__ )); extern char *__stpcpy_chk (char *__restrict __dest, const char *__restrict __src, size_t __destlen) __attribute__ ((__nothrow__ )); extern char *__strncpy_chk (char *__restrict __dest, const char *__restrict __src, size_t __len, size_t __destlen) __attribute__ ((__nothrow__ )); extern char *__strcat_chk (char *__restrict __dest, const char *__restrict __src, size_t __destlen) __attribute__ ((__nothrow__ )); extern char *__strncat_chk (char *__restrict __dest, const char *__restrict __src, size_t __len, size_t __destlen) __attribute__ ((__nothrow__ )); # 35 "plural.y" 2 # 1 "../include/plural-exp.h" 1 # 1 "../intl/plural-exp.h" 1 # 30 "../intl/plural-exp.h" enum expression_operator { var, num, lnot, mult, divide, module, plus, minus, less_than, greater_than, less_or_equal, greater_or_equal, equal, not_equal, land, lor, qmop }; struct expression { int nargs; enum expression_operator operation; union { unsigned long int num; struct expression *args[3]; } val; }; struct parse_args { const char *cp; struct expression *res; }; # 104 "../intl/plural-exp.h" extern void __gettext_free_exp (struct expression *exp) ; extern int __gettextparse (struct parse_args *arg); extern const struct expression __gettext_germanic_plural ; extern void __gettext_extract_plural (const char *nullentry, const struct expression **pluralp, unsigned long int *npluralsp) ; # 3 "../include/plural-exp.h" 2 extern __typeof (__gettextparse) __gettextparse ; # 36 "plural.y" 2 # 116 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" # 145 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" enum yytokentype { EQUOP2 = 258, CMPOP2 = 259, ADDOP2 = 260, MULOP2 = 261, NUMBER = 262 }; # 164 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" union YYSTYPE { # 49 "plural.y" unsigned long int num; enum expression_operator op; struct expression *exp; # 173 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" }; typedef union YYSTYPE YYSTYPE; int __gettextparse (struct parse_args *arg); # 55 "plural.y" static int __gettextlex (YYSTYPE *lval, struct parse_args *arg); static void __gettexterror (struct parse_args *arg, const char *str); static struct expression * new_exp (int nargs, enum expression_operator op, struct expression * const *args) { int i; struct expression *newp; for (i = nargs - 1; i >= 0; i--) if (args[i] == # 71 "plural.y" 3 4 ((void *)0) # 71 "plural.y" ) goto fail; newp = (struct expression *) malloc (sizeof (*newp)); if (newp != # 76 "plural.y" 3 4 ((void *)0) # 76 "plural.y" ) { newp->nargs = nargs; newp->operation = op; for (i = nargs - 1; i >= 0; i--) newp->val.args[i] = args[i]; return newp; } fail: for (i = nargs - 1; i >= 0; i--) __gettext_free_exp (args[i]); return # 89 "plural.y" 3 4 ((void *)0) # 89 "plural.y" ; } static inline struct expression * new_exp_0 (enum expression_operator op) { return new_exp (0, op, # 95 "plural.y" 3 4 ((void *)0) # 95 "plural.y" ); } static inline struct expression * new_exp_1 (enum expression_operator op, struct expression *right) { struct expression *args[1]; args[0] = right; return new_exp (1, op, args); } static struct expression * new_exp_2 (enum expression_operator op, struct expression *left, struct expression *right) { struct expression *args[2]; args[0] = left; args[1] = right; return new_exp (2, op, args); } static inline struct expression * new_exp_3 (enum expression_operator op, struct expression *bexp, struct expression *tbranch, struct expression *fbranch) { struct expression *args[3]; args[0] = bexp; args[1] = tbranch; args[2] = fbranch; return new_exp (3, op, args); } # 265 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" # 273 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" typedef unsigned char yytype_uint8; typedef signed char yytype_int8; typedef unsigned short int yytype_uint16; typedef short int yytype_int16; # 448 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" union yyalloc { yytype_int16 yyss_alloc; YYSTYPE yyvs_alloc; }; # 527 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2, 2, 2, 2, 5, 2, 14, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 6, 7, 8, 9, 11 }; # 600 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" static const yytype_int8 yypact[] = { -9, -9, -10, -10, -9, 8, 36, -10, 13, -10, -9, -9, -9, -9, -9, -9, -9, -10, 26, 41, 45, 18, -2, 14, -10, -9, 36 }; static const yytype_uint8 yydefact[] = { 0, 0, 12, 11, 0, 0, 2, 10, 0, 1, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 5, 6, 7, 8, 9, 0, 3 }; static const yytype_int8 yypgoto[] = { -10, -10, -1 }; static const yytype_int8 yydefgoto[] = { -1, 5, 6 }; static const yytype_uint8 yytable[] = { 7, 1, 2, 8, 3, 4, 15, 16, 9, 18, 19, 20, 21, 22, 23, 24, 10, 11, 12, 13, 14, 15, 16, 16, 26, 14, 15, 16, 17, 10, 11, 12, 13, 14, 15, 16, 0, 0, 25, 10, 11, 12, 13, 14, 15, 16, 12, 13, 14, 15, 16, 13, 14, 15, 16 }; static const yytype_int8 yycheck[] = { 1, 10, 11, 4, 13, 14, 8, 9, 0, 10, 11, 12, 13, 14, 15, 16, 3, 4, 5, 6, 7, 8, 9, 9, 25, 7, 8, 9, 15, 3, 4, 5, 6, 7, 8, 9, -1, -1, 12, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 6, 7, 8, 9 }; static const yytype_uint8 yystos[] = { 0, 10, 11, 13, 14, 17, 18, 18, 18, 0, 3, 4, 5, 6, 7, 8, 9, 15, 18, 18, 18, 18, 18, 18, 18, 12, 18 }; static const yytype_uint8 yyr1[] = { 0, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; static const yytype_uint8 yyr2[] = { 0, 2, 1, 5, 3, 3, 3, 3, 3, 3, 2, 1, 1, 3 }; # 1085 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, struct parse_args *arg) { ((void) (yyvaluep)); ((void) (arg)); if (!yymsg) yymsg = "Deleting"; ; # 1094 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic push # 1094 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" # 1094 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic ignored "-Wuninitialized" # 1094 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" # 1094 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" # 1094 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" ((void) (yytype)); # 1096 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic pop # 1096 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" } # 1106 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" int __gettextparse (struct parse_args *arg) { int yychar; YYSTYPE yylval ; int __gettextnerrs; int yystate; int yyerrstatus; # 1134 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" yytype_int16 yyssa[200]; yytype_int16 *yyss; yytype_int16 *yyssp; YYSTYPE yyvsa[200]; YYSTYPE *yyvs; YYSTYPE *yyvsp; long unsigned int yystacksize; int yyn; int yyresult; int yytoken = 0; YYSTYPE yyval; # 1164 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" int yylen = 0; yyssp = yyss = yyssa; yyvsp = yyvs = yyvsa; yystacksize = 200; ; yystate = 0; yyerrstatus = 0; __gettextnerrs = 0; yychar = (-2); goto yysetstate; yynewstate: yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { long unsigned int yysize = yyssp - yyss + 1; # 1219 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" if (10000 <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (10000 < yystacksize) yystacksize = 10000; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) malloc (((yystacksize) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) + (sizeof (union yyalloc) - 1))); if (! yyptr) goto yyexhaustedlab; do { long unsigned int yynewbytes; __builtin_memcpy (&yyptr->yyss_alloc, yyss, (yysize) * sizeof (*(yyss))); yyss = &yyptr->yyss_alloc; yynewbytes = yystacksize * sizeof (*yyss) + (sizeof (union yyalloc) - 1); yyptr += yynewbytes / sizeof (*yyptr); } while (0); do { long unsigned int yynewbytes; __builtin_memcpy (&yyptr->yyvs_alloc, yyvs, (yysize) * sizeof (*(yyvs))); yyvs = &yyptr->yyvs_alloc; yynewbytes = yystacksize * sizeof (*yyvs) + (sizeof (union yyalloc) - 1); yyptr += yynewbytes / sizeof (*yyptr); } while (0); if (yyss1 != yyssa) free (yyss1); } yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; ; if (yyss + yystacksize - 1 <= yyssp) goto yyabortlab; } ; if (yystate == 9) goto yyacceptlab; goto yybackup; yybackup: yyn = yypact[yystate]; if ((!!((yyn) == (-10)))) goto yydefault; if (yychar == (-2)) { ; yychar = __gettextlex (&yylval, arg); } if (yychar <= 0) { yychar = yytoken = 0; ; } else { yytoken = ((unsigned int) (yychar) <= 262 ? yytranslate[yychar] : 2); ; } yyn += yytoken; if (yyn < 0 || 54 < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (0) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyerrstatus) yyerrstatus--; ; yychar = (-2); yystate = yyn; # 1316 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic push # 1316 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" # 1316 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic ignored "-Wuninitialized" # 1316 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" # 1316 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" # 1316 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" *++yyvsp = yylval; # 1318 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic pop # 1318 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" goto yynewstate; yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; yyreduce: yylen = yyr2[yyn]; # 1348 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" yyval = yyvsp[1-yylen]; ; switch (yyn) { case 2: # 153 "plural.y" { if ((yyvsp[0].exp) == # 154 "plural.y" 3 4 ((void *)0) # 154 "plural.y" ) goto yyabortlab; arg->res = (yyvsp[0].exp); } # 1362 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; case 3: # 161 "plural.y" { (yyval.exp) = new_exp_3 (qmop, (yyvsp[-4].exp), (yyvsp[-2].exp), (yyvsp[0].exp)); } # 1370 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; case 4: # 165 "plural.y" { (yyval.exp) = new_exp_2 (lor, (yyvsp[-2].exp), (yyvsp[0].exp)); } # 1378 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; case 5: # 169 "plural.y" { (yyval.exp) = new_exp_2 (land, (yyvsp[-2].exp), (yyvsp[0].exp)); } # 1386 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; case 6: # 173 "plural.y" { (yyval.exp) = new_exp_2 ((yyvsp[-1].op), (yyvsp[-2].exp), (yyvsp[0].exp)); } # 1394 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; case 7: # 177 "plural.y" { (yyval.exp) = new_exp_2 ((yyvsp[-1].op), (yyvsp[-2].exp), (yyvsp[0].exp)); } # 1402 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; case 8: # 181 "plural.y" { (yyval.exp) = new_exp_2 ((yyvsp[-1].op), (yyvsp[-2].exp), (yyvsp[0].exp)); } # 1410 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; case 9: # 185 "plural.y" { (yyval.exp) = new_exp_2 ((yyvsp[-1].op), (yyvsp[-2].exp), (yyvsp[0].exp)); } # 1418 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; case 10: # 189 "plural.y" { (yyval.exp) = new_exp_1 (lnot, (yyvsp[0].exp)); } # 1426 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; case 11: # 193 "plural.y" { (yyval.exp) = new_exp_0 (var); } # 1434 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; case 12: # 197 "plural.y" { if (((yyval.exp) = new_exp_0 (num)) != # 198 "plural.y" 3 4 ((void *)0) # 198 "plural.y" ) (yyval.exp)->val.num = (yyvsp[0].num); } # 1443 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; case 13: # 202 "plural.y" { (yyval.exp) = (yyvsp[-1].exp); } # 1451 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" break; # 1455 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" default: break; } # 1468 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" ; (yyvsp -= (yylen), yyssp -= (yylen)); yylen = 0; ; *++yyvsp = yyval; yyn = yyr1[yyn]; yystate = yypgoto[yyn - 16] + *yyssp; if (0 <= yystate && yystate <= 54 && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - 16]; goto yynewstate; yyerrlab: yytoken = yychar == (-2) ? (-2) : ((unsigned int) (yychar) <= 262 ? yytranslate[yychar] : 2); if (!yyerrstatus) { ++__gettextnerrs; __gettexterror (arg, "syntax error"); # 1537 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" } if (yyerrstatus == 3) { if (yychar <= 0) { if (yychar == 0) goto yyabortlab; } else { yydestruct ("Error: discarding", yytoken, &yylval, arg); yychar = (-2); } } goto yyerrlab1; yyerrorlab: if ( 0) goto yyerrorlab; (yyvsp -= (yylen), yyssp -= (yylen)); yylen = 0; ; yystate = *yyssp; goto yyerrlab1; yyerrlab1: yyerrstatus = 3; for (;;) { yyn = yypact[yystate]; if (!(!!((yyn) == (-10)))) { yyn += 1; if (0 <= yyn && yyn <= 54 && yycheck[yyn] == 1) { yyn = yytable[yyn]; if (0 < yyn) break; } } if (yyssp == yyss) goto yyabortlab; yydestruct ("Error: popping", yystos[yystate], yyvsp, arg); (yyvsp -= (1), yyssp -= (1)); yystate = *yyssp; ; } # 1617 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic push # 1617 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" # 1617 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic ignored "-Wuninitialized" # 1617 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" # 1617 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" # 1617 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" *++yyvsp = yylval; # 1619 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" #pragma GCC diagnostic pop # 1619 "/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c" ; yystate = yyn; goto yynewstate; yyacceptlab: yyresult = 0; goto yyreturn; yyabortlab: yyresult = 1; goto yyreturn; yyexhaustedlab: __gettexterror (arg, "memory exhausted"); yyresult = 2; yyreturn: if (yychar != (-2)) { yytoken = ((unsigned int) (yychar) <= 262 ? yytranslate[yychar] : 2); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, arg); } (yyvsp -= (yylen), yyssp -= (yylen)); ; while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, arg); (yyvsp -= (1), yyssp -= (1)); } if (yyss != yyssa) free (yyss); return yyresult; } # 207 "plural.y" void __gettext_free_exp (struct expression *exp) { if (exp == # 212 "plural.y" 3 4 ((void *)0) # 212 "plural.y" ) return; switch (exp->nargs) { case 3: __gettext_free_exp (exp->val.args[2]); case 2: __gettext_free_exp (exp->val.args[1]); case 1: __gettext_free_exp (exp->val.args[0]); default: break; } free (exp); } static int __gettextlex (YYSTYPE *lval, struct parse_args *arg) { const char *exp = arg->cp; int result; while (1) { if (exp[0] == '\0') { arg->cp = exp; return 0; } if (exp[0] != ' ' && exp[0] != '\t') break; ++exp; } result = *exp++; switch (result) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { unsigned long int n = result - '0'; while (exp[0] >= '0' && exp[0] <= '9') { n *= 10; n += exp[0] - '0'; ++exp; } lval->num = n; result = 262; } break; case '=': if (exp[0] == '=') { ++exp; lval->op = equal; result = 258; } else result = 256; break; case '!': if (exp[0] == '=') { ++exp; lval->op = not_equal; result = 258; } break; case '&': case '|': if (exp[0] == result) ++exp; else result = 256; break; case '<': if (exp[0] == '=') { ++exp; lval->op = less_or_equal; } else lval->op = less_than; result = 259; break; case '>': if (exp[0] == '=') { ++exp; lval->op = greater_or_equal; } else lval->op = greater_than; result = 259; break; case '*': lval->op = mult; result = 261; break; case '/': lval->op = divide; result = 261; break; case '%': lval->op = module; result = 261; break; case '+': lval->op = plus; result = 260; break; case '-': lval->op = minus; result = 260; break; case 'n': case '?': case ':': case '(': case ')': break; case ';': case '\n': case '\0': --exp; result = 0; break; default: result = 256; break; } arg->cp = exp; return result; } static void __gettexterror (struct parse_args *arg, const char *str) { } ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-15 12:07 ` Joseph Myers @ 2018-08-15 21:02 ` Martin Sebor 2018-08-15 21:14 ` Jeff Law 2018-08-15 21:34 ` Jeff Law 0 siblings, 2 replies; 43+ messages in thread From: Martin Sebor @ 2018-08-15 21:02 UTC (permalink / raw) To: Joseph Myers; +Cc: James Greenhalgh, Jason Merrill, Gcc Patch List, nd [-- Attachment #1: Type: text/plain, Size: 3705 bytes --] On 08/15/2018 06:07 AM, Joseph Myers wrote: > On Tue, 14 Aug 2018, Martin Sebor wrote: > >>> This is with Bison 3.0.4, should the version used to produce intl/plural.c >>> prove relevant. >> >> Can you send me the translation unit and the options it was compiled >> with that triggered the errors? > > I've attached plural.i. The error is a static link error linking sln, but > maybe comparing results of compiling plural.i before and after the changes > may be enlightening (unless it's actually a difference in code elsewhere > in glibc causing a link error reported in plural.o). > > Compiled with: > > alpha-glibc-linux-gnu-gcc > /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c > -c -std=gnu11 -fgnu89-inline -O2 -Wall -Werror -Wundef -Wwrite-strings > -fmerge-all-constants -fno-stack-protector -frounding-math -g > -Wstrict-prototypes -Wold-style-definition -fno-math-errno > -mlong-double-128 -mieee -mfp-rounding-mode=d -ftls-model=initial-exec > -I../include > -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl > -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu > -I../sysdeps/unix/sysv/linux/alpha/alpha > -I../sysdeps/unix/sysv/linux/alpha/fpu -I../sysdeps/alpha/fpu > -I../sysdeps/unix/sysv/linux/alpha -I../sysdeps/alpha/nptl > -I../sysdeps/unix/sysv/linux/wordsize-64 -I../sysdeps/ieee754/ldbl-64-128 > -I../sysdeps/ieee754/ldbl-opt -I../sysdeps/unix/sysv/linux/include > -I../sysdeps/unix/sysv/linux -I../sysdeps/nptl -I../sysdeps/pthread > -I../sysdeps/gnu -I../sysdeps/unix/inet -I../sysdeps/unix/sysv > -I../sysdeps/unix/alpha -I../sysdeps/unix -I../sysdeps/posix > -I../sysdeps/alpha -I../sysdeps/wordsize-64 > -I../sysdeps/ieee754/ldbl-128 -I../sysdeps/ieee754/dbl-64/wordsize-64 > -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 > -I../sysdeps/ieee754 -I../sysdeps/generic -I.. -I../libio -I. > -D_LIBC_REENTRANT -include > /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/libc-modules.h > -DMODULE_NAME=libc -include ../include/libc-symbols.h > -DTOP_NAMESPACE=glibc -D'LOCALEDIR="/usr/share/locale"' > -D'LOCALE_ALIAS_PATH="/usr/share/locale"' -o > /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o > -MD -MP -MF > /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o.dt > -MT > /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o > Thanks. I don't see anything obviously wrong but I don't know much about Alpha assembly. Attached are the two .s files, with (plural-new.s) and without (plural-old.s) the array-to-string transformation. There are also only a handful of transformed arrays in the file and they all look reasonable to me (see the attachment named plural-array-to-string.txt). The only arrays in the .sdata section are yydefgoto and yypgoto, both before and after. They are each just 3 bytes in size. There is one unusual difference in the loads of one of them in the assembly emitted by GCC for __gettextparse. Before: ldah $22,yypgoto($29) !gprelhigh ... lda $2,yypgoto($22) !gprellow After: ldah $2,yypgoto+2305843009213693936($29) !gprelhigh ... lda $2,yypgoto+2305843009213693936($2) !gprellow I don't know if it's significant -- the lda instruction uses just the least significant 16 bits of the constant displacement, shifted left by 16. I don't see any obviously bogus constants in the disassembly produced by objdump. I'll need some help from someone who knows more about Alpha to understand what's going on. Martin [-- Attachment #2: plural-old.s --] [-- Type: text/plain, Size: 29233 bytes --] plural-old.o: file format elf64-alpha Disassembly of section .text: 0000000000000000 <__gettext_free_exp>: 0: 00 00 bb 27 ldah gp,0(t12) 4: 00 00 bd 23 lda gp,0(gp) 8: f0 ff de 23 lda sp,-16(sp) c: 08 00 3e b5 stq s0,8(sp) 10: 09 04 f0 47 mov a0,s0 14: 00 00 5e b7 stq ra,0(sp) 18: 11 00 00 e6 beq a0,60 <__gettext_free_exp+0x60> 1c: 00 00 30 a0 ldl t0,0(a0) 20: a2 5d 20 40 cmple t0,0x2,t1 24: 12 00 40 e4 beq t1,70 <__gettext_free_exp+0x70> 28: a2 55 20 40 cmpeq t0,0x2,t1 2c: 17 00 40 f4 bne t1,8c <__gettext_free_exp+0x8c> 30: a1 35 20 40 cmpeq t0,0x1,t0 34: 05 00 20 e4 beq t0,4c <__gettext_free_exp+0x4c> 38: 08 00 09 a6 ldq a0,8(s0) 3c: 00 00 7d a7 ldq t12,0(gp) 40: 00 40 5b 6b jsr ra,(t12),44 <__gettext_free_exp+0x44> 44: 00 00 ba 27 ldah gp,0(ra) 48: 00 00 bd 23 lda gp,0(gp) 4c: 10 04 e9 47 mov s0,a0 50: 00 00 7d a7 ldq t12,0(gp) 54: 00 40 5b 6b jsr ra,(t12),58 <__gettext_free_exp+0x58> 58: 00 00 ba 27 ldah gp,0(ra) 5c: 00 00 bd 23 lda gp,0(gp) 60: 00 00 5e a7 ldq ra,0(sp) 64: 08 00 3e a5 ldq s0,8(sp) 68: 10 00 de 23 lda sp,16(sp) 6c: 01 80 fa 6b ret 70: a1 75 20 40 cmpeq t0,0x3,t0 74: f5 ff 3f e4 beq t0,4c <__gettext_free_exp+0x4c> 78: 18 00 10 a6 ldq a0,24(a0) 7c: 00 00 7d a7 ldq t12,0(gp) 80: 00 40 5b 6b jsr ra,(t12),84 <__gettext_free_exp+0x84> 84: 00 00 ba 27 ldah gp,0(ra) 88: 00 00 bd 23 lda gp,0(gp) 8c: 10 00 09 a6 ldq a0,16(s0) 90: 00 00 7d a7 ldq t12,0(gp) 94: 00 40 5b 6b jsr ra,(t12),98 <__gettext_free_exp+0x98> 98: 00 00 ba 27 ldah gp,0(ra) 9c: 00 00 bd 23 lda gp,0(gp) a0: e5 ff ff c3 br 38 <__gettext_free_exp+0x38> a4: 00 00 fe 2f unop a8: 1f 04 ff 47 nop ac: 00 00 fe 2f unop 00000000000000b0 <new_exp>: b0: 00 00 bb 27 ldah gp,0(t12) b4: 00 00 bd 23 lda gp,0(gp) b8: d0 ff de 23 lda sp,-48(sp) bc: 08 00 3e b5 stq s0,8(sp) c0: 29 31 00 42 subl a0,0x1,s0 c4: 10 00 5e b5 stq s1,16(sp) c8: 01 00 29 20 lda t0,1(s0) cc: 18 00 7e b5 stq s2,24(sp) d0: 0a 04 f2 47 mov a2,s1 d4: 20 00 9e b5 stq s3,32(sp) d8: 0b 04 f0 47 mov a0,s2 dc: 00 00 5e b7 stq ra,0(sp) e0: 0c 04 f1 47 mov a1,s3 e4: 35 00 20 e4 beq t0,1bc <new_exp+0x10c> e8: 01 04 e9 47 mov s0,t0 ec: 01 00 e0 c3 br f4 <new_exp+0x44> f0: 1b 00 40 e4 beq t1,160 <new_exp+0xb0> f4: 43 06 2a 40 s8addq t0,s1,t2 f8: ff ff 21 20 lda t0,-1(t0) fc: 02 00 e1 43 sextl t0,t1 100: 00 00 63 a4 ldq t2,0(t2) 104: 01 00 42 20 lda t1,1(t1) 108: f9 ff 7f f4 bne t2,f0 <new_exp+0x40> 10c: 00 00 fe 2f unop 110: 41 06 2a 41 s8addq s0,s1,t0 114: ff ff 29 21 lda s0,-1(s0) 118: 00 00 01 a6 ldq a0,0(t0) 11c: 00 00 7d a7 ldq t12,0(gp) 120: 00 40 5b 6b jsr ra,(t12),124 <new_exp+0x74> 124: 00 00 ba 27 ldah gp,0(ra) 128: 00 00 bd 23 lda gp,0(gp) 12c: 01 00 e9 43 sextl s0,t0 130: 01 00 21 20 lda t0,1(t0) 134: f6 ff 3f f4 bne t0,110 <new_exp+0x60> 138: 00 00 5e a7 ldq ra,0(sp) 13c: 08 00 3e a5 ldq s0,8(sp) 140: 10 00 5e a5 ldq s1,16(sp) 144: 18 00 7e a5 ldq s2,24(sp) 148: 00 04 ff 47 clr v0 14c: 20 00 9e a5 ldq s3,32(sp) 150: 30 00 de 23 lda sp,48(sp) 154: 01 80 fa 6b ret 158: 1f 04 ff 47 nop 15c: 00 00 fe 2f unop 160: 20 00 1f 22 lda a0,32 164: 00 00 7d a7 ldq t12,0(gp) 168: 00 40 5b 6b jsr ra,(t12),16c <new_exp+0xbc> 16c: 00 00 ba 27 ldah gp,0(ra) 170: 00 00 bd 23 lda gp,0(gp) 174: e6 ff 1f e4 beq v0,110 <new_exp+0x60> 178: 00 00 60 b1 stl s2,0(v0) 17c: 04 00 80 b1 stl s3,4(v0) 180: 41 06 2a 41 s8addq s0,s1,t0 184: 42 06 20 41 s8addq s0,v0,t1 188: ff ff 29 21 lda s0,-1(s0) 18c: 00 00 61 a4 ldq t2,0(t0) 190: 01 00 e9 43 sextl s0,t0 194: 01 00 21 20 lda t0,1(t0) 198: 08 00 62 b4 stq t2,8(t1) 19c: f8 ff 3f f4 bne t0,180 <new_exp+0xd0> 1a0: 00 00 5e a7 ldq ra,0(sp) 1a4: 08 00 3e a5 ldq s0,8(sp) 1a8: 10 00 5e a5 ldq s1,16(sp) 1ac: 18 00 7e a5 ldq s2,24(sp) 1b0: 20 00 9e a5 ldq s3,32(sp) 1b4: 30 00 de 23 lda sp,48(sp) 1b8: 01 80 fa 6b ret 1bc: 20 00 1f 22 lda a0,32 1c0: 00 00 7d a7 ldq t12,0(gp) 1c4: 00 40 5b 6b jsr ra,(t12),1c8 <new_exp+0x118> 1c8: 00 00 ba 27 ldah gp,0(ra) 1cc: 00 00 bd 23 lda gp,0(gp) 1d0: d9 ff 1f e4 beq v0,138 <new_exp+0x88> 1d4: 04 00 80 b1 stl s3,4(v0) 1d8: 00 00 5e a7 ldq ra,0(sp) 1dc: 08 00 3e a5 ldq s0,8(sp) 1e0: 10 00 5e a5 ldq s1,16(sp) 1e4: 18 00 7e a5 ldq s2,24(sp) 1e8: 20 00 9e a5 ldq s3,32(sp) 1ec: 00 00 e0 b3 stl zero,0(v0) 1f0: 30 00 de 23 lda sp,48(sp) 1f4: 01 80 fa 6b ret 1f8: 1f 04 ff 47 nop 1fc: 00 00 fe 2f unop 0000000000000200 <__gettextparse>: 200: 00 00 bb 27 ldah gp,0(t12) 204: 00 00 bd 23 lda gp,0(gp) 208: 90 f7 de 23 lda sp,-2160(sp) 20c: 00 00 9d 24 ldah t3,0(gp) 210: 80 06 3e a0 ldl t0,1664(sp) 214: 08 00 3e b5 stq s0,8(sp) 218: 80 06 3e 21 lda s0,1664(sp) 21c: 10 00 5e b5 stq s1,16(sp) 220: 40 00 5e 21 lda s1,64(sp) 224: 21 96 3f 48 zapnot t0,0xfc,t0 228: 20 00 9e b5 stq s3,32(sp) 22c: 00 00 9d 25 ldah s3,0(gp) 230: 18 00 7e b5 stq s2,24(sp) 234: 28 00 be b5 stq s4,40(sp) 238: fe ff bf 20 lda t4,-2 23c: 38 00 fe b5 stq fp,56(sp) 240: c8 00 7f 21 lda s2,200 244: 80 06 3e b0 stl t0,1664(sp) 248: 0f 04 ea 47 mov s1,fp 24c: 01 04 ff 47 clr t0 250: 00 00 5e b7 stq ra,0(sp) 254: 0d 04 e9 47 mov s0,s4 258: 30 00 de b5 stq s5,48(sp) 25c: 00 00 84 20 lda t3,0(t3) 260: 40 08 1e b6 stq a0,2112(sp) 264: 00 00 8c 21 lda s3,0(s3) 268: 38 08 fe b7 stq zero,2104(sp) 26c: 30 08 3e b5 stq s0,2096(sp) 270: 02 04 81 40 addq t3,t0,t1 274: 01 00 c2 20 lda t5,1(t1) 278: 00 00 e2 2c ldq_u t6,0(t1) 27c: 47 0f e6 48 extqh t6,t5,t6 280: 87 17 e7 48 sra t6,0x38,t6 284: 0a 00 47 20 lda t1,10(t6) 288: 1d 00 40 e4 beq t1,300 <__gettextparse+0x100> 28c: 02 00 45 20 lda t1,2(t4) 290: 17 01 40 e4 beq t1,6f0 <__gettextparse+0x4f0> 294: 86 00 a0 ec ble t4,4b0 <__gettextparse+0x2b0> 298: 00 00 5d 24 ldah t1,0(gp) 29c: 00 00 42 20 lda t1,0(t1) 2a0: 02 04 a2 40 addq t4,t1,t1 2a4: 00 00 02 2d ldq_u t7,0(t1) 2a8: c8 00 02 49 extbl t7,t1,t7 2ac: 07 00 e8 40 addl t6,t7,t6 2b0: 26 f6 e1 48 zapnot t6,0xf,t5 2b4: a6 d7 c6 40 cmpule t5,0x36,t5 2b8: 11 00 c0 e4 beq t5,300 <__gettextparse+0x100> 2bc: 06 04 ec 40 addq t6,s3,t5 2c0: 01 00 c6 22 lda t8,1(t5) 2c4: 00 00 46 2c ldq_u t1,0(t5) 2c8: 42 0f 56 48 extqh t1,t8,t1 2cc: 82 17 47 48 sra t1,0x38,t1 2d0: a2 05 48 40 cmpeq t1,t7,t1 2d4: 0a 00 40 e4 beq t1,300 <__gettextparse+0x100> 2d8: 00 00 3d 24 ldah t0,0(gp) 2dc: 00 00 21 20 lda t0,0(t0) 2e0: 07 04 e1 40 addq t6,t0,t6 2e4: 00 00 27 2c ldq_u t0,0(t6) 2e8: c1 00 27 48 extbl t0,t6,t0 2ec: 20 01 20 f4 bne t0,770 <__gettextparse+0x570> 2f0: 08 04 ea 47 mov s1,t7 2f4: 08 00 0a a4 ldq v0,8(s1) 2f8: f0 ff ff 20 lda t6,-16 2fc: 8d 00 e0 c3 br 534 <__gettextparse+0x334> 300: 00 00 5d 24 ldah t1,0(gp) 304: 00 00 42 20 lda t1,0(t1) 308: 02 04 22 40 addq t0,t1,t1 30c: 00 00 c2 2c ldq_u t5,0(t1) 310: c2 00 c2 48 extbl t5,t1,t1 314: 08 00 e2 43 sextl t1,t7 318: 45 00 40 f4 bne t1,430 <__gettextparse+0x230> 31c: 38 08 5e a4 ldq t1,2104(sp) 320: ae 75 40 40 cmpeq t1,0x3,s5 324: 16 00 c0 e5 beq s5,380 <__gettextparse+0x180> 328: 1d 01 a0 fc bgt t4,7a0 <__gettextparse+0x5a0> 32c: 14 00 a0 f4 bne t4,380 <__gettextparse+0x180> 330: 09 04 ed 47 mov s4,s0 334: 01 00 5f 21 lda s1,1 338: 27 00 e0 c3 br 3d8 <__gettextparse+0x1d8> 33c: 00 00 fe 2f unop 340: 00 00 5d 24 ldah t1,0(gp) 344: 00 00 42 20 lda t1,0(t1) 348: 01 04 22 40 addq t0,t1,t0 34c: 00 00 41 2c ldq_u t1,0(t0) 350: c1 00 41 48 extbl t1,t0,t0 354: 9d 01 20 f4 bne t0,9cc <__gettextparse+0x7cc> 358: 1f 04 ff 47 nop 35c: 00 00 fe 2f unop 360: a1 05 2d 41 cmpeq s0,s4,t0 364: 1b 00 20 f4 bne t0,3d4 <__gettextparse+0x1d4> 368: fe ff 29 21 lda s0,-2(s0) 36c: 02 00 49 20 lda t1,2(s0) 370: f8 ff 4a 21 lda s1,-8(s1) 374: 00 00 29 2c ldq_u t0,0(s0) 378: 41 0f 22 48 extqh t0,t1,t0 37c: 81 17 26 48 sra t0,0x30,t0 380: 01 04 81 40 addq t3,t0,t0 384: 01 00 41 20 lda t1,1(t0) 388: 00 00 21 2c ldq_u t0,0(t0) 38c: 41 0f 22 48 extqh t0,t1,t0 390: 81 17 27 48 sra t0,0x38,t0 394: 0a 00 41 20 lda t1,10(t0) 398: f1 ff 5f e4 beq t1,360 <__gettextparse+0x160> 39c: 01 30 20 40 addl t0,0x1,t0 3a0: 22 f6 21 48 zapnot t0,0xf,t1 3a4: 01 00 e1 43 sextl t0,t0 3a8: a2 d7 46 40 cmpule t1,0x36,t1 3ac: ec ff 5f e4 beq t1,360 <__gettextparse+0x160> 3b0: 06 04 2c 40 addq t0,s3,t5 3b4: 01 00 e6 20 lda t6,1(t5) 3b8: 00 00 46 2c ldq_u t1,0(t5) 3bc: 42 0f 47 48 extqh t1,t6,t1 3c0: 82 17 47 48 sra t1,0x38,t1 3c4: a2 35 40 40 cmpeq t1,0x1,t1 3c8: dd ff 5f f4 bne t1,340 <__gettextparse+0x140> 3cc: a1 05 2d 41 cmpeq s0,s4,t0 3d0: e5 ff 3f e4 beq t0,368 <__gettextparse+0x168> 3d4: 01 00 5f 21 lda s1,1 3d8: 30 08 7e a4 ldq t2,2096(sp) 3dc: a1 05 23 41 cmpeq s0,t2,t0 3e0: 05 00 20 f4 bne t0,3f8 <__gettextparse+0x1f8> 3e4: 10 04 e9 47 mov s0,a0 3e8: 00 00 7d a7 ldq t12,0(gp) 3ec: 00 40 5b 6b jsr ra,(t12),3f0 <__gettextparse+0x1f0> 3f0: 00 00 ba 27 ldah gp,0(ra) 3f4: 00 00 bd 23 lda gp,0(gp) 3f8: 00 04 ea 47 mov s1,v0 3fc: 00 00 5e a7 ldq ra,0(sp) 400: 08 00 3e a5 ldq s0,8(sp) 404: 10 00 5e a5 ldq s1,16(sp) 408: 18 00 7e a5 ldq s2,24(sp) 40c: 20 00 9e a5 ldq s3,32(sp) 410: 28 00 be a5 ldq s4,40(sp) 414: 30 00 de a5 ldq s5,48(sp) 418: 38 00 fe a5 ldq fp,56(sp) 41c: 70 08 de 23 lda sp,2160(sp) 420: 01 80 fa 6b ret 424: 00 00 fe 2f unop 428: 1f 04 ff 47 nop 42c: 00 00 fe 2f unop 430: 00 00 3d 24 ldah t0,0(gp) 434: 00 00 21 20 lda t0,0(t0) 438: 01 04 01 41 addq t7,t0,t0 43c: a7 b7 41 40 cmpule t1,0xd,t6 440: 00 00 c1 2c ldq_u t5,0(t0) 444: c1 00 c1 48 extbl t5,t0,t0 448: 01 00 df 20 lda t5,1 44c: 26 01 c1 40 subl t5,t0,t5 450: 46 06 ca 40 s8addq t5,s1,t5 454: 00 00 06 a4 ldq v0,0(t5) 458: 19 00 e0 f4 bne t6,4c0 <__gettextparse+0x2c0> 45c: 00 00 5d 24 ldah t1,0(gp) 460: 00 00 42 20 lda t1,0(t1) 464: 02 04 02 41 addq t7,t1,t1 468: 00 00 dd 26 ldah t8,0(gp) 46c: 48 16 20 40 s8addq t0,0,t7 470: 00 00 e2 2c ldq_u t6,0(t1) 474: 01 04 21 40 addq t0,t0,t0 478: 29 05 21 41 subq s0,t0,s0 47c: c2 00 e2 48 extbl t6,t1,t1 480: 28 05 48 41 subq s1,t7,t7 484: 27 11 42 40 subl t1,0x10,t6 488: 00 00 56 20 lda t1,0(t8) 48c: 02 04 e2 40 addq t6,t1,t1 490: 01 00 c2 20 lda t5,1(t1) 494: 00 00 22 2c ldq_u t0,0(t1) 498: 41 0f 26 48 extqh t0,t5,t0 49c: 81 17 27 48 sra t0,0x38,t0 4a0: 24 00 e0 c3 br 534 <__gettextparse+0x334> 4a4: 00 00 fe 2f unop 4a8: 1f 04 ff 47 nop 4ac: 00 00 fe 2f unop 4b0: 08 04 ff 47 clr t7 4b4: 05 04 ff 47 clr t4 4b8: 7d ff ff c3 br 2b0 <__gettextparse+0xb0> 4bc: 00 00 fe 2f unop 4c0: 00 00 dd 24 ldah t5,0(gp) 4c4: 00 00 c6 20 lda t5,0(t5) 4c8: 42 04 46 40 s4addq t1,t5,t1 4cc: 00 00 42 a0 ldl t1,0(t1) 4d0: 02 04 a2 43 addq gp,t1,t1 4d4: 00 00 e2 6b jmp (t1) 4d8: 1f 04 ff 47 nop 4dc: 00 00 fe 2f unop 4e0: 10 08 5e 22 lda a2,2064(sp) 4e4: f8 ff 2a a2 ldl a1,-8(s1) 4e8: 00 00 4a a4 ldq t1,0(s1) 4ec: f0 ff 2a a4 ldq t0,-16(s1) 4f0: 10 08 3e b4 stq t0,2064(sp) 4f4: 02 00 1f 22 lda a0,2 4f8: ff ff 3f 20 lda t0,-1 4fc: 68 08 9e b4 stq t3,2152(sp) 500: 58 08 3e b4 stq t0,2136(sp) 504: fa ff 29 21 lda s0,-6(s0) 508: 60 08 be b4 stq t4,2144(sp) 50c: 18 08 5e b4 stq t1,2072(sp) 510: 00 00 7d a7 ldq t12,0(gp) 514: 00 40 5b 6b jsr ra,(t12),518 <__gettextparse+0x318> 518: 00 00 ba 27 ldah gp,0(ra) 51c: 00 00 bd 23 lda gp,0(gp) 520: e8 ff 0a 21 lda t7,-24(s1) 524: 58 08 3e a4 ldq t0,2136(sp) 528: 02 00 ff 20 lda t6,2 52c: 68 08 9e a4 ldq t3,2152(sp) 530: 60 08 be a4 ldq t4,2144(sp) 534: 08 00 08 b4 stq v0,8(t7) 538: 02 00 49 20 lda t1,2(s0) 53c: 08 00 48 21 lda s1,8(t7) 540: 00 00 c9 2c ldq_u t5,0(s0) 544: 46 0f c2 48 extqh t5,t1,t5 548: 86 17 c6 48 sra t5,0x30,t5 54c: 01 00 c1 40 addl t5,t0,t0 550: 28 f6 21 48 zapnot t0,0xf,t7 554: 01 00 e1 43 sextl t0,t0 558: a8 d7 06 41 cmpule t7,0x36,t7 55c: 07 00 00 e5 beq t7,57c <__gettextparse+0x37c> 560: 16 04 2c 40 addq t0,s3,t8 564: 01 00 f6 22 lda t9,1(t8) 568: 00 00 16 2d ldq_u t7,0(t8) 56c: 48 0f 17 49 extqh t7,t9,t7 570: 88 17 07 49 sra t7,0x38,t7 574: a6 05 06 41 cmpeq t7,t5,t5 578: 8d 00 c0 f4 bne t5,7b0 <__gettextparse+0x5b0> 57c: 00 00 dd 24 ldah t5,0(gp) 580: 00 00 c6 20 lda t5,0(t5) 584: 06 04 e6 40 addq t6,t5,t5 588: 01 00 e6 20 lda t6,1(t5) 58c: 00 00 26 2c ldq_u t0,0(t5) 590: 41 0f 27 48 extqh t0,t6,t0 594: 81 17 27 48 sra t0,0x38,t0 598: 16 04 6b 41 addq s2,s2,t8 59c: 02 00 09 2d ldq_u t7,2(s0) 5a0: 67 03 22 48 inswl t0,t1,t6 5a4: fe ff d6 20 lda t5,-2(t8) 5a8: 48 02 02 49 mskwl t7,t1,t7 5ac: 06 04 a6 41 addq s4,t5,t5 5b0: 07 04 e8 44 or t6,t7,t6 5b4: 02 00 e9 3c stq_u t6,2(s0) 5b8: a6 03 46 40 cmpult t1,t5,t5 5bc: 09 04 e2 47 mov t1,s0 5c0: 44 00 c0 f4 bne t5,6d4 <__gettextparse+0x4d4> 5c4: 2a 05 4d 40 subq t1,s4,s1 5c8: 8a 37 40 49 sra s1,0x1,s1 5cc: 0f 27 df 20 lda t5,9999 5d0: ab 07 66 41 cmpule s2,t5,s2 5d4: 01 00 4a 21 lda s1,1(s1) 5d8: b2 01 60 e5 beq s2,ca4 <__gettextparse+0xaa4> 5dc: 10 27 5f 20 lda t1,10000 5e0: 00 00 7d a7 ldq t12,0(gp) 5e4: ab 03 c2 42 cmpult t8,t1,s2 5e8: 58 08 3e b4 stq t0,2136(sp) 5ec: 68 08 9e b4 stq t3,2152(sp) 5f0: c2 04 76 45 cmovne s2,t8,t1 5f4: 60 08 be b4 stq t4,2144(sp) 5f8: 50 04 42 40 s4addq t1,t1,a0 5fc: 10 04 10 42 addq a0,a0,a0 600: 07 00 10 22 lda a0,7(a0) 604: 0b 04 e2 47 mov t1,s2 608: 00 40 5b 6b jsr ra,(t12),60c <__gettextparse+0x40c> 60c: 00 00 ba 27 ldah gp,0(ra) 610: 00 00 bd 23 lda gp,0(gp) 614: 0e 04 e0 47 mov v0,s5 618: a2 01 00 e4 beq v0,ca4 <__gettextparse+0xaa4> 61c: 09 04 4a 41 addq s1,s1,s0 620: 00 00 7d a7 ldq t12,0(gp) 624: 12 04 e9 47 mov s0,a2 628: 11 04 ed 47 mov s4,a1 62c: 10 04 e0 47 mov v0,a0 630: 00 40 5b 6b jsr ra,(t12),634 <__gettextparse+0x434> 634: 00 00 ba 27 ldah gp,0(ra) 638: 4a 16 40 41 s8addq s1,0,s1 63c: 06 04 6b 41 addq s2,s2,t5 640: 00 00 bd 23 lda gp,0(gp) 644: 06 04 c6 41 addq s5,t5,t5 648: 11 04 ef 47 mov fp,a1 64c: 00 00 7d a7 ldq t12,0(gp) 650: 10 04 e6 47 mov t5,a0 654: 12 04 ea 47 mov s1,a2 658: 00 40 5b 6b jsr ra,(t12),65c <__gettextparse+0x45c> 65c: 00 00 ba 27 ldah gp,0(ra) 660: 0f 04 6b 41 addq s2,s2,fp 664: 30 08 5e a4 ldq t1,2096(sp) 668: 00 00 bd 23 lda gp,0(gp) 66c: 58 08 3e a4 ldq t0,2136(sp) 670: 06 04 e0 47 mov v0,t5 674: 68 08 9e a4 ldq t3,2152(sp) 678: a7 05 a2 41 cmpeq s4,t1,t6 67c: 60 08 be a4 ldq t4,2144(sp) 680: 0a 00 e0 f4 bne t6,6ac <__gettextparse+0x4ac> 684: 10 04 ed 47 mov s4,a0 688: 00 00 7d a7 ldq t12,0(gp) 68c: 50 08 1e b4 stq v0,2128(sp) 690: 00 40 5b 6b jsr ra,(t12),694 <__gettextparse+0x494> 694: 00 00 ba 27 ldah gp,0(ra) 698: 50 08 de a4 ldq t5,2128(sp) 69c: 00 00 bd 23 lda gp,0(gp) 6a0: 60 08 be a4 ldq t4,2144(sp) 6a4: 68 08 9e a4 ldq t3,2152(sp) 6a8: 58 08 3e a4 ldq t0,2136(sp) 6ac: fe ff 29 21 lda s0,-2(s0) 6b0: fe ff ef 21 lda fp,-2(fp) 6b4: 09 04 c9 41 addq s5,s0,s0 6b8: 0f 04 cf 41 addq s5,fp,fp 6bc: f8 ff 4a 21 lda s1,-8(s1) 6c0: af 03 2f 41 cmpult s0,fp,fp 6c4: 0a 04 ca 40 addq t5,s1,s1 6c8: 79 01 e0 e5 beq fp,cb0 <__gettextparse+0xab0> 6cc: 0f 04 e6 47 mov t5,fp 6d0: 0d 04 ee 47 mov s5,s4 6d4: a2 35 21 40 cmpeq t0,0x9,t1 6d8: e5 fe 5f e4 beq t1,270 <__gettextparse+0x70> 6dc: 09 04 ed 47 mov s4,s0 6e0: 0a 04 ff 47 clr s1 6e4: 3c ff ff c3 br 3d8 <__gettextparse+0x1d8> 6e8: 1f 04 ff 47 nop 6ec: 00 00 fe 2f unop 6f0: 40 08 7e a4 ldq t2,2112(sp) 6f4: 00 00 c3 a6 ldq t8,0(t2) 6f8: 01 00 16 21 lda t7,1(t8) 6fc: 00 00 56 2c ldq_u t1,0(t8) 700: 42 0f 48 48 extqh t1,t7,t1 704: 82 17 47 48 sra t1,0x38,t1 708: 08 00 40 f4 bne t1,72c <__gettextparse+0x52c> 70c: 2e 00 e0 c3 br 7c8 <__gettextparse+0x5c8> 710: 02 00 b6 20 lda t4,2(t8) 714: 00 00 48 2c ldq_u t1,0(t7) 718: 16 04 e8 47 mov t7,t8 71c: 42 0f 45 48 extqh t1,t4,t1 720: 82 17 47 48 sra t1,0x38,t1 724: 2a 00 40 e4 beq t1,7d0 <__gettextparse+0x5d0> 728: 01 00 08 21 lda t7,1(t7) 72c: a6 15 44 40 cmpeq t1,0x20,t5 730: a5 35 41 40 cmpeq t1,0x9,t4 734: a6 15 c0 40 cmpeq t5,0,t5 738: a5 15 a0 40 cmpeq t4,0,t4 73c: 17 04 e8 47 mov t7,t9 740: 05 00 c5 44 and t5,t4,t4 744: f2 ff bf e4 beq t4,710 <__gettextparse+0x510> 748: 06 f0 5f 44 and t1,0xff,t5 74c: a6 97 cf 40 cmpule t5,0x7c,t5 750: 05 00 e2 43 sextl t1,t4 754: 97 00 c0 f4 bne t5,9b4 <__gettextparse+0x7b4> 758: 40 08 be a4 ldq t4,2112(sp) 75c: 00 00 05 b5 stq t7,0(t4) 760: 01 00 1f 21 lda t7,1 764: 00 01 bf 20 lda t4,256 768: d0 fe ff c3 br 2ac <__gettextparse+0xac> 76c: 00 00 fe 2f unop 770: 38 08 7e a4 ldq t2,2104(sp) 774: 08 00 4a 21 lda s1,8(s1) 778: 48 08 be a4 ldq t4,2120(sp) 77c: 22 31 60 40 subl t2,0x1,t1 780: 00 00 aa b4 stq t4,0(s1) 784: c3 04 62 44 cmovne t2,t1,t2 788: fe ff bf 20 lda t4,-2 78c: 38 08 7e b4 stq t2,2104(sp) 790: 02 00 49 20 lda t1,2(s0) 794: 80 ff ff c3 br 598 <__gettextparse+0x398> 798: 1f 04 ff 47 nop 79c: 00 00 fe 2f unop 7a0: fe ff bf 20 lda t4,-2 7a4: f6 fe ff c3 br 380 <__gettextparse+0x180> 7a8: 1f 04 ff 47 nop 7ac: 00 00 fe 2f unop 7b0: 00 00 7d 24 ldah t2,0(gp) 7b4: 00 00 63 20 lda t2,0(t2) 7b8: 01 04 23 40 addq t0,t2,t0 7bc: 00 00 c1 2c ldq_u t5,0(t0) 7c0: c1 00 c1 48 extbl t5,t0,t0 7c4: 74 ff ff c3 br 598 <__gettextparse+0x398> 7c8: 17 04 f6 47 mov t8,t9 7cc: 00 00 fe 2f unop 7d0: 08 04 ff 47 clr t7 7d4: 40 08 be a4 ldq t4,2112(sp) 7d8: 00 00 e5 b6 stq t9,0(t4) 7dc: 05 04 ff 47 clr t4 7e0: b3 fe ff c3 br 2b0 <__gettextparse+0xb0> 7e4: 00 00 fe 2f unop 7e8: 1f 04 ff 47 nop 7ec: 00 00 fe 2f unop 7f0: 10 08 5e 22 lda a2,2064(sp) 7f4: 00 00 2a a4 ldq t0,0(s1) 7f8: 02 00 3f 22 lda a1,2 7fc: 68 08 9e b4 stq t3,2152(sp) 800: 01 00 1f 22 lda a0,1 804: 60 08 be b4 stq t4,2144(sp) 808: 10 08 3e b4 stq t0,2064(sp) 80c: ff ff 3f 20 lda t0,-1 810: 58 08 3e b4 stq t0,2136(sp) 814: fc ff 29 21 lda s0,-4(s0) 818: 00 00 7d a7 ldq t12,0(gp) 81c: 00 40 5b 6b jsr ra,(t12),820 <__gettextparse+0x620> 820: 00 00 ba 27 ldah gp,0(ra) 824: 00 00 bd 23 lda gp,0(gp) 828: f0 ff 0a 21 lda t7,-16(s1) 82c: 58 08 3e a4 ldq t0,2136(sp) 830: 02 00 ff 20 lda t6,2 834: 68 08 9e a4 ldq t3,2152(sp) 838: 60 08 be a4 ldq t4,2144(sp) 83c: 3d ff ff c3 br 534 <__gettextparse+0x334> 840: 12 04 ff 47 clr a2 844: 68 08 9e b4 stq t3,2152(sp) 848: 11 04 ff 47 clr a1 84c: 60 08 be b4 stq t4,2144(sp) 850: 10 04 ff 47 clr a0 854: 00 00 7d a7 ldq t12,0(gp) 858: 00 40 5b 6b jsr ra,(t12),85c <__gettextparse+0x65c> 85c: 00 00 ba 27 ldah gp,0(ra) 860: 00 00 bd 23 lda gp,0(gp) 864: fe ff 29 21 lda s0,-2(s0) 868: f8 ff 0a 21 lda t7,-8(s1) 86c: 68 08 9e a4 ldq t3,2152(sp) 870: ff ff 3f 20 lda t0,-1 874: 60 08 be a4 ldq t4,2144(sp) 878: 02 00 ff 20 lda t6,2 87c: 2d ff ff c3 br 534 <__gettextparse+0x334> 880: 12 04 ff 47 clr a2 884: 68 08 9e b4 stq t3,2152(sp) 888: 01 00 3f 22 lda a1,1 88c: 60 08 be b4 stq t4,2144(sp) 890: 10 04 ff 47 clr a0 894: 00 00 7d a7 ldq t12,0(gp) 898: 00 40 5b 6b jsr ra,(t12),89c <__gettextparse+0x69c> 89c: 00 00 ba 27 ldah gp,0(ra) 8a0: 00 00 bd 23 lda gp,0(gp) 8a4: fe ff 29 21 lda s0,-2(s0) 8a8: f8 ff 0a 21 lda t7,-8(s1) 8ac: 68 08 9e a4 ldq t3,2152(sp) 8b0: ff ff 3f 20 lda t0,-1 8b4: 60 08 be a4 ldq t4,2144(sp) 8b8: 02 00 ff 20 lda t6,2 8bc: 1d ff 1f e4 beq v0,534 <__gettextparse+0x334> 8c0: 00 00 4a a4 ldq t1,0(s1) 8c4: 08 00 40 b4 stq t1,8(v0) 8c8: 1a ff ff c3 br 534 <__gettextparse+0x334> 8cc: 00 00 fe 2f unop 8d0: e8 ff 0a 21 lda t7,-24(s1) 8d4: f8 ff 0a a4 ldq v0,-8(s1) 8d8: fa ff 29 21 lda s0,-6(s0) 8dc: ff ff 3f 20 lda t0,-1 8e0: 02 00 ff 20 lda t6,2 8e4: 13 ff ff c3 br 534 <__gettextparse+0x334> 8e8: 1f 04 ff 47 nop 8ec: 00 00 fe 2f unop 8f0: 10 08 5e 22 lda a2,2064(sp) 8f4: 00 00 4a a4 ldq t1,0(s1) 8f8: 0e 00 3f 22 lda a1,14 8fc: f0 ff 2a a4 ldq t0,-16(s1) 900: fb fe ff c3 br 4f0 <__gettextparse+0x2f0> 904: 00 00 fe 2f unop 908: 1f 04 ff 47 nop 90c: 00 00 fe 2f unop 910: 10 08 5e 22 lda a2,2064(sp) 914: 00 00 4a a4 ldq t1,0(s1) 918: 0f 00 3f 22 lda a1,15 91c: f0 ff 2a a4 ldq t0,-16(s1) 920: f3 fe ff c3 br 4f0 <__gettextparse+0x2f0> 924: 00 00 fe 2f unop 928: 1f 04 ff 47 nop 92c: 00 00 fe 2f unop 930: e0 ff 2a a4 ldq t0,-32(s1) 934: f0 ff ca a4 ldq t5,-16(s1) 938: 10 08 5e 22 lda a2,2064(sp) 93c: 00 00 4a a4 ldq t1,0(s1) 940: 10 08 3e b4 stq t0,2064(sp) 944: 10 00 3f 22 lda a1,16 948: ff ff 3f 20 lda t0,-1 94c: 68 08 9e b4 stq t3,2152(sp) 950: 03 00 1f 22 lda a0,3 954: 58 08 3e b4 stq t0,2136(sp) 958: 60 08 be b4 stq t4,2144(sp) 95c: f6 ff 29 21 lda s0,-10(s0) 960: 18 08 de b4 stq t5,2072(sp) 964: 20 08 5e b4 stq t1,2080(sp) 968: 00 00 7d a7 ldq t12,0(gp) 96c: 00 40 5b 6b jsr ra,(t12),970 <__gettextparse+0x770> 970: 00 00 ba 27 ldah gp,0(ra) 974: 00 00 bd 23 lda gp,0(gp) 978: d8 ff 0a 21 lda t7,-40(s1) 97c: 58 08 3e a4 ldq t0,2136(sp) 980: 02 00 ff 20 lda t6,2 984: 68 08 9e a4 ldq t3,2152(sp) 988: 60 08 be a4 ldq t4,2144(sp) 98c: e9 fe ff c3 br 534 <__gettextparse+0x334> 990: 00 00 2a a4 ldq t0,0(s1) 994: 66 fe 3f e4 beq t0,330 <__gettextparse+0x130> 998: f8 ff 0a 21 lda t7,-8(s1) 99c: 40 08 7e a4 ldq t2,2112(sp) 9a0: fe ff 29 21 lda s0,-2(s0) 9a4: 01 00 ff 20 lda t6,1 9a8: 08 00 23 b4 stq t0,8(t2) 9ac: f6 ff 3f 20 lda t0,-10 9b0: e0 fe ff c3 br 534 <__gettextparse+0x334> 9b4: 00 00 dd 24 ldah t5,0(gp) 9b8: 00 00 c6 20 lda t5,0(t5) 9bc: 46 04 46 40 s4addq t1,t5,t5 9c0: 00 00 c6 a0 ldl t5,0(t5) 9c4: 06 04 a6 43 addq gp,t5,t5 9c8: 00 00 e6 6b jmp (t5) 9cc: 03 00 5f 20 lda t1,3 9d0: 48 08 7e a4 ldq t2,2120(sp) 9d4: 38 08 5e b4 stq t1,2104(sp) 9d8: 08 00 4a 21 lda s1,8(s1) 9dc: 02 00 49 20 lda t1,2(s0) 9e0: 00 00 6a b4 stq t2,0(s1) 9e4: ec fe ff c3 br 598 <__gettextparse+0x398> 9e8: 1f 04 ff 47 nop 9ec: 00 00 fe 2f unop 9f0: 40 08 7e a4 ldq t2,2112(sp) 9f4: 00 00 e3 b6 stq t9,0(t2) 9f8: 26 fe ff c3 br 294 <__gettextparse+0x94> 9fc: 00 00 fe 2f unop a00: 02 00 b6 20 lda t4,2(t8) a04: 01 00 56 2c ldq_u t1,1(t8) a08: 42 0f 45 48 extqh t1,t4,t1 a0c: 82 17 47 48 sra t1,0x38,t1 a10: a2 b5 47 40 cmpeq t1,0x3d,t1 a14: b2 00 40 f4 bne t1,ce0 <__gettextparse+0xae0> a18: 48 08 be a4 ldq t4,2120(sp) a1c: 40 08 7e a4 ldq t2,2112(sp) a20: 22 16 be 48 zapnot t4,0xf0,t1 a24: 00 00 03 b5 stq t7,0(t2) a28: 03 01 bf 20 lda t4,259 a2c: 02 34 41 44 or t1,0x9,t1 a30: 48 08 5e b4 stq t1,2120(sp) a34: 07 00 1f 21 lda t7,7 a38: 1c fe ff c3 br 2ac <__gettextparse+0xac> a3c: 00 00 fe 2f unop a40: 48 08 be a4 ldq t4,2120(sp) a44: 40 08 7e a4 ldq t2,2112(sp) a48: 22 16 be 48 zapnot t4,0xf0,t1 a4c: 00 00 03 b5 stq t7,0(t2) a50: 05 01 bf 20 lda t4,261 a54: 02 74 40 44 or t1,0x3,t1 a58: 48 08 5e b4 stq t1,2120(sp) a5c: 09 00 1f 21 lda t7,9 a60: 12 fe ff c3 br 2ac <__gettextparse+0xac> a64: 00 00 fe 2f unop a68: 1f 04 ff 47 nop a6c: 00 00 fe 2f unop a70: 48 08 be a4 ldq t4,2120(sp) a74: 40 08 7e a4 ldq t2,2112(sp) a78: 22 16 be 48 zapnot t4,0xf0,t1 a7c: 00 00 03 b5 stq t7,0(t2) a80: 04 01 bf 20 lda t4,260 a84: 02 f4 40 44 or t1,0x7,t1 a88: 48 08 5e b4 stq t1,2120(sp) a8c: 08 00 1f 21 lda t7,8 a90: 06 fe ff c3 br 2ac <__gettextparse+0xac> a94: 00 00 fe 2f unop a98: 1f 04 ff 47 nop a9c: 00 00 fe 2f unop aa0: 48 08 be a4 ldq t4,2120(sp) aa4: 40 08 7e a4 ldq t2,2112(sp) aa8: 22 16 be 48 zapnot t4,0xf0,t1 aac: 00 00 03 b5 stq t7,0(t2) ab0: 04 01 bf 20 lda t4,260 ab4: 02 d4 40 44 or t1,0x6,t1 ab8: 48 08 5e b4 stq t1,2120(sp) abc: 08 00 1f 21 lda t7,8 ac0: fa fd ff c3 br 2ac <__gettextparse+0xac> ac4: 00 00 fe 2f unop ac8: 1f 04 ff 47 nop acc: 00 00 fe 2f unop ad0: 02 00 f6 22 lda t9,2(t8) ad4: 01 00 d6 2c ldq_u t5,1(t8) ad8: 46 0f d7 48 extqh t5,t9,t5 adc: 86 17 c7 48 sra t5,0x38,t5 ae0: a2 05 c2 40 cmpeq t5,t1,t1 ae4: c2 ff 5f f4 bne t1,9f0 <__gettextparse+0x7f0> ae8: 00 01 bf 20 lda t4,256 aec: 40 08 7e a4 ldq t2,2112(sp) af0: 00 00 03 b5 stq t7,0(t2) af4: 01 00 1f 21 lda t7,1 af8: ec fd ff c3 br 2ac <__gettextparse+0xac> afc: 00 00 fe 2f unop b00: 48 08 be a4 ldq t4,2120(sp) b04: 40 08 7e a4 ldq t2,2112(sp) b08: 22 16 be 48 zapnot t4,0xf0,t1 b0c: 00 00 03 b5 stq t7,0(t2) b10: 05 01 bf 20 lda t4,261 b14: 02 b4 40 44 or t1,0x5,t1 b18: 48 08 5e b4 stq t1,2120(sp) b1c: 09 00 1f 21 lda t7,9 b20: e2 fd ff c3 br 2ac <__gettextparse+0xac> b24: 00 00 fe 2f unop b28: 1f 04 ff 47 nop b2c: 00 00 fe 2f unop b30: 02 00 b6 20 lda t4,2(t8) b34: 01 00 56 2c ldq_u t1,1(t8) b38: 42 0f 45 48 extqh t1,t4,t1 b3c: 82 17 47 48 sra t1,0x38,t1 b40: a2 b5 47 40 cmpeq t1,0x3d,t1 b44: 6f 00 40 f4 bne t1,d04 <__gettextparse+0xb04> b48: 21 00 bf 20 lda t4,33 b4c: 40 08 5e a4 ldq t1,2112(sp) b50: 00 00 02 b5 stq t7,0(t1) b54: 0a 00 1f 21 lda t7,10 b58: d4 fd ff c3 br 2ac <__gettextparse+0xac> b5c: 00 00 fe 2f unop b60: 08 04 ff 47 clr t7 b64: 40 08 5e a4 ldq t1,2112(sp) b68: 05 04 ff 47 clr t4 b6c: 00 00 c2 b6 stq t8,0(t1) b70: cf fd ff c3 br 2b0 <__gettextparse+0xb0> b74: 00 00 fe 2f unop b78: 1f 04 ff 47 nop b7c: 00 00 fe 2f unop b80: 02 00 b6 20 lda t4,2(t8) b84: 01 00 56 2c ldq_u t1,1(t8) b88: 42 0f 45 48 extqh t1,t4,t1 b8c: 82 17 47 48 sra t1,0x38,t1 b90: a2 b5 47 40 cmpeq t1,0x3d,t1 b94: f0 fe 5f e4 beq t1,758 <__gettextparse+0x558> b98: 06 00 1f 21 lda t7,6 b9c: 48 08 7e a4 ldq t2,2120(sp) ba0: 22 16 7e 48 zapnot t2,0xf0,t1 ba4: 40 08 7e a4 ldq t2,2112(sp) ba8: 02 94 41 44 or t1,0xc,t1 bac: 48 08 5e b4 stq t1,2120(sp) bb0: 00 00 a3 b4 stq t4,0(t2) bb4: 02 01 bf 20 lda t4,258 bb8: bc fd ff c3 br 2ac <__gettextparse+0xac> bbc: 00 00 fe 2f unop bc0: 02 00 b6 20 lda t4,2(t8) bc4: 01 00 56 2c ldq_u t1,1(t8) bc8: 42 0f 45 48 extqh t1,t4,t1 bcc: 82 17 47 48 sra t1,0x38,t1 bd0: a2 b5 47 40 cmpeq t1,0x3d,t1 bd4: 39 00 40 f4 bne t1,cbc <__gettextparse+0xabc> bd8: 48 08 be a4 ldq t4,2120(sp) bdc: 40 08 7e a4 ldq t2,2112(sp) be0: 22 16 be 48 zapnot t4,0xf0,t1 be4: 00 00 03 b5 stq t7,0(t2) be8: 03 01 bf 20 lda t4,259 bec: 02 14 41 44 or t1,0x8,t1 bf0: 48 08 5e b4 stq t1,2120(sp) bf4: 07 00 1f 21 lda t7,7 bf8: ac fd ff c3 br 2ac <__gettextparse+0xac> bfc: 00 00 fe 2f unop c00: 02 00 d6 20 lda t5,2(t8) c04: 01 00 56 2c ldq_u t1,1(t8) c08: 25 11 a6 40 subl t4,0x30,t4 c0c: 42 0f 46 48 extqh t1,t5,t1 c10: 82 17 47 48 sra t1,0x38,t1 c14: 22 11 46 40 subl t1,0x30,t1 c18: 06 f0 5f 44 and t1,0xff,t5 c1c: a6 37 c1 40 cmpule t5,0x9,t5 c20: 0e 00 c0 e4 beq t5,c5c <__gettextparse+0xa5c> c24: 01 00 08 21 lda t7,1(t7) c28: 17 04 e8 47 mov t7,t9 c2c: 01 00 08 21 lda t7,1(t7) c30: 45 04 a5 40 s4addq t4,t4,t4 c34: 00 00 d7 2c ldq_u t5,0(t9) c38: 02 00 e2 43 sextl t1,t1 c3c: 05 04 a5 40 addq t4,t4,t4 c40: 46 0f c8 48 extqh t5,t7,t5 c44: 05 04 45 40 addq t1,t4,t4 c48: 82 17 c7 48 sra t5,0x38,t1 c4c: 22 11 46 40 subl t1,0x30,t1 c50: 06 f0 5f 44 and t1,0xff,t5 c54: a6 37 c1 40 cmpule t5,0x9,t5 c58: f3 ff df f4 bne t5,c28 <__gettextparse+0xa28> c5c: 40 08 5e a4 ldq t1,2112(sp) c60: 48 08 be b4 stq t4,2120(sp) c64: 0b 00 1f 21 lda t7,11 c68: 06 01 bf 20 lda t4,262 c6c: 00 00 e2 b6 stq t9,0(t1) c70: 8e fd ff c3 br 2ac <__gettextparse+0xac> c74: 00 00 fe 2f unop c78: 1f 04 ff 47 nop c7c: 00 00 fe 2f unop c80: 48 08 be a4 ldq t4,2120(sp) c84: 40 08 7e a4 ldq t2,2112(sp) c88: 22 16 be 48 zapnot t4,0xf0,t1 c8c: 00 00 03 b5 stq t7,0(t2) c90: 05 01 bf 20 lda t4,261 c94: 02 94 40 44 or t1,0x4,t1 c98: 48 08 5e b4 stq t1,2120(sp) c9c: 09 00 1f 21 lda t7,9 ca0: 82 fd ff c3 br 2ac <__gettextparse+0xac> ca4: 09 04 ed 47 mov s4,s0 ca8: 02 00 5f 21 lda s1,2 cac: ca fd ff c3 br 3d8 <__gettextparse+0x1d8> cb0: 09 04 ee 47 mov s5,s0 cb4: 01 00 5f 21 lda s1,1 cb8: ca fd ff c3 br 3e4 <__gettextparse+0x1e4> cbc: 07 00 1f 21 lda t7,7 cc0: 48 08 7e a4 ldq t2,2120(sp) cc4: 22 16 7e 48 zapnot t2,0xf0,t1 cc8: 40 08 7e a4 ldq t2,2112(sp) ccc: 02 54 41 44 or t1,0xa,t1 cd0: 48 08 5e b4 stq t1,2120(sp) cd4: 00 00 a3 b4 stq t4,0(t2) cd8: 03 01 bf 20 lda t4,259 cdc: 73 fd ff c3 br 2ac <__gettextparse+0xac> ce0: 07 00 1f 21 lda t7,7 ce4: 48 08 7e a4 ldq t2,2120(sp) ce8: 22 16 7e 48 zapnot t2,0xf0,t1 cec: 40 08 7e a4 ldq t2,2112(sp) cf0: 02 74 41 44 or t1,0xb,t1 cf4: 48 08 5e b4 stq t1,2120(sp) cf8: 00 00 a3 b4 stq t4,0(t2) cfc: 03 01 bf 20 lda t4,259 d00: 6a fd ff c3 br 2ac <__gettextparse+0xac> d04: 06 00 1f 21 lda t7,6 d08: 48 08 7e a4 ldq t2,2120(sp) d0c: 22 16 7e 48 zapnot t2,0xf0,t1 d10: 40 08 7e a4 ldq t2,2112(sp) d14: 02 b4 41 44 or t1,0xd,t1 d18: 48 08 5e b4 stq t1,2120(sp) d1c: 00 00 a3 b4 stq t4,0(t2) d20: 02 01 bf 20 lda t4,258 d24: 61 fd ff c3 br 2ac <__gettextparse+0xac> d28: 1f 04 ff 47 nop d2c: 00 00 fe 2f unop [-- Attachment #3: plural-new.s --] [-- Type: text/plain, Size: 29023 bytes --] plural-new.o: file format elf64-alpha Disassembly of section .text: 0000000000000000 <__gettext_free_exp>: 0: 00 00 bb 27 ldah gp,0(t12) 4: 00 00 bd 23 lda gp,0(gp) 8: f0 ff de 23 lda sp,-16(sp) c: 08 00 3e b5 stq s0,8(sp) 10: 09 04 f0 47 mov a0,s0 14: 00 00 5e b7 stq ra,0(sp) 18: 11 00 00 e6 beq a0,60 <__gettext_free_exp+0x60> 1c: 00 00 30 a0 ldl t0,0(a0) 20: a2 5d 20 40 cmple t0,0x2,t1 24: 12 00 40 e4 beq t1,70 <__gettext_free_exp+0x70> 28: a2 55 20 40 cmpeq t0,0x2,t1 2c: 17 00 40 f4 bne t1,8c <__gettext_free_exp+0x8c> 30: a1 35 20 40 cmpeq t0,0x1,t0 34: 05 00 20 e4 beq t0,4c <__gettext_free_exp+0x4c> 38: 08 00 09 a6 ldq a0,8(s0) 3c: 00 00 7d a7 ldq t12,0(gp) 40: 00 40 5b 6b jsr ra,(t12),44 <__gettext_free_exp+0x44> 44: 00 00 ba 27 ldah gp,0(ra) 48: 00 00 bd 23 lda gp,0(gp) 4c: 10 04 e9 47 mov s0,a0 50: 00 00 7d a7 ldq t12,0(gp) 54: 00 40 5b 6b jsr ra,(t12),58 <__gettext_free_exp+0x58> 58: 00 00 ba 27 ldah gp,0(ra) 5c: 00 00 bd 23 lda gp,0(gp) 60: 00 00 5e a7 ldq ra,0(sp) 64: 08 00 3e a5 ldq s0,8(sp) 68: 10 00 de 23 lda sp,16(sp) 6c: 01 80 fa 6b ret 70: a1 75 20 40 cmpeq t0,0x3,t0 74: f5 ff 3f e4 beq t0,4c <__gettext_free_exp+0x4c> 78: 18 00 10 a6 ldq a0,24(a0) 7c: 00 00 7d a7 ldq t12,0(gp) 80: 00 40 5b 6b jsr ra,(t12),84 <__gettext_free_exp+0x84> 84: 00 00 ba 27 ldah gp,0(ra) 88: 00 00 bd 23 lda gp,0(gp) 8c: 10 00 09 a6 ldq a0,16(s0) 90: 00 00 7d a7 ldq t12,0(gp) 94: 00 40 5b 6b jsr ra,(t12),98 <__gettext_free_exp+0x98> 98: 00 00 ba 27 ldah gp,0(ra) 9c: 00 00 bd 23 lda gp,0(gp) a0: e5 ff ff c3 br 38 <__gettext_free_exp+0x38> a4: 00 00 fe 2f unop a8: 1f 04 ff 47 nop ac: 00 00 fe 2f unop 00000000000000b0 <new_exp>: b0: 00 00 bb 27 ldah gp,0(t12) b4: 00 00 bd 23 lda gp,0(gp) b8: d0 ff de 23 lda sp,-48(sp) bc: 08 00 3e b5 stq s0,8(sp) c0: 29 31 00 42 subl a0,0x1,s0 c4: 10 00 5e b5 stq s1,16(sp) c8: 01 00 29 20 lda t0,1(s0) cc: 18 00 7e b5 stq s2,24(sp) d0: 0a 04 f2 47 mov a2,s1 d4: 20 00 9e b5 stq s3,32(sp) d8: 0b 04 f0 47 mov a0,s2 dc: 00 00 5e b7 stq ra,0(sp) e0: 0c 04 f1 47 mov a1,s3 e4: 35 00 20 e4 beq t0,1bc <new_exp+0x10c> e8: 01 04 e9 47 mov s0,t0 ec: 01 00 e0 c3 br f4 <new_exp+0x44> f0: 1b 00 40 e4 beq t1,160 <new_exp+0xb0> f4: 43 06 2a 40 s8addq t0,s1,t2 f8: ff ff 21 20 lda t0,-1(t0) fc: 02 00 e1 43 sextl t0,t1 100: 00 00 63 a4 ldq t2,0(t2) 104: 01 00 42 20 lda t1,1(t1) 108: f9 ff 7f f4 bne t2,f0 <new_exp+0x40> 10c: 00 00 fe 2f unop 110: 41 06 2a 41 s8addq s0,s1,t0 114: ff ff 29 21 lda s0,-1(s0) 118: 00 00 01 a6 ldq a0,0(t0) 11c: 00 00 7d a7 ldq t12,0(gp) 120: 00 40 5b 6b jsr ra,(t12),124 <new_exp+0x74> 124: 00 00 ba 27 ldah gp,0(ra) 128: 00 00 bd 23 lda gp,0(gp) 12c: 01 00 e9 43 sextl s0,t0 130: 01 00 21 20 lda t0,1(t0) 134: f6 ff 3f f4 bne t0,110 <new_exp+0x60> 138: 00 00 5e a7 ldq ra,0(sp) 13c: 08 00 3e a5 ldq s0,8(sp) 140: 10 00 5e a5 ldq s1,16(sp) 144: 18 00 7e a5 ldq s2,24(sp) 148: 00 04 ff 47 clr v0 14c: 20 00 9e a5 ldq s3,32(sp) 150: 30 00 de 23 lda sp,48(sp) 154: 01 80 fa 6b ret 158: 1f 04 ff 47 nop 15c: 00 00 fe 2f unop 160: 20 00 1f 22 lda a0,32 164: 00 00 7d a7 ldq t12,0(gp) 168: 00 40 5b 6b jsr ra,(t12),16c <new_exp+0xbc> 16c: 00 00 ba 27 ldah gp,0(ra) 170: 00 00 bd 23 lda gp,0(gp) 174: e6 ff 1f e4 beq v0,110 <new_exp+0x60> 178: 00 00 60 b1 stl s2,0(v0) 17c: 04 00 80 b1 stl s3,4(v0) 180: 41 06 2a 41 s8addq s0,s1,t0 184: 42 06 20 41 s8addq s0,v0,t1 188: ff ff 29 21 lda s0,-1(s0) 18c: 00 00 61 a4 ldq t2,0(t0) 190: 01 00 e9 43 sextl s0,t0 194: 01 00 21 20 lda t0,1(t0) 198: 08 00 62 b4 stq t2,8(t1) 19c: f8 ff 3f f4 bne t0,180 <new_exp+0xd0> 1a0: 00 00 5e a7 ldq ra,0(sp) 1a4: 08 00 3e a5 ldq s0,8(sp) 1a8: 10 00 5e a5 ldq s1,16(sp) 1ac: 18 00 7e a5 ldq s2,24(sp) 1b0: 20 00 9e a5 ldq s3,32(sp) 1b4: 30 00 de 23 lda sp,48(sp) 1b8: 01 80 fa 6b ret 1bc: 20 00 1f 22 lda a0,32 1c0: 00 00 7d a7 ldq t12,0(gp) 1c4: 00 40 5b 6b jsr ra,(t12),1c8 <new_exp+0x118> 1c8: 00 00 ba 27 ldah gp,0(ra) 1cc: 00 00 bd 23 lda gp,0(gp) 1d0: d9 ff 1f e4 beq v0,138 <new_exp+0x88> 1d4: 04 00 80 b1 stl s3,4(v0) 1d8: 00 00 5e a7 ldq ra,0(sp) 1dc: 08 00 3e a5 ldq s0,8(sp) 1e0: 10 00 5e a5 ldq s1,16(sp) 1e4: 18 00 7e a5 ldq s2,24(sp) 1e8: 20 00 9e a5 ldq s3,32(sp) 1ec: 00 00 e0 b3 stl zero,0(v0) 1f0: 30 00 de 23 lda sp,48(sp) 1f4: 01 80 fa 6b ret 1f8: 1f 04 ff 47 nop 1fc: 00 00 fe 2f unop 0000000000000200 <__gettextparse>: 200: 00 00 bb 27 ldah gp,0(t12) 204: 00 00 bd 23 lda gp,0(gp) 208: 90 f7 de 23 lda sp,-2160(sp) 20c: 00 00 9d 24 ldah t3,0(gp) 210: 80 06 3e a0 ldl t0,1664(sp) 214: 08 00 3e b5 stq s0,8(sp) 218: 00 00 5d 24 ldah t1,0(gp) 21c: 80 06 3e 21 lda s0,1664(sp) 220: 10 00 5e b5 stq s1,16(sp) 224: 21 96 3f 48 zapnot t0,0xfc,t0 228: 18 00 7e b5 stq s2,24(sp) 22c: 40 00 5e 21 lda s1,64(sp) 230: 20 00 9e b5 stq s3,32(sp) 234: 28 00 be b5 stq s4,40(sp) 238: 00 00 42 20 lda t1,0(t1) 23c: 30 00 de b5 stq s5,48(sp) 240: fe ff bf 20 lda t4,-2 244: 80 06 3e b0 stl t0,1664(sp) 248: c8 00 7f 21 lda s2,200 24c: 01 04 ff 47 clr t0 250: 00 00 5e b7 stq ra,0(sp) 254: 0e 04 ea 47 mov s1,s5 258: 38 00 fe b5 stq fp,56(sp) 25c: 0d 04 e9 47 mov s0,s4 260: 40 08 1e b6 stq a0,2112(sp) 264: 00 00 84 21 lda s3,0(t3) 268: 38 08 fe b7 stq zero,2104(sp) 26c: 01 00 42 20 lda t1,1(t1) 270: 30 08 3e b5 stq s0,2096(sp) 274: 48 08 5e b4 stq t1,2120(sp) 278: 02 04 81 41 addq s3,t0,t1 27c: 01 00 c2 20 lda t5,1(t1) 280: 00 00 e2 2c ldq_u t6,0(t1) 284: 47 0f e6 48 extqh t6,t5,t6 288: 87 17 e7 48 sra t6,0x38,t6 28c: 0a 00 47 20 lda t1,10(t6) 290: 27 00 40 e4 beq t1,330 <__gettextparse+0x130> 294: 02 00 45 20 lda t1,2(t4) 298: 21 01 40 e4 beq t1,720 <__gettextparse+0x520> 29c: 94 00 a0 ec ble t4,4f0 <__gettextparse+0x2f0> 2a0: 00 00 5d 24 ldah t1,0(gp) 2a4: 00 00 42 20 lda t1,0(t1) 2a8: 02 04 a2 40 addq t4,t1,t1 2ac: 00 00 02 2d ldq_u t7,0(t1) 2b0: c8 00 02 49 extbl t7,t1,t7 2b4: 07 00 e8 40 addl t6,t7,t6 2b8: 26 f6 e1 48 zapnot t6,0xf,t5 2bc: a6 d7 c6 40 cmpule t5,0x36,t5 2c0: 1b 00 c0 e4 beq t5,330 <__gettextparse+0x130> 2c4: 00 00 dd 24 ldah t5,0(gp) 2c8: 00 00 c6 20 lda t5,0(t5) 2cc: 06 04 e6 40 addq t6,t5,t5 2d0: 01 00 c6 22 lda t8,1(t5) 2d4: 00 00 46 2c ldq_u t1,0(t5) 2d8: 42 0f 56 48 extqh t1,t8,t1 2dc: 82 17 47 48 sra t1,0x38,t1 2e0: a2 05 48 40 cmpeq t1,t7,t1 2e4: 12 00 40 e4 beq t1,330 <__gettextparse+0x130> 2e8: 00 00 3d 24 ldah t0,0(gp) 2ec: 00 00 21 20 lda t0,0(t0) 2f0: 07 04 e1 40 addq t6,t0,t6 2f4: 00 00 27 2c ldq_u t0,0(t6) 2f8: c1 00 27 48 extbl t0,t6,t0 2fc: 28 01 20 f4 bne t0,7a0 <__gettextparse+0x5a0> 300: 00 00 5d 24 ldah t1,0(gp) 304: 48 08 7e a4 ldq t2,2120(sp) 308: 00 00 42 20 lda t1,0(t1) 30c: 08 00 0a a4 ldq v0,8(s1) 310: 08 04 ea 47 mov s1,t7 314: f0 ff ff 20 lda t6,-16 318: 00 00 22 2c ldq_u t0,0(t1) 31c: 41 0f 23 48 extqh t0,t2,t0 320: 81 17 27 48 sra t0,0x38,t0 324: 8f 00 e0 c3 br 564 <__gettextparse+0x364> 328: 1f 04 ff 47 nop 32c: 00 00 fe 2f unop 330: 00 00 5d 24 ldah t1,0(gp) 334: 00 00 42 20 lda t1,0(t1) 338: 02 04 22 40 addq t0,t1,t1 33c: 00 00 c2 2c ldq_u t5,0(t1) 340: c2 00 c2 48 extbl t5,t1,t1 344: 08 00 e2 43 sextl t1,t7 348: 35 00 40 f4 bne t1,420 <__gettextparse+0x220> 34c: 38 08 9e a4 ldq t3,2104(sp) 350: a2 75 80 40 cmpeq t3,0x3,t1 354: 02 00 40 e4 beq t1,360 <__gettextparse+0x160> 358: 1d 01 a0 fc bgt t4,7d0 <__gettextparse+0x5d0> 35c: 4d 02 a0 e4 beq t4,c94 <__gettextparse+0xa94> 360: 00 00 dd 24 ldah t5,0(gp) 364: 00 00 fd 24 ldah t6,0(gp) 368: 00 00 c6 20 lda t5,0(t5) 36c: 00 00 e7 20 lda t6,0(t6) 370: 0b 00 e0 c3 br 3a0 <__gettextparse+0x1a0> 374: 00 00 fe 2f unop 378: 1f 04 ff 47 nop 37c: 00 00 fe 2f unop 380: a1 05 2d 41 cmpeq s0,s4,t0 384: 46 00 20 f4 bne t0,4a0 <__gettextparse+0x2a0> 388: fe ff 29 21 lda s0,-2(s0) 38c: 02 00 49 20 lda t1,2(s0) 390: f8 ff 4a 21 lda s1,-8(s1) 394: 00 00 29 2c ldq_u t0,0(s0) 398: 41 0f 22 48 extqh t0,t1,t0 39c: 81 17 26 48 sra t0,0x30,t0 3a0: 01 04 81 41 addq s3,t0,t0 3a4: 01 00 41 20 lda t1,1(t0) 3a8: 00 00 21 2c ldq_u t0,0(t0) 3ac: 41 0f 22 48 extqh t0,t1,t0 3b0: 81 17 27 48 sra t0,0x38,t0 3b4: 0a 00 41 20 lda t1,10(t0) 3b8: f1 ff 5f e4 beq t1,380 <__gettextparse+0x180> 3bc: 01 30 20 40 addl t0,0x1,t0 3c0: 22 f6 21 48 zapnot t0,0xf,t1 3c4: 01 00 e1 43 sextl t0,t0 3c8: a2 d7 46 40 cmpule t1,0x36,t1 3cc: ec ff 5f e4 beq t1,380 <__gettextparse+0x180> 3d0: 08 04 26 40 addq t0,t5,t7 3d4: 01 00 c8 22 lda t8,1(t7) 3d8: 00 00 48 2c ldq_u t1,0(t7) 3dc: 42 0f 56 48 extqh t1,t8,t1 3e0: 82 17 47 48 sra t1,0x38,t1 3e4: a2 35 40 40 cmpeq t1,0x1,t1 3e8: e5 ff 5f e4 beq t1,380 <__gettextparse+0x180> 3ec: 01 04 27 40 addq t0,t6,t0 3f0: 00 00 41 2c ldq_u t1,0(t0) 3f4: c1 00 41 48 extbl t1,t0,t0 3f8: e1 ff 3f e4 beq t0,380 <__gettextparse+0x180> 3fc: 03 00 9f 20 lda t3,3 400: 50 08 7e a4 ldq t2,2128(sp) 404: 38 08 9e b4 stq t3,2104(sp) 408: 08 00 4a 21 lda s1,8(s1) 40c: 02 00 49 20 lda t1,2(s0) 410: 00 00 6a b4 stq t2,0(s1) 414: 6e 00 e0 c3 br 5d0 <__gettextparse+0x3d0> 418: 1f 04 ff 47 nop 41c: 00 00 fe 2f unop 420: 00 00 3d 24 ldah t0,0(gp) 424: 00 00 21 20 lda t0,0(t0) 428: 01 04 01 41 addq t7,t0,t0 42c: a7 b7 41 40 cmpule t1,0xd,t6 430: 00 00 c1 2c ldq_u t5,0(t0) 434: c1 00 c1 48 extbl t5,t0,t0 438: 01 00 df 20 lda t5,1 43c: 26 01 c1 40 subl t5,t0,t5 440: 46 06 ca 40 s8addq t5,s1,t5 444: 00 00 06 a4 ldq v0,0(t5) 448: 2d 00 e0 f4 bne t6,500 <__gettextparse+0x300> 44c: 00 00 5d 24 ldah t1,0(gp) 450: 00 00 42 20 lda t1,0(t1) 454: 02 04 02 41 addq t7,t1,t1 458: 00 00 9d 24 ldah t3,0(gp) 45c: 48 16 20 40 s8addq t0,0,t7 460: 00 00 e2 2c ldq_u t6,0(t1) 464: 01 04 21 40 addq t0,t0,t0 468: 00 00 84 20 lda t3,0(t3) 46c: c2 00 e2 48 extbl t6,t1,t1 470: 29 05 21 41 subq s0,t0,s0 474: 27 11 42 40 subl t1,0x10,t6 478: 01 04 e4 40 addq t6,t3,t0 47c: 01 00 41 20 lda t1,1(t0) 480: 28 05 48 41 subq s1,t7,t7 484: 00 00 21 2c ldq_u t0,0(t0) 488: 41 0f 22 48 extqh t0,t1,t0 48c: 81 17 27 48 sra t0,0x38,t0 490: 34 00 e0 c3 br 564 <__gettextparse+0x364> 494: 00 00 fe 2f unop 498: 1f 04 ff 47 nop 49c: 00 00 fe 2f unop 4a0: 01 00 5f 21 lda s1,1 4a4: 30 08 3e a4 ldq t0,2096(sp) 4a8: ad 05 21 41 cmpeq s0,t0,s4 4ac: 05 00 a0 f5 bne s4,4c4 <__gettextparse+0x2c4> 4b0: 10 04 e9 47 mov s0,a0 4b4: 00 00 7d a7 ldq t12,0(gp) 4b8: 00 40 5b 6b jsr ra,(t12),4bc <__gettextparse+0x2bc> 4bc: 00 00 ba 27 ldah gp,0(ra) 4c0: 00 00 bd 23 lda gp,0(gp) 4c4: 00 04 ea 47 mov s1,v0 4c8: 00 00 5e a7 ldq ra,0(sp) 4cc: 08 00 3e a5 ldq s0,8(sp) 4d0: 10 00 5e a5 ldq s1,16(sp) 4d4: 18 00 7e a5 ldq s2,24(sp) 4d8: 20 00 9e a5 ldq s3,32(sp) 4dc: 28 00 be a5 ldq s4,40(sp) 4e0: 30 00 de a5 ldq s5,48(sp) 4e4: 38 00 fe a5 ldq fp,56(sp) 4e8: 70 08 de 23 lda sp,2160(sp) 4ec: 01 80 fa 6b ret 4f0: 08 04 ff 47 clr t7 4f4: 05 04 ff 47 clr t4 4f8: 6f ff ff c3 br 2b8 <__gettextparse+0xb8> 4fc: 00 00 fe 2f unop 500: 00 00 dd 24 ldah t5,0(gp) 504: 00 00 c6 20 lda t5,0(t5) 508: 42 04 46 40 s4addq t1,t5,t1 50c: 00 00 42 a0 ldl t1,0(t1) 510: 02 04 a2 43 addq gp,t1,t1 514: 00 00 e2 6b jmp (t1) 518: 1f 04 ff 47 nop 51c: 00 00 fe 2f unop 520: 10 08 5e 22 lda a2,2064(sp) 524: f8 ff 2a a2 ldl a1,-8(s1) 528: 00 00 4a a4 ldq t1,0(s1) 52c: f0 ff 2a a4 ldq t0,-16(s1) 530: 02 00 1f 22 lda a0,2 534: 10 08 3e b4 stq t0,2064(sp) 538: 68 08 be b4 stq t4,2152(sp) 53c: fa ff 29 21 lda s0,-6(s0) 540: 18 08 5e b4 stq t1,2072(sp) 544: 00 00 7d a7 ldq t12,0(gp) 548: 00 40 5b 6b jsr ra,(t12),54c <__gettextparse+0x34c> 54c: 00 00 ba 27 ldah gp,0(ra) 550: 00 00 bd 23 lda gp,0(gp) 554: e8 ff 0a 21 lda t7,-24(s1) 558: 68 08 be a4 ldq t4,2152(sp) 55c: ff ff 3f 20 lda t0,-1 560: 02 00 ff 20 lda t6,2 564: 08 00 08 b4 stq v0,8(t7) 568: 02 00 49 20 lda t1,2(s0) 56c: 08 00 48 21 lda s1,8(t7) 570: 00 00 c9 2c ldq_u t5,0(s0) 574: 46 0f c2 48 extqh t5,t1,t5 578: 86 17 c6 48 sra t5,0x30,t5 57c: 01 00 c1 40 addl t5,t0,t0 580: 28 f6 21 48 zapnot t0,0xf,t7 584: 01 00 e1 43 sextl t0,t0 588: a8 d7 06 41 cmpule t7,0x36,t7 58c: 09 00 00 e5 beq t7,5b4 <__gettextparse+0x3b4> 590: 00 00 dd 26 ldah t8,0(gp) 594: 00 00 d6 22 lda t8,0(t8) 598: 16 04 36 40 addq t0,t8,t8 59c: 01 00 f6 22 lda t9,1(t8) 5a0: 00 00 16 2d ldq_u t7,0(t8) 5a4: 48 0f 17 49 extqh t7,t9,t7 5a8: 88 17 07 49 sra t7,0x38,t7 5ac: a6 05 06 41 cmpeq t7,t5,t5 5b0: 8b 00 c0 f4 bne t5,7e0 <__gettextparse+0x5e0> 5b4: 00 00 dd 24 ldah t5,0(gp) 5b8: 00 00 c6 20 lda t5,0(t5) 5bc: 06 04 e6 40 addq t6,t5,t5 5c0: 01 00 e6 20 lda t6,1(t5) 5c4: 00 00 26 2c ldq_u t0,0(t5) 5c8: 41 0f 27 48 extqh t0,t6,t0 5cc: 81 17 27 48 sra t0,0x38,t0 5d0: 16 04 6b 41 addq s2,s2,t8 5d4: 02 00 09 2d ldq_u t7,2(s0) 5d8: 67 03 22 48 inswl t0,t1,t6 5dc: fe ff d6 20 lda t5,-2(t8) 5e0: 48 02 02 49 mskwl t7,t1,t7 5e4: 06 04 a6 41 addq s4,t5,t5 5e8: 07 04 e8 44 or t6,t7,t6 5ec: 02 00 e9 3c stq_u t6,2(s0) 5f0: a6 03 46 40 cmpult t1,t5,t5 5f4: 09 04 e2 47 mov t1,s0 5f8: 41 00 c0 f4 bne t5,700 <__gettextparse+0x500> 5fc: 2a 05 4d 40 subq t1,s4,s1 600: 8a 37 40 49 sra s1,0x1,s1 604: 0f 27 df 20 lda t5,9999 608: ab 07 66 41 cmpule s2,t5,s2 60c: 01 00 4a 21 lda s1,1(s1) 610: a3 01 60 e5 beq s2,ca0 <__gettextparse+0xaa0> 614: 10 27 5f 20 lda t1,10000 618: 00 00 7d a7 ldq t12,0(gp) 61c: ab 03 c2 42 cmpult t8,t1,s2 620: 60 08 3e b4 stq t0,2144(sp) 624: 68 08 be b4 stq t4,2152(sp) 628: c2 04 76 45 cmovne s2,t8,t1 62c: 50 04 42 40 s4addq t1,t1,a0 630: 10 04 10 42 addq a0,a0,a0 634: 07 00 10 22 lda a0,7(a0) 638: 0b 04 e2 47 mov t1,s2 63c: 00 40 5b 6b jsr ra,(t12),640 <__gettextparse+0x440> 640: 00 00 ba 27 ldah gp,0(ra) 644: 00 00 bd 23 lda gp,0(gp) 648: 0f 04 e0 47 mov v0,fp 64c: 94 01 00 e4 beq v0,ca0 <__gettextparse+0xaa0> 650: 09 04 4a 41 addq s1,s1,s0 654: 00 00 7d a7 ldq t12,0(gp) 658: 12 04 e9 47 mov s0,a2 65c: 11 04 ed 47 mov s4,a1 660: 10 04 e0 47 mov v0,a0 664: 00 40 5b 6b jsr ra,(t12),668 <__gettextparse+0x468> 668: 00 00 ba 27 ldah gp,0(ra) 66c: 4a 16 40 41 s8addq s1,0,s1 670: 06 04 6b 41 addq s2,s2,t5 674: 00 00 bd 23 lda gp,0(gp) 678: 06 04 e6 41 addq fp,t5,t5 67c: 11 04 ee 47 mov s5,a1 680: 00 00 7d a7 ldq t12,0(gp) 684: 10 04 e6 47 mov t5,a0 688: 12 04 ea 47 mov s1,a2 68c: 00 40 5b 6b jsr ra,(t12),690 <__gettextparse+0x490> 690: 00 00 ba 27 ldah gp,0(ra) 694: 0e 04 6b 41 addq s2,s2,s5 698: 30 08 7e a4 ldq t2,2096(sp) 69c: 00 00 bd 23 lda gp,0(gp) 6a0: 60 08 3e a4 ldq t0,2144(sp) 6a4: 06 04 e0 47 mov v0,t5 6a8: 68 08 be a4 ldq t4,2152(sp) 6ac: a7 05 a3 41 cmpeq s4,t2,t6 6b0: 09 00 e0 f4 bne t6,6d8 <__gettextparse+0x4d8> 6b4: 10 04 ed 47 mov s4,a0 6b8: 00 00 7d a7 ldq t12,0(gp) 6bc: 58 08 1e b4 stq v0,2136(sp) 6c0: 00 40 5b 6b jsr ra,(t12),6c4 <__gettextparse+0x4c4> 6c4: 00 00 ba 27 ldah gp,0(ra) 6c8: 58 08 de a4 ldq t5,2136(sp) 6cc: 00 00 bd 23 lda gp,0(gp) 6d0: 68 08 be a4 ldq t4,2152(sp) 6d4: 60 08 3e a4 ldq t0,2144(sp) 6d8: fe ff 29 21 lda s0,-2(s0) 6dc: fe ff ce 21 lda s5,-2(s5) 6e0: 09 04 e9 41 addq fp,s0,s0 6e4: 0e 04 ee 41 addq fp,s5,s5 6e8: f8 ff 4a 21 lda s1,-8(s1) 6ec: ae 03 2e 41 cmpult s0,s5,s5 6f0: 0a 04 ca 40 addq t5,s1,s1 6f4: 6d 01 c0 e5 beq s5,cac <__gettextparse+0xaac> 6f8: 0e 04 e6 47 mov t5,s5 6fc: 0d 04 ef 47 mov fp,s4 700: a2 35 21 40 cmpeq t0,0x9,t1 704: dc fe 5f e4 beq t1,278 <__gettextparse+0x78> 708: 09 04 ed 47 mov s4,s0 70c: 0a 04 ff 47 clr s1 710: 64 ff ff c3 br 4a4 <__gettextparse+0x2a4> 714: 00 00 fe 2f unop 718: 1f 04 ff 47 nop 71c: 00 00 fe 2f unop 720: 40 08 9e a4 ldq t3,2112(sp) 724: 00 00 c4 a6 ldq t8,0(t3) 728: 01 00 16 21 lda t7,1(t8) 72c: 00 00 56 2c ldq_u t1,0(t8) 730: 42 0f 48 48 extqh t1,t7,t1 734: 82 17 47 48 sra t1,0x38,t1 738: 08 00 40 f4 bne t1,75c <__gettextparse+0x55c> 73c: 2e 00 e0 c3 br 7f8 <__gettextparse+0x5f8> 740: 02 00 b6 20 lda t4,2(t8) 744: 00 00 48 2c ldq_u t1,0(t7) 748: 16 04 e8 47 mov t7,t8 74c: 42 0f 45 48 extqh t1,t4,t1 750: 82 17 47 48 sra t1,0x38,t1 754: 2a 00 40 e4 beq t1,800 <__gettextparse+0x600> 758: 01 00 08 21 lda t7,1(t7) 75c: a6 15 44 40 cmpeq t1,0x20,t5 760: a5 35 41 40 cmpeq t1,0x9,t4 764: a6 15 c0 40 cmpeq t5,0,t5 768: a5 15 a0 40 cmpeq t4,0,t4 76c: 17 04 e8 47 mov t7,t9 770: 05 00 c5 44 and t5,t4,t4 774: f2 ff bf e4 beq t4,740 <__gettextparse+0x540> 778: 06 f0 5f 44 and t1,0xff,t5 77c: a6 97 cf 40 cmpule t5,0x7c,t5 780: 05 00 e2 43 sextl t1,t4 784: 8f 00 c0 f4 bne t5,9c4 <__gettextparse+0x7c4> 788: 00 01 bf 20 lda t4,256 78c: 40 08 9e a4 ldq t3,2112(sp) 790: 00 00 04 b5 stq t7,0(t3) 794: 01 00 1f 21 lda t7,1 798: c6 fe ff c3 br 2b4 <__gettextparse+0xb4> 79c: 00 00 fe 2f unop 7a0: 38 08 9e a4 ldq t3,2104(sp) 7a4: 08 00 4a 21 lda s1,8(s1) 7a8: 50 08 7e a4 ldq t2,2128(sp) 7ac: fe ff bf 20 lda t4,-2 7b0: 22 31 80 40 subl t3,0x1,t1 7b4: c4 04 82 44 cmovne t3,t1,t3 7b8: 00 00 6a b4 stq t2,0(s1) 7bc: 38 08 9e b4 stq t3,2104(sp) 7c0: 02 00 49 20 lda t1,2(s0) 7c4: 82 ff ff c3 br 5d0 <__gettextparse+0x3d0> 7c8: 1f 04 ff 47 nop 7cc: 00 00 fe 2f unop 7d0: fe ff bf 20 lda t4,-2 7d4: e2 fe ff c3 br 360 <__gettextparse+0x160> 7d8: 1f 04 ff 47 nop 7dc: 00 00 fe 2f unop 7e0: 00 00 dd 24 ldah t5,0(gp) 7e4: 00 00 c6 20 lda t5,0(t5) 7e8: 01 04 26 40 addq t0,t5,t0 7ec: 00 00 c1 2c ldq_u t5,0(t0) 7f0: c1 00 c1 48 extbl t5,t0,t0 7f4: 76 ff ff c3 br 5d0 <__gettextparse+0x3d0> 7f8: 17 04 f6 47 mov t8,t9 7fc: 00 00 fe 2f unop 800: 08 04 ff 47 clr t7 804: 40 08 5e a4 ldq t1,2112(sp) 808: 05 04 ff 47 clr t4 80c: 00 00 e2 b6 stq t9,0(t1) 810: a9 fe ff c3 br 2b8 <__gettextparse+0xb8> 814: 00 00 fe 2f unop 818: 1f 04 ff 47 nop 81c: 00 00 fe 2f unop 820: 10 08 5e 22 lda a2,2064(sp) 824: 00 00 2a a4 ldq t0,0(s1) 828: 02 00 3f 22 lda a1,2 82c: 68 08 be b4 stq t4,2152(sp) 830: 01 00 1f 22 lda a0,1 834: 10 08 3e b4 stq t0,2064(sp) 838: fc ff 29 21 lda s0,-4(s0) 83c: 00 00 7d a7 ldq t12,0(gp) 840: 00 40 5b 6b jsr ra,(t12),844 <__gettextparse+0x644> 844: 00 00 ba 27 ldah gp,0(ra) 848: 00 00 bd 23 lda gp,0(gp) 84c: f0 ff 0a 21 lda t7,-16(s1) 850: 68 08 be a4 ldq t4,2152(sp) 854: ff ff 3f 20 lda t0,-1 858: 02 00 ff 20 lda t6,2 85c: 41 ff ff c3 br 564 <__gettextparse+0x364> 860: 12 04 ff 47 clr a2 864: 68 08 be b4 stq t4,2152(sp) 868: 11 04 ff 47 clr a1 86c: 10 04 ff 47 clr a0 870: 00 00 7d a7 ldq t12,0(gp) 874: 00 40 5b 6b jsr ra,(t12),878 <__gettextparse+0x678> 878: 00 00 ba 27 ldah gp,0(ra) 87c: 00 00 bd 23 lda gp,0(gp) 880: fe ff 29 21 lda s0,-2(s0) 884: f8 ff 0a 21 lda t7,-8(s1) 888: 68 08 be a4 ldq t4,2152(sp) 88c: ff ff 3f 20 lda t0,-1 890: 02 00 ff 20 lda t6,2 894: 33 ff ff c3 br 564 <__gettextparse+0x364> 898: 1f 04 ff 47 nop 89c: 00 00 fe 2f unop 8a0: 12 04 ff 47 clr a2 8a4: 68 08 be b4 stq t4,2152(sp) 8a8: 01 00 3f 22 lda a1,1 8ac: 10 04 ff 47 clr a0 8b0: 00 00 7d a7 ldq t12,0(gp) 8b4: 00 40 5b 6b jsr ra,(t12),8b8 <__gettextparse+0x6b8> 8b8: 00 00 ba 27 ldah gp,0(ra) 8bc: 00 00 bd 23 lda gp,0(gp) 8c0: fe ff 29 21 lda s0,-2(s0) 8c4: f8 ff 0a 21 lda t7,-8(s1) 8c8: 68 08 be a4 ldq t4,2152(sp) 8cc: ff ff 3f 20 lda t0,-1 8d0: 02 00 ff 20 lda t6,2 8d4: 23 ff 1f e4 beq v0,564 <__gettextparse+0x364> 8d8: 00 00 4a a4 ldq t1,0(s1) 8dc: 08 00 40 b4 stq t1,8(v0) 8e0: 20 ff ff c3 br 564 <__gettextparse+0x364> 8e4: 00 00 fe 2f unop 8e8: 1f 04 ff 47 nop 8ec: 00 00 fe 2f unop 8f0: e8 ff 0a 21 lda t7,-24(s1) 8f4: f8 ff 0a a4 ldq v0,-8(s1) 8f8: fa ff 29 21 lda s0,-6(s0) 8fc: ff ff 3f 20 lda t0,-1 900: 02 00 ff 20 lda t6,2 904: 17 ff ff c3 br 564 <__gettextparse+0x364> 908: 1f 04 ff 47 nop 90c: 00 00 fe 2f unop 910: 10 08 5e 22 lda a2,2064(sp) 914: 00 00 4a a4 ldq t1,0(s1) 918: 0e 00 3f 22 lda a1,14 91c: f0 ff 2a a4 ldq t0,-16(s1) 920: 03 ff ff c3 br 530 <__gettextparse+0x330> 924: 00 00 fe 2f unop 928: 1f 04 ff 47 nop 92c: 00 00 fe 2f unop 930: 10 08 5e 22 lda a2,2064(sp) 934: 00 00 4a a4 ldq t1,0(s1) 938: 0f 00 3f 22 lda a1,15 93c: f0 ff 2a a4 ldq t0,-16(s1) 940: fb fe ff c3 br 530 <__gettextparse+0x330> 944: 00 00 fe 2f unop 948: 1f 04 ff 47 nop 94c: 00 00 fe 2f unop 950: e0 ff 2a a4 ldq t0,-32(s1) 954: f0 ff ca a4 ldq t5,-16(s1) 958: 10 08 5e 22 lda a2,2064(sp) 95c: 00 00 4a a4 ldq t1,0(s1) 960: 10 00 3f 22 lda a1,16 964: 10 08 3e b4 stq t0,2064(sp) 968: 03 00 1f 22 lda a0,3 96c: 68 08 be b4 stq t4,2152(sp) 970: 18 08 de b4 stq t5,2072(sp) 974: f6 ff 29 21 lda s0,-10(s0) 978: 20 08 5e b4 stq t1,2080(sp) 97c: 00 00 7d a7 ldq t12,0(gp) 980: 00 40 5b 6b jsr ra,(t12),984 <__gettextparse+0x784> 984: 00 00 ba 27 ldah gp,0(ra) 988: 00 00 bd 23 lda gp,0(gp) 98c: d8 ff 0a 21 lda t7,-40(s1) 990: 68 08 be a4 ldq t4,2152(sp) 994: ff ff 3f 20 lda t0,-1 998: 02 00 ff 20 lda t6,2 99c: f1 fe ff c3 br 564 <__gettextparse+0x364> 9a0: 00 00 2a a4 ldq t0,0(s1) 9a4: bb 00 20 e4 beq t0,c94 <__gettextparse+0xa94> 9a8: f8 ff 0a 21 lda t7,-8(s1) 9ac: 40 08 5e a4 ldq t1,2112(sp) 9b0: fe ff 29 21 lda s0,-2(s0) 9b4: 01 00 ff 20 lda t6,1 9b8: 08 00 22 b4 stq t0,8(t1) 9bc: f6 ff 3f 20 lda t0,-10 9c0: e8 fe ff c3 br 564 <__gettextparse+0x364> 9c4: 00 00 dd 24 ldah t5,0(gp) 9c8: 00 00 c6 20 lda t5,0(t5) 9cc: 46 04 46 40 s4addq t1,t5,t5 9d0: 00 00 c6 a0 ldl t5,0(t5) 9d4: 06 04 a6 43 addq gp,t5,t5 9d8: 00 00 e6 6b jmp (t5) 9dc: 00 00 fe 2f unop 9e0: 40 08 7e a4 ldq t2,2112(sp) 9e4: 00 00 e3 b6 stq t9,0(t2) 9e8: 2c fe ff c3 br 29c <__gettextparse+0x9c> 9ec: 00 00 fe 2f unop 9f0: 02 00 b6 20 lda t4,2(t8) 9f4: 01 00 56 2c ldq_u t1,1(t8) 9f8: 50 08 9e a4 ldq t3,2128(sp) 9fc: 42 0f 45 48 extqh t1,t4,t1 a00: 82 17 47 48 sra t1,0x38,t1 a04: a2 b5 47 40 cmpeq t1,0x3d,t1 a08: b3 00 40 f4 bne t1,cd8 <__gettextparse+0xad8> a0c: 22 16 9e 48 zapnot t3,0xf0,t1 a10: 40 08 7e a4 ldq t2,2112(sp) a14: 03 01 bf 20 lda t4,259 a18: 02 34 41 44 or t1,0x9,t1 a1c: 50 08 5e b4 stq t1,2128(sp) a20: 00 00 03 b5 stq t7,0(t2) a24: 07 00 1f 21 lda t7,7 a28: 22 fe ff c3 br 2b4 <__gettextparse+0xb4> a2c: 00 00 fe 2f unop a30: 50 08 9e a4 ldq t3,2128(sp) a34: 05 01 bf 20 lda t4,261 a38: 40 08 7e a4 ldq t2,2112(sp) a3c: 22 16 9e 48 zapnot t3,0xf0,t1 a40: 00 00 03 b5 stq t7,0(t2) a44: 09 00 1f 21 lda t7,9 a48: 02 74 40 44 or t1,0x3,t1 a4c: 50 08 5e b4 stq t1,2128(sp) a50: 18 fe ff c3 br 2b4 <__gettextparse+0xb4> a54: 00 00 fe 2f unop a58: 1f 04 ff 47 nop a5c: 00 00 fe 2f unop a60: 50 08 9e a4 ldq t3,2128(sp) a64: 04 01 bf 20 lda t4,260 a68: 40 08 7e a4 ldq t2,2112(sp) a6c: 22 16 9e 48 zapnot t3,0xf0,t1 a70: 00 00 03 b5 stq t7,0(t2) a74: 08 00 1f 21 lda t7,8 a78: 02 f4 40 44 or t1,0x7,t1 a7c: 50 08 5e b4 stq t1,2128(sp) a80: 0c fe ff c3 br 2b4 <__gettextparse+0xb4> a84: 00 00 fe 2f unop a88: 1f 04 ff 47 nop a8c: 00 00 fe 2f unop a90: 50 08 9e a4 ldq t3,2128(sp) a94: 04 01 bf 20 lda t4,260 a98: 40 08 7e a4 ldq t2,2112(sp) a9c: 22 16 9e 48 zapnot t3,0xf0,t1 aa0: 00 00 03 b5 stq t7,0(t2) aa4: 08 00 1f 21 lda t7,8 aa8: 02 d4 40 44 or t1,0x6,t1 aac: 50 08 5e b4 stq t1,2128(sp) ab0: 00 fe ff c3 br 2b4 <__gettextparse+0xb4> ab4: 00 00 fe 2f unop ab8: 1f 04 ff 47 nop abc: 00 00 fe 2f unop ac0: 02 00 f6 22 lda t9,2(t8) ac4: 01 00 d6 2c ldq_u t5,1(t8) ac8: 46 0f d7 48 extqh t5,t9,t5 acc: 86 17 c7 48 sra t5,0x38,t5 ad0: a2 05 c2 40 cmpeq t5,t1,t1 ad4: c2 ff 5f f4 bne t1,9e0 <__gettextparse+0x7e0> ad8: 00 01 bf 20 lda t4,256 adc: 40 08 7e a4 ldq t2,2112(sp) ae0: 00 00 03 b5 stq t7,0(t2) ae4: 01 00 1f 21 lda t7,1 ae8: f2 fd ff c3 br 2b4 <__gettextparse+0xb4> aec: 00 00 fe 2f unop af0: 50 08 9e a4 ldq t3,2128(sp) af4: 05 01 bf 20 lda t4,261 af8: 40 08 7e a4 ldq t2,2112(sp) afc: 22 16 9e 48 zapnot t3,0xf0,t1 b00: 00 00 03 b5 stq t7,0(t2) b04: 09 00 1f 21 lda t7,9 b08: 02 b4 40 44 or t1,0x5,t1 b0c: 50 08 5e b4 stq t1,2128(sp) b10: e8 fd ff c3 br 2b4 <__gettextparse+0xb4> b14: 00 00 fe 2f unop b18: 1f 04 ff 47 nop b1c: 00 00 fe 2f unop b20: 02 00 b6 20 lda t4,2(t8) b24: 01 00 56 2c ldq_u t1,1(t8) b28: 42 0f 45 48 extqh t1,t4,t1 b2c: 82 17 47 48 sra t1,0x38,t1 b30: a2 b5 47 40 cmpeq t1,0x3d,t1 b34: 70 00 40 f4 bne t1,cf8 <__gettextparse+0xaf8> b38: 21 00 bf 20 lda t4,33 b3c: 40 08 5e a4 ldq t1,2112(sp) b40: 00 00 02 b5 stq t7,0(t1) b44: 0a 00 1f 21 lda t7,10 b48: da fd ff c3 br 2b4 <__gettextparse+0xb4> b4c: 00 00 fe 2f unop b50: 08 04 ff 47 clr t7 b54: 40 08 5e a4 ldq t1,2112(sp) b58: 05 04 ff 47 clr t4 b5c: 00 00 c2 b6 stq t8,0(t1) b60: d5 fd ff c3 br 2b8 <__gettextparse+0xb8> b64: 00 00 fe 2f unop b68: 1f 04 ff 47 nop b6c: 00 00 fe 2f unop b70: 02 00 b6 20 lda t4,2(t8) b74: 01 00 56 2c ldq_u t1,1(t8) b78: 42 0f 45 48 extqh t1,t4,t1 b7c: 82 17 47 48 sra t1,0x38,t1 b80: a2 b5 47 40 cmpeq t1,0x3d,t1 b84: 00 ff 5f e4 beq t1,788 <__gettextparse+0x588> b88: 50 08 9e a4 ldq t3,2128(sp) b8c: 06 00 1f 21 lda t7,6 b90: 40 08 7e a4 ldq t2,2112(sp) b94: 22 16 9e 48 zapnot t3,0xf0,t1 b98: 00 00 a3 b4 stq t4,0(t2) b9c: 02 01 bf 20 lda t4,258 ba0: 02 94 41 44 or t1,0xc,t1 ba4: 50 08 5e b4 stq t1,2128(sp) ba8: c2 fd ff c3 br 2b4 <__gettextparse+0xb4> bac: 00 00 fe 2f unop bb0: 02 00 b6 20 lda t4,2(t8) bb4: 01 00 56 2c ldq_u t1,1(t8) bb8: 50 08 9e a4 ldq t3,2128(sp) bbc: 42 0f 45 48 extqh t1,t4,t1 bc0: 82 17 47 48 sra t1,0x38,t1 bc4: a2 b5 47 40 cmpeq t1,0x3d,t1 bc8: 3b 00 40 f4 bne t1,cb8 <__gettextparse+0xab8> bcc: 22 16 9e 48 zapnot t3,0xf0,t1 bd0: 40 08 7e a4 ldq t2,2112(sp) bd4: 03 01 bf 20 lda t4,259 bd8: 02 14 41 44 or t1,0x8,t1 bdc: 50 08 5e b4 stq t1,2128(sp) be0: 00 00 03 b5 stq t7,0(t2) be4: 07 00 1f 21 lda t7,7 be8: b2 fd ff c3 br 2b4 <__gettextparse+0xb4> bec: 00 00 fe 2f unop bf0: 02 00 d6 20 lda t5,2(t8) bf4: 01 00 56 2c ldq_u t1,1(t8) bf8: 25 11 a6 40 subl t4,0x30,t4 bfc: 42 0f 46 48 extqh t1,t5,t1 c00: 82 17 47 48 sra t1,0x38,t1 c04: 22 11 46 40 subl t1,0x30,t1 c08: 06 f0 5f 44 and t1,0xff,t5 c0c: a6 37 c1 40 cmpule t5,0x9,t5 c10: 0e 00 c0 e4 beq t5,c4c <__gettextparse+0xa4c> c14: 01 00 08 21 lda t7,1(t7) c18: 17 04 e8 47 mov t7,t9 c1c: 01 00 08 21 lda t7,1(t7) c20: 45 04 a5 40 s4addq t4,t4,t4 c24: 00 00 d7 2c ldq_u t5,0(t9) c28: 02 00 e2 43 sextl t1,t1 c2c: 05 04 a5 40 addq t4,t4,t4 c30: 46 0f c8 48 extqh t5,t7,t5 c34: 05 04 45 40 addq t1,t4,t4 c38: 82 17 c7 48 sra t5,0x38,t1 c3c: 22 11 46 40 subl t1,0x30,t1 c40: 06 f0 5f 44 and t1,0xff,t5 c44: a6 37 c1 40 cmpule t5,0x9,t5 c48: f3 ff df f4 bne t5,c18 <__gettextparse+0xa18> c4c: 40 08 7e a4 ldq t2,2112(sp) c50: 50 08 be b4 stq t4,2128(sp) c54: 0b 00 1f 21 lda t7,11 c58: 06 01 bf 20 lda t4,262 c5c: 00 00 e3 b6 stq t9,0(t2) c60: 94 fd ff c3 br 2b4 <__gettextparse+0xb4> c64: 00 00 fe 2f unop c68: 1f 04 ff 47 nop c6c: 00 00 fe 2f unop c70: 50 08 9e a4 ldq t3,2128(sp) c74: 05 01 bf 20 lda t4,261 c78: 40 08 7e a4 ldq t2,2112(sp) c7c: 22 16 9e 48 zapnot t3,0xf0,t1 c80: 00 00 03 b5 stq t7,0(t2) c84: 09 00 1f 21 lda t7,9 c88: 02 94 40 44 or t1,0x4,t1 c8c: 50 08 5e b4 stq t1,2128(sp) c90: 88 fd ff c3 br 2b4 <__gettextparse+0xb4> c94: 09 04 ed 47 mov s4,s0 c98: 01 00 5f 21 lda s1,1 c9c: 01 fe ff c3 br 4a4 <__gettextparse+0x2a4> ca0: 09 04 ed 47 mov s4,s0 ca4: 02 00 5f 21 lda s1,2 ca8: fe fd ff c3 br 4a4 <__gettextparse+0x2a4> cac: 09 04 ef 47 mov fp,s0 cb0: 01 00 5f 21 lda s1,1 cb4: fe fd ff c3 br 4b0 <__gettextparse+0x2b0> cb8: 22 16 9e 48 zapnot t3,0xf0,t1 cbc: 40 08 7e a4 ldq t2,2112(sp) cc0: 07 00 1f 21 lda t7,7 cc4: 02 54 41 44 or t1,0xa,t1 cc8: 50 08 5e b4 stq t1,2128(sp) ccc: 00 00 a3 b4 stq t4,0(t2) cd0: 03 01 bf 20 lda t4,259 cd4: 77 fd ff c3 br 2b4 <__gettextparse+0xb4> cd8: 22 16 9e 48 zapnot t3,0xf0,t1 cdc: 40 08 7e a4 ldq t2,2112(sp) ce0: 07 00 1f 21 lda t7,7 ce4: 02 74 41 44 or t1,0xb,t1 ce8: 50 08 5e b4 stq t1,2128(sp) cec: 00 00 a3 b4 stq t4,0(t2) cf0: 03 01 bf 20 lda t4,259 cf4: 6f fd ff c3 br 2b4 <__gettextparse+0xb4> cf8: 50 08 9e a4 ldq t3,2128(sp) cfc: 06 00 1f 21 lda t7,6 d00: 40 08 7e a4 ldq t2,2112(sp) d04: 22 16 9e 48 zapnot t3,0xf0,t1 d08: 00 00 a3 b4 stq t4,0(t2) d0c: 02 01 bf 20 lda t4,258 d10: 02 b4 41 44 or t1,0xd,t1 d14: 50 08 5e b4 stq t1,2128(sp) d18: 66 fd ff c3 br 2b4 <__gettextparse+0xb4> d1c: 00 00 fe 2f unop [-- Attachment #4: plural-array-to-string.txt --] [-- Type: text/plain, Size: 3316 bytes --] /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:527:1: note: yytranslate = "\000\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\012\002\002\002\002\005\002\016\017\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\014\002\002\002\002\003\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\015\002\002\002\002\002\002\002\002\002\002\002\002\002\004\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\001\002\006\007\010\011" /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:600:1: note: yypact = "\37777777767\37777777767\37777777766\37777777766\37777777767\010$\37777777766\015\37777777766\37777777767\37777777767\37777777767\37777777767\37777777767\37777777767\37777777767\37777777766\032)-\022\37777777776\016\37777777766\37777777767" /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:610:1: note: yydefact = "\000\000\014\013\000\000\002\012\000\001\000\000\000\000\000\000\000\015\000\004\005\006\007\010\011\000" /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:618:1: note: yypgoto = "\37777777766\37777777766" /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:624:1: note: yydefgoto = "\37777777777\005" /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:632:1: note: yytable = "\007\001\002\010\003\004\017\020\011\022\023\024\025\026\027\030\012\013\014\015\016\017\020\020\032\016\017\020\021\012\013\014\015\016\017\020\000\000\031\012\013\014\015\016\017\020\014\015\016\017\020\015\016\017" /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:642:1: note: yycheck = "\001\012\013\004\015\016\010\011\000\012\013\014\015\016\017\020\003\004\005\006\007\010\011\011\031\007\010\011\017\003\004\005\006\007\010\011\37777777777\37777777777\014\003\004\005\006\007\010\011\005\006\007\010\011\006\007\010" /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:654:1: note: yystos = "\000\012\013\015\016\021\022\022\022\000\003\004\005\006\007\010\011\017\022\022\022\022\022\022\022\014" /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:662:1: note: yyr1 = "\000\020\021\022\022\022\022\022\022\022\022\022\022" /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c:669:1: note: yyr2 = "\000\002\001\005\003\003\003\003\003\003\002\001\001" ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-15 21:02 ` Martin Sebor @ 2018-08-15 21:14 ` Jeff Law 2018-08-15 21:34 ` Jeff Law 1 sibling, 0 replies; 43+ messages in thread From: Jeff Law @ 2018-08-15 21:14 UTC (permalink / raw) To: Martin Sebor, Joseph Myers Cc: James Greenhalgh, Jason Merrill, Gcc Patch List, nd On 08/15/2018 03:02 PM, Martin Sebor wrote: > On 08/15/2018 06:07 AM, Joseph Myers wrote: >> On Tue, 14 Aug 2018, Martin Sebor wrote: >> >>>> This is with Bison 3.0.4, should the version used to produce >>>> intl/plural.c >>>> prove relevant. >>> >>> Can you send me the translation unit and the options it was compiled >>> with that triggered the errors? >> >> I've attached plural.i. The error is a static link error linking sln, >> but >> maybe comparing results of compiling plural.i before and after the >> changes >> may be enlightening (unless it's actually a difference in code elsewhere >> in glibc causing a link error reported in plural.o). >> >> Compiled with: >> >> alpha-glibc-linux-gnu-gcc >> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c >> >> -c -std=gnu11 -fgnu89-inline -O2 -Wall -Werror -Wundef -Wwrite-strings >> -fmerge-all-constants -fno-stack-protector -frounding-math -g >> -Wstrict-prototypes -Wold-style-definition -fno-math-errno >> -mlong-double-128 -mieee -mfp-rounding-mode=d    >> -ftls-model=initial-exec >> -I../include >> -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl >> >> -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu >> >> -I../sysdeps/unix/sysv/linux/alpha/alpha >> -I../sysdeps/unix/sysv/linux/alpha/fpu -I../sysdeps/alpha/fpu >> -I../sysdeps/unix/sysv/linux/alpha -I../sysdeps/alpha/nptl >> -I../sysdeps/unix/sysv/linux/wordsize-64 >> -I../sysdeps/ieee754/ldbl-64-128 >> -I../sysdeps/ieee754/ldbl-opt -I../sysdeps/unix/sysv/linux/include >> -I../sysdeps/unix/sysv/linux -I../sysdeps/nptl -I../sysdeps/pthread >> -I../sysdeps/gnu -I../sysdeps/unix/inet -I../sysdeps/unix/sysv >> -I../sysdeps/unix/alpha -I../sysdeps/unix -I../sysdeps/posix >> -I../sysdeps/alpha -I../sysdeps/wordsize-64 >> -I../sysdeps/ieee754/ldbl-128 -I../sysdeps/ieee754/dbl-64/wordsize-64 >> -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 >> -I../sysdeps/ieee754 -I../sysdeps/generic -I.. -I../libio -I. >> -D_LIBC_REENTRANT -include >> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/libc-modules.h >> >> -DMODULE_NAME=libc -include ../include/libc-symbols.h >> -DTOP_NAMESPACE=glibc -D'LOCALEDIR="/usr/share/locale"' >> -D'LOCALE_ALIAS_PATH="/usr/share/locale"' -o >> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o >> >> -MD -MP -MF >> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o.dt >> >> -MT >> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o >> >> > > Thanks. I don't see anything obviously wrong but I don't know > much about Alpha assembly. Attached are the two .s files, with > (plural-new.s) and without (plural-old.s) the array-to-string > transformation. > > There are also only a handful of transformed arrays in the file > and they all look reasonable to me (see the attachment named > plural-array-to-string.txt). The only arrays in the .sdata > section are yydefgoto and yypgoto, both before and after. > They are each just 3 bytes in size. > > There is one unusual difference in the loads of one of them in > the assembly emitted by GCC for __gettextparse. > > Before: > >     ldah $22,yypgoto($29)               !gprelhigh >     ... >     lda $2,yypgoto($22)               !gprellow > > After: > >     ldah $2,yypgoto+2305843009213693936($29)   !gprelhigh >     ... >     lda $2,yypgoto+2305843009213693936($2)       !gprellow > > I don't know if it's significant -- the lda instruction uses > just the least significant 16 bits of the constant displacement, > shifted left by 16. I don't see any obviously bogus constants > in the disassembly produced by objdump. > > I'll need some help from someone who knows more about Alpha > to understand what's going on. I wonder if the change to how we set up the initializers is ultimately changing the section those go into and ultimately causing an overflow of the .sdata section. Jeff > > Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-15 21:02 ` Martin Sebor 2018-08-15 21:14 ` Jeff Law @ 2018-08-15 21:34 ` Jeff Law 2018-08-16 15:23 ` Martin Sebor 1 sibling, 1 reply; 43+ messages in thread From: Jeff Law @ 2018-08-15 21:34 UTC (permalink / raw) To: Martin Sebor, Joseph Myers Cc: James Greenhalgh, Jason Merrill, Gcc Patch List, nd On 08/15/2018 03:02 PM, Martin Sebor wrote: > On 08/15/2018 06:07 AM, Joseph Myers wrote: >> On Tue, 14 Aug 2018, Martin Sebor wrote: >> >>>> This is with Bison 3.0.4, should the version used to produce >>>> intl/plural.c >>>> prove relevant. >>> >>> Can you send me the translation unit and the options it was compiled >>> with that triggered the errors? >> >> I've attached plural.i. The error is a static link error linking sln, >> but >> maybe comparing results of compiling plural.i before and after the >> changes >> may be enlightening (unless it's actually a difference in code elsewhere >> in glibc causing a link error reported in plural.o). >> >> Compiled with: >> >> alpha-glibc-linux-gnu-gcc >> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c >> >> -c -std=gnu11 -fgnu89-inline -O2 -Wall -Werror -Wundef -Wwrite-strings >> -fmerge-all-constants -fno-stack-protector -frounding-math -g >> -Wstrict-prototypes -Wold-style-definition -fno-math-errno >> -mlong-double-128 -mieee -mfp-rounding-mode=d    >> -ftls-model=initial-exec >> -I../include >> -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl >> >> -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu >> >> -I../sysdeps/unix/sysv/linux/alpha/alpha >> -I../sysdeps/unix/sysv/linux/alpha/fpu -I../sysdeps/alpha/fpu >> -I../sysdeps/unix/sysv/linux/alpha -I../sysdeps/alpha/nptl >> -I../sysdeps/unix/sysv/linux/wordsize-64 >> -I../sysdeps/ieee754/ldbl-64-128 >> -I../sysdeps/ieee754/ldbl-opt -I../sysdeps/unix/sysv/linux/include >> -I../sysdeps/unix/sysv/linux -I../sysdeps/nptl -I../sysdeps/pthread >> -I../sysdeps/gnu -I../sysdeps/unix/inet -I../sysdeps/unix/sysv >> -I../sysdeps/unix/alpha -I../sysdeps/unix -I../sysdeps/posix >> -I../sysdeps/alpha -I../sysdeps/wordsize-64 >> -I../sysdeps/ieee754/ldbl-128 -I../sysdeps/ieee754/dbl-64/wordsize-64 >> -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 >> -I../sysdeps/ieee754 -I../sysdeps/generic -I.. -I../libio -I. >> -D_LIBC_REENTRANT -include >> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/libc-modules.h >> >> -DMODULE_NAME=libc -include ../include/libc-symbols.h >> -DTOP_NAMESPACE=glibc -D'LOCALEDIR="/usr/share/locale"' >> -D'LOCALE_ALIAS_PATH="/usr/share/locale"' -o >> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o >> >> -MD -MP -MF >> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o.dt >> >> -MT >> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o >> >> > > Thanks. I don't see anything obviously wrong but I don't know > much about Alpha assembly. Attached are the two .s files, with > (plural-new.s) and without (plural-old.s) the array-to-string > transformation. I'd focus on these insns which correspond to the error from the linker: They're in plural.o within the fucntion gettextparse ldah $2,yypgoto+2305843009213693936($29) !gprelhigh Something certainly doesn't look right... At the .o level this turns into: 218: 00 00 5d 24 ldah t1,0(gp) 218: GPRELHIGH .sdata+0x1ffffffffffffff3 300: 00 00 5d 24 ldah t1,0(gp) 300: GPRELHIGH .sdata+0x1ffffffffffffff3 It's not really a matter of what the instruction does, but a matter of the relocation. You'd have to look at the definition of GPRELHIGH which you can find in BFD. Jeff ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-15 21:34 ` Jeff Law @ 2018-08-16 15:23 ` Martin Sebor 2018-08-16 15:32 ` Jeff Law 0 siblings, 1 reply; 43+ messages in thread From: Martin Sebor @ 2018-08-16 15:23 UTC (permalink / raw) To: Jeff Law, Joseph Myers Cc: James Greenhalgh, Jason Merrill, Gcc Patch List, nd On 08/15/2018 03:34 PM, Jeff Law wrote: > On 08/15/2018 03:02 PM, Martin Sebor wrote: >> On 08/15/2018 06:07 AM, Joseph Myers wrote: >>> On Tue, 14 Aug 2018, Martin Sebor wrote: >>> >>>>> This is with Bison 3.0.4, should the version used to produce >>>>> intl/plural.c >>>>> prove relevant. >>>> >>>> Can you send me the translation unit and the options it was compiled >>>> with that triggered the errors? >>> >>> I've attached plural.i. The error is a static link error linking sln, >>> but >>> maybe comparing results of compiling plural.i before and after the >>> changes >>> may be enlightening (unless it's actually a difference in code elsewhere >>> in glibc causing a link error reported in plural.o). >>> >>> Compiled with: >>> >>> alpha-glibc-linux-gnu-gcc >>> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c >>> >>> -c -std=gnu11 -fgnu89-inline -O2 -Wall -Werror -Wundef -Wwrite-strings >>> -fmerge-all-constants -fno-stack-protector -frounding-math -g >>> -Wstrict-prototypes -Wold-style-definition -fno-math-errno >>> -mlong-double-128 -mieee -mfp-rounding-mode=d >>> -ftls-model=initial-exec >>> -I../include >>> -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl >>> >>> -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu >>> >>> -I../sysdeps/unix/sysv/linux/alpha/alpha >>> -I../sysdeps/unix/sysv/linux/alpha/fpu -I../sysdeps/alpha/fpu >>> -I../sysdeps/unix/sysv/linux/alpha -I../sysdeps/alpha/nptl >>> -I../sysdeps/unix/sysv/linux/wordsize-64 >>> -I../sysdeps/ieee754/ldbl-64-128 >>> -I../sysdeps/ieee754/ldbl-opt -I../sysdeps/unix/sysv/linux/include >>> -I../sysdeps/unix/sysv/linux -I../sysdeps/nptl -I../sysdeps/pthread >>> -I../sysdeps/gnu -I../sysdeps/unix/inet -I../sysdeps/unix/sysv >>> -I../sysdeps/unix/alpha -I../sysdeps/unix -I../sysdeps/posix >>> -I../sysdeps/alpha -I../sysdeps/wordsize-64 >>> -I../sysdeps/ieee754/ldbl-128 -I../sysdeps/ieee754/dbl-64/wordsize-64 >>> -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 >>> -I../sysdeps/ieee754 -I../sysdeps/generic -I.. -I../libio -I. >>> -D_LIBC_REENTRANT -include >>> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/libc-modules.h >>> >>> -DMODULE_NAME=libc -include ../include/libc-symbols.h >>> -DTOP_NAMESPACE=glibc -D'LOCALEDIR="/usr/share/locale"' >>> -D'LOCALE_ALIAS_PATH="/usr/share/locale"' -o >>> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o >>> >>> -MD -MP -MF >>> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o.dt >>> >>> -MT >>> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o >>> >>> >> >> Thanks. I don't see anything obviously wrong but I don't know >> much about Alpha assembly. Attached are the two .s files, with >> (plural-new.s) and without (plural-old.s) the array-to-string >> transformation. > I'd focus on these insns which correspond to the error from the linker: > > They're in plural.o within the fucntion gettextparse > > > ldah $2,yypgoto+2305843009213693936($29) !gprelhigh > > Something certainly doesn't look right... Thanks. I also get the same exact same assembly with both forms of initializers for the two constant arrays, i.e., static const yytype_int8 yypgoto[3] = "\366\366\377"; static const yytype_int8 yydefgoto[3] = "\377\005\006"; and static const yytype_int8 yypgoto[] = { -10, -10, -1 }; static const yytype_int8 yydefgoto[] = { -1, 5, 6 }; They end up in the .sdata section either way (the former both with and without the GCC change as might be expected): .section .sdata,"aws" .type yydefgoto, @object .size yydefgoto, 3 yydefgoto: .ascii "\377\005\006" .type yypgoto, @object .size yypgoto, 3 yypgoto: .ascii "\366\366\377" .section .rodata and also before the GCC change: .section .sdata,"aws" .type yydefgoto, @object .size yydefgoto, 3 yydefgoto: .byte -1 .byte 5 .byte 6 .type yypgoto, @object .size yypgoto, 3 yypgoto: .byte -10 .byte -10 .byte -1 > At the .o level this turns into: > 218: 00 00 5d 24 ldah t1,0(gp) > 218: GPRELHIGH .sdata+0x1ffffffffffffff3 > > > 300: 00 00 5d 24 ldah t1,0(gp) > 300: GPRELHIGH .sdata+0x1ffffffffffffff3 > > It's not really a matter of what the instruction does, but a matter of > the relocation. You'd have to look at the definition of GPRELHIGH which > you can find in BFD. The definitions match the assembly with both kinds of initializers, and with the string literal also with GCC before the change: 0000000000000218 GPRELHIGH .sdata+0x1ffffffffffffff3 0000000000000238 GPRELLOW .sdata+0x1ffffffffffffff3 0000000000000300 GPRELHIGH .sdata+0x1ffffffffffffff3 0000000000000308 GPRELLOW .sdata+0x1ffffffffffffff3 0000000000000458 GPRELHIGH .sdata+0x0000000000000003 0000000000000468 GPRELLOW .sdata+0x0000000000000003 vs the array form before the GCC change: 0000000000000468 GPRELHIGH .sdata+0x0000000000000003 0000000000000488 GPRELLOW .sdata+0x0000000000000003 000000000000057c GPRELHIGH .sdata 0000000000000580 GPRELLOW .sdata So it seems as though using the string literal as an initializer tickles a latent bug in GCC and the question is where. Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-16 15:23 ` Martin Sebor @ 2018-08-16 15:32 ` Jeff Law 0 siblings, 0 replies; 43+ messages in thread From: Jeff Law @ 2018-08-16 15:32 UTC (permalink / raw) To: Martin Sebor, Joseph Myers Cc: James Greenhalgh, Jason Merrill, Gcc Patch List, nd On 08/16/2018 09:23 AM, Martin Sebor wrote: > On 08/15/2018 03:34 PM, Jeff Law wrote: >> On 08/15/2018 03:02 PM, Martin Sebor wrote: >>> On 08/15/2018 06:07 AM, Joseph Myers wrote: >>>> On Tue, 14 Aug 2018, Martin Sebor wrote: >>>> >>>>>> This is with Bison 3.0.4, should the version used to produce >>>>>> intl/plural.c >>>>>> prove relevant. >>>>> >>>>> Can you send me the translation unit and the options it was compiled >>>>> with that triggered the errors? >>>> >>>> I've attached plural.i. The error is a static link error linking sln, >>>> but >>>> maybe comparing results of compiling plural.i before and after the >>>> changes >>>> may be enlightening (unless it's actually a difference in code >>>> elsewhere >>>> in glibc causing a link error reported in plural.o). >>>> >>>> Compiled with: >>>> >>>> alpha-glibc-linux-gnu-gcc >>>> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.c >>>> >>>> >>>> -c -std=gnu11 -fgnu89-inline -O2 -Wall -Werror -Wundef -Wwrite-strings >>>> -fmerge-all-constants -fno-stack-protector -frounding-math -g >>>> -Wstrict-prototypes -Wold-style-definition -fno-math-errno >>>> -mlong-double-128 -mieee -mfp-rounding-mode=d >>>> -ftls-model=initial-exec >>>> -I../include >>>> -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl >>>> >>>> >>>> -I/scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu >>>> >>>> >>>> -I../sysdeps/unix/sysv/linux/alpha/alpha >>>> -I../sysdeps/unix/sysv/linux/alpha/fpu -I../sysdeps/alpha/fpu >>>> -I../sysdeps/unix/sysv/linux/alpha -I../sysdeps/alpha/nptl >>>> -I../sysdeps/unix/sysv/linux/wordsize-64 >>>> -I../sysdeps/ieee754/ldbl-64-128 >>>> -I../sysdeps/ieee754/ldbl-opt -I../sysdeps/unix/sysv/linux/include >>>> -I../sysdeps/unix/sysv/linux -I../sysdeps/nptl -I../sysdeps/pthread >>>> -I../sysdeps/gnu -I../sysdeps/unix/inet -I../sysdeps/unix/sysv >>>> -I../sysdeps/unix/alpha -I../sysdeps/unix -I../sysdeps/posix >>>> -I../sysdeps/alpha -I../sysdeps/wordsize-64 >>>> -I../sysdeps/ieee754/ldbl-128 -I../sysdeps/ieee754/dbl-64/wordsize-64 >>>> -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 >>>> -I../sysdeps/ieee754 -I../sysdeps/generic -I.. -I../libio -I. >>>> -D_LIBC_REENTRANT -include >>>> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/libc-modules.h >>>> >>>> >>>> -DMODULE_NAME=libc -include ../include/libc-symbols.h >>>> -DTOP_NAMESPACE=glibc -D'LOCALEDIR="/usr/share/locale"' >>>> -D'LOCALE_ALIAS_PATH="/usr/share/locale"' -o >>>> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o >>>> >>>> >>>> -MD -MP -MF >>>> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o.dt >>>> >>>> >>>> -MT >>>> /scratch/jmyers/glibc/many9/build/compilers/alpha-linux-gnu/glibc/alpha-linux-gnu/intl/plural.o >>>> >>>> >>>> >>> >>> Thanks. I don't see anything obviously wrong but I don't know >>> much about Alpha assembly. Attached are the two .s files, with >>> (plural-new.s) and without (plural-old.s) the array-to-string >>> transformation. >> I'd focus on these insns which correspond to the error from the linker: >> >> They're in plural.o within the fucntion gettextparse >> >> >>        ldah $2,yypgoto+2305843009213693936($29)               >> !gprelhigh >> >> Something certainly doesn't look right... > > Thanks. I also get the same exact same assembly with both > forms of initializers for the two constant arrays, i.e., > >  static const yytype_int8 yypgoto[3] = "\366\366\377"; >  static const yytype_int8 yydefgoto[3] = "\377\005\006"; > > and > >  static const yytype_int8 yypgoto[] = { -10, -10, -1 }; >  static const yytype_int8 yydefgoto[] = { -1, 5, 6 }; > > They end up in the .sdata section either way (the former > both with and without the GCC change as might be expected): > >        .section       .sdata,"aws" >        .type  yydefgoto, @object >        .size  yydefgoto, 3 >  yydefgoto: >        .ascii "\377\005\006" >        .type  yypgoto, @object >        .size  yypgoto, 3 >  yypgoto: >        .ascii "\366\366\377" >        .section       .rodata > > and also before the GCC change: > >        .section       .sdata,"aws" >        .type  yydefgoto, @object >        .size  yydefgoto, 3 >  yydefgoto: >        .byte  -1 >        .byte  5 >        .byte  6 >        .type  yypgoto, @object >        .size  yypgoto, 3 >  yypgoto: >        .byte  -10 >        .byte  -10 >        .byte  -1 > >> At the .o level this turns into: >> 218:  00 00 5d 24    ldah   t1,0(gp) >>                        218: GPRELHIGH .sdata+0x1ffffffffffffff3 >> >> >> 300:  00 00 5d 24    ldah   t1,0(gp) >>                        300: GPRELHIGH .sdata+0x1ffffffffffffff3 >> >> It's not really a matter of what the instruction does, but a matter of >> the relocation. You'd have to look at the definition of GPRELHIGH which >> you can find in BFD. > > The definitions match the assembly with both kinds of > initializers, and with the string literal also with GCC before > the change: > >  0000000000000218 GPRELHIGH        .sdata+0x1ffffffffffffff3 >  0000000000000238 GPRELLOW         .sdata+0x1ffffffffffffff3 >  0000000000000300 GPRELHIGH        .sdata+0x1ffffffffffffff3 >  0000000000000308 GPRELLOW         .sdata+0x1ffffffffffffff3 >  0000000000000458 GPRELHIGH        .sdata+0x0000000000000003 >  0000000000000468 GPRELLOW         .sdata+0x0000000000000003 > > vs the array form before the GCC change: > >  0000000000000468 GPRELHIGH        .sdata+0x0000000000000003 >  0000000000000488 GPRELLOW         .sdata+0x0000000000000003 >  000000000000057c GPRELHIGH        .sdata >  0000000000000580 GPRELLOW         .sdata > > So it seems as though using the string literal as an initializer > tickles a latent bug in GCC and the question is where. I'd start working backwards from alpha_print_operand_address using a cross compiler. I'd also get a -dap dump and look at the actual address in the insn that's emitting the offending ldah instructions. Jeff ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-07-30 23:51 Martin Sebor 2018-07-31 13:39 ` Jason Merrill @ 2018-08-06 16:41 ` Martin Sebor 2018-08-06 17:04 ` Joseph Myers 1 sibling, 1 reply; 43+ messages in thread From: Martin Sebor @ 2018-08-06 16:41 UTC (permalink / raw) To: Gcc Patch List; +Cc: Jason Merrill, Joseph Myers Ping: https://gcc.gnu.org/ml/gcc-patches/2018-07/msg01884.html On 07/30/2018 05:51 PM, Martin Sebor wrote: > The middle-end contains code to determine the lengths of constant > character arrays initialized by string literals. The code is used > in a number of optimizations and warnings. > > However, the code is unable to deal with constant arrays initialized > using the braced initializer syntax, as in > > const char a[] = { '1', '2', '\0' }; > > The attached patch extends the C and C++ front-ends to convert such > initializers into a STRING_CST form. > > The goal of this work is to both enable existing optimizations for > such arrays, and to help detect bugs due to using non-nul terminated > arrays where nul-terminated strings are expected. The latter is > an extension of the GCC 8 _Wstringop-overflow and > -Wstringop-truncation warnings that help detect or prevent reading > past the end of dynamically created character arrays. Future work > includes detecting potential past-the-end reads from uninitialized > local character arrays. > > Tested on x86_64-linux. > > Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-06 16:41 ` Martin Sebor @ 2018-08-06 17:04 ` Joseph Myers 2018-08-07 2:02 ` Martin Sebor 0 siblings, 1 reply; 43+ messages in thread From: Joseph Myers @ 2018-08-06 17:04 UTC (permalink / raw) To: Martin Sebor; +Cc: Gcc Patch List, Jason Merrill On Mon, 6 Aug 2018, Martin Sebor wrote: > Ping: https://gcc.gnu.org/ml/gcc-patches/2018-07/msg01884.html I'd expect testcases with signed char and unsigned char as well, if those work for C, including tests for signed char where some of the initializers are negative. (Tests that actual array contents are still correct after this conversion, as well as that the optimizations occur, would also be a good idea.) The c-parser.c patch adds a comment that ends in the middle of a word. -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-06 17:04 ` Joseph Myers @ 2018-08-07 2:02 ` Martin Sebor 2018-08-07 11:31 ` Joseph Myers 0 siblings, 1 reply; 43+ messages in thread From: Martin Sebor @ 2018-08-07 2:02 UTC (permalink / raw) To: Joseph Myers; +Cc: Gcc Patch List, Jason Merrill [-- Attachment #1: Type: text/plain, Size: 992 bytes --] On 08/06/2018 11:04 AM, Joseph Myers wrote: > On Mon, 6 Aug 2018, Martin Sebor wrote: > >> Ping: https://gcc.gnu.org/ml/gcc-patches/2018-07/msg01884.html > > I'd expect testcases with signed char and unsigned char as well, if those > work for C, including tests for signed char where some of the initializers > are negative. (Tests that actual array contents are still correct after > this conversion, as well as that the optimizations occur, would also be a > good idea.) > > The c-parser.c patch adds a comment that ends in the middle of a word. Thanks. Adding more tests revealed a couple of oversights: 1) using tree_fits_uhwi_p excluded initializers with negative values, 2) skipping embedded nuls made it possible to create a string with fewer elements than the initializer array, which caused arrays with unspecified bound to be smaller than they would have been otherwise The attached update fixes both of these and makes the C/C++ front-end code simpler and more alike. Martin [-- Attachment #2: gcc-71625.diff --] [-- Type: text/x-patch, Size: 19309 bytes --] PR tree-optimization/71625 - missing strlen optimization on different array initialization style gcc/c/ChangeLog: PR tree-optimization/71625 * c-parser.c (c_parser_declaration_or_fndef): Call braced_list_to_string. gcc/c-family/ChangeLog: PR tree-optimization/71625 * c-common.c (braced_list_to_string): New function. * c-common.h (braced_list_to_string): Declare it. gcc/cp/ChangeLog: PR tree-optimization/71625 * parser.c (cp_parser_init_declarator): Call braced_list_to_string. gcc/testsuite/ChangeLog: PR tree-optimization/71625 * g++.dg/init/string2.C: New test. * g++.dg/init/string3.C: New test. * gcc.dg/strlenopt-55.c: New test. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c Index: gcc/c/c-parser.c =================================================================== --- gcc/c/c-parser.c (revision 263341) +++ gcc/c/c-parser.c (working copy) @@ -2126,6 +2126,24 @@ c_parser_declaration_or_fndef (c_parser *parser, b if (d != error_mark_node) { maybe_warn_string_init (init_loc, TREE_TYPE (d), init); + + /* Convert a string CONSTRUCTOR into a STRING_CST. */ + tree valtype = TREE_TYPE (init.value); + if (TREE_CODE (init.value) == CONSTRUCTOR + && TREE_CODE (valtype) == ARRAY_TYPE) + { + if (TYPE_STRING_FLAG (TREE_TYPE (valtype))) + { + if (tree str = braced_list_to_string (valtype, + init.value)) + { + /* Replace the initializer with the string + constant. */ + init.value = str; + } + } + } + finish_decl (d, init_loc, init.value, init.original_type, asm_name); } Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c (revision 263341) +++ gcc/c-family/c-common.c (working copy) @@ -8509,4 +8509,83 @@ maybe_add_include_fixit (rich_location *richloc, c free (text); } +/* Attempt to convert a braced array initializer list CTOR for array + TYPE into a STRING_CST for convenience and efficiency. When non-null, + use EVAL to attempt to evalue constants (used by C++). Return + the converted string on success or null on failure. */ + +tree +braced_list_to_string (tree type, tree ctor, tree (*eval)(tree)) +{ + /* If the array has an explicit bound, use it to constrain the size + of the string. If it doesn't, be sure to create a string that's + as long as implied by the index of the last zero specified via + a designator, as in: + const char a[] = { [7] = 0 }; */ + unsigned HOST_WIDE_INT maxelts = HOST_WIDE_INT_M1U; + if (tree nelts = TYPE_SIZE_UNIT (type)) + if (tree_fits_uhwi_p (nelts)) + { + maxelts = tree_to_uhwi (nelts); + maxelts /= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type))); + } + + unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (ctor); + + auto_vec<char> str; + str.reserve (nelts + 1); + + unsigned HOST_WIDE_INT i; + tree index, value; + + FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, index, value) + { + unsigned HOST_WIDE_INT idx = index ? tree_to_uhwi (index) : i; + + /* auto_vec is limited to UINT_MAX elements. */ + if (idx > UINT_MAX) + return NULL_TREE; + + /* Attempt to evaluate constants. */ + if (eval) + value = eval (value); + + /* Avoid non-constant initializers. */ + if (!tree_fits_shwi_p (value)) + return NULL_TREE; + + /* Skip over embedded nuls. */ + unsigned val = tree_to_shwi (value); + if (!val && i + 1 < nelts) + continue; + + /* Bail if the CTOR has a block of more than 256 embedded nuls + due to implicitly initialized elements. */ + unsigned nelts = (idx - str.length ()) + 1; + if (nelts > 256) + return NULL_TREE; + + if (nelts > 1) + { + str.reserve (idx); + str.quick_grow_cleared (idx); + } + + if (idx > maxelts) + return NULL_TREE; + + str.safe_insert (idx, val); + } + + if (!nelts || str.length () < i) + /* Append a nul for the empty initializer { } and for the last + explicit initializer in the loop above that is a nul. */ + str.safe_push (0); + + /* Build a string literal but return the embedded STRING_CST. */ + tree res = build_string_literal (str.length (), str.begin ()); + res = TREE_OPERAND (TREE_OPERAND (res, 0), 0); + return res; +} + #include "gt-c-family-c-common.h" Index: gcc/c-family/c-common.h =================================================================== --- gcc/c-family/c-common.h (revision 263341) +++ gcc/c-family/c-common.h (working copy) @@ -1331,6 +1331,7 @@ extern void maybe_add_include_fixit (rich_location extern void maybe_suggest_missing_token_insertion (rich_location *richloc, enum cpp_ttype token_type, location_t prev_token_loc); +extern tree braced_list_to_string (tree, tree, tree (*)(tree) = NULL); #if CHECKING_P namespace selftest { Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 263341) +++ gcc/cp/parser.c (working copy) @@ -19825,6 +19825,24 @@ cp_parser_init_declarator (cp_parser* parser, finish_lambda_scope (); if (initializer == error_mark_node) cp_parser_skip_to_end_of_statement (parser); + else if (decl) + { + tree valtype = TREE_TYPE (decl); + if (TREE_CODE (valtype) == ARRAY_TYPE + && TYPE_STRING_FLAG (TREE_TYPE (valtype)) + && TYPE_MAIN_VARIANT (TREE_TYPE (valtype)) == char_type_node) + { + /* Convert a string CONSTRUCTOR into a STRING_CST. */ + if (TREE_CODE (initializer) == CONSTRUCTOR + && TREE_TYPE (initializer) == init_list_type_node) + { + if (tree str + = braced_list_to_string (valtype, initializer, + scalar_constant_value)) + initializer = str; + } + } + } } } Index: gcc/testsuite/g++.dg/init/string2.C =================================================================== --- gcc/testsuite/g++.dg/init/string2.C (nonexistent) +++ gcc/testsuite/g++.dg/init/string2.C (working copy) @@ -0,0 +1,48 @@ +// PR tree-optimization/71625 - missing strlen optimization on different +// array initialization style +// +// Verify that strlen() calls with constant character array arguments +// initialized with string constants are folded. (This is a small +// subset of pr63989). +// { dg-do compile } +// { dg-options "-O0 -fdump-tree-gimple" } + +const char a0[] = { 'a', 'b', 'c', '\0' }; + +int len0 () +{ + return __builtin_strlen (a0); +} + +const char c = 0; +const char a1[] = { 'a', 'b', 'c', c }; + +int len1 () +{ + return __builtin_strlen (a1); +} + +#if 0 + +// The following aren't handled. + +const char &cref = c; +const char a2[] = { 'a', 'b', 'c', cref }; + +int len2 () +{ + return __builtin_strlen (a2); +} + + +const char* const cptr = &cref; +const char a3[] = { 'a', 'b', 'c', *cptr }; + +int len3 () +{ + return __builtin_strlen (a3); +} + +#endif + +// { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } Index: gcc/testsuite/g++.dg/init/string3.C =================================================================== --- gcc/testsuite/g++.dg/init/string3.C (nonexistent) +++ gcc/testsuite/g++.dg/init/string3.C (working copy) @@ -0,0 +1,36 @@ +// PR tree-optimization/71625 - missing strlen optimization on different +// array initialization style +// +// Verify that strlen() call with a constant character array argument +// initialized with non-constant elements isn't folded. (This is a small +// subset of pr63989). +// +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-optimized" } + + +extern const char c; +const char a0[] = { 'a', 'b', 'c', c }; + +int len0 () +{ + return __builtin_strlen (a0); +} + +const char &ref = c; +const char a1[] = { 'a', 'b', 'c', ref }; + +int len1 () +{ + return __builtin_strlen (a1); +} + +const char* const ptr = &c; +const char a2[] = { 'a', 'b', 'c', *ptr }; + +int len2 () +{ + return __builtin_strlen (a2); +} + +// { dg-final { scan-tree-dump-times "strlen" 3 "optimized" } } Index: gcc/testsuite/gcc.dg/strlenopt-55.c =================================================================== --- gcc/testsuite/gcc.dg/strlenopt-55.c (nonexistent) +++ gcc/testsuite/gcc.dg/strlenopt-55.c (working copy) @@ -0,0 +1,227 @@ +/* PR tree-optimization/71625 - missing strlen optimization on different + array initialization style + + Verify that strlen() of braced initialized array is folded + { dg-do compile } + { dg-options "-O1 -Wall -fdump-tree-gimple -fdump-tree-optimized" } */ + +#include "strlenopt.h" + +#define S \ + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" \ + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \ + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \ + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" \ + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \ + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" \ + "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \ + "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \ + "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \ + "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \ + "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" \ + "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \ + "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" \ + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" + +/* Arrays of char, signed char, and unsigned char to verify that + the length and contents of all are the same as that of the string + literal above. */ + +const char c256[] = { + S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[8], S[9], S[10], + S[11], S[12], S[13], S[14], S[15], S[16], S[17], S[18], S[19], S[20], + S[21], S[22], S[23], S[24], S[25], S[26], S[27], S[28], S[29], S[30], + S[31], S[32], S[33], S[34], S[35], S[36], S[37], S[38], S[39], S[40], + S[41], S[42], S[43], S[44], S[45], S[46], S[47], S[48], S[49], S[50], + S[51], S[52], S[53], S[54], S[55], S[56], S[57], S[58], S[59], S[60], + S[61], S[62], S[63], S[64], S[65], S[66], S[67], S[68], S[69], S[70], + S[71], S[72], S[73], S[74], S[75], S[76], S[77], S[78], S[79], S[80], + S[81], S[82], S[83], S[84], S[85], S[86], S[87], S[88], S[89], S[90], + S[91], S[92], S[93], S[94], S[95], S[96], S[97], S[98], S[99], S[100], + S[101], S[102], S[103], S[104], S[105], S[106], S[107], S[108], S[109], + S[110], S[111], S[112], S[113], S[114], S[115], S[116], S[117], S[118], + S[119], S[120], S[121], S[122], S[123], S[124], S[125], S[126], S[127], + S[128], S[129], S[130], S[131], S[132], S[133], S[134], S[135], S[136], + S[137], S[138], S[139], S[140], S[141], S[142], S[143], S[144], S[145], + S[146], S[147], S[148], S[149], S[150], S[151], S[152], S[153], S[154], + S[155], S[156], S[157], S[158], S[159], S[160], S[161], S[162], S[163], + S[164], S[165], S[166], S[167], S[168], S[169], S[170], S[171], S[172], + S[173], S[174], S[175], S[176], S[177], S[178], S[179], S[180], S[181], + S[182], S[183], S[184], S[185], S[186], S[187], S[188], S[189], S[190], + S[191], S[192], S[193], S[194], S[195], S[196], S[197], S[198], S[199], + S[200], S[201], S[202], S[203], S[204], S[205], S[206], S[207], S[208], + S[209], S[210], S[211], S[212], S[213], S[214], S[215], S[216], S[217], + S[218], S[219], S[220], S[221], S[222], S[223], S[224], S[225], S[226], + S[227], S[228], S[229], S[230], S[231], S[232], S[233], S[234], S[235], + S[236], S[237], S[238], S[239], S[240], S[241], S[242], S[243], S[244], + S[245], S[246], S[247], S[248], S[249], S[250], S[251], S[252], S[253], + S[254], S[255] /* = NUL */ +}; + +const signed char sc256[] = { + S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[8], S[9], S[10], + S[11], S[12], S[13], S[14], S[15], S[16], S[17], S[18], S[19], S[20], + S[21], S[22], S[23], S[24], S[25], S[26], S[27], S[28], S[29], S[30], + S[31], S[32], S[33], S[34], S[35], S[36], S[37], S[38], S[39], S[40], + S[41], S[42], S[43], S[44], S[45], S[46], S[47], S[48], S[49], S[50], + S[51], S[52], S[53], S[54], S[55], S[56], S[57], S[58], S[59], S[60], + S[61], S[62], S[63], S[64], S[65], S[66], S[67], S[68], S[69], S[70], + S[71], S[72], S[73], S[74], S[75], S[76], S[77], S[78], S[79], S[80], + S[81], S[82], S[83], S[84], S[85], S[86], S[87], S[88], S[89], S[90], + S[91], S[92], S[93], S[94], S[95], S[96], S[97], S[98], S[99], S[100], + S[101], S[102], S[103], S[104], S[105], S[106], S[107], S[108], S[109], + S[110], S[111], S[112], S[113], S[114], S[115], S[116], S[117], S[118], + S[119], S[120], S[121], S[122], S[123], S[124], S[125], S[126], S[127], + S[128], S[129], S[130], S[131], S[132], S[133], S[134], S[135], S[136], + S[137], S[138], S[139], S[140], S[141], S[142], S[143], S[144], S[145], + S[146], S[147], S[148], S[149], S[150], S[151], S[152], S[153], S[154], + S[155], S[156], S[157], S[158], S[159], S[160], S[161], S[162], S[163], + S[164], S[165], S[166], S[167], S[168], S[169], S[170], S[171], S[172], + S[173], S[174], S[175], S[176], S[177], S[178], S[179], S[180], S[181], + S[182], S[183], S[184], S[185], S[186], S[187], S[188], S[189], S[190], + S[191], S[192], S[193], S[194], S[195], S[196], S[197], S[198], S[199], + S[200], S[201], S[202], S[203], S[204], S[205], S[206], S[207], S[208], + S[209], S[210], S[211], S[212], S[213], S[214], S[215], S[216], S[217], + S[218], S[219], S[220], S[221], S[222], S[223], S[224], S[225], S[226], + S[227], S[228], S[229], S[230], S[231], S[232], S[233], S[234], S[235], + S[236], S[237], S[238], S[239], S[240], S[241], S[242], S[243], S[244], + S[245], S[246], S[247], S[248], S[249], S[250], S[251], S[252], S[253], + S[254], S[255] /* = NUL */ +}; + +const unsigned char uc256[] = { + S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[8], S[9], S[10], + S[11], S[12], S[13], S[14], S[15], S[16], S[17], S[18], S[19], S[20], + S[21], S[22], S[23], S[24], S[25], S[26], S[27], S[28], S[29], S[30], + S[31], S[32], S[33], S[34], S[35], S[36], S[37], S[38], S[39], S[40], + S[41], S[42], S[43], S[44], S[45], S[46], S[47], S[48], S[49], S[50], + S[51], S[52], S[53], S[54], S[55], S[56], S[57], S[58], S[59], S[60], + S[61], S[62], S[63], S[64], S[65], S[66], S[67], S[68], S[69], S[70], + S[71], S[72], S[73], S[74], S[75], S[76], S[77], S[78], S[79], S[80], + S[81], S[82], S[83], S[84], S[85], S[86], S[87], S[88], S[89], S[90], + S[91], S[92], S[93], S[94], S[95], S[96], S[97], S[98], S[99], S[100], + S[101], S[102], S[103], S[104], S[105], S[106], S[107], S[108], S[109], + S[110], S[111], S[112], S[113], S[114], S[115], S[116], S[117], S[118], + S[119], S[120], S[121], S[122], S[123], S[124], S[125], S[126], S[127], + S[128], S[129], S[130], S[131], S[132], S[133], S[134], S[135], S[136], + S[137], S[138], S[139], S[140], S[141], S[142], S[143], S[144], S[145], + S[146], S[147], S[148], S[149], S[150], S[151], S[152], S[153], S[154], + S[155], S[156], S[157], S[158], S[159], S[160], S[161], S[162], S[163], + S[164], S[165], S[166], S[167], S[168], S[169], S[170], S[171], S[172], + S[173], S[174], S[175], S[176], S[177], S[178], S[179], S[180], S[181], + S[182], S[183], S[184], S[185], S[186], S[187], S[188], S[189], S[190], + S[191], S[192], S[193], S[194], S[195], S[196], S[197], S[198], S[199], + S[200], S[201], S[202], S[203], S[204], S[205], S[206], S[207], S[208], + S[209], S[210], S[211], S[212], S[213], S[214], S[215], S[216], S[217], + S[218], S[219], S[220], S[221], S[222], S[223], S[224], S[225], S[226], + S[227], S[228], S[229], S[230], S[231], S[232], S[233], S[234], S[235], + S[236], S[237], S[238], S[239], S[240], S[241], S[242], S[243], S[244], + S[245], S[246], S[247], S[248], S[249], S[250], S[251], S[252], S[253], + S[254], S[255] /* = NUL */ +}; + +const __CHAR16_TYPE__ c16_4[] = { + 1, 0x7fff, 0x8000, 0xffff, + 0x10000 /* { dg-warning "\\\[-Woverflow]" } */ +}; + +const char a2_implicit[2] = { }; +const char a3_implicit[3] = { }; + +const char a3_nul[3] = { 0 }; +const char a5_nul1[3] = { [1] = 0 }; +const char a7_nul2[3] = { [2] = 0 }; + +const char ax_2_nul[] = { '1', '2', '\0' }; +const char ax_3_nul[] = { '1', '2', '3', '\0' }; + +const char ax_3_des_nul[] = { [3] = 0, [2] = '3', [1] = '2', [0] = '1' }; + +const char ax_3[] = { '1', '2', '3' }; +const char a3_3[3] = { '1', '2', '3' }; + +const char a100_3[] = { '1', '2', '3', [100] = '\0' }; + +#define CONCAT(x, y) x ## y +#define CAT(x, y) CONCAT (x, y) +#define FAILNAME(name) CAT (call_ ## name ##_on_line_, __LINE__) + +#define FAIL(name) do { \ + extern void FAILNAME (name) (void); \ + FAILNAME (name)(); \ + } while (0) + +/* Macro to emit a call to funcation named + call_in_true_branch_not_eliminated_on_line_NNN() + for each call that's expected to be eliminated. The dg-final + scan-tree-dump-time directive at the bottom of the test verifies + that no such call appears in output. */ +#define ELIM(expr) \ + if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0 + +#define T(s, n) ELIM (strlen (s) == n) + +void test_nulstring (void) +{ + T (a2_implicit, 0); + T (a3_implicit, 0); + + T (a3_nul, 0); + T (a5_nul1, 0); + T (a7_nul2, 0); + + T (ax_2_nul, 2); + T (ax_3_nul, 3); + T (ax_3_des_nul, 3); + + T (a100_3, 3); + + /* Verify that all three character arrays have the same length + as the string literal they are initialized with. */ + T (S, 255); + T (c256, 255); + T ((const char*)sc256, 255); + T ((const char*)uc256, 255); + + /* Verify that all three character arrays have the same contents + as the string literal they are initialized with. */ + ELIM (0 == memcmp (c256, S, sizeof c256)); + ELIM (0 == memcmp (c256, (const char*)sc256, sizeof c256)); + ELIM (0 == memcmp (c256, (const char*)uc256, sizeof c256)); + + ELIM (0 == strcmp (c256, (const char*)sc256)); + ELIM (0 == strcmp (c256, (const char*)uc256)); + + /* Verify that the char16_t array has the expected contents. */ + ELIM (c16_4[0] == 1 && c16_4[1] == 0x7fff + && c16_4[2] == 0x8000 && c16_4[3] == 0xffff + && c16_4[4] == 0); +} + +/* Verify that excessively large initializers don't run out of + memory. Also verify that the they have the expected size and + contents. */ + +#define MAX (__PTRDIFF_MAX__ - 1) + +const char large_string[] = { 'a', [1234] = 'b', [MAX] = '\0' }; + +const void test_large_string_size (void) +{ + ELIM (sizeof large_string == MAX + 1); + + /* The following expressions are not folded without optimization. */ + ELIM ('a' == large_string[0]); + ELIM ('\0' == large_string[1233]); + ELIM ('b' == large_string[1234]); + ELIM ('\0' == large_string[1235]); + ELIM ('\0' == large_string[MAX - 1]); +} + + +/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } + { dg-final { scan-tree-dump-times "memcmp" 0 "gimple" } } + { dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } } + { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */ ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-07 2:02 ` Martin Sebor @ 2018-08-07 11:31 ` Joseph Myers 2018-08-07 23:05 ` Martin Sebor 0 siblings, 1 reply; 43+ messages in thread From: Joseph Myers @ 2018-08-07 11:31 UTC (permalink / raw) To: Martin Sebor; +Cc: Gcc Patch List, Jason Merrill On Tue, 7 Aug 2018, Martin Sebor wrote: > 2) skipping embedded nuls made it possible to create a string > with fewer elements than the initializer array, which caused > arrays with unspecified bound to be smaller than they would > have been otherwise I think there should be explicit tests of sizeof for arrays with unspecified bound - to make sure both that it isn't any smaller than it should be, but also that any NULs implicitly added for a STRING_CST don't make the arrays any larger than their size should be for the originally given initializer that doesn't have a 0 as the last element. -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH] convert braced initializers to strings (PR 71625) 2018-08-07 11:31 ` Joseph Myers @ 2018-08-07 23:05 ` Martin Sebor 0 siblings, 0 replies; 43+ messages in thread From: Martin Sebor @ 2018-08-07 23:05 UTC (permalink / raw) To: Joseph Myers; +Cc: Gcc Patch List, Jason Merrill On 08/07/2018 05:31 AM, Joseph Myers wrote: > On Tue, 7 Aug 2018, Martin Sebor wrote: > >> 2) skipping embedded nuls made it possible to create a string >> with fewer elements than the initializer array, which caused >> arrays with unspecified bound to be smaller than they would >> have been otherwise > > I think there should be explicit tests of sizeof for arrays with > unspecified bound - to make sure both that it isn't any smaller than it > should be, but also that any NULs implicitly added for a STRING_CST don't > make the arrays any larger than their size should be for the originally > given initializer that doesn't have a 0 as the last element. I added some more tests to the latest revision of the patch. Please see it in my other response. Thanks Martin ^ permalink raw reply [flat|nested] 43+ messages in thread
end of thread, other threads:[~2018-08-18 17:09 UTC | newest] Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-08-08 17:33 [PATCH] convert braced initializers to strings (PR 71625) Bernd Edlinger 2018-08-08 18:34 ` Bernd Edlinger 2018-08-08 19:50 ` Martin Sebor 2018-08-08 20:35 ` Bernd Edlinger 2018-08-08 20:48 ` Joseph Myers 2018-08-09 0:23 ` Martin Sebor 2018-08-09 10:47 ` Joseph Myers -- strict thread matches above, loose matches on Subject: below -- 2018-08-16 6:37 Bernd Edlinger 2018-08-17 22:26 ` Bernd Edlinger 2018-08-18 4:13 ` Jeff Law 2018-08-18 10:40 ` Richard Sandiford 2018-08-18 14:25 ` Bernd Edlinger 2018-08-18 16:46 ` Richard Sandiford 2018-08-18 17:09 ` Bernd Edlinger 2018-07-30 23:51 Martin Sebor 2018-07-31 13:39 ` Jason Merrill 2018-07-31 14:49 ` Martin Sebor 2018-08-07 8:58 ` Jason Merrill 2018-08-07 23:04 ` Martin Sebor 2018-08-08 11:09 ` Jason Merrill 2018-08-09 0:17 ` Martin Sebor 2018-08-09 22:07 ` Joseph Myers 2018-08-13 10:36 ` Jason Merrill 2018-08-14 13:27 ` James Greenhalgh 2018-08-14 15:08 ` Martin Sebor 2018-08-14 15:24 ` Martin Sebor 2018-08-15 2:34 ` Martin Sebor 2018-08-15 10:29 ` James Greenhalgh 2018-08-15 15:04 ` Richard Biener 2018-08-15 15:51 ` Martin Sebor 2018-08-14 21:14 ` Joseph Myers 2018-08-14 22:18 ` Martin Sebor 2018-08-15 12:07 ` Joseph Myers 2018-08-15 21:02 ` Martin Sebor 2018-08-15 21:14 ` Jeff Law 2018-08-15 21:34 ` Jeff Law 2018-08-16 15:23 ` Martin Sebor 2018-08-16 15:32 ` Jeff Law 2018-08-06 16:41 ` Martin Sebor 2018-08-06 17:04 ` Joseph Myers 2018-08-07 2:02 ` Martin Sebor 2018-08-07 11:31 ` Joseph Myers 2018-08-07 23:05 ` Martin Sebor
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).