diagnostics: fix end-points of ranges within macros (PR c++/79300)
authorDavid Malcolm <dmalcolm@redhat.com>
Thu, 6 Jul 2017 14:17:24 +0000 (14:17 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Thu, 6 Jul 2017 14:17:24 +0000 (14:17 +0000)
gcc/ChangeLog:
PR c++/79300
* diagnostic-show-locus.c (layout::layout): Use start and finish
spelling location for the start and finish of each range.
* genmatch.c (linemap_client_expand_location_to_spelling_point):
Add unused aspect param.
* input.c (expand_location_1): Add "aspect" param, and use it
to access the correct part of the location.
(expand_location): Pass LOCATION_ASPECT_CARET to new param of
expand_location_1.
(expand_location_to_spelling_point): Likewise.
(linemap_client_expand_location_to_spelling_point): Add "aspect"
param, and pass it to expand_location_1.

gcc/testsuite/ChangeLog:
PR c++/79300
* c-c++-common/Wmisleading-indentation-3.c (fn_14): Update
expected underlining within macro expansion.
* c-c++-common/pr70264.c: Likewise.
* g++.dg/plugin/diagnostic-test-expressions-1.C
(test_within_macro_1): New test.
(test_within_macro_2): Likewise.
(test_within_macro_3): Likewise.
(test_within_macro_4): Likewise.
* gcc.dg/format/diagnostic-ranges.c (test_macro_3): Update
expected underlining within macro expansion.
(test_macro_4): Likewise.
* gcc.dg/plugin/diagnostic-test-expressions-1.c
(test_within_macro_1): New test.
(test_within_macro_2): Likewise.
(test_within_macro_3): Likewise.
(test_within_macro_4): Likewise.
* gcc.dg/spellcheck-fields-2.c (test_macro): Update expected
underlining within macro expansion.

libcpp/ChangeLog:
PR c++/79300
* include/line-map.h (enum location_aspect): New enum.
(linemap_client_expand_location_to_spelling_point): Add
enum location_aspect param.
* line-map.c (rich_location::get_expanded_location): Update for
new param of linemap_client_expand_location_to_spelling_point.
(rich_location::maybe_add_fixit): Likewise.
(fixit_hint::affects_line_p): Likewise.

From-SVN: r250022

14 files changed:
gcc/ChangeLog
gcc/diagnostic-show-locus.c
gcc/genmatch.c
gcc/input.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wmisleading-indentation-3.c
gcc/testsuite/c-c++-common/pr70264.c
gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C
gcc/testsuite/gcc.dg/format/diagnostic-ranges.c
gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c
gcc/testsuite/gcc.dg/spellcheck-fields-2.c
libcpp/ChangeLog
libcpp/include/line-map.h
libcpp/line-map.c

index 49efdcd26b9424f150e2fa195360064f89b52694..14d34098a2b873324c726e82e3c5aa088416f4d9 100644 (file)
@@ -1,3 +1,18 @@
+2017-07-06  David Malcolm  <dmalcolm@redhat.com>
+
+       PR c++/79300
+       * diagnostic-show-locus.c (layout::layout): Use start and finish
+       spelling location for the start and finish of each range.
+       * genmatch.c (linemap_client_expand_location_to_spelling_point):
+       Add unused aspect param.
+       * input.c (expand_location_1): Add "aspect" param, and use it
+       to access the correct part of the location.
+       (expand_location): Pass LOCATION_ASPECT_CARET to new param of
+       expand_location_1.
+       (expand_location_to_spelling_point): Likewise.
+       (linemap_client_expand_location_to_spelling_point): Add "aspect"
+       param, and pass it to expand_location_1.
+
 2017-07-06  Sebastian Peryt  <sebastian.peryt@intel.com>
 
        * config/i386/avx512fintrin.h (_mm_mask_getexp_round_ss,
index 8bf4d9e2c85e1945b5e8fe8b66d4cccaf7e04ed3..8a4fd5f17dc8a4e41c91f85d4ebb6333faae23dc 100644 (file)
@@ -788,11 +788,14 @@ layout::layout (diagnostic_context * context,
 
       /* Expand the various locations.  */
       expanded_location start
-       = linemap_client_expand_location_to_spelling_point (src_range.m_start);
+       = linemap_client_expand_location_to_spelling_point
+           (src_range.m_start, LOCATION_ASPECT_START);
       expanded_location finish
-       = linemap_client_expand_location_to_spelling_point (src_range.m_finish);
+       = linemap_client_expand_location_to_spelling_point
+           (src_range.m_finish, LOCATION_ASPECT_FINISH);
       expanded_location caret
-       = linemap_client_expand_location_to_spelling_point (loc_range->m_loc);
+       = linemap_client_expand_location_to_spelling_point
+           (loc_range->m_loc, LOCATION_ASPECT_CARET);
 
       /* If any part of the range isn't in the same file as the primary
         location of this diagnostic, ignore the range.  */
index f20e39f91587c9a391abb821403fd6c21d09811c..7045bb9103c24340ff0330edec8f66ada6b3e503 100644 (file)
@@ -61,7 +61,8 @@ static struct line_maps *line_table;
    This is the implementation for genmatch.  */
 
 expanded_location
-linemap_client_expand_location_to_spelling_point (source_location loc)
+linemap_client_expand_location_to_spelling_point (source_location loc,
+                                                 enum location_aspect)
 {
   const struct line_map_ordinary *map;
   loc = linemap_resolve_location (line_table, loc, LRK_SPELLING_LOCATION, &map);
index 80718100d0c5fac5baf22d8518aebad0788f89f3..0480eb24ec01b51c8353258db8c3cf59e6b66931 100644 (file)
@@ -147,11 +147,14 @@ static const size_t fcache_line_record_size = 100;
    associated line/column) in the context of a macro expansion, the
    returned location is the first one (while unwinding the macro
    location towards its expansion point) that is in real source
-   code.  */
+   code.
+
+   ASPECT controls which part of the location to use.  */
 
 static expanded_location
 expand_location_1 (source_location loc,
-                  bool expansion_point_p)
+                  bool expansion_point_p,
+                  enum location_aspect aspect)
 {
   expanded_location xloc;
   const line_map_ordinary *map;
@@ -181,8 +184,36 @@ expand_location_1 (source_location loc,
                                                          loc, NULL);
          lrk = LRK_SPELLING_LOCATION;
        }
-      loc = linemap_resolve_location (line_table, loc,
-                                     lrk, &map);
+      loc = linemap_resolve_location (line_table, loc, lrk, &map);
+
+      /* loc is now either in an ordinary map, or is a reserved location.
+        If it is a compound location, the caret is in a spelling location,
+        but the start/finish might still be a virtual location.
+        Depending of what the caller asked for, we may need to recurse
+        one level in order to resolve any virtual locations in the
+        end-points.  */
+      switch (aspect)
+       {
+       default:
+         gcc_unreachable ();
+         /* Fall through.  */
+       case LOCATION_ASPECT_CARET:
+         break;
+       case LOCATION_ASPECT_START:
+         {
+           source_location start = get_start (loc);
+           if (start != loc)
+             return expand_location_1 (start, expansion_point_p, aspect);
+         }
+         break;
+       case LOCATION_ASPECT_FINISH:
+         {
+           source_location finish = get_finish (loc);
+           if (finish != loc)
+             return expand_location_1 (finish, expansion_point_p, aspect);
+         }
+         break;
+       }
       xloc = linemap_expand_location (line_table, map, loc);
     }
 
@@ -773,7 +804,8 @@ is_location_from_builtin_token (source_location loc)
 expanded_location
 expand_location (source_location loc)
 {
-  return expand_location_1 (loc, /*expansion_point_p=*/true);
+  return expand_location_1 (loc, /*expansion_point_p=*/true,
+                           LOCATION_ASPECT_CARET);
 }
 
 /* Expand the source location LOC into a human readable location.  If
@@ -785,7 +817,8 @@ expand_location (source_location loc)
 expanded_location
 expand_location_to_spelling_point (source_location loc)
 {
-  return expand_location_1 (loc, /*expansion_point_p=*/false);
+  return expand_location_1 (loc, /*expansion_point_p=*/false,
+                           LOCATION_ASPECT_CARET);
 }
 
 /* The rich_location class within libcpp requires a way to expand
@@ -795,12 +828,13 @@ expand_location_to_spelling_point (source_location loc)
    to do this.
 
    This is the implementation for libcommon.a (all host binaries),
-   which simply calls into expand_location_to_spelling_point.  */
+   which simply calls into expand_location_1.  */
 
 expanded_location
