* Re: [PATCH][gcc] libgccjit: handle long literals in playback::context::new_string_literal
[not found] <1579772431.117590.ezmlm@gcc.gnu.org>
@ 2020-01-01 0:00 ` Andrea Corallo
0 siblings, 0 replies; 7+ messages in thread
From: Andrea Corallo @ 2020-01-01 0:00 UTC (permalink / raw)
To: David Malcolm, jit, gcc-patches, nd
> Andrea Corallo writes:
>
>> Andrea Corallo writes:
>>
>>> Andrea Corallo writes:
>>>
>>>> Hi all,
>>>> yesterday I've found an interesting bug in libgccjit.
>>>> Seems we have an hard limitation of 200 characters for literal strings.
>>>> Attempting to create longer strings lead to ICE during pass_expand
>>>> while performing a sanity check in get_constant_size.
>>>>
>>>> Tracking down the issue seems the code we have was inspired from
>>>> c-family/c-common.c:c_common_nodes_and_builtins were array_domain_type
>>>> is actually defined with a size of 200.
>>>> The comment that follows that point sounded premonitory :) :)
>>>>
>>>> /* Make a type for arrays of characters.
>>>> With luck nothing will ever really depend on the length of this
>>>> array type. */
>>>>
>>>> At least in the current implementation the type is set by
>>>> fix_string_type were the actual string length is taken in account.
>>>>
>>>> I attach a patch updating the logic accordingly and a new testcase
>>>> for that.
>>>>
>>>> make check-jit is passing clean.
>>>>
>>>> Best Regards
>>>> Andrea
>>>>
>>>> gcc/jit/ChangeLog
>>>> 2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
>>>>
>>>> * jit-playback.h
>>>> (gcc::jit::recording::context m_recording_ctxt): Remove
>>>> m_char_array_type_node field.
>>>> * jit-playback.c
>>>> (playback::context::context) Remove m_char_array_type_node from member
>>>> initializer list.
>>>> (playback::context::new_string_literal) Fix logic to handle string
>>>> length > 200.
>>>>
>>>> gcc/testsuite/ChangeLog
>>>> 2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
>>>>
>>>> * jit.dg/all-non-failing-tests.h: Add test-long-string-literal.c.
>>>> * jit.dg/test-long-string-literal.c: New testcase.
>>>> diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
>>>> index 9eeb2a7..a26b8d3 100644
>>>> --- a/gcc/jit/jit-playback.c
>>>> +++ b/gcc/jit/jit-playback.c
>>>> @@ -88,7 +88,6 @@ playback::context::context (recording::context *ctxt)
>>>> : log_user (ctxt->get_logger ()),
>>>> m_recording_ctxt (ctxt),
>>>> m_tempdir (NULL),
>>>> - m_char_array_type_node (NULL),
>>>> m_const_char_ptr (NULL)
>>>> {
>>>> JIT_LOG_SCOPE (get_logger ());
>>>> @@ -670,9 +669,12 @@ playback::rvalue *
>>>> playback::context::
>>>> new_string_literal (const char *value)
>>>> {
>>>> - tree t_str = build_string (strlen (value), value);
>>>> - gcc_assert (m_char_array_type_node);
>>>> - TREE_TYPE (t_str) = m_char_array_type_node;
>>>> + /* Compare with c-family/c-common.c: fix_string_type. */
>>>> + size_t len = strlen (value);
>>>> + tree i_type = build_index_type (size_int (len));
>>>> + tree a_type = build_array_type (char_type_node, i_type);
>>>> + tree t_str = build_string (len, value);
>>>> + TREE_TYPE (t_str) = a_type;
>>>>
>>>> /* Convert to (const char*), loosely based on
>>>> c/c-typeck.c: array_to_pointer_conversion,
>>>> @@ -2703,10 +2705,6 @@ playback::context::
>>>> replay ()
>>>> {
>>>> JIT_LOG_SCOPE (get_logger ());
>>>> - /* Adapted from c-common.c:c_common_nodes_and_builtins. */
>>>> - tree array_domain_type = build_index_type (size_int (200));
>>>> - m_char_array_type_node
>>>> - = build_array_type (char_type_node, array_domain_type);
>>>>
>>>> m_const_char_ptr
>>>> = build_pointer_type (build_qualified_type (char_type_node,
>>>> diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
>>>> index d4b148e..801f610 100644
>>>> --- a/gcc/jit/jit-playback.h
>>>> +++ b/gcc/jit/jit-playback.h
>>>> @@ -322,7 +322,6 @@ private:
>>>>
>>>> auto_vec<function *> m_functions;
>>>> auto_vec<tree> m_globals;
>>>> - tree m_char_array_type_node;
>>>> tree m_const_char_ptr;
>>>>
>>>> /* Source location handling. */
>>>> diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
>>>> index 0272e6f8..1b3d561 100644
>>>> --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
>>>> +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
>>>> @@ -220,6 +220,13 @@
>>>> #undef create_code
>>>> #undef verify_code
>>>>
>>>> +/* test-long-string-literal.c */
>>>> +#define create_code create_code_long_string_literal
>>>> +#define verify_code verify_code_long_string_literal
>>>> +#include "test-long-string-literal.c"
>>>> +#undef create_code
>>>> +#undef verify_code
>>>> +
>>>> /* test-sum-of-squares.c */
>>>> #define create_code create_code_sum_of_squares
>>>> #define verify_code verify_code_sum_of_squares
>>>> diff --git a/gcc/testsuite/jit.dg/test-long-string-literal.c b/gcc/testsuite/jit.dg/test-long-string-literal.c
>>>> new file mode 100644
>>>> index 0000000..882567c
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/jit.dg/test-long-string-literal.c
>>>> @@ -0,0 +1,48 @@
>>>> +#include <stdlib.h>
>>>> +#include <stdio.h>
>>>> +#include <string.h>
>>>> +
>>>> +#include "libgccjit.h"
>>>> +
>>>> +#include "harness.h"
>>>> +
>>>> +const char very_long_string[] =
>>>> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
>>>> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
>>>> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
>>>> + "abcabcabcabcabcabcabcabcabcabca";
>>>> +
>>>> +void
>>>> +create_code (gcc_jit_context *ctxt, void *user_data)
>>>> +{
>>>> + /* Build the test_fn. */
>>>> + gcc_jit_function *f =
>>>> + gcc_jit_context_new_function (
>>>> + ctxt, NULL,
>>>> + GCC_JIT_FUNCTION_EXPORTED,
>>>> + gcc_jit_context_get_type(ctxt,
>>>> + GCC_JIT_TYPE_CONST_CHAR_PTR),
>>>> + "test_long_string_literal",
>>>> + 0, NULL, 0);
>>>> + gcc_jit_block *blk =
>>>> + gcc_jit_function_new_block (f, "init_block");
>>>> + gcc_jit_rvalue *res =
>>>> + gcc_jit_context_new_string_literal (ctxt, very_long_string);
>>>> +
>>>> + gcc_jit_block_end_with_return (blk, NULL, res);
>>>> +}
>>>> +
>>>> +void
>>>> +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
>>>> +{
>>>> + typedef const char *(*fn_type) (void);
>>>> + CHECK_NON_NULL (result);
>>>> + fn_type test_long_string_literal =
>>>> + (fn_type)gcc_jit_result_get_code (result, "test_long_string_literal");
>>>> + CHECK_NON_NULL (test_long_string_literal);
>>>> +
>>>> + /* Call the JIT-generated function. */
>>>> + const char *str = test_long_string_literal ();
>>>> + CHECK_NON_NULL (str);
>>>> + CHECK_VALUE (strcmp (str, very_long_string), 0);
>>>> +}
>>>
>>> Kindly pinging
>>>
>>> Bests
>>> Andrea
>>
>> Hi,
>> I'd like to ping this patch.
>>
>> Bests
>> Andrea
>
> Pinging again.
>
> Bests
> Andrea
> ----------
Ping
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH][gcc] libgccjit: handle long literals in playback::context::new_string_literal
2020-01-01 0:00 ` David Malcolm
@ 2020-03-07 21:43 ` Andrea Corallo
0 siblings, 0 replies; 7+ messages in thread
From: Andrea Corallo @ 2020-03-07 21:43 UTC (permalink / raw)
To: David Malcolm; +Cc: jit, gcc-patches, nd
David Malcolm <dmalcolm@redhat.com> writes:
> On Mon, 2019-09-02 at 09:16 +0000, Andrea Corallo wrote:
>> Hi all,
>> yesterday I've found an interesting bug in libgccjit.
>> Seems we have an hard limitation of 200 characters for literal
>> strings.
>> Attempting to create longer strings lead to ICE during pass_expand
>> while performing a sanity check in get_constant_size.
>>
>> Tracking down the issue seems the code we have was inspired from
>> c-family/c-common.c:c_common_nodes_and_builtins were
>> array_domain_type
>> is actually defined with a size of 200.
>> The comment that follows that point sounded premonitory :) :)
>>
>> /* Make a type for arrays of characters.
>> With luck nothing will ever really depend on the length of this
>> array type. */
>>
>> At least in the current implementation the type is set by
>> fix_string_type were the actual string length is taken in account.
>>
>> I attach a patch updating the logic accordingly and a new testcase
>> for that.
>>
>> make check-jit is passing clean.
>>
>> Best Regards
>> Andrea
>
> Sorry about the long delay in reviewing this patch.
>
>> gcc/jit/ChangeLog
>> 2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
>>
>> * jit-playback.h
>> (gcc::jit::recording::context m_recording_ctxt): Remove
> ^^^^^^^^^
> "playback" here
>
>> m_char_array_type_node field.
>
> [...]
>
>> @@ -670,9 +669,12 @@ playback::rvalue *
>> playback::context::
>> new_string_literal (const char *value)
>> {
>> - tree t_str = build_string (strlen (value), value);
>> - gcc_assert (m_char_array_type_node);
>> - TREE_TYPE (t_str) = m_char_array_type_node;
>> + /* Compare with c-family/c-common.c: fix_string_type. */
>> + size_t len = strlen (value);
>> + tree i_type = build_index_type (size_int (len));
>> + tree a_type = build_array_type (char_type_node, i_type);
>> + tree t_str = build_string (len, value);
>> + TREE_TYPE (t_str) = a_type;
>
> This code works with string lengths and string sizes which always
> requires a little extra care. I'd like to see at least a comment
> discussing this, as it's not immediately clear to me that we're
> correctly handling the NUL terminator here.
>
> Consider the string "foo".
> This has strlen == 3, and its size is 4 chars.
>
> build_string's comment says "Note that for a C string literal, LEN
> should include the trailing NUL."
>
> However, build_string appears to allocate one byte more than LEN, and
> write a NUL in that final position.
>
> fix_string_type has:
>
> int length = TREE_STRING_LENGTH (value);
>
> where tree.h has:
>
> /* In C terms, this is sizeof, not strlen. */
> #define TREE_STRING_LENGTH(NODE) (STRING_CST_CHECK (NODE)-
>>string.length)
>
> and:
> nchars = length / charsz;
>
> where for our purposes charsz == 1 and so nchars == length.
>
> fix_string_type has:
>
> i_type = build_index_type (size_int (nchars - 1));
>
> So I *think* the patch is correct, but there ought to be a comment at
> least.
>
> Or maybe use TREE_STRING_LENGTH (t_str) to more closely follow
> fix_string_type?
>
Mmmm when I wrote the patch I looked into the build_string code missing
the comment and that was my understanding too. But looking better now
in the compiler I think the patch is *not* correct. The trouble is that
if we call build_string (3, "foo") (as we would do now) we set
TREE_STRING_LENGTH to 3 and this appears to be wrong.
Actually build_string can be called using the strlen as argument (see
for example the various definition of DEF_ATTR_STRING) but apparently
this is not how is done for C strings in the frontends. Given that this
is what the comment suggests and that modifying the patch with the +1
keeps it functional I think doing what the front-end does is the right
thing.
> Also, please add an assertion and comment to the testcase to assert
> that the very long string is indeed longer than the previous limit of
> 200.
Ack
> Thanks
> Dave
Thanks for reviewing
Andrea
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH][gcc] libgccjit: handle long literals in playback::context::new_string_literal
2019-01-01 0:00 Andrea Corallo
2019-01-01 0:00 ` Andrea Corallo
@ 2020-01-01 0:00 ` David Malcolm
2020-03-07 21:43 ` Andrea Corallo
1 sibling, 1 reply; 7+ messages in thread
From: David Malcolm @ 2020-01-01 0:00 UTC (permalink / raw)
To: Andrea Corallo, jit, gcc-patches; +Cc: nd
On Mon, 2019-09-02 at 09:16 +0000, Andrea Corallo wrote:
> Hi all,
> yesterday I've found an interesting bug in libgccjit.
> Seems we have an hard limitation of 200 characters for literal
> strings.
> Attempting to create longer strings lead to ICE during pass_expand
> while performing a sanity check in get_constant_size.
>
> Tracking down the issue seems the code we have was inspired from
> c-family/c-common.c:c_common_nodes_and_builtins were
> array_domain_type
> is actually defined with a size of 200.
> The comment that follows that point sounded premonitory :) :)
>
> /* Make a type for arrays of characters.
> With luck nothing will ever really depend on the length of this
> array type. */
>
> At least in the current implementation the type is set by
> fix_string_type were the actual string length is taken in account.
>
> I attach a patch updating the logic accordingly and a new testcase
> for that.
>
> make check-jit is passing clean.
>
> Best Regards
> Andrea
Sorry about the long delay in reviewing this patch.
> gcc/jit/ChangeLog
> 2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
>
> * jit-playback.h
> (gcc::jit::recording::context m_recording_ctxt): Remove
^^^^^^^^^
"playback" here
> m_char_array_type_node field.
[...]
> @@ -670,9 +669,12 @@ playback::rvalue *
> playback::context::
> new_string_literal (const char *value)
> {
> - tree t_str = build_string (strlen (value), value);
> - gcc_assert (m_char_array_type_node);
> - TREE_TYPE (t_str) = m_char_array_type_node;
> + /* Compare with c-family/c-common.c: fix_string_type. */
> + size_t len = strlen (value);
> + tree i_type = build_index_type (size_int (len));
> + tree a_type = build_array_type (char_type_node, i_type);
> + tree t_str = build_string (len, value);
> + TREE_TYPE (t_str) = a_type;
This code works with string lengths and string sizes which always
requires a little extra care. I'd like to see at least a comment
discussing this, as it's not immediately clear to me that we're
correctly handling the NUL terminator here.
Consider the string "foo".
This has strlen == 3, and its size is 4 chars.
build_string's comment says "Note that for a C string literal, LEN
should include the trailing NUL."
However, build_string appears to allocate one byte more than LEN, and
write a NUL in that final position.
fix_string_type has:
int length = TREE_STRING_LENGTH (value);
where tree.h has:
/* In C terms, this is sizeof, not strlen. */
#define TREE_STRING_LENGTH(NODE) (STRING_CST_CHECK (NODE)-
>string.length)
and:
nchars = length / charsz;
where for our purposes charsz == 1 and so nchars == length.
fix_string_type has:
i_type = build_index_type (size_int (nchars - 1));
So I *think* the patch is correct, but there ought to be a comment at
least.
Or maybe use TREE_STRING_LENGTH (t_str) to more closely follow
fix_string_type?
[...]
Also, please add an assertion and comment to the testcase to assert
that the very long string is indeed longer than the previous limit of
200.
Thanks
Dave
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH][gcc] libgccjit: handle long literals in playback::context::new_string_literal
2019-01-01 0:00 Andrea Corallo
@ 2019-01-01 0:00 ` Andrea Corallo
2019-01-01 0:00 ` Andrea Corallo
2020-01-01 0:00 ` David Malcolm
1 sibling, 1 reply; 7+ messages in thread
From: Andrea Corallo @ 2019-01-01 0:00 UTC (permalink / raw)
To: David Malcolm; +Cc: jit, gcc-patches, nd, Andrea Corallo
Andrea Corallo writes:
> Hi all,
> yesterday I've found an interesting bug in libgccjit.
> Seems we have an hard limitation of 200 characters for literal strings.
> Attempting to create longer strings lead to ICE during pass_expand
> while performing a sanity check in get_constant_size.
>
> Tracking down the issue seems the code we have was inspired from
> c-family/c-common.c:c_common_nodes_and_builtins were array_domain_type
> is actually defined with a size of 200.
> The comment that follows that point sounded premonitory :) :)
>
> /* Make a type for arrays of characters.
> With luck nothing will ever really depend on the length of this
> array type. */
>
> At least in the current implementation the type is set by
> fix_string_type were the actual string length is taken in account.
>
> I attach a patch updating the logic accordingly and a new testcase
> for that.
>
> make check-jit is passing clean.
>
> Best Regards
> Andrea
>
> gcc/jit/ChangeLog
> 2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
>
> * jit-playback.h
> (gcc::jit::recording::context m_recording_ctxt): Remove
> m_char_array_type_node field.
> * jit-playback.c
> (playback::context::context) Remove m_char_array_type_node from member
> initializer list.
> (playback::context::new_string_literal) Fix logic to handle string
> length > 200.
>
> gcc/testsuite/ChangeLog
> 2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
>
> * jit.dg/all-non-failing-tests.h: Add test-long-string-literal.c.
> * jit.dg/test-long-string-literal.c: New testcase.
> diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
> index 9eeb2a7..a26b8d3 100644
> --- a/gcc/jit/jit-playback.c
> +++ b/gcc/jit/jit-playback.c
> @@ -88,7 +88,6 @@ playback::context::context (recording::context *ctxt)
> : log_user (ctxt->get_logger ()),
> m_recording_ctxt (ctxt),
> m_tempdir (NULL),
> - m_char_array_type_node (NULL),
> m_const_char_ptr (NULL)
> {
> JIT_LOG_SCOPE (get_logger ());
> @@ -670,9 +669,12 @@ playback::rvalue *
> playback::context::
> new_string_literal (const char *value)
> {
> - tree t_str = build_string (strlen (value), value);
> - gcc_assert (m_char_array_type_node);
> - TREE_TYPE (t_str) = m_char_array_type_node;
> + /* Compare with c-family/c-common.c: fix_string_type. */
> + size_t len = strlen (value);
> + tree i_type = build_index_type (size_int (len));
> + tree a_type = build_array_type (char_type_node, i_type);
> + tree t_str = build_string (len, value);
> + TREE_TYPE (t_str) = a_type;
>
> /* Convert to (const char*), loosely based on
> c/c-typeck.c: array_to_pointer_conversion,
> @@ -2703,10 +2705,6 @@ playback::context::
> replay ()
> {
> JIT_LOG_SCOPE (get_logger ());
> - /* Adapted from c-common.c:c_common_nodes_and_builtins. */
> - tree array_domain_type = build_index_type (size_int (200));
> - m_char_array_type_node
> - = build_array_type (char_type_node, array_domain_type);
>
> m_const_char_ptr
> = build_pointer_type (build_qualified_type (char_type_node,
> diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
> index d4b148e..801f610 100644
> --- a/gcc/jit/jit-playback.h
> +++ b/gcc/jit/jit-playback.h
> @@ -322,7 +322,6 @@ private:
>
> auto_vec<function *> m_functions;
> auto_vec<tree> m_globals;
> - tree m_char_array_type_node;
> tree m_const_char_ptr;
>
> /* Source location handling. */
> diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
> index 0272e6f8..1b3d561 100644
> --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
> +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
> @@ -220,6 +220,13 @@
> #undef create_code
> #undef verify_code
>
> +/* test-long-string-literal.c */
> +#define create_code create_code_long_string_literal
> +#define verify_code verify_code_long_string_literal
> +#include "test-long-string-literal.c"
> +#undef create_code
> +#undef verify_code
> +
> /* test-sum-of-squares.c */
> #define create_code create_code_sum_of_squares
> #define verify_code verify_code_sum_of_squares
> diff --git a/gcc/testsuite/jit.dg/test-long-string-literal.c b/gcc/testsuite/jit.dg/test-long-string-literal.c
> new file mode 100644
> index 0000000..882567c
> --- /dev/null
> +++ b/gcc/testsuite/jit.dg/test-long-string-literal.c
> @@ -0,0 +1,48 @@
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +
> +#include "libgccjit.h"
> +
> +#include "harness.h"
> +
> +const char very_long_string[] =
> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
> + "abcabcabcabcabcabcabcabcabcabca";
> +
> +void
> +create_code (gcc_jit_context *ctxt, void *user_data)
> +{
> + /* Build the test_fn. */
> + gcc_jit_function *f =
> + gcc_jit_context_new_function (
> + ctxt, NULL,
> + GCC_JIT_FUNCTION_EXPORTED,
> + gcc_jit_context_get_type(ctxt,
> + GCC_JIT_TYPE_CONST_CHAR_PTR),
> + "test_long_string_literal",
> + 0, NULL, 0);
> + gcc_jit_block *blk =
> + gcc_jit_function_new_block (f, "init_block");
> + gcc_jit_rvalue *res =
> + gcc_jit_context_new_string_literal (ctxt, very_long_string);
> +
> + gcc_jit_block_end_with_return (blk, NULL, res);
> +}
> +
> +void
> +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
> +{
> + typedef const char *(*fn_type) (void);
> + CHECK_NON_NULL (result);
> + fn_type test_long_string_literal =
> + (fn_type)gcc_jit_result_get_code (result, "test_long_string_literal");
> + CHECK_NON_NULL (test_long_string_literal);
> +
> + /* Call the JIT-generated function. */
> + const char *str = test_long_string_literal ();
> + CHECK_NON_NULL (str);
> + CHECK_VALUE (strcmp (str, very_long_string), 0);
> +}
Kindly pinging
Bests
Andrea
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH][gcc] libgccjit: handle long literals in playback::context::new_string_literal
2019-01-01 0:00 ` Andrea Corallo
@ 2019-01-01 0:00 ` Andrea Corallo
2019-01-01 0:00 ` Andrea Corallo
0 siblings, 1 reply; 7+ messages in thread
From: Andrea Corallo @ 2019-01-01 0:00 UTC (permalink / raw)
To: David Malcolm; +Cc: Andrea Corallo, jit, gcc-patches, nd
Andrea Corallo writes:
> Andrea Corallo writes:
>
>> Hi all,
>> yesterday I've found an interesting bug in libgccjit.
>> Seems we have an hard limitation of 200 characters for literal strings.
>> Attempting to create longer strings lead to ICE during pass_expand
>> while performing a sanity check in get_constant_size.
>>
>> Tracking down the issue seems the code we have was inspired from
>> c-family/c-common.c:c_common_nodes_and_builtins were array_domain_type
>> is actually defined with a size of 200.
>> The comment that follows that point sounded premonitory :) :)
>>
>> /* Make a type for arrays of characters.
>> With luck nothing will ever really depend on the length of this
>> array type. */
>>
>> At least in the current implementation the type is set by
>> fix_string_type were the actual string length is taken in account.
>>
>> I attach a patch updating the logic accordingly and a new testcase
>> for that.
>>
>> make check-jit is passing clean.
>>
>> Best Regards
>> Andrea
>>
>> gcc/jit/ChangeLog
>> 2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
>>
>> * jit-playback.h
>> (gcc::jit::recording::context m_recording_ctxt): Remove
>> m_char_array_type_node field.
>> * jit-playback.c
>> (playback::context::context) Remove m_char_array_type_node from member
>> initializer list.
>> (playback::context::new_string_literal) Fix logic to handle string
>> length > 200.
>>
>> gcc/testsuite/ChangeLog
>> 2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
>>
>> * jit.dg/all-non-failing-tests.h: Add test-long-string-literal.c.
>> * jit.dg/test-long-string-literal.c: New testcase.
>> diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
>> index 9eeb2a7..a26b8d3 100644
>> --- a/gcc/jit/jit-playback.c
>> +++ b/gcc/jit/jit-playback.c
>> @@ -88,7 +88,6 @@ playback::context::context (recording::context *ctxt)
>> : log_user (ctxt->get_logger ()),
>> m_recording_ctxt (ctxt),
>> m_tempdir (NULL),
>> - m_char_array_type_node (NULL),
>> m_const_char_ptr (NULL)
>> {
>> JIT_LOG_SCOPE (get_logger ());
>> @@ -670,9 +669,12 @@ playback::rvalue *
>> playback::context::
>> new_string_literal (const char *value)
>> {
>> - tree t_str = build_string (strlen (value), value);
>> - gcc_assert (m_char_array_type_node);
>> - TREE_TYPE (t_str) = m_char_array_type_node;
>> + /* Compare with c-family/c-common.c: fix_string_type. */
>> + size_t len = strlen (value);
>> + tree i_type = build_index_type (size_int (len));
>> + tree a_type = build_array_type (char_type_node, i_type);
>> + tree t_str = build_string (len, value);
>> + TREE_TYPE (t_str) = a_type;
>>
>> /* Convert to (const char*), loosely based on
>> c/c-typeck.c: array_to_pointer_conversion,
>> @@ -2703,10 +2705,6 @@ playback::context::
>> replay ()
>> {
>> JIT_LOG_SCOPE (get_logger ());
>> - /* Adapted from c-common.c:c_common_nodes_and_builtins. */
>> - tree array_domain_type = build_index_type (size_int (200));
>> - m_char_array_type_node
>> - = build_array_type (char_type_node, array_domain_type);
>>
>> m_const_char_ptr
>> = build_pointer_type (build_qualified_type (char_type_node,
>> diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
>> index d4b148e..801f610 100644
>> --- a/gcc/jit/jit-playback.h
>> +++ b/gcc/jit/jit-playback.h
>> @@ -322,7 +322,6 @@ private:
>>
>> auto_vec<function *> m_functions;
>> auto_vec<tree> m_globals;
>> - tree m_char_array_type_node;
>> tree m_const_char_ptr;
>>
>> /* Source location handling. */
>> diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
>> index 0272e6f8..1b3d561 100644
>> --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
>> +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
>> @@ -220,6 +220,13 @@
>> #undef create_code
>> #undef verify_code
>>
>> +/* test-long-string-literal.c */
>> +#define create_code create_code_long_string_literal
>> +#define verify_code verify_code_long_string_literal
>> +#include "test-long-string-literal.c"
>> +#undef create_code
>> +#undef verify_code
>> +
>> /* test-sum-of-squares.c */
>> #define create_code create_code_sum_of_squares
>> #define verify_code verify_code_sum_of_squares
>> diff --git a/gcc/testsuite/jit.dg/test-long-string-literal.c b/gcc/testsuite/jit.dg/test-long-string-literal.c
>> new file mode 100644
>> index 0000000..882567c
>> --- /dev/null
>> +++ b/gcc/testsuite/jit.dg/test-long-string-literal.c
>> @@ -0,0 +1,48 @@
>> +#include <stdlib.h>
>> +#include <stdio.h>
>> +#include <string.h>
>> +
>> +#include "libgccjit.h"
>> +
>> +#include "harness.h"
>> +
>> +const char very_long_string[] =
>> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
>> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
>> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
>> + "abcabcabcabcabcabcabcabcabcabca";
>> +
>> +void
>> +create_code (gcc_jit_context *ctxt, void *user_data)
>> +{
>> + /* Build the test_fn. */
>> + gcc_jit_function *f =
>> + gcc_jit_context_new_function (
>> + ctxt, NULL,
>> + GCC_JIT_FUNCTION_EXPORTED,
>> + gcc_jit_context_get_type(ctxt,
>> + GCC_JIT_TYPE_CONST_CHAR_PTR),
>> + "test_long_string_literal",
>> + 0, NULL, 0);
>> + gcc_jit_block *blk =
>> + gcc_jit_function_new_block (f, "init_block");
>> + gcc_jit_rvalue *res =
>> + gcc_jit_context_new_string_literal (ctxt, very_long_string);
>> +
>> + gcc_jit_block_end_with_return (blk, NULL, res);
>> +}
>> +
>> +void
>> +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
>> +{
>> + typedef const char *(*fn_type) (void);
>> + CHECK_NON_NULL (result);
>> + fn_type test_long_string_literal =
>> + (fn_type)gcc_jit_result_get_code (result, "test_long_string_literal");
>> + CHECK_NON_NULL (test_long_string_literal);
>> +
>> + /* Call the JIT-generated function. */
>> + const char *str = test_long_string_literal ();
>> + CHECK_NON_NULL (str);
>> + CHECK_VALUE (strcmp (str, very_long_string), 0);
>> +}
>
> Kindly pinging
>
> Bests
> Andrea
Hi,
I'd like to ping this patch.
Bests
Andrea
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH][gcc] libgccjit: handle long literals in playback::context::new_string_literal
@ 2019-01-01 0:00 Andrea Corallo
2019-01-01 0:00 ` Andrea Corallo
2020-01-01 0:00 ` David Malcolm
0 siblings, 2 replies; 7+ messages in thread
From: Andrea Corallo @ 2019-01-01 0:00 UTC (permalink / raw)
To: jit, gcc-patches; +Cc: nd
[-- Attachment #1: Type: text/plain, Size: 1496 bytes --]
Hi all,
yesterday I've found an interesting bug in libgccjit.
Seems we have an hard limitation of 200 characters for literal strings.
Attempting to create longer strings lead to ICE during pass_expand
while performing a sanity check in get_constant_size.
Tracking down the issue seems the code we have was inspired from
c-family/c-common.c:c_common_nodes_and_builtins were array_domain_type
is actually defined with a size of 200.
The comment that follows that point sounded premonitory :) :)
/* Make a type for arrays of characters.
With luck nothing will ever really depend on the length of this
array type. */
At least in the current implementation the type is set by
fix_string_type were the actual string length is taken in account.
I attach a patch updating the logic accordingly and a new testcase
for that.
make check-jit is passing clean.
Best Regards
Andrea
gcc/jit/ChangeLog
2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
* jit-playback.h
(gcc::jit::recording::context m_recording_ctxt): Remove
m_char_array_type_node field.
* jit-playback.c
(playback::context::context) Remove m_char_array_type_node from member
initializer list.
(playback::context::new_string_literal) Fix logic to handle string
length > 200.
gcc/testsuite/ChangeLog
2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
* jit.dg/all-non-failing-tests.h: Add test-long-string-literal.c.
* jit.dg/test-long-string-literal.c: New testcase.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: str.patch --]
[-- Type: text/x-diff; name="str.patch", Size: 4245 bytes --]
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index 9eeb2a7..a26b8d3 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -88,7 +88,6 @@ playback::context::context (recording::context *ctxt)
: log_user (ctxt->get_logger ()),
m_recording_ctxt (ctxt),
m_tempdir (NULL),
- m_char_array_type_node (NULL),
m_const_char_ptr (NULL)
{
JIT_LOG_SCOPE (get_logger ());
@@ -670,9 +669,12 @@ playback::rvalue *
playback::context::
new_string_literal (const char *value)
{
- tree t_str = build_string (strlen (value), value);
- gcc_assert (m_char_array_type_node);
- TREE_TYPE (t_str) = m_char_array_type_node;
+ /* Compare with c-family/c-common.c: fix_string_type. */
+ size_t len = strlen (value);
+ tree i_type = build_index_type (size_int (len));
+ tree a_type = build_array_type (char_type_node, i_type);
+ tree t_str = build_string (len, value);
+ TREE_TYPE (t_str) = a_type;
/* Convert to (const char*), loosely based on
c/c-typeck.c: array_to_pointer_conversion,
@@ -2703,10 +2705,6 @@ playback::context::
replay ()
{
JIT_LOG_SCOPE (get_logger ());
- /* Adapted from c-common.c:c_common_nodes_and_builtins. */
- tree array_domain_type = build_index_type (size_int (200));
- m_char_array_type_node
- = build_array_type (char_type_node, array_domain_type);
m_const_char_ptr
= build_pointer_type (build_qualified_type (char_type_node,
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index d4b148e..801f610 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -322,7 +322,6 @@ private:
auto_vec<function *> m_functions;
auto_vec<tree> m_globals;
- tree m_char_array_type_node;
tree m_const_char_ptr;
/* Source location handling. */
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 0272e6f8..1b3d561 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -220,6 +220,13 @@
#undef create_code
#undef verify_code
+/* test-long-string-literal.c */
+#define create_code create_code_long_string_literal
+#define verify_code verify_code_long_string_literal
+#include "test-long-string-literal.c"
+#undef create_code
+#undef verify_code
+
/* test-sum-of-squares.c */
#define create_code create_code_sum_of_squares
#define verify_code verify_code_sum_of_squares
diff --git a/gcc/testsuite/jit.dg/test-long-string-literal.c b/gcc/testsuite/jit.dg/test-long-string-literal.c
new file mode 100644
index 0000000..882567c
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-long-string-literal.c
@@ -0,0 +1,48 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+const char very_long_string[] =
+ "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
+ "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
+ "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
+ "abcabcabcabcabcabcabcabcabcabca";
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Build the test_fn. */
+ gcc_jit_function *f =
+ gcc_jit_context_new_function (
+ ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ gcc_jit_context_get_type(ctxt,
+ GCC_JIT_TYPE_CONST_CHAR_PTR),
+ "test_long_string_literal",
+ 0, NULL, 0);
+ gcc_jit_block *blk =
+ gcc_jit_function_new_block (f, "init_block");
+ gcc_jit_rvalue *res =
+ gcc_jit_context_new_string_literal (ctxt, very_long_string);
+
+ gcc_jit_block_end_with_return (blk, NULL, res);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef const char *(*fn_type) (void);
+ CHECK_NON_NULL (result);
+ fn_type test_long_string_literal =
+ (fn_type)gcc_jit_result_get_code (result, "test_long_string_literal");
+ CHECK_NON_NULL (test_long_string_literal);
+
+ /* Call the JIT-generated function. */
+ const char *str = test_long_string_literal ();
+ CHECK_NON_NULL (str);
+ CHECK_VALUE (strcmp (str, very_long_string), 0);
+}
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH][gcc] libgccjit: handle long literals in playback::context::new_string_literal
2019-01-01 0:00 ` Andrea Corallo
@ 2019-01-01 0:00 ` Andrea Corallo
0 siblings, 0 replies; 7+ messages in thread
From: Andrea Corallo @ 2019-01-01 0:00 UTC (permalink / raw)
To: David Malcolm; +Cc: Andrea Corallo, jit, gcc-patches, nd
Andrea Corallo writes:
> Andrea Corallo writes:
>
>> Andrea Corallo writes:
>>
>>> Hi all,
>>> yesterday I've found an interesting bug in libgccjit.
>>> Seems we have an hard limitation of 200 characters for literal strings.
>>> Attempting to create longer strings lead to ICE during pass_expand
>>> while performing a sanity check in get_constant_size.
>>>
>>> Tracking down the issue seems the code we have was inspired from
>>> c-family/c-common.c:c_common_nodes_and_builtins were array_domain_type
>>> is actually defined with a size of 200.
>>> The comment that follows that point sounded premonitory :) :)
>>>
>>> /* Make a type for arrays of characters.
>>> With luck nothing will ever really depend on the length of this
>>> array type. */
>>>
>>> At least in the current implementation the type is set by
>>> fix_string_type were the actual string length is taken in account.
>>>
>>> I attach a patch updating the logic accordingly and a new testcase
>>> for that.
>>>
>>> make check-jit is passing clean.
>>>
>>> Best Regards
>>> Andrea
>>>
>>> gcc/jit/ChangeLog
>>> 2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
>>>
>>> * jit-playback.h
>>> (gcc::jit::recording::context m_recording_ctxt): Remove
>>> m_char_array_type_node field.
>>> * jit-playback.c
>>> (playback::context::context) Remove m_char_array_type_node from member
>>> initializer list.
>>> (playback::context::new_string_literal) Fix logic to handle string
>>> length > 200.
>>>
>>> gcc/testsuite/ChangeLog
>>> 2019-??-?? Andrea Corallo <andrea.corallo@arm.com>
>>>
>>> * jit.dg/all-non-failing-tests.h: Add test-long-string-literal.c.
>>> * jit.dg/test-long-string-literal.c: New testcase.
>>> diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
>>> index 9eeb2a7..a26b8d3 100644
>>> --- a/gcc/jit/jit-playback.c
>>> +++ b/gcc/jit/jit-playback.c
>>> @@ -88,7 +88,6 @@ playback::context::context (recording::context *ctxt)
>>> : log_user (ctxt->get_logger ()),
>>> m_recording_ctxt (ctxt),
>>> m_tempdir (NULL),
>>> - m_char_array_type_node (NULL),
>>> m_const_char_ptr (NULL)
>>> {
>>> JIT_LOG_SCOPE (get_logger ());
>>> @@ -670,9 +669,12 @@ playback::rvalue *
>>> playback::context::
>>> new_string_literal (const char *value)
>>> {
>>> - tree t_str = build_string (strlen (value), value);
>>> - gcc_assert (m_char_array_type_node);
>>> - TREE_TYPE (t_str) = m_char_array_type_node;
>>> + /* Compare with c-family/c-common.c: fix_string_type. */
>>> + size_t len = strlen (value);
>>> + tree i_type = build_index_type (size_int (len));
>>> + tree a_type = build_array_type (char_type_node, i_type);
>>> + tree t_str = build_string (len, value);
>>> + TREE_TYPE (t_str) = a_type;
>>>
>>> /* Convert to (const char*), loosely based on
>>> c/c-typeck.c: array_to_pointer_conversion,
>>> @@ -2703,10 +2705,6 @@ playback::context::
>>> replay ()
>>> {
>>> JIT_LOG_SCOPE (get_logger ());
>>> - /* Adapted from c-common.c:c_common_nodes_and_builtins. */
>>> - tree array_domain_type = build_index_type (size_int (200));
>>> - m_char_array_type_node
>>> - = build_array_type (char_type_node, array_domain_type);
>>>
>>> m_const_char_ptr
>>> = build_pointer_type (build_qualified_type (char_type_node,
>>> diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
>>> index d4b148e..801f610 100644
>>> --- a/gcc/jit/jit-playback.h
>>> +++ b/gcc/jit/jit-playback.h
>>> @@ -322,7 +322,6 @@ private:
>>>
>>> auto_vec<function *> m_functions;
>>> auto_vec<tree> m_globals;
>>> - tree m_char_array_type_node;
>>> tree m_const_char_ptr;
>>>
>>> /* Source location handling. */
>>> diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
>>> index 0272e6f8..1b3d561 100644
>>> --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
>>> +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
>>> @@ -220,6 +220,13 @@
>>> #undef create_code
>>> #undef verify_code
>>>
>>> +/* test-long-string-literal.c */
>>> +#define create_code create_code_long_string_literal
>>> +#define verify_code verify_code_long_string_literal
>>> +#include "test-long-string-literal.c"
>>> +#undef create_code
>>> +#undef verify_code
>>> +
>>> /* test-sum-of-squares.c */
>>> #define create_code create_code_sum_of_squares
>>> #define verify_code verify_code_sum_of_squares
>>> diff --git a/gcc/testsuite/jit.dg/test-long-string-literal.c b/gcc/testsuite/jit.dg/test-long-string-literal.c
>>> new file mode 100644
>>> index 0000000..882567c
>>> --- /dev/null
>>> +++ b/gcc/testsuite/jit.dg/test-long-string-literal.c
>>> @@ -0,0 +1,48 @@
>>> +#include <stdlib.h>
>>> +#include <stdio.h>
>>> +#include <string.h>
>>> +
>>> +#include "libgccjit.h"
>>> +
>>> +#include "harness.h"
>>> +
>>> +const char very_long_string[] =
>>> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
>>> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
>>> + "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
>>> + "abcabcabcabcabcabcabcabcabcabca";
>>> +
>>> +void
>>> +create_code (gcc_jit_context *ctxt, void *user_data)
>>> +{
>>> + /* Build the test_fn. */
>>> + gcc_jit_function *f =
>>> + gcc_jit_context_new_function (
>>> + ctxt, NULL,
>>> + GCC_JIT_FUNCTION_EXPORTED,
>>> + gcc_jit_context_get_type(ctxt,
>>> + GCC_JIT_TYPE_CONST_CHAR_PTR),
>>> + "test_long_string_literal",
>>> + 0, NULL, 0);
>>> + gcc_jit_block *blk =
>>> + gcc_jit_function_new_block (f, "init_block");
>>> + gcc_jit_rvalue *res =
>>> + gcc_jit_context_new_string_literal (ctxt, very_long_string);
>>> +
>>> + gcc_jit_block_end_with_return (blk, NULL, res);
>>> +}
>>> +
>>> +void
>>> +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
>>> +{
>>> + typedef const char *(*fn_type) (void);
>>> + CHECK_NON_NULL (result);
>>> + fn_type test_long_string_literal =
>>> + (fn_type)gcc_jit_result_get_code (result, "test_long_string_literal");
>>> + CHECK_NON_NULL (test_long_string_literal);
>>> +
>>> + /* Call the JIT-generated function. */
>>> + const char *str = test_long_string_literal ();
>>> + CHECK_NON_NULL (str);
>>> + CHECK_VALUE (strcmp (str, very_long_string), 0);
>>> +}
>>
>> Kindly pinging
>>
>> Bests
>> Andrea
>
> Hi,
> I'd like to ping this patch.
>
> Bests
> Andrea
Pinging again.
Bests
Andrea
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-03-07 21:44 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <1579772431.117590.ezmlm@gcc.gnu.org>
2020-01-01 0:00 ` [PATCH][gcc] libgccjit: handle long literals in playback::context::new_string_literal Andrea Corallo
2019-01-01 0:00 Andrea Corallo
2019-01-01 0:00 ` Andrea Corallo
2019-01-01 0:00 ` Andrea Corallo
2019-01-01 0:00 ` Andrea Corallo
2020-01-01 0:00 ` David Malcolm
2020-03-07 21:43 ` Andrea Corallo
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).