From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) by sourceware.org (Postfix) with ESMTPS id 6BFB4385801E for ; Thu, 5 May 2022 18:50:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6BFB4385801E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=palves.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wr1-f45.google.com with SMTP id t6so7257616wra.4 for ; Thu, 05 May 2022 11:50:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XbZuIxbNIYA7uom/JZHyTx9rLOnclIeZ2VCPjRduyp4=; b=ebE2+ETTVgOsJE0BPfVyHHoMEA/YvBUksPEOf97mvYyAgGd7Xm9JH0GxDuyZpMrA8I Myxnr8CZnIKq2s2qFyZ6CjvDFdqD74rDPVX1hfkKy03U5gfe1kUMJtrdBX0K4bqlrvP1 8mVZxnPPg6j96TyQm48VCkAf5yYCKeZ2fY0Om0K6KM1uDZEAA5ZX42HDTjV8R9j51PXT WbsBGusYnlE8iS/2WZDnW0El0tguDXfKci4Kmk8y6z5OgH9PB/xvrGSYzxC37Wrs62Vz JIX/ChFcRDl/TRn7TrldKx3qgmgUUp2rN4GXX3S1Ml3VLT4ld9pHYG4h7K7DbSi3qF7l /5Lg== X-Gm-Message-State: AOAM5313SfgZdPxtH95bqpOPWVQXwka6KoyHlz2Yln/1iVEtnO/an0YB nOIFOSWc4oWt7TufoaECyKiMXeN1G9o= X-Google-Smtp-Source: ABdhPJwNUCBqQduW/0GMPSqKJJfjBeaEhYcueFWLL3/pqHqNcsrOtrhx7i7AZtmuO0DaeiHAO5dDXA== X-Received: by 2002:a5d:54c4:0:b0:20a:d2ea:1f7f with SMTP id x4-20020a5d54c4000000b0020ad2ea1f7fmr21853645wrv.306.1651776630727; Thu, 05 May 2022 11:50:30 -0700 (PDT) Received: from localhost ([2001:8a0:f924:2600:209d:85e2:409e:8726]) by smtp.gmail.com with ESMTPSA id c17-20020a7bc011000000b003942a244f40sm7073244wmb.25.2022.05.05.11.50.29 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 05 May 2022 11:50:29 -0700 (PDT) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 3/3] Fix "b f(std::string)" when current language is C Date: Thu, 5 May 2022 19:50:20 +0100 Message-Id: <20220505185020.3648774-4-pedro@palves.net> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220505185020.3648774-1-pedro@palves.net> References: <20220505185020.3648774-1-pedro@palves.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-9.5 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 May 2022 18:50:33 -0000 If you try to set a breakpoint at a function such as "b f(std::string)", and the current language is C, the breakpoint fails to be set, like so: (gdb) set language c break f(std::string) Function "f(std::string)" not defined. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) The problem is that the code in GDB that expands the std::string typedef hits this in c-typeprint.c: /* If we have "typedef struct foo {. . .} bar;" do we want to print it as "struct foo" or as "bar"? Pick the latter for C++, because C++ folk tend to expect things like "class5 *foo" rather than "struct class5 *foo". We rather arbitrarily choose to make language_minimal work in a C-like way. */ if (language == language_c || language == language_minimal) { if (type->code () == TYPE_CODE_UNION) gdb_printf (stream, "union "); else if (type->code () == TYPE_CODE_STRUCT) { if (type->is_declared_class ()) gdb_printf (stream, "class "); else gdb_printf (stream, "struct "); } else if (type->code () == TYPE_CODE_ENUM) gdb_printf (stream, "enum "); } I.e., std::string is expanded to "class std::..." instead of just "std::...", and then the "f(class std::..." symbol doesn't exist. Fix this by making cp-support.c:inspect_type print the expanded typedef type using the language of the symbol whose type we're expanding the typedefs for -- in the example in question, the "std::string" typedef symbol, which is a C++ symbol. Use type_print_raw_options as it seems to me that in this scenario we always want raw types, to match the real symbol names. Adjust the gdb.cp/break-std-string.exp testcase to try setting a breakpoint at "f(std::string)" in both C and C++. Change-Id: Ib54fab4cf0fd307bfd55bf1dd5056830096a653b --- gdb/cp-support.c | 10 +++++++++- gdb/testsuite/gdb.cp/break-f-std-string.exp | 13 ++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/gdb/cp-support.c b/gdb/cp-support.c index 1ddc2045808..06d541f0603 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -41,6 +41,7 @@ #include #include "event-top.h" #include "run-on-main-thread.h" +#include "typeprint.h" #define d_left(dc) (dc)->u.s_binary.left #define d_right(dc) (dc)->u.s_binary.right @@ -229,7 +230,14 @@ inspect_type (struct demangle_parse_info *info, string_file buf; try { - type_print (type, "", &buf, -1); + /* Avoid using the current language. If the language is + C, and TYPE is a struct/class, the printed type is + prefixed with "struct " or "class ", which we don't + want when we're expanding a C++ typedef. Print using + the type symbol's language to expand a C++ typedef + the C++ way even if the current language is C. */ + const language_defn *lang = language_def (sym->language ()); + lang->print_type (type, "", &buf, -1, 0, &type_print_raw_options); } /* If type_print threw an exception, there is little point in continuing, so just bow out gracefully. */ diff --git a/gdb/testsuite/gdb.cp/break-f-std-string.exp b/gdb/testsuite/gdb.cp/break-f-std-string.exp index 0869912bb29..e222bae8ab3 100644 --- a/gdb/testsuite/gdb.cp/break-f-std-string.exp +++ b/gdb/testsuite/gdb.cp/break-f-std-string.exp @@ -93,10 +93,17 @@ proc test {cxx11_abi} { } } - gdb_test "break f($type)" "$srcfile, line $::decimal\\." + # GDB should be able to expand the std::string typedef in the + # function prototype using C++ logic even if the current language + # is C. + foreach_with_prefix lang {"c" "c++"} { + gdb_test_no_output "set language $lang" - if { $realtype != "" } { - gdb_test "break f($realtype)" "$srcfile, line $::decimal\\." + gdb_test "break f($type)" "$srcfile, line $::decimal\\." + + if { $realtype != "" } { + gdb_test "break f($realtype)" "$srcfile, line $::decimal\\." + } } } -- 2.36.0