-linemap_client_expand_location_to_spelling_point (source_location loc)
+linemap_client_expand_location_to_spelling_point (source_location loc,
+                                                 enum location_aspect aspect)
 {
-  return expand_location_to_spelling_point (loc);
+  return expand_location_1 (loc, /*expansion_point_p=*/false, aspect);
 }
 
 
index f4f2c0f17ec17754a07738356c6f2ddb73c0d017..910f30284a8a60d79bf6bf8d1cdd88d047b71729 100644 (file)
@@ -1,3 +1,25 @@
+2017-07-06  David Malcolm  <dmalcolm@redhat.com>
+
+       PR c++/79300
+       * c-c++-common/Wmisleading-indentation-3.c (fn_14): Update
+       expected underlining within macro expansion.
+       * c-c++-common/pr70264.c: Likewise.
+       * g++.dg/plugin/diagnostic-test-expressions-1.C
+       (test_within_macro_1): New test.
+       (test_within_macro_2): Likewise.
+       (test_within_macro_3): Likewise.
+       (test_within_macro_4): Likewise.
+       * gcc.dg/format/diagnostic-ranges.c (test_macro_3): Update
+       expected underlining within macro expansion.
+       (test_macro_4): Likewise.
+       * gcc.dg/plugin/diagnostic-test-expressions-1.c
+       (test_within_macro_1): New test.
+       (test_within_macro_2): Likewise.
+       (test_within_macro_3): Likewise.
+       (test_within_macro_4): Likewise.
+       * gcc.dg/spellcheck-fields-2.c (test_macro): Update expected
+       underlining within macro expansion.
+
 2017-07-06  Sebastian Peryt  <sebastian.peryt@intel.com>
 
        * gcc.target/i386/avx512f-vgetexpsd-1.c (_mm_mask_getexp_sd,
index 6482b006c7fc7f05ca9fdd9e55c8f54547f219b5..870ba720c5f143aa3fb1040ee61e04b801a558b9 100644 (file)
@@ -68,7 +68,7 @@ void fn_14 (void)
 
 /* { dg-begin-multiline-output "" }
    for ((VAR) = (START); (VAR) < (STOP); (VAR++))
-   ^
+   ^~~
    { dg-end-multiline-output "" } */
 /* { dg-begin-multiline-output "" }
    FOR_EACH (i, 0, 10)
index 815aad175e53bc8fa35ba0836616ec124ac95218..c446942d0b8d2ff42fac62fe1ac1a20dba0e971f 100644 (file)
@@ -5,7 +5,7 @@ X
 
 /* { dg-begin-multiline-output "" }
  #define X __LINE__
-           ^
+           ^~~~~~~~
    { dg-end-multiline-output "" } */
 /* { dg-begin-multiline-output "" }
  X
index 62d3c361ab71a47b2dd960c8b395240b3fa21c8f..a145dfea28ccd9eab44cb39c399831e1d7e60af4 100644 (file)
@@ -880,3 +880,81 @@ void test_typeid (int i)
                                ~~~~~~~~~~~~^~~
    { dg-end-multiline-output "" } */
 }
