* [PATCH] Offer suggestions for misspelled attributes (PR c/70186)
@ 2016-12-19 16:18 David Malcolm
2016-12-19 16:46 ` Jakub Jelinek
0 siblings, 1 reply; 2+ messages in thread
From: David Malcolm @ 2016-12-19 16:18 UTC (permalink / raw)
To: gcc-patches; +Cc: David Malcolm
Our -Wattributes warnings can be rather cryptic. The following patch
improves this warning:
../../src/pr70186.c:1:8: warning: 'visbility' attribute directive ignored [-Wattributes]
struct S *foo __attribute__ ((visbility("hidden")));
^
by adding suggestions when unrecognized attributes are encountered,
turning it into this:
../../src/pr70186.c:1:8: warning: 'visbility' attribute directive ignored; did you mean 'visibility'? [-Wattributes]
struct S *foo __attribute__ ((visbility("hidden")));
^
Successfully bootstrapped®rtested on x86_64-pc-linux-gnu.
Rather late for gcc 7, sorry. Is this OK for next stage 1,
or OK for stage 3 now? (if this looks low-enough risk)
gcc/ChangeLog:
PR c/70186
* attribs.c: Include "spellcheck.h".
(extract_attribute_substring): Fix leading comment. Return a bool
signifying if truncation for underscores occurred.
(struct edit_distance_traits<struct substring *>): New class.
(fuzzy_lookup_scoped_attribute_spec): New function, based on
lookup_scoped_attribute_spec.
(decl_attributes): Move warning about ignored attributes to..
(warn_about_unidentified_attribute): ...this new function, and
potentially offer suggestions for misspelled attributes.
gcc/testsuite/ChangeLog:
PR c/70186
* c-c++-common/spellcheck-attributes.c: New test case.
* g++.dg/cpp0x/spellcheck-attributes.C: New test case.
---
gcc/attribs.c | 115 ++++++++++++++++++---
gcc/testsuite/c-c++-common/spellcheck-attributes.c | 5 +
gcc/testsuite/g++.dg/cpp0x/spellcheck-attributes.C | 18 ++++
3 files changed, 126 insertions(+), 12 deletions(-)
create mode 100644 gcc/testsuite/c-c++-common/spellcheck-attributes.c
create mode 100644 gcc/testsuite/g++.dg/cpp0x/spellcheck-attributes.C
diff --git a/gcc/attribs.c b/gcc/attribs.c
index e66349a..ff5ce0d 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "stor-layout.h"
#include "langhooks.h"
#include "plugin.h"
+#include "spellcheck.h"
/* Table of the tables of attributes (common, language, format, machine)
searched. */
@@ -97,10 +98,11 @@ static const struct attribute_spec empty_attribute_table[] =
{ NULL, 0, 0, false, false, false, NULL, false }
};
-/* Return base name of the attribute. Ie '__attr__' is turned into 'attr'.
- To avoid need for copying, we simply return length of the string. */
+/* Extract base name of the attribute. Ie '__attr__' is turned into 'attr'.
+ To avoid need for copying, we simply update length of the string.
+ Return true if the string was truncated, false otherwise. */
-static void
+static bool
extract_attribute_substring (struct substring *str)
{
if (str->length > 4 && str->str[0] == '_' && str->str[1] == '_'
@@ -108,7 +110,9 @@ extract_attribute_substring (struct substring *str)
{
str->length -= 4;
str->str += 2;
+ return true;
}
+ return false;
}
/* Insert an array of attributes ATTRIBUTES into a namespace. This
@@ -343,6 +347,101 @@ get_attribute_namespace (const_tree attr)
return get_identifier ("gnu");
}
+/* Specialization of edit_distance_traits for struct substring. */
+
+template <>
+struct edit_distance_traits<struct substring *>
+{
+ static size_t get_length (struct substring *substr)
+ {
+ gcc_assert (substr);
+ return substr->length;
+ }
+
+ static const char *get_string (struct substring *substr)
+ {
+ gcc_assert (substr);
+ return substr->str;
+ }
+};
+
+/* Look for near matches for the scoped attribute with namespace NS and
+ name NAME.
+ Return the best matching attribute name, or NULL if none is found.
+ If it returns non-NULL then *UNDERSCORES is written to, with true
+ iff leading and trailing underscores were stripped from NAME
+ before the match. */
+
+static const char *
+fuzzy_lookup_scoped_attribute_spec (const_tree ns, const_tree name,
+ bool *underscores)
+{
+ struct substring attr;
+ scoped_attributes *attrs;
+
+ const char *ns_str = (ns != NULL_TREE) ? IDENTIFIER_POINTER (ns): NULL;
+
+ attrs = find_attribute_namespace (ns_str);
+
+ if (attrs == NULL)
+ return NULL;
+
+ attr.str = IDENTIFIER_POINTER (name);
+ attr.length = IDENTIFIER_LENGTH (name);
+ *underscores = extract_attribute_substring (&attr);
+
+ best_match <struct substring *, const char *> bm (&attr);
+
+ hash_table<attribute_hasher> *h = attrs->attribute_hash;
+ for (hash_table<attribute_hasher>::iterator iter = h->begin ();
+ iter != h->end (); ++iter)
+ bm.consider ((*iter)->name);
+ return bm.get_best_meaningful_candidate ();
+}
+
+/* Warn about attribute A being unrecognized with name NAME (an identifier),
+ within namespace NS (an identifier, or NULL_TREE).
+ Issue a hint if it appears to be misspelled. */
+
+static void
+warn_about_unidentified_attribute (tree a, tree ns, tree name)
+{
+ bool underscores;
+ const char *hint
+ = fuzzy_lookup_scoped_attribute_spec (ns, name, &underscores);
+
+ if (ns == NULL_TREE || !cxx11_attribute_p (a))
+ if (hint)
+ if (underscores)
+ warning (OPT_Wattributes,
+ ("%qE attribute directive ignored"
+ "; did you mean %<__%s__%>?"),
+ name, hint);
+ else
+ warning (OPT_Wattributes,
+ ("%qE attribute directive ignored"
+ "; did you mean %qs?"),
+ name, hint);
+ else
+ warning (OPT_Wattributes, "%qE attribute directive ignored",
+ name);
+ else
+ if (hint)
+ if (underscores)
+ warning (OPT_Wattributes,
+ ("%<%E::%E%> scoped attribute directive"
+ " ignored; did you mean %<%E::__%s__%>?"),
+ ns, name, ns, hint);
+ else
+ warning (OPT_Wattributes,
+ ("%<%E::%E%> scoped attribute directive ignored"
+ "; did you mean %<%E::%s%>?"),
+ ns, name, ns, hint);
+ else
+ warning (OPT_Wattributes,
+ "%<%E::%E%> scoped attribute directive ignored",
+ ns, name);
+}
/* Process the attributes listed in ATTRIBUTES and install them in *NODE,
which is either a DECL (including a TYPE_DECL) or a TYPE. If a DECL,
@@ -431,15 +530,7 @@ decl_attributes (tree *node, tree attributes, int flags)
if (spec == NULL)
{
if (!(flags & (int) ATTR_FLAG_BUILT_IN))
- {
- if (ns == NULL_TREE || !cxx11_attribute_p (a))
- warning (OPT_Wattributes, "%qE attribute directive ignored",
- name);
- else
- warning (OPT_Wattributes,
- "%<%E::%E%> scoped attribute directive ignored",
- ns, name);
- }
+ warn_about_unidentified_attribute (a, ns, name);
continue;
}
else if (list_length (args) < spec->min_length
diff --git a/gcc/testsuite/c-c++-common/spellcheck-attributes.c b/gcc/testsuite/c-c++-common/spellcheck-attributes.c
new file mode 100644
index 0000000..a0da879
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/spellcheck-attributes.c
@@ -0,0 +1,5 @@
+struct S *s1 __attribute__ ((visbility("hidden")));
+/* { dg-warning ".visbility. attribute directive ignored; did you mean .visibility." "" { target *-*-* } .-1 } */
+
+struct S *s2 __attribute__ ((__visbility__("hidden")));
+/* { dg-warning ".__visbility__. attribute directive ignored; did you mean .__visibility__." "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/g++.dg/cpp0x/spellcheck-attributes.C b/gcc/testsuite/g++.dg/cpp0x/spellcheck-attributes.C
new file mode 100644
index 0000000..ca72608
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/spellcheck-attributes.C
@@ -0,0 +1,18 @@
+// { dg-do compile { target c++11 } }
+
+int
+test ()
+{
+ [[gnu::unused]] lab_1:
+
+ [[gnu::unuse]] lab_2:
+ /* { dg-warning ".gnu::unuse. scoped attribute directive ignored; did you mean .gnu::unused.." "" { target *-*-* } .-1 } */
+ return 0;
+
+ [[gnu::__unused__]] lab_3:
+
+ [[gnu::__unuse__]] lab_4:
+ /* { dg-warning ".gnu::__unuse__. scoped attribute directive ignored; did you mean .gnu::__unused__.." "" { target *-*-* } .-1 } */
+ return 0;
+
+}
--
1.8.5.3
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] Offer suggestions for misspelled attributes (PR c/70186)
2016-12-19 16:18 [PATCH] Offer suggestions for misspelled attributes (PR c/70186) David Malcolm
@ 2016-12-19 16:46 ` Jakub Jelinek
0 siblings, 0 replies; 2+ messages in thread
From: Jakub Jelinek @ 2016-12-19 16:46 UTC (permalink / raw)
To: David Malcolm; +Cc: gcc-patches
Hi!
On Mon, Dec 19, 2016 at 11:51:29AM -0500, David Malcolm wrote:
> +/* Look for near matches for the scoped attribute with namespace NS and
> + name NAME.
> + Return the best matching attribute name, or NULL if none is found.
> + If it returns non-NULL then *UNDERSCORES is written to, with true
> + iff leading and trailing underscores were stripped from NAME
> + before the match. */
> +
> +static const char *
> +fuzzy_lookup_scoped_attribute_spec (const_tree ns, const_tree name,
> + bool *underscores)
> +{
> + struct substring attr;
> + scoped_attributes *attrs;
> +
> + const char *ns_str = (ns != NULL_TREE) ? IDENTIFIER_POINTER (ns): NULL;
> +
> + attrs = find_attribute_namespace (ns_str);
> +
> + if (attrs == NULL)
> + return NULL;
> +
> + attr.str = IDENTIFIER_POINTER (name);
> + attr.length = IDENTIFIER_LENGTH (name);
> + *underscores = extract_attribute_substring (&attr);
> +
> + best_match <struct substring *, const char *> bm (&attr);
> +
> + hash_table<attribute_hasher> *h = attrs->attribute_hash;
> + for (hash_table<attribute_hasher>::iterator iter = h->begin ();
> + iter != h->end (); ++iter)
> + bm.consider ((*iter)->name);
> + return bm.get_best_meaningful_candidate ();
Does this consider the decl_req, type_req and fn_type_req flags in the
attribute tables (i.e. that for attribute on a VAR_DECL it doesn't suggest
attributes that apply to functions only, on FUNCTION_DECL suggest attributes
that apply only to non-function decls, etc.)?
Does it ignore internal only attributes (i.e. attributes containing spaces
or * characters in their names)?
Say
void foo (void) __attribute ((omp_declare_target));
should not suggest the omp declare target attribute, since users can't type
it in.
Jakub
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-12-19 16:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-19 16:18 [PATCH] Offer suggestions for misspelled attributes (PR c/70186) David Malcolm
2016-12-19 16:46 ` Jakub Jelinek
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).