From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id mUK2GUyV12pjDTsAWB0awg (envelope-from ) for ; Tue, 20 Oct 2026 12:22:36 -0400 Received: by simark.ca (Postfix, from userid 112) id 6499E1E04D; Tue, 20 Oct 2026 12:22:36 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.3 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id BCFF21E04D for ; Tue, 20 Oct 2026 12:22:35 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6B7484A9C01E for ; Tue, 20 Oct 2026 16:22:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6B7484A9C01E Received: from simark.ca (simark.ca [158.69.221.121]) by sourceware.org (Postfix) with ESMTPS id 66F904A9C01F for ; Tue, 20 Oct 2026 16:21:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 66F904A9C01F Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 66F904A9C01F Authentication-Results: sourceware.org; arc=none smtp.remote-ip=158.69.221.121 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1792513263; cv=none; b=ktP3knK3yaF9u4yR72WscZf6ULuu3ZDquiIDzXTBH79/LW+UZNzxEjXYBifzYwy+d5H4YBTielzDN2zpNiDyiYdhSsbi4tlKtq/CjY2fsyCFWOJo9e1kJkgJr2hH3ssDPQg+0GaNfxYrrWDcZ4+8K4jannmMddIu5UT++Xu+X/s= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1792513263; c=relaxed/simple; bh=EtD5WSBEZWTgrXFsckacT6Rr6u9PmUqZme9eGXOCRzo=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=WY8pG96kNOxIEHZWsmNJGjHkeqLFrghnr3h1VDxqahfDg/XWxx7YJmul3WcuelpbN54BhLMfO8GqSs2XkZF9cciHJPXbT6ydfU/8o42OU3N5/ASHp7HD+22U6NsHxGTZEC4zh0jmixHg9XGsD+iEohV49FO2/QX4HT8z3/hpfno= ARC-Authentication-Results: i=1; sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 66F904A9C01F Received: by simark.ca (Postfix) id 84D6D1E0BC; Tue, 20 Oct 2026 12:21:00 -0400 (EDT) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 07/13] gdb: extract lex_char_literal from cpname_yylex Date: Tue, 20 Oct 2026 12:17:29 -0400 Message-ID: <20261020162054.2140671-8-simon.marchi@efficios.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261020162054.2140671-1-simon.marchi@efficios.com> References: <20261020162054.2140671-1-simon.marchi@efficios.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org From: Simon Marchi Move the code lexing character constants in the C++ name parser to its own function, lex_char_literal. This makes the code easier to read, but also a later patch will call it from another place. The comment mentioned that a quote could also start a quoted symbol reference, like 'foo(int,int)', but this code doesn't seem handle that, it really just handles character constants, so drop that part of the comment. While at it, add selftests for the error paths of this function ("empty character constant" and "invalid character constant"). Add a new should_not_parse helper for that. Change-Id: I6413606d03d8291f29117decf1c34000323e4533 --- gdb/cp-name-parser.c | 87 ++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 31 deletions(-) diff --git a/gdb/cp-name-parser.c b/gdb/cp-name-parser.c index 8012d6cc0a20..d7ecb534b718 100644 --- a/gdb/cp-name-parser.c +++ b/gdb/cp-name-parser.c @@ -554,6 +554,45 @@ cpname_yyerror (cp_name_parser::cpname_state *state, const char *msg) state->global_errmsg = msg ? msg : "parse error"; } +/* Lex a character constant ('0' or '\177' for example), starting at the + opening quote at STATE->LEXPTR. Store the result in LVALP and return + INT, or ERROR on error. */ + +static int +lex_char_literal (cp_name_parser_YYSTYPE *lvalp, + cp_name_parser::cpname_state *state) +{ + /* Skip opening quote. */ + state->lexptr++; + + int c = *state->lexptr++; + if (c == '\\') + c = cp_parse_escape (&state->lexptr); + else if (c == '\'') + { + cpname_yyerror (state, _("empty character constant")); + return ERROR; + } + + /* We over-allocate here, but it doesn't really matter. */ + char *copy = (char *) obstack_alloc (&state->demangle_info->obstack, 30); + xsnprintf (copy, 30, "%d", c); + + c = *state->lexptr++; + if (c != '\'') + { + cpname_yyerror (state, _("invalid character constant")); + return ERROR; + } + + lvalp->comp + = state->fill_comp (DEMANGLE_COMPONENT_LITERAL, + state->make_builtin_type ("char"), + state->make_name (copy, strlen (copy))); + + return INT; +} + /* Read one token, getting characters through LEXPTR. */ int @@ -563,7 +602,6 @@ cpname_yylex (cp_name_parser_YYSTYPE *lvalp, int c; int namelen; const char *tokstart; - char *copy; /* If the input starts with OP_STR, consume it, use OP_STR as the token's operator name and return true. Otherwise, return false. */ @@ -605,36 +643,7 @@ cpname_yylex (cp_name_parser_YYSTYPE *lvalp, goto retry; case '\'': - /* We either have a character constant ('0' or '\177' for example) - or we have a quoted symbol reference ('foo(int,int)' in C++ - for example). */ - state->lexptr++; - c = *state->lexptr++; - if (c == '\\') - c = cp_parse_escape (&state->lexptr); - else if (c == '\'') - { - cpname_yyerror (state, _("empty character constant")); - return ERROR; - } - - /* We over-allocate here, but it doesn't really matter . */ - copy = (char *) obstack_alloc (&state->demangle_info->obstack, 30); - xsnprintf (copy, 30, "%d", c); - - c = *state->lexptr++; - if (c != '\'') - { - cpname_yyerror (state, _("invalid character constant")); - return ERROR; - } - - lvalp->comp - = state->fill_comp (DEMANGLE_COMPONENT_LITERAL, - state->make_builtin_type ("char"), - state->make_name (copy, strlen (copy))); - - return INT; + return lex_char_literal (lvalp, state); case '(': if (startswith (tokstart, "(anonymous namespace)")) @@ -1038,6 +1047,8 @@ should_canonicalize_to (const char *name, const char *expected) SELF_CHECK (streq (result, expected)); } +/* Check that parsing NAME succeeds. */ + static void should_parse (const char *name) { @@ -1045,6 +1056,17 @@ should_parse (const char *name) SELF_CHECK (parsed != nullptr); } +/* Check that parsing NAME fails with error message EXPECTED_ERRMSG. */ + +static void +should_not_parse (const char *name, const char *expected_errmsg) +{ + std::string errmsg; + auto parsed = cp_demangled_name_to_comp (name, &errmsg); + SELF_CHECK (parsed == nullptr); + SELF_CHECK (errmsg == expected_errmsg); +} + static void canonicalize_tests () { @@ -1084,6 +1106,9 @@ static void parser_tests () { should_parse ("void whatever::operator<=>"); + + should_not_parse ("C<''>", "empty character constant"); + should_not_parse ("C<'ab'>", "invalid character constant"); } #endif -- 2.56.0