+
+/* Various tests of locations involving macros.  */
+
+void test_within_macro_1 (int lhs, int rhs)
+{
+#define MACRO_1(EXPR) EXPR
+
+  __emit_expression_range (0, MACRO_1 (lhs == rhs));
+
+/* { dg-warning "range" "" { target *-*-* } .-2 } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, MACRO_1 (lhs == rhs));
+                                        ~~~~^~~~~~
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+ #define MACRO_1(EXPR) EXPR
+                       ^~~~
+   { dg-end-multiline-output "" } */
+
+#undef MACRO_1
+}
+
+void test_within_macro_2 (int lhs, int rhs)
+{
+#define MACRO_2(EXPR) EXPR
+
+  __emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
+
+/* { dg-warning "range" "" { target *-*-* } .-2 } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
+                                                 ~~~~^~~~~~
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
+                                        ^~~~~~~
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+ #define MACRO_2(EXPR) EXPR
+                       ^~~~
+   { dg-end-multiline-output "" } */
+
+#undef MACRO_2
+}
+
+void test_within_macro_3 (int lhs, int rhs)
+{
+#define MACRO_3(EXPR) EXPR
+
+  __emit_expression_range (0, MACRO_3 (lhs) == MACRO_3 (rhs));
+
+/* { dg-warning "range" "" { target *-*-* } .-2 } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, MACRO_3 (lhs) == MACRO_3 (rhs));
+                                             ^
+   { dg-end-multiline-output "" } */
+
+#undef MACRO_3
+}
+
+void test_within_macro_4 (int lhs, int rhs)
+{
+#define MACRO_4(EXPR) EXPR
+
+  __emit_expression_range (0, MACRO_4 (MACRO_4 (lhs) == MACRO_4 (rhs)));
+
+/* { dg-warning "range" "" { target *-*-* } .-2 } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, MACRO_4 (MACRO_4 (lhs) == MACRO_4 (rhs)));
+                                                      ^
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+ #define MACRO_4(EXPR) EXPR
+                       ^~~~
+   { dg-end-multiline-output "" } */
+
+#undef MACRO_4
+}
index cab30f2d7f6958b290125576f8fde0b88d1580d7..8cce5b38c9f56d2b8b01ffdf51d421bca2732bac 100644 (file)
@@ -278,7 +278,7 @@ void test_macro_3 (const char *msg)
   printf(FMT_STRING, msg);  /* { dg-message "10: in expansion of macro 'FMT_STRING" } */
 /* { dg-begin-multiline-output "" }
  #define FMT_STRING "hello %i world"
-                    ^
+                    ^~~~~~~~~~~~~~~~
    { dg-end-multiline-output "" } */
 /* { dg-begin-multiline-output "" }
    printf(FMT_STRING, msg);
@@ -293,7 +293,7 @@ void test_macro_4 (const char *msg)
   printf(FMT_STRING "\n", msg);  /* { dg-message "10: in expansion of macro 'FMT_STRING" } */
 /* { dg-begin-multiline-output "" }
  #define FMT_STRING "hello %i world"
-                    ^
+                    ^~~~~~~~~~~~~~~~
    { dg-end-multiline-output "" } */
 /* { dg-begin-multiline-output "" }
    printf(FMT_STRING "\n", msg);
index b0dbc05bc1dfa79b3751c9c788a49a3a873ad43d..03b780421076b5d1306feccd7e13cfc8b6115109 100644 (file)
@@ -708,3 +708,82 @@ baz");
  ~~~~                           
    { dg-end-multiline-output "" } */
 }
