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.cora...@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.cora...@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