aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2015-11-20 20:08:47 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2015-11-20 20:08:47 +0000
commita87a86e1e97610650fb4305edc76a8f4a399a46e (patch)
treef65f921f35a1b100513886cbde83b0f1b31e72d9 /gcc/c
parent48a78aee68fe0d88f01fcdef61782b4f8008f651 (diff)
downloadgcc-a87a86e1e97610650fb4305edc76a8f4a399a46e.zip
gcc-a87a86e1e97610650fb4305edc76a8f4a399a46e.tar.gz
gcc-a87a86e1e97610650fb4305edc76a8f4a399a46e.tar.bz2
PR 62314: add ability to add fixit-hints to a diagnostic
This is the combination of two patches: [PATCH 01/02] PR/62314: add ability to add fixit-hints [PATCH 02/02] C FE: add fix-it hint for . vs -> gcc/ChangeLog: PR 62314 * diagnostic-show-locus.c (colorizer::set_fixit_hint): New. (class layout): Update comment (layout::print_any_fixits): New method. (layout::move_to_column): New method. (diagnostic_show_locus): Add call to layout.print_any_fixits. gcc/c/ChangeLog: PR 62314 * c-typeck.c (should_suggest_deref_p): New function. (build_component_ref): Special-case POINTER_TYPE when generating a "not a structure of union" error message, and suggest a "->" rather than a ".", providing a fix-it hint. gcc/testsuite/ChangeLog: PR 62314 * gcc.dg/fixits.c: New file. * gcc.dg/plugin/diagnostic-test-show-locus-ascii-bw.c (test_fixit_insert): New. (test_fixit_remove): New. (test_fixit_replace): New. * gcc.dg/plugin/diagnostic-test-show-locus-ascii-color.c (test_fixit_insert): New. (test_fixit_remove): New. (test_fixit_replace): New. * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c (test_show_locus): Add tests of rendering fixit hints. libcpp/ChangeLog: PR 62314 * include/line-map.h (source_range::intersects_line_p): New method. (rich_location::~rich_location): New. (rich_location::add_fixit_insert): New method. (rich_location::add_fixit_remove): New method. (rich_location::add_fixit_replace): New method. (rich_location::get_num_fixit_hints): New accessor. (rich_location::get_fixit_hint): New accessor. (rich_location::MAX_FIXIT_HINTS): New constant. (rich_location::m_num_fixit_hints): New field. (rich_location::m_fixit_hints): New field. (class fixit_hint): New class. (class fixit_insert): New class. (class fixit_remove): New class. (class fixit_replace): New class. * line-map.c (source_range::intersects_line_p): New method. (rich_location::rich_location): Add initialization of m_num_fixit_hints to both ctors. (rich_location::~rich_location): New. (rich_location::add_fixit_insert): New method. (rich_location::add_fixit_remove): New method. (rich_location::add_fixit_replace): New method. (fixit_insert::fixit_insert): New. (fixit_insert::~fixit_insert): New. (fixit_insert::affects_line_p): New. (fixit_remove::fixit_remove): New. (fixit_remove::affects_line_p): New. (fixit_replace::fixit_replace): New. (fixit_replace::~fixit_replace): New. (fixit_replace::affects_line_p): New. From-SVN: r230674
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog8
-rw-r--r--gcc/c/c-typeck.c39
2 files changed, 47 insertions, 0 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 9399053..96c5823 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,11 @@
+2015-11-20 David Malcolm <dmalcolm@redhat.com>
+
+ PR 62314
+ * c-typeck.c (should_suggest_deref_p): New function.
+ (build_component_ref): Special-case POINTER_TYPE when
+ generating a "not a structure of union" error message, and
+ suggest a "->" rather than a ".", providing a fix-it hint.
+
2015-11-19 David Malcolm <dmalcolm@redhat.com>
* c-typeck.c (lookup_field_fuzzy): Move determination of closest
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 9284bfc..741c75c 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -2277,6 +2277,33 @@ lookup_field_fuzzy (tree type, tree component)
return find_closest_identifier (component, &candidates);
}
+/* Support function for build_component_ref's error-handling.
+
+ Given DATUM_TYPE, and "DATUM.COMPONENT", where DATUM is *not* a
+ struct or union, should we suggest "DATUM->COMPONENT" as a hint? */
+
+static bool
+should_suggest_deref_p (tree datum_type)
+{
+ /* We don't do it for Objective-C, since Objective-C 2.0 dot-syntax
+ allows "." for ptrs; we could be handling a failed attempt
+ to access a property. */
+ if (c_dialect_objc ())
+ return false;
+
+ /* Only suggest it for pointers... */
+ if (TREE_CODE (datum_type) != POINTER_TYPE)
+ return false;
+
+ /* ...to structs/unions. */
+ tree underlying_type = TREE_TYPE (datum_type);
+ enum tree_code code = TREE_CODE (underlying_type);
+ if (code == RECORD_TYPE || code == UNION_TYPE)
+ return true;
+ else
+ return false;
+}
+
/* Make an expression to refer to the COMPONENT field of structure or
union value DATUM. COMPONENT is an IDENTIFIER_NODE. LOC is the
location of the COMPONENT_REF. */
@@ -2369,6 +2396,18 @@ build_component_ref (location_t loc, tree datum, tree component)
return ref;
}
+ else if (should_suggest_deref_p (type))
+ {
+ /* Special-case the error message for "ptr.field" for the case
+ where the user has confused "." vs "->". */
+ rich_location richloc (line_table, loc);
+ /* "loc" should be the "." token. */
+ richloc.add_fixit_replace (source_range::from_location (loc), "->");
+ error_at_rich_loc (&richloc,
+ "%qE is a pointer; did you mean to use %<->%>?",
+ datum);
+ return error_mark_node;
+ }
else if (code != ERROR_MARK)
error_at (loc,
"request for member %qE in something not a structure or union",