+
+/* Various tests of locations involving macros.  */
+
+void test_within_macro_1 (int lhs, int rhs)
+{
+#define MACRO_1(EXPR) EXPR
+
+  __emit_expression_range (0, MACRO_1 (lhs == rhs));
+
+/* { dg-warning "range" "" { target *-*-* } .-2 } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, MACRO_1 (lhs == rhs));
+                                        ~~~~^~~~~~
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+ #define MACRO_1(EXPR) EXPR
+                       ^~~~
+   { dg-end-multiline-output "" } */
+
+#undef MACRO_1
+}
+
+void test_within_macro_2 (int lhs, int rhs)
+{
+#define MACRO_2(EXPR) EXPR
+
+  __emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
+
+/* { dg-warning "range" "" { target *-*-* } .-2 } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
+                                                 ~~~~^~~~~~
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
+                                        ^~~~~~~
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+ #define MACRO_2(EXPR) EXPR
+                       ^~~~
+   { dg-end-multiline-output "" } */
+
+#undef MACRO_2
+}
+
+void test_within_macro_3 (int lhs, int rhs)
+{
+#define MACRO_3(EXPR) EXPR
+
+  __emit_expression_range (0, MACRO_3 (lhs) == MACRO_3 (rhs));
+
+/* { dg-warning "range" "" { target *-*-* } .-2 } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, MACRO_3 (lhs) == MACRO_3 (rhs));
+                                             ^
+   { dg-end-multiline-output "" } */
+
+#undef MACRO_3
+}
+
+void test_within_macro_4 (int lhs, int rhs)
+{
+#define MACRO_4(EXPR) EXPR
+
+  __emit_expression_range (0, MACRO_4 (MACRO_4 (lhs) == MACRO_4 (rhs)));
+
+/* { dg-warning "range" "" { target *-*-* } .-2 } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, MACRO_4 (MACRO_4 (lhs) == MACRO_4 (rhs)));
+                                                      ^
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+ #define MACRO_4(EXPR) EXPR
+                       ^~~~
+   { dg-end-multiline-output "" } */
+
+#undef MACRO_4
+}
+
index 7c542145b07b238a948e3a42cc09e50e725b10c2..76684f71c80c8a60271ed082dbc4b9f18d0eb140 100644 (file)
@@ -28,7 +28,7 @@ int test_macro (union u *ptr)
 
 /* { dg-begin-multiline-output "" }
  #define FIELD colour
-               ^
+               ^~~~~~
    { dg-end-multiline-output "" } */
 
 /* { dg-begin-multiline-output "" }
index 526b8023b3886fe679fd7c63be9f355719438db4..d080b0168766b65b19088ef3ac04d62183ccb79e 100644 (file)
@@ -1,3 +1,14 @@
+2017-07-06  David Malcolm  <dmalcolm@redhat.com>
+
+       PR c++/79300
+       * include/line-map.h (enum location_aspect): New enum.
+       (linemap_client_expand_location_to_spelling_point): Add
+       enum location_aspect param.
+       * line-map.c (rich_location::get_expanded_location): Update for
+       new param of linemap_client_expand_location_to_spelling_point.
+       (rich_location::maybe_add_fixit): Likewise.
+       (fixit_hint::affects_line_p): Likewise.
+
 2017-06-21  Jakub Jelinek  <jakub@redhat.com>
 
        * line-map.c (location_adhoc_data_update): Perform addition in
index f5c19e31a9483945374cb3ef5297ce81d72a4763..e6960410c00d36b0962afa130ae5cba9fc9dbbed 100644 (file)
@@ -1905,6 +1905,15 @@ void linemap_dump (FILE *, struct line_maps *, unsigned, bool);
    specifies how many macro maps to dump.  */
 void line_table_dump (FILE *, struct line_maps *, unsigned int, unsigned int);
 
