From ede14092bc33e182ee6c811c335bf9aac789d7be Mon Sep 17 00:00:00 2001 From: Antoni Boucher <bouanto@zoho.com> Date: Thu, 15 Feb 2024 17:03:22 -0500 Subject: [PATCH] libgccjit: Add option to allow special characters in function names gcc/jit/ChangeLog: * docs/topics/contexts.rst: Add documentation for new option. * jit-recording.cc (recording::context::get_str_option): New method. * jit-recording.h (get_str_option): New method. * libgccjit.cc (gcc_jit_context_new_function): Allow special characters in function names. * libgccjit.h (enum gcc_jit_str_option): New option. gcc/testsuite/ChangeLog: * jit.dg/test-special-chars.c: New test. --- gcc/jit/docs/topics/contexts.rst | 9 +++-- gcc/jit/jit-recording.cc | 17 ++++++++-- gcc/jit/jit-recording.h | 3 ++ gcc/jit/libgccjit.cc | 8 +++-- gcc/jit/libgccjit.h | 3 ++ gcc/testsuite/jit.dg/test-special-chars.c | 41 +++++++++++++++++++++++ 6 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/jit.dg/test-special-chars.c diff --git a/gcc/jit/docs/topics/contexts.rst b/gcc/jit/docs/topics/contexts.rst index 10a0e50f9f62..ba075cd71d35 100644 --- a/gcc/jit/docs/topics/contexts.rst +++ b/gcc/jit/docs/topics/contexts.rst @@ -317,13 +317,18 @@ String Options copy of the underlying string, so it is valid to pass in a pointer to an on-stack buffer. - There is just one string option specified this way: - .. macro:: GCC_JIT_STR_OPTION_PROGNAME The name of the program, for use as a prefix when printing error messages to stderr. If `NULL`, or default, "libgccjit.so" is used. + .. macro:: GCC_JIT_STR_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES + + Alphabetic ASCII characters and underscores are always valid. Numeric + ASCII characters are always valid after the initial character of the + string. Use this entrypoint to specify additional ASCII characters that + are valid throughout function names (ex.: ".$"). + Boolean options *************** diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc index 7cbe383c79db..90ac5bdafffc 100644 --- a/gcc/jit/jit-recording.cc +++ b/gcc/jit/jit-recording.cc @@ -1424,6 +1424,18 @@ recording::context::set_str_option (enum gcc_jit_str_option opt, log_str_option (opt); } +const char* +recording::context::get_str_option (enum gcc_jit_str_option opt) +{ + if (opt < 0 || opt >= GCC_JIT_NUM_STR_OPTIONS) + { + add_error (NULL, + "unrecognized (enum gcc_jit_str_option) value: %i", opt); + return NULL; + } + return m_str_options[opt]; +} + /* Set the given integer option for this context, or add an error if it's not recognized. @@ -1765,7 +1777,8 @@ recording::context::dump_to_file (const char *path, bool update_locations) static const char * const str_option_reproducer_strings[GCC_JIT_NUM_STR_OPTIONS] = { - "GCC_JIT_STR_OPTION_PROGNAME" + "GCC_JIT_STR_OPTION_PROGNAME", + "GCC_JIT_STR_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES", }; static const char * const @@ -1782,7 +1795,7 @@ static const char * const "GCC_JIT_BOOL_OPTION_DUMP_SUMMARY", "GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING", "GCC_JIT_BOOL_OPTION_SELFCHECK_GC", - "GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES" + "GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES", }; static const char * const diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index e5a920fac499..13c2ea735027 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -255,6 +255,9 @@ public: set_str_option (enum gcc_jit_str_option opt, const char *value); + const char* + get_str_option (enum gcc_jit_str_option opt); + void set_int_option (enum gcc_jit_int_option opt, int value); diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc index 63dee7049af9..3a7a4e26931f 100644 --- a/gcc/jit/libgccjit.cc +++ b/gcc/jit/libgccjit.cc @@ -1201,10 +1201,13 @@ gcc_jit_context_new_function (gcc_jit_context *ctxt, Eventually we'll need some way to interact with e.g. C++ name mangling. */ { + const char* special_chars_allowed + = ctxt->get_str_option (GCC_JIT_STR_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES); /* Leading char: */ char ch = *name; RETURN_NULL_IF_FAIL_PRINTF2 ( - ISALPHA (ch) || ch == '_', + ISALPHA (ch) || ch == '_' || (special_chars_allowed + && strchr (special_chars_allowed, ch)), ctxt, loc, "name \"%s\" contains invalid character: '%c'", name, ch); @@ -1212,7 +1215,8 @@ gcc_jit_context_new_function (gcc_jit_context *ctxt, for (const char *ptr = name + 1; (ch = *ptr); ptr++) { RETURN_NULL_IF_FAIL_PRINTF2 ( - ISALNUM (ch) || ch == '_', + ISALNUM (ch) || ch == '_' || (special_chars_allowed + && strchr (special_chars_allowed, ch)), ctxt, loc, "name \"%s\" contains invalid character: '%c'", name, ch); diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index ae3745a91aa3..1274a1bb61b6 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -177,6 +177,9 @@ enum gcc_jit_str_option messages to stderr. If NULL, or default, "libgccjit.so" is used. */ GCC_JIT_STR_OPTION_PROGNAME, + /* Special characters to allow in function names. */ + GCC_JIT_STR_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES, + GCC_JIT_NUM_STR_OPTIONS }; diff --git a/gcc/testsuite/jit.dg/test-special-chars.c b/gcc/testsuite/jit.dg/test-special-chars.c new file mode 100644 index 000000000000..8cd77323050a --- /dev/null +++ b/gcc/testsuite/jit.dg/test-special-chars.c @@ -0,0 +1,41 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + gcc_jit_context_set_str_option (ctxt, + GCC_JIT_STR_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES, "$."); + + /* Let's try to inject the equivalent of: + void + name$with.special_chars (void) + { + } + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + + /* Build the test_fn. */ + gcc_jit_function *test_fn = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "name$with.special_chars", + 0, NULL, + 0); + + gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); + gcc_jit_block_end_with_void_return ( + block, NULL); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_NON_NULL (result); +} -- GitLab