libcpp: preserve ranges within macro expansions (PR c++/79300)
authorDavid Malcolm <dmalcolm@redhat.com>
Fri, 7 Jul 2017 18:49:09 +0000 (18:49 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Fri, 7 Jul 2017 18:49:09 +0000 (18:49 +0000)
gcc/testsuite/ChangeLog:
PR c++/79300
* g++.dg/diagnostic/pr79300.C: New test case.

libcpp/ChangeLog:
PR c++/79300
* line-map.c (linemap_macro_loc_to_def_point): Preserve range
information for macro expansions by delaying resolving ad-hoc
locations until within the loop.

From-SVN: r250058

gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/diagnostic/pr79300.C [new file with mode: 0644]
libcpp/ChangeLog
libcpp/line-map.c

index b2e43ef..73db4a7 100644 (file)
@@ -1,3 +1,8 @@
+2017-07-07  David Malcolm  <dmalcolm@redhat.com>
+
+       PR c++/79300
+       * g++.dg/diagnostic/pr79300.C: New test case.
+
 2017-07-07  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * gcc.target/powerpc/clone1.c: Add check to make sure the
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr79300.C b/gcc/testsuite/g++.dg/diagnostic/pr79300.C
new file mode 100644 (file)
index 0000000..6805e85
--- /dev/null
@@ -0,0 +1,44 @@
+// { dg-options "-fdiagnostics-show-caret" }
+
+#define TEST_1_DEPTH_0 throw bad_alloc; // { dg-line define_TEST_1_DEPTH_0 }
+
+void test_1 ()
+{
+  TEST_1_DEPTH_0 // { dg-line use_TEST_1_DEPTH_0 }
+}
+
+// { dg-error "'bad_alloc' was not declared in this scope" "" { target *-*-* } define_TEST_1_DEPTH_0 }
+/* { dg-begin-multiline-output "" }
+ #define TEST_1_DEPTH_0 throw bad_alloc;
+                              ^~~~~~~~~
+   { dg-end-multiline-output "" } */
+// { dg-message "in expansion of macro 'TEST_1_DEPTH_0'" "" { target *-*-* } use_TEST_1_DEPTH_0 }
+/* { dg-begin-multiline-output "" }
+   TEST_1_DEPTH_0
+   ^~~~~~~~~~~~~~
+   { dg-end-multiline-output "" } */
+
+
+#define TEST_2_DEPTH_0 throw bad_alloc; // { dg-line define_TEST_2_DEPTH_0 }
+#define TEST_2_DEPTH_1 TEST_2_DEPTH_0 // { dg-line define_TEST_2_DEPTH_1 }
+
+void test_2 ()
+{
+  TEST_2_DEPTH_1 // { dg-line use_TEST_2_DEPTH_1 }
+}
+
+// { dg-error "'bad_alloc' was not declared in this scope" "" { target *-*-* } define_TEST_2_DEPTH_0 }
+/* { dg-begin-multiline-output "" }
+ #define TEST_2_DEPTH_0 throw bad_alloc;
+                              ^~~~~~~~~
+   { dg-end-multiline-output "" } */
+// { dg-message "in expansion of macro 'TEST_2_DEPTH_0'" "" { target *-*-* } define_TEST_2_DEPTH_1 }
+/* { dg-begin-multiline-output "" }
+ #define TEST_2_DEPTH_1 TEST_2_DEPTH_0
+                        ^~~~~~~~~~~~~~
+   { dg-end-multiline-output "" } */
+// { dg-message "in expansion of macro 'TEST_2_DEPTH_1'" "" { target *-*-* } use_TEST_2_DEPTH_1 }
+/* { dg-begin-multiline-output "" }
+   TEST_2_DEPTH_1
+   ^~~~~~~~~~~~~~
+   { dg-end-multiline-output "" } */
index d080b01..cf6f924 100644 (file)
@@ -1,3 +1,10 @@
+2017-07-07  David Malcolm  <dmalcolm@redhat.com>
+
+       PR c++/79300
+       * line-map.c (linemap_macro_loc_to_def_point): Preserve range
+       information for macro expansions by delaying resolving ad-hoc
+       locations until within the loop.
+
 2017-07-06  David Malcolm  <dmalcolm@redhat.com>
 
        PR c++/79300
index 3b65a46..0e5804b 100644 (file)
@@ -1440,21 +1440,23 @@ linemap_macro_loc_to_def_point (struct line_maps *set,
 {
   struct line_map *map;
 
-  if (IS_ADHOC_LOC (location))
-    location = set->location_adhoc_data_map.data[location
-                                                & MAX_SOURCE_LOCATION].locus;
-
   linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
 
   while (true)
     {
-      map = const_cast <line_map *> (linemap_lookup (set, location));
+      source_location caret_loc;
+      if (IS_ADHOC_LOC (location))
+       caret_loc = get_location_from_adhoc_loc (set, location);
+      else
+       caret_loc = location;
+
+      map = const_cast <line_map *> (linemap_lookup (set, caret_loc));
       if (!linemap_macro_expansion_map_p (map))
        break;
 
       location =
        linemap_macro_map_loc_to_def_point (linemap_check_macro (map),
-                                           location);
+                                           caret_loc);
     }
 
   if (original_map)