+/* An enum for distinguishing the various parts within a source_location.  */
+
+enum location_aspect
+{
+  LOCATION_ASPECT_CARET,
+  LOCATION_ASPECT_START,
+  LOCATION_ASPECT_FINISH
+};
+
 /* The rich_location class requires a way to expand source_location instances.
    We would directly use expand_location_to_spelling_point, which is
    implemented in gcc/input.c, but we also need to use it for rich_location
@@ -1912,6 +1921,7 @@ void line_table_dump (FILE *, struct line_maps *, unsigned int, unsigned int);
    Hence we require client code of libcpp to implement the following
    symbol.  */
 extern expanded_location
-linemap_client_expand_location_to_spelling_point (source_location );
+linemap_client_expand_location_to_spelling_point (source_location,
+                                                 enum location_aspect);
 
 #endif /* !LIBCPP_LINE_MAP_H  */
index 476a465efa08675ef3a9a76275cad284ef7464ee..3b65a464647f550c2fc3ddac8ef4a125cd0f32cb 100644 (file)
@@ -2066,7 +2066,8 @@ rich_location::get_expanded_location (unsigned int idx)
      if (!m_have_expanded_location)
        {
          m_expanded_location
-           = linemap_client_expand_location_to_spelling_point (get_loc (0));
+           = linemap_client_expand_location_to_spelling_point
+               (get_loc (0), LOCATION_ASPECT_CARET);
          if (m_column_override)
            m_expanded_location.column = m_column_override;
          m_have_expanded_location = true;
@@ -2075,7 +2076,8 @@ rich_location::get_expanded_location (unsigned int idx)
      return m_expanded_location;
    }
   else
-    return linemap_client_expand_location_to_spelling_point (get_loc (idx));
+    return linemap_client_expand_location_to_spelling_point
+            (get_loc (idx), LOCATION_ASPECT_CARET);
 }
 
 /* Set the column of the primary location, with 0 meaning
@@ -2331,9 +2333,11 @@ rich_location::maybe_add_fixit (source_location start,
   /* Only allow fix-it hints that affect a single line in one file.
      Compare the end-points.  */
   expanded_location exploc_start
-    = linemap_client_expand_location_to_spelling_point (start);
+    = linemap_client_expand_location_to_spelling_point (start,
+                                                       LOCATION_ASPECT_START);
   expanded_location exploc_next_loc
-    = linemap_client_expand_location_to_spelling_point (next_loc);
+    = linemap_client_expand_location_to_spelling_point (next_loc,
+                                                       LOCATION_ASPECT_START);
   /* They must be within the same file...  */
   if (exploc_start.file != exploc_next_loc.file)
     {
@@ -2407,13 +2411,15 @@ bool
 fixit_hint::affects_line_p (const char *file, int line) const
 {
   expanded_location exploc_start
-    = linemap_client_expand_location_to_spelling_point (m_start);
+    = linemap_client_expand_location_to_spelling_point (m_start,
+                                                       LOCATION_ASPECT_START);
   if (file != exploc_start.file)
     return false;
   if (line < exploc_start.line)
       return false;
   expanded_location exploc_next_loc
-    = linemap_client_expand_location_to_spelling_point (m_next_loc);
+    = linemap_client_expand_location_to_spelling_point (m_next_loc,
+                                                       LOCATION_ASPECT_START);
   if (file != exploc_next_loc.file)
     return false;
   if (line > exploc_next_loc.line)