From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 96679 invoked by alias); 26 Jun 2019 08:59:24 -0000 Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org Received: (qmail 96671 invoked by uid 89); 26 Jun 2019 08:59:24 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.3 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_STOCKGEN autolearn=ham version=3.3.1 spammy=capability, UD:de, nicole, Nicole X-HELO: mga03.intel.com Received: from mga03.intel.com (HELO mga03.intel.com) (134.134.136.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 26 Jun 2019 08:59:22 +0000 Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Jun 2019 01:59:19 -0700 Received: from irsmsx109.ger.corp.intel.com ([163.33.3.23]) by fmsmga005.fm.intel.com with ESMTP; 26 Jun 2019 01:59:18 -0700 Received: from irsmsx103.ger.corp.intel.com ([169.254.3.140]) by IRSMSX109.ger.corp.intel.com ([169.254.13.220]) with mapi id 14.03.0439.000; Wed, 26 Jun 2019 09:59:17 +0100 From: "Aktemur, Tankut Baris" To: "gdb@sourceware.org" CC: "Metzger, Markus T" Subject: RE: Infcall of a template function in a C++ program Date: Wed, 26 Jun 2019 08:59:00 -0000 Message-ID: References: In-Reply-To: Content-Type: multipart/mixed; boundary="_002_B98F7326B8E238409968F562D326E1A90D03B27BIRSMSX103gercor_" MIME-Version: 1.0 X-IsSubscribed: yes X-SW-Source: 2019-06/txt/msg00067.txt.bz2 --_002_B98F7326B8E238409968F562D326E1A90D03B27BIRSMSX103gercor_ Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-length: 7500 * On Fri, 7 Jun 2019 14:45:40 +0000, "Aktemur, Tankut Baris" wrote: >=20 > Dear All, >=20 > Suppose we have the following small C++ program: >=20 > ~~~ > #include >=20 > template > T foo (T t) > { > return t; > } >=20 > int main (void) > { > std::cout << foo (5) << std::endl; > std::cout << foo ('a') << std::endl; >=20 > return 0; > } > ~~~ >=20 > The compiler is able to do the type inference, template function > instantiation, and function invocation based on the expressions `foo (5)` > and `foo ('a')`. When we start GDB and attempt to evaluate these > expressions, the corresponding functions are not resolved, though. > Here is a sample session: >=20 > ~~~ > (gdb) start > ... > (gdb) print foo(5) > No symbol "foo" in current context. > (gdb) print foo(5) > $1 =3D 5 > (gdb) print foo('a') > $2 =3D 97 'a' > ~~~ >=20 > The DWARF info contains DIE's for the subprograms named "foo" and > "foo": >=20 > 0x00002849: DW_TAG_subprogram > DW_AT_name ("foo") > ... > 0x00002882: DW_TAG_subprogram > DW_AT_name ("foo") > ... >=20 > Is there any on-going or planned work to add type inference/resolution > capability to GDB so that an expression such as `foo (5)` would be evalua= ted > correctly? This might not be possible in general, but does GDB try any he= uristics > to find the right template instance? I've evaluated the following straightforward idea to address this problem: When looking up function names, ignore the template arguments if the user did not enter them explicitly. This way, all the function instances can be found. GDB already does overload resolution. After finding the potential set of function symbols, the overload resolution mechanism can take over to pick the best match. E.g. Consider the example above. If the user enters `foo(5)`, we can look up symbols matching `foo`. Ignoring template arguments would yield `foo` and `foo`. Because the argument 5 is an int, overload resolution can pick `foo` successfully among these candidates. If the user enters template arguments explicitly as in `foo(5)`, then we would look up `foo`, find only `foo`, and proceed with that. 1. To look up symbols, GDB retains a hash map. It calculates the hash of the search phrase, finds the corresponding bucket, and then performs a linear search in the bucket. To make sure that all the template instances of a function fall into the same bucket, we should ignore template arguments when calculating the hash of a function name. 2. When comparing two symbols, we must ignore template arguments if the search phrase does not contain them. Otherwise, they must be taken into account. The patch given at the end of this email does these two things (also attached as a file). So far so good. There is a remaining problem, though. For expression evaluation, GDB does the following: 1. parse the input string, obtain an expression (a flattened abstract syntax tree). 2. evaluate the expression. In step 1, while parsing, the function name is converted to a symbol by performing a lookup and picking the first match (no overload resolution). In this step, the search phrase is the function name input by the user. In step 2, GDB does a lookup (again) followed by overload resolution, but this time the search phrase is the name of the symbol found in step 1. This means the information about whether the user originally entered template arguments explicitly is lost! Moreover, this could lead to incorrect deduction. Example: User enters `foo(5)`. Step 1 looks up "foo", finds and picks `foo` as the first match. In step 2, the function name to be used for lookup is `foo`. There is only one match for that. So GDB picks `foo` for execution. Opinions on how to address this problem properly are welcome. Regards, -Baris ~~~ diff --git a/gdb/cp-support.c b/gdb/cp-support.c index 3ce5f60b12c..f27f04b8999 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -1642,6 +1642,17 @@ cp_search_name_hash (const char *search_name) && string[5] !=3D ':') break; + /* Skip template arguments such as ">". + This is needed in case the user enters the plain function name + without the explicit template arguments when evaluating an + expression, so that all the symbol candidates will be found in + the same bucket. */ + if (skip_template_args (&string)) + { + string--; /* Adjust for the loop's post-expr. */ + continue; + } + hash =3D SYMBOL_HASH_NEXT (hash, *string); } return hash; diff --git a/gdb/utils.c b/gdb/utils.c index 09381d9092d..89cccbbf1e9 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -2257,6 +2257,34 @@ skip_abi_tag (const char **name) /* See utils.h. */ +bool +skip_template_args (const char **name) +{ + const char *p =3D *name; + + if (*p =3D=3D '\0' || *p !=3D '<') + return false; + + p++; + int depth =3D 1; + + while (*p !=3D '\0' && depth > 0) + { + if (*p =3D=3D '<') + depth++; + else if (*p =3D=3D '>') + depth--; + p++; + } + + if (depth =3D=3D 0) + *name =3D p; + + return (depth =3D=3D 0); +} + +/* See utils.h. */ + int strncmp_iw_with_mode (const char *string1, const char *string2, size_t string2_len, strncmp_iw_mode mode, @@ -2311,6 +2339,26 @@ strncmp_iw_with_mode (const char *string1, const cha= r *string2, string1++; } + /* Skip template args in the symbol name if the lookup name + doesn't include them. E.g.: + + string1: function>(int) + string2: function + */ + if (language =3D=3D language_cplus + && (string2 =3D=3D end_str2 || *string2 !=3D '<')) + { + const char *template_start =3D string1; + + bool skipped =3D skip_template_args (&string1); + + if (match_for_lcd !=3D NULL && skipped) + match_for_lcd->mark_ignored_range (template_start, string1); + + while (isspace (*string1)) + string1++; + } + if (*string1 =3D=3D '\0' || string2 =3D=3D end_str2) break; diff --git a/gdb/utils.h b/gdb/utils.h index c728449429e..21e34cfec6b 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -89,6 +89,19 @@ extern int strcmp_iw (const char *string1, const char *s= tring2); extern int strcmp_iw_ordered (const char *, const char *); +/* If *NAME points at template args, skip it and return true. Otherwise + leave *NAME unmodified and return false. E.g., + Before: ">(int)". + *NAME --^ + After: ">(int)". + *NAME -------------------------^ + + If the angle brackets are not balanced, *NAME is unmodified, and the + return value is false. This could be the case, for instance, if *NAME + points to the first '<' inside "operator<<(...)". */ + +extern bool skip_template_args (const char **name); + /* Return true if the strings are equal. */ extern bool streq (const char *, const char *); ~~~ Intel Deutschland GmbH Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Christin Eisenschmid, Gary Kershaw Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928 --_002_B98F7326B8E238409968F562D326E1A90D03B27BIRSMSX103gercor_ Content-Type: application/octet-stream; name="template-args.patch" Content-Description: template-args.patch Content-Disposition: attachment; filename="template-args.patch"; size=3016; creation-date="Wed, 26 Jun 2019 08:47:54 GMT"; modification-date="Wed, 26 Jun 2019 08:47:54 GMT" Content-Transfer-Encoding: base64 Content-length: 4092 ZGlmZiAtLWdpdCBhL2dkYi9jcC1zdXBwb3J0LmMgYi9nZGIvY3Atc3VwcG9y dC5jCmluZGV4IDNjZTVmNjBiMTJjLi5mMjdmMDRiODk5OSAxMDA2NDQKLS0t IGEvZ2RiL2NwLXN1cHBvcnQuYworKysgYi9nZGIvY3Atc3VwcG9ydC5jCkBA IC0xNjQyLDYgKzE2NDIsMTcgQEAgY3Bfc2VhcmNoX25hbWVfaGFzaCAoY29u c3QgY2hhciAqc2VhcmNoX25hbWUpCiAJICAmJiBzdHJpbmdbNV0gIT0gJzon KQogCWJyZWFrOwogCisgICAgICAvKiBTa2lwIHRlbXBsYXRlIGFyZ3VtZW50 cyBzdWNoIGFzICI8aW50LCBzdGQ6OnZlY3RvcjxjaGFyPj4iLgorCSBUaGlz IGlzIG5lZWRlZCBpbiBjYXNlIHRoZSB1c2VyIGVudGVycyB0aGUgcGxhaW4g ZnVuY3Rpb24gbmFtZQorCSB3aXRob3V0IHRoZSBleHBsaWNpdCB0ZW1wbGF0 ZSBhcmd1bWVudHMgd2hlbiBldmFsdWF0aW5nIGFuCisJIGV4cHJlc3Npb24s IHNvIHRoYXQgYWxsIHRoZSBzeW1ib2wgY2FuZGlkYXRlcyB3aWxsIGJlIGZv dW5kIGluCisJIHRoZSBzYW1lIGJ1Y2tldC4gICovCisgICAgICBpZiAoc2tp cF90ZW1wbGF0ZV9hcmdzICgmc3RyaW5nKSkKKwl7CisJICBzdHJpbmctLTsg LyogQWRqdXN0IGZvciB0aGUgbG9vcCdzIHBvc3QtZXhwci4gICovCisJICBj b250aW51ZTsKKwl9CisKICAgICAgIGhhc2ggPSBTWU1CT0xfSEFTSF9ORVhU IChoYXNoLCAqc3RyaW5nKTsKICAgICB9CiAgIHJldHVybiBoYXNoOwpkaWZm IC0tZ2l0IGEvZ2RiL3V0aWxzLmMgYi9nZGIvdXRpbHMuYwppbmRleCAwOTM4 MWQ5MDkyZC4uODljY2NiYmYxZTkgMTAwNjQ0Ci0tLSBhL2dkYi91dGlscy5j CisrKyBiL2dkYi91dGlscy5jCkBAIC0yMjU3LDYgKzIyNTcsMzQgQEAgc2tp cF9hYmlfdGFnIChjb25zdCBjaGFyICoqbmFtZSkKIAogLyogU2VlIHV0aWxz LmguICAqLwogCitib29sCitza2lwX3RlbXBsYXRlX2FyZ3MgKGNvbnN0IGNo YXIgKipuYW1lKQoreworICBjb25zdCBjaGFyICpwID0gKm5hbWU7CisKKyAg aWYgKCpwID09ICdcMCcgfHwgKnAgIT0gJzwnKQorICAgIHJldHVybiBmYWxz ZTsKKworICBwKys7CisgIGludCBkZXB0aCA9IDE7CisKKyAgd2hpbGUgKCpw ICE9ICdcMCcgJiYgZGVwdGggPiAwKQorICAgIHsKKyAgICAgIGlmICgqcCA9 PSAnPCcpCisJZGVwdGgrKzsKKyAgICAgIGVsc2UgaWYgKCpwID09ICc+JykK KwlkZXB0aC0tOworICAgICAgcCsrOworICAgIH0KKworICBpZiAoZGVwdGgg PT0gMCkKKyAgICAqbmFtZSA9IHA7CisKKyAgcmV0dXJuIChkZXB0aCA9PSAw KTsKK30KKworLyogU2VlIHV0aWxzLmguICAqLworCiBpbnQKIHN0cm5jbXBf aXdfd2l0aF9tb2RlIChjb25zdCBjaGFyICpzdHJpbmcxLCBjb25zdCBjaGFy ICpzdHJpbmcyLAogCQkgICAgICBzaXplX3Qgc3RyaW5nMl9sZW4sIHN0cm5j bXBfaXdfbW9kZSBtb2RlLApAQCAtMjMxMSw2ICsyMzM5LDI2IEBAIHN0cm5j bXBfaXdfd2l0aF9tb2RlIChjb25zdCBjaGFyICpzdHJpbmcxLCBjb25zdCBj aGFyICpzdHJpbmcyLAogCSAgICBzdHJpbmcxKys7CiAJfQogCisgICAgICAv KiBTa2lwIHRlbXBsYXRlIGFyZ3MgaW4gdGhlIHN5bWJvbCBuYW1lIGlmIHRo ZSBsb29rdXAgbmFtZQorCSBkb2Vzbid0IGluY2x1ZGUgdGhlbS4gIEUuZy46 CisKKwkgc3RyaW5nMTogZnVuY3Rpb248aW50LCBzdGQ6OnZlY3RvcjxpbnQ+ PihpbnQpCisJIHN0cmluZzI6IGZ1bmN0aW9uCisgICAgICAqLworICAgICAg aWYgKGxhbmd1YWdlID09IGxhbmd1YWdlX2NwbHVzCisJICAmJiAoc3RyaW5n MiA9PSBlbmRfc3RyMiB8fCAqc3RyaW5nMiAhPSAnPCcpKQorCXsKKwkgIGNv bnN0IGNoYXIgKnRlbXBsYXRlX3N0YXJ0ID0gc3RyaW5nMTsKKworCSAgYm9v bCBza2lwcGVkID0gc2tpcF90ZW1wbGF0ZV9hcmdzICgmc3RyaW5nMSk7CisK KwkgIGlmIChtYXRjaF9mb3JfbGNkICE9IE5VTEwgJiYgc2tpcHBlZCkKKwkg ICAgbWF0Y2hfZm9yX2xjZC0+bWFya19pZ25vcmVkX3JhbmdlICh0ZW1wbGF0 ZV9zdGFydCwgc3RyaW5nMSk7CisKKwkgIHdoaWxlIChpc3NwYWNlICgqc3Ry aW5nMSkpCisJICAgIHN0cmluZzErKzsKKwl9CisKICAgICAgIGlmICgqc3Ry aW5nMSA9PSAnXDAnIHx8IHN0cmluZzIgPT0gZW5kX3N0cjIpCiAJYnJlYWs7 CiAKZGlmZiAtLWdpdCBhL2dkYi91dGlscy5oIGIvZ2RiL3V0aWxzLmgKaW5k ZXggYzcyODQ0OTQyOWUuLjIxZTM0Y2ZlYzZiIDEwMDY0NAotLS0gYS9nZGIv dXRpbHMuaAorKysgYi9nZGIvdXRpbHMuaApAQCAtODksNiArODksMTkgQEAg ZXh0ZXJuIGludCBzdHJjbXBfaXcgKGNvbnN0IGNoYXIgKnN0cmluZzEsIGNv bnN0IGNoYXIgKnN0cmluZzIpOwogCiBleHRlcm4gaW50IHN0cmNtcF9pd19v cmRlcmVkIChjb25zdCBjaGFyICosIGNvbnN0IGNoYXIgKik7CiAKKy8qIElm ICpOQU1FIHBvaW50cyBhdCB0ZW1wbGF0ZSBhcmdzLCBza2lwIGl0IGFuZCBy ZXR1cm4gdHJ1ZS4gIE90aGVyd2lzZQorICAgbGVhdmUgKk5BTUUgdW5tb2Rp ZmllZCBhbmQgcmV0dXJuIGZhbHNlLiAgRS5nLiwKKyAgIEJlZm9yZTogICAi PGludCwgc3RkOjp2ZWN0b3I8aW50Pj4oaW50KSIuCisgICAgICAqTkFNRSAt LV4KKyAgIEFmdGVyOiAgICAiPGludCwgc3RkOjp2ZWN0b3I8aW50Pj4oaW50 KSIuCisgICAgICAqTkFNRSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXgor CisgICBJZiB0aGUgYW5nbGUgYnJhY2tldHMgYXJlIG5vdCBiYWxhbmNlZCwg Kk5BTUUgaXMgdW5tb2RpZmllZCwgYW5kIHRoZQorICAgcmV0dXJuIHZhbHVl IGlzIGZhbHNlLiAgVGhpcyBjb3VsZCBiZSB0aGUgY2FzZSwgZm9yIGluc3Rh bmNlLCBpZiAqTkFNRQorICAgcG9pbnRzIHRvIHRoZSBmaXJzdCAnPCcgaW5z aWRlICJvcGVyYXRvcjw8KC4uLikiLiAgKi8KKworZXh0ZXJuIGJvb2wgc2tp cF90ZW1wbGF0ZV9hcmdzIChjb25zdCBjaGFyICoqbmFtZSk7CisKIC8qIFJl dHVybiB0cnVlIGlmIHRoZSBzdHJpbmdzIGFyZSBlcXVhbC4gICovCiAKIGV4 dGVybiBib29sIHN0cmVxIChjb25zdCBjaGFyICosIGNvbnN0IGNoYXIgKik7 Cg== --_002_B98F7326B8E238409968F562D326E1A90D03B27BIRSMSX103gercor_--