From: Jason Merrill <jason@redhat.com>
To: Matthias Kretz <m.kretz@gsi.de>, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH v4] c++: Add gnu::diagnose_as attribute
Date: Tue, 17 Aug 2021 11:31:54 -0700 [thread overview]
Message-ID: <f3d3b6db-1e98-b12e-cbb0-f6ed9cbea2b9@redhat.com> (raw)
In-Reply-To: <4019800.7NyaFmOyK0@excalibur>
[-- Attachment #1: Type: text/plain, Size: 9585 bytes --]
On 7/23/21 4:58 AM, Matthias Kretz wrote:
> Hi Jason,
Hi, thanks for your patience; I've been out on PTO a lot in the last
month, and will be again this week.
> I found a few regressions from the last patch in the meantime. Version 4 of
> the patch is attached.
>
> Questions:
>
> 1. I simplified the condition for calling dump_template_parms in
> dump_function_name. !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t) is
> equivalent to DECL_USE_TEMPLATE (t) in this context; implying that
> dump_template_parms is unconditionally called with `primary = false`. Or am I
> missing something?
Ah, good catch. That suggests that
DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION gives false positives;
DECL_USE_TEMPLATE is also 0 for template patterns themselves, which
would be why for
template <class T>
void f() { foo; }
the error refers to 'void f()' rather than 'void f<T>()'
The macro should probably also check DECL_FRIEND_CONTEXT.
And then the use of !DECL_USE_TEMPLATE is intending to check whether t
is a primary template pattern, and pass true in that case. This would
be more correct if it also checked instantiates_primary_template_p.
> 2. Given a DECL_TI_ARGS tree, can I query whether an argument was deduced or
> explicitly specified? I'm asking because I still consider diagnostics of
> function templates unfortunate. `template <class T> void f()` is fine, as is
> `void f(T) [with T = float]`, but `void f() [with T = float]` could be better.
> I.e. if the template parameter appears somewhere in the function parameter
> list, dump_template_parms would only produce noise. If, however, the template
> parameter was given explicitly, it would be nice if it could show up
> accordingly in diagnostics.
NON_DEFAULT_TEMPLATE_ARGS_COUNT has that information, though there are
some issues with it. Attached is my WIP from May to improve it
somewhat, if that's interesting.
> 3. When parsing tentatively and the parse is rejected, input_location is not
> reset, correct? In the attached patch I therefore made
> cp_parser_namespace_alias_definition reset input_location on a failed
> tentative parse. But it feels wrong. Shouldn't input_location be restored on
> cp_parser_parse_definitely?
Makes sense, I guess cp_lexer_rollback_tokens should call
cp_lexer_set_source_position_from_token.
I'll look at the patch soon.
> --
>
> This attribute overrides the diagnostics output string for the entity it
> appertains to. The motivation is to improve QoI for library TS
> implementations, where diagnostics have a very bad signal-to-noise ratio
> due to the long namespaces involved.
>
> With the attribute, it is possible to solve PR89370 and make
> std::__cxx11::basic_string<_CharT, _Traits, _Alloc> appear as
> std::string in diagnostic output without extra hacks to recognize the
> type in the C++ frontend.
>
> Signed-off-by: Matthias Kretz <m.kretz@gsi.de>
>
> gcc/ChangeLog:
>
> PR c++/89370
> * doc/extend.texi: Document the diagnose_as attribute.
> * doc/invoke.texi: Document -fno-diagnostics-use-aliases.
>
> gcc/c-family/ChangeLog:
>
> PR c++/89370
> * c.opt (fdiagnostics-use-aliases): New diagnostics flag.
>
> gcc/cp/ChangeLog:
>
> PR c++/89370
> * cp-tree.h: Add is_alias_template_p declaration.
> * decl2.c (is_alias_template_p): New function. Determines
> whether a given TYPE_DECL is actually an alias template that is
> still missing its template_info.
> (is_late_template_attribute): Decls with diagnose_as attribute
> are early attributes only if they are alias templates.
> * error.c (dump_scope): When printing the name of a namespace,
> look for the diagnose_as attribute. If found, print the
> associated string instead of calling dump_decl.
> (dump_decl_name_or_diagnose_as): New function to replace
> dump_decl (pp, DECL_NAME(t), flags) and inspect the tree for the
> diagnose_as attribute before printing the DECL_NAME.
> (dump_template_scope): New function. Prints the scope of a
> template instance correctly applying diagnose_as attributes and
> adjusting the list of template parms accordingly.
> (dump_aggr_type): If the type has a diagnose_as attribute, print
> the associated string instead of printing the original type
> name. Print template parms only if the attribute was not applied
> to the instantiation / full specialization. Delay call to
> dump_scope until the diagnose_as attribute is found. If the
> attribute has a second argument, use it to override the context
> passed to dump_scope.
> (dump_simple_decl): Call dump_decl_name_or_diagnose_as instead
> of dump_decl.
> (dump_decl): Ditto.
> (lang_decl_name): Ditto.
> (dump_function_decl): Walk the functions context list to
> determine whether a call to dump_template_scope is required.
> Ensure function templates diagnosed with pretty templates set
> TFF_TEMPLATE_NAME to skip dump_template_parms.
> (dump_function_name): Replace the function's identifier with the
> diagnose_as attribute value, if set. Expand
> DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION to DECL_USE_TEMPLATE
> and consequently call dump_template_parms with primary = false.
> (comparable_template_types_p): Consider the types not a template
> if one carries a diagnose_as attribute.
> (print_template_differences): Replace the identifier with the
> diagnose_as attribute value on the most general template, if it
> is set.
> * name-lookup.c (handle_namespace_attrs): Handle the diagnose_as
> attribute on namespaces. Ensure exactly one string argument.
> Ensure previous diagnose_as attributes used the same name.
> 'diagnose_as' on namespace aliases are forwarded to the original
> namespace. Support no-argument 'diagnose_as' on namespace
> aliases.
> (do_namespace_alias): Add attributes parameter and call
> handle_namespace_attrs.
> * name-lookup.h (do_namespace_alias): Add attributes tree
> parameter.
> * parser.c (cp_parser_declaration): If the next token is
> RID_NAMESPACE, tentatively parse a namespace alias definition.
> If this fails expect a namespace definition.
> (cp_parser_namespace_alias_definition): Allow optional
> attributes before and after the identifier. Fast exit, restoring
> input_location, if the expected CPP_EQ token is missing. Pass
> attributes to do_namespace_alias.
> * tree.c (cxx_attribute_table): Add diagnose_as attribute to the
> table.
> (check_diagnose_as_redeclaration): New function; copied and
> adjusted from check_abi_tag_redeclaration.
> (handle_diagnose_as_attribute): New function; copied and
> adjusted from handle_abi_tag_attribute. If the given *node is a
> TYPE_DECL: allow no argument to the attribute, using DECL_NAME
> instead; apply the attribute to the type on the RHS in place,
> even if the type is complete. Allow 2 arguments when called from
> handle_diagnose_as_attribute. For type aliases, append
> CP_DECL_CONTEXT as second attribute argument when the RHS type
> has a different context. Warn about alias templates without
> matching template arguments. Apply the attribute to the primary
> template type for alias templates.
>
> gcc/testsuite/ChangeLog:
>
> PR c++/89370
> * g++.dg/diagnostic/diagnose-as1.C: New test.
> * g++.dg/diagnostic/diagnose-as2.C: New test.
> * g++.dg/diagnostic/diagnose-as3.C: New test.
> * g++.dg/diagnostic/diagnose-as4.C: New test.
> * g++.dg/diagnostic/diagnose-as5.C: New test.
> * g++.dg/diagnostic/diagnose-as6.C: New test.
> ---
> gcc/c-family/c.opt | 4 +
> gcc/cp/cp-tree.h | 1 +
> gcc/cp/decl2.c | 45 ++++
> gcc/cp/error.c | 247 ++++++++++++++++--
> gcc/cp/name-lookup.c | 52 +++-
> gcc/cp/name-lookup.h | 2 +-
> gcc/cp/parser.c | 41 +--
> gcc/cp/tree.c | 148 +++++++++++
> gcc/doc/extend.texi | 45 ++++
> gcc/doc/invoke.texi | 9 +-
> .../g++.dg/diagnostic/diagnose-as1.C | 213 +++++++++++++++
> .../g++.dg/diagnostic/diagnose-as2.C | 144 ++++++++++
> .../g++.dg/diagnostic/diagnose-as3.C | 152 +++++++++++
> .../g++.dg/diagnostic/diagnose-as4.C | 158 +++++++++++
> .../g++.dg/diagnostic/diagnose-as5.C | 21 ++
> .../g++.dg/diagnostic/diagnose-as6.C | 45 ++++
> 16 files changed, 1291 insertions(+), 36 deletions(-)
> create mode 100644 gcc/testsuite/g++.dg/diagnostic/diagnose-as1.C
> create mode 100644 gcc/testsuite/g++.dg/diagnostic/diagnose-as2.C
> create mode 100644 gcc/testsuite/g++.dg/diagnostic/diagnose-as3.C
> create mode 100644 gcc/testsuite/g++.dg/diagnostic/diagnose-as4.C
> create mode 100644 gcc/testsuite/g++.dg/diagnostic/diagnose-as5.C
> create mode 100644 gcc/testsuite/g++.dg/diagnostic/diagnose-as6.C
>
[-- Attachment #2: 0001-default.patch --]
[-- Type: text/x-patch, Size: 5751 bytes --]
From 857e349f43a59c88634664ec8635ae49dd7bd50f Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Thu, 27 May 2021 14:04:45 -0400
Subject: [PATCH] default
To: gcc-patches@gcc.gnu.org
---
gcc/cp/error.c | 13 +++++++------
gcc/cp/pt.c | 44 +++++++++++++++++++++++++++-----------------
2 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 9cb8bfc413e..cac4d3e2089 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -87,8 +87,6 @@ static void dump_exception_spec (cxx_pretty_printer *, tree, int);
static void dump_template_argument (cxx_pretty_printer *, tree, int);
static void dump_template_argument_list (cxx_pretty_printer *, tree, int);
static void dump_template_parameter (cxx_pretty_printer *, tree, int);
-static void dump_template_bindings (cxx_pretty_printer *, tree, tree,
- vec<tree, va_gc> *);
static void dump_scope (cxx_pretty_printer *, tree, int);
static void dump_template_parms (cxx_pretty_printer *, tree, int, int);
static int get_non_default_template_args_count (tree, int);
@@ -375,7 +373,7 @@ dump_template_parameter (cxx_pretty_printer *pp, tree parm, int flags)
static void
dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
- vec<tree, va_gc> *typenames)
+ vec<tree, va_gc> *typenames, int flags)
{
/* Print "[with" and ']', conditional on whether anything is printed at all.
This is tied to whether a semicolon is needed to separate multiple template
@@ -425,7 +423,8 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
if (TMPL_ARGS_DEPTH (args) >= lvl)
lvl_args = TMPL_ARGS_LEVEL (args, lvl);
- for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
+ int len = get_non_default_template_args_count (lvl_args, flags);
+ for (i = 0; i < len; ++i)
{
tree arg = NULL_TREE;
@@ -1663,7 +1662,8 @@ dump_substitution (cxx_pretty_printer *pp,
&& !(flags & TFF_NO_TEMPLATE_BINDINGS))
{
vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL;
- dump_template_bindings (pp, template_parms, template_args, typenames);
+ dump_template_bindings (pp, template_parms, template_args, typenames,
+ flags);
}
}
@@ -3449,7 +3449,8 @@ subst_to_string (tree p)
return "";
dump_template_decl (cxx_pp, TREE_PURPOSE (p), flags);
- dump_substitution (cxx_pp, NULL, tparms, targs, /*flags=*/0);
+ dump_substitution (cxx_pp, NULL, tparms, targs,
+ /*TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS*/0);
return pp_ggc_formatted_text (cxx_pp);
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 0870ccdc9f6..691f1b82535 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2518,7 +2518,7 @@ determine_specialization (tree template_id,
if (candidates)
{
tree fn = TREE_VALUE (candidates);
- *targs_out = copy_node (DECL_TI_ARGS (fn));
+ *targs_out = copy_template_args (DECL_TI_ARGS (fn));
/* Propagate the candidate's constraints to the declaration. */
if (tsk != tsk_template)
@@ -4816,11 +4816,16 @@ template_parms_level_to_args (tree parms)
{
tree a = copy_node (parms);
TREE_TYPE (a) = NULL_TREE;
+ int nondefault = 0;
for (int i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i)
- TREE_VEC_ELT (a, i) = template_parm_to_arg (TREE_VEC_ELT (a, i));
+ {
+ tree elt = TREE_VEC_ELT (a, i);
+ TREE_VEC_ELT (a, i) = template_parm_to_arg (elt);
+ if (!elt || elt == error_mark_node || !TREE_PURPOSE (elt))
+ ++nondefault;
+ }
- if (CHECKING_P)
- SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (a, TREE_VEC_LENGTH (a));
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (a, nondefault);
return a;
}
@@ -13276,8 +13281,9 @@ copy_template_args (tree t)
TREE_VEC_ELT (new_vec, i) = elt;
}
- NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_vec)
- = NON_DEFAULT_TEMPLATE_ARGS_COUNT (t);
+ if (!TMPL_ARGS_HAVE_MULTIPLE_LEVELS (t))
+ NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_vec)
+ = NON_DEFAULT_TEMPLATE_ARGS_COUNT (t);
return new_vec;
}
@@ -22339,9 +22345,17 @@ type_unification_real (tree tparms,
be NULL_TREE or ERROR_MARK_NODE, so we do not need
to explicitly check cxx_dialect here. */
if (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)))
- /* OK, there is a default argument. Wait until after the
- conversion check to do substitution. */
- continue;
+ {
+ /* The position of the first default template argument,
+ is also the number of non-defaulted arguments in TARGS.
+ Record that. */
+ if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
+
+ /* OK, there is a default argument. Wait until after the
+ conversion check to do substitution. */
+ continue;
+ }
/* If the type parameter is a parameter pack, then it will
be deduced to an empty parameter pack. */
@@ -22444,14 +22458,7 @@ type_unification_real (tree tparms,
if (arg == error_mark_node)
return 1;
else if (arg)
- {
- TREE_VEC_ELT (targs, i) = arg;
- /* The position of the first default template argument,
- is also the number of non-defaulted arguments in TARGS.
- Record that. */
- if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
- SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
- }
+ TREE_VEC_ELT (targs, i) = arg;
}
if (saw_undeduced++ == 1)
@@ -24821,6 +24828,9 @@ get_partial_spec_bindings (tree tmpl, tree spec_tmpl, tree args)
if (!template_template_parm_bindings_ok_p (tparms, deduced_args))
return NULL_TREE;
+ if (CHECKING_P)
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (deduced_args, ntparms);
+
return deduced_args;
}
--
2.27.0
next prev parent reply other threads:[~2021-08-17 18:32 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-15 12:21 [PATCH v3] " Matthias Kretz
2021-07-23 8:58 ` [PATCH v4] " Matthias Kretz
2021-08-17 18:31 ` Jason Merrill [this message]
2021-11-08 16:40 ` [RFC] c++: Print function template parms when relevant (was: [PATCH v4] c++: Add gnu::diagnose_as attribute) Matthias Kretz
2021-11-08 20:00 ` Matthias Kretz
2021-11-16 20:25 ` Jason Merrill
2021-11-16 20:42 ` Matthias Kretz
2021-11-16 20:49 ` Jason Merrill
2021-11-16 20:51 ` Matthias Kretz
2021-11-17 6:09 ` Jason Merrill
2021-11-17 9:04 ` Matthias Kretz
2021-11-17 18:25 ` Jason Merrill
2021-11-17 22:51 ` Matthias Kretz
2021-11-18 19:24 ` Jason Merrill
2021-11-19 9:53 ` Matthias Kretz
2021-11-19 12:02 ` Matthias Kretz
2021-11-19 22:26 ` Jason Merrill
2021-11-19 23:11 ` Matthias Kretz
2021-11-26 15:23 ` [PATCH 0/2] " Matthias Kretz
2021-11-26 15:24 ` [PATCH 1/2] c++: Print function template parms when relevant Matthias Kretz
2021-12-02 8:35 ` [PATCH v2 " Matthias Kretz
2021-11-26 15:24 ` [PATCH 2/2] c++: Print function template parms when relevant [part 2] Matthias Kretz
2021-09-08 2:21 ` [PATCH v4] c++: Add gnu::diagnose_as attribute Jason Merrill
2021-11-15 0:35 ` [PATCH v5] " Matthias Kretz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f3d3b6db-1e98-b12e-cbb0-f6ed9cbea2b9@redhat.com \
--to=jason@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=m.kretz@gsi.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).