summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/input.c36
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/warn/Wconversion-real-integer-3.C20
-rw-r--r--gcc/testsuite/g++.dg/warn/Wconversion-real-integer2.C33
-rw-r--r--gcc/testsuite/g++.dg/warn/conversion-real-integer-3.h3
-rw-r--r--gcc/tree-diagnostic.c12
-rw-r--r--libcpp/ChangeLog7
-rw-r--r--libcpp/include/line-map.h20
-rw-r--r--libcpp/line-map.c49
10 files changed, 185 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a6e8cbb7778..9ec7dde25fd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2012-04-30 Dodji Seketeli <dodji@redhat.com>
+ Strip "<built-in>" loc from displayed expansion context
+ * input.c (expand_location_1): When expanding to spelling location
+ in a context of a macro expansion, skip reserved system header
+ locations. Update comments. * tree-diagnostic.c
+ (maybe_unwind_expanded_macro_loc): Likewise.
+
Make expand_location resolve to locus in main source file
* input.c (expand_location_1): New. Takes a parameter to choose
whether to resolve the location to spelling or expansion point.
diff --git a/gcc/input.c b/gcc/input.c
index e9ba301c229..260be7e7d55 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -35,7 +35,14 @@ struct line_maps *line_table;
location is set to the string "<built-in>". If EXPANSION_POINT_P is
TRUE and LOC is virtual, then it is resolved to the expansion
point of the involved macro. Otherwise, it is resolved to the
- spelling location of the token. */
+ spelling location of the token.
+
+ When resolving to the spelling location of the token, if the
+ resulting location is for a built-in location (that is, it has no
+ 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. */
static expanded_location
expand_location_1 (source_location loc,
@@ -43,12 +50,29 @@ expand_location_1 (source_location loc,
{
expanded_location xloc;
const struct line_map *map;
+ enum location_resolution_kind lrk = LRK_MACRO_EXPANSION_POINT;
+
+ memset (&xloc, 0, sizeof (xloc));
- loc = linemap_resolve_location (line_table, loc,
- expansion_point_p
- ? LRK_MACRO_EXPANSION_POINT
- : LRK_SPELLING_LOCATION, &map);
- xloc = linemap_expand_location (line_table, map, loc);
+ if (loc >= RESERVED_LOCATION_COUNT)
+ {
+ if (!expansion_point_p)
+ {
+ /* We want to resolve LOC to its spelling location.
+
+ But if that spelling location is a reserved location that
+ appears in the context of a macro expansion (like for a
+ location for a built-in token), let's consider the first
+ location (toward the expansion point) that is not reserved;
+ that is, the first location that is in real source code. */
+ loc = linemap_unwind_to_first_non_reserved_loc (line_table,
+ loc, &map);
+ lrk = LRK_SPELLING_LOCATION;
+ }
+ loc = linemap_resolve_location (line_table, loc,
+ lrk, &map);
+ xloc = linemap_expand_location (line_table, map, loc);
+ }
if (loc <= BUILTINS_LOCATION)
xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ed2779e83ad..71948097024 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2012-04-30 Dodji Seketeli <dodji@redhat.com>
+ Strip "<built-in>" loc from displayed expansion context
+ * g++.dg/warn/Wconversion-real-integer2.C: New test.
+ * g++.dg/warn/Wconversion-real-integer-3.C: Likewise.
+ * g++.dg/warn/conversion-real-integer-3.h: New header used by the
+ new test above.
+
Fix expansion point loc for macro-like tokens
* gcc.dg/debug/dwarf2/pr41445-5.c: Adjust.
* gcc.dg/debug/dwarf2/pr41445-6.c: Likewise.
diff --git a/gcc/testsuite/g++.dg/warn/Wconversion-real-integer-3.C b/gcc/testsuite/g++.dg/warn/Wconversion-real-integer-3.C
new file mode 100644
index 00000000000..a4df0100a71
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wconversion-real-integer-3.C
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-options "-Wconversion -ftrack-macro-expansion=2" }
+// { dg-require-effective-target int32plus }
+
+#include "conversion-real-integer-3.h"
+
+float vfloat;
+
+void h (void)
+{
+ // We want to trigger an error on the token INT_MAX below, that is
+ // a macro that expands to the built-in __INT_MAX__. Furthermore,
+ // INT_MAX is defined inside a system header.
+ //
+ // The behaviour we want is that the diagnostic should point to
+ // the locus that inside the source code here, at the relevant
+ // line below, even with -ftrack-macro-expansion. We don't want
+ // it to point to the any locus that is inside the system header.
+ vfloat = INT_MAX; // { dg-warning "conversion to .float. alters .int. constant value" }
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wconversion-real-integer2.C b/gcc/testsuite/g++.dg/warn/Wconversion-real-integer2.C
new file mode 100644
index 00000000000..29130f1836f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wconversion-real-integer2.C
@@ -0,0 +1,33 @@
+/* { dg-do compile }
+/* { dg-options "-Wconversion -ftrack-macro-expansion=2" } */
+/* { dg-require-effective-target int32plus } */
+
+// Before the fix that came with this test, we'd output an error for
+// the __INT_MAX__ token. That token has a BUILTINS_LOCATION
+// location, so the the location prefix in the warning message would
+// be:
+// <built-in>:0:0: warning: conversion to 'float' alters 'int' constant value
+//
+// Note the useless and confusing <built-in>:0:0 prefix. This is
+// because '__INT_MAX__' being an internal macro token, it has a
+// BUILTINS_LOCATION location.
+//
+// In this case, we want the error message to refer to the first
+// location (in the macro expansion context) that is not a location
+// for a built-in token. That location would be the one for where (in
+// real source code) the __INT_MAX__ macro has been expanded.
+//
+// That would be something like:
+//
+// gcc/testsuite/g++.dg/warn/Wconversion-real-integer2.C:21:17: warning: conversion to 'float' alters 'int' constant value
+//
+// That is more useful.
+
+#define INT_MAX __INT_MAX__ // { dg-warning "conversion to .float. alters .int. constant value" }
+
+float vfloat;
+
+void h (void)
+{
+ vfloat = INT_MAX; // { dg-message "expanded from here" }
+}
diff --git a/gcc/testsuite/g++.dg/warn/conversion-real-integer-3.h b/gcc/testsuite/g++.dg/warn/conversion-real-integer-3.h
new file mode 100644
index 00000000000..6ed5b2c42ab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/conversion-real-integer-3.h
@@ -0,0 +1,3 @@
+#pragma GCC system_header
+
+#define INT_MAX __INT_MAX__
diff --git a/gcc/tree-diagnostic.c b/gcc/tree-diagnostic.c
index 48c78000703..0a55925fb31 100644
--- a/gcc/tree-diagnostic.c
+++ b/gcc/tree-diagnostic.c
@@ -166,6 +166,18 @@ maybe_unwind_expanded_macro_loc (diagnostic_context *context,
linemap_resolve_location (line_table, iter->where,
LRK_MACRO_DEFINITION_LOCATION, NULL);
+ /* Don't print trace for locations that are reserved or from
+ within a system header. */
+ {
+ const struct line_map *m = NULL;
+ source_location l = linemap_resolve_location (line_table, resolved_def_loc,
+ LRK_SPELLING_LOCATION,
+ &m);
+ if (l < RESERVED_LOCATION_COUNT
+ || LINEMAP_SYSP (m))
+ continue;
+ }
+
/* Resolve the location of the expansion point of the macro
which expansion gave the token represented by def_loc.
This is the locus 2/ of the earlier comment. */
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 5e93396ac75..2c05214d4f7 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,5 +1,12 @@
2012-04-30 Dodji Seketeli <dodji@redhat.com>
+ Strip "<built-in>" loc from displayed expansion context
+ * include/line-map.h (linemap_unwind_toward_expansion): Fix typo
+ in comment.
+ (linemap_unwind_to_first_non_reserved_loc): Declare new function.
+ * line-map.c (linemap_unwind_to_first_non_reserved_loc): Define
+ new function.
+
Fix expansion point loc for macro-like tokens
* macro.c (macro_of_context): New static function.
(_cpp_push_token_context, push_extended_tokens_context): If the
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 22e2f0fc3c6..1c81fc52ad7 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -666,12 +666,30 @@ source_location linemap_resolve_location (struct line_maps *,
location L of the point where M got expanded. If L is a spelling
location inside a macro expansion M', then this function returns
the point where M' was expanded. LOC_MAP is an output parameter.
- When non-NULL, *LOC_MAP is set the the map of the returned
+ When non-NULL, *LOC_MAP is set to the map of the returned
location. */
source_location linemap_unwind_toward_expansion (struct line_maps *,
source_location loc,
const struct line_map **loc_map);
+/* If LOC is the virtual location of a token coming from the expansion
+ of a macro M and if its spelling location is reserved (e.g, a
+ location for a built-in token), then this function unwinds (using
+ linemap_unwind_toward_expansion) the location until a location that
+ is not reserved and is not in a system header is reached. In other
+ words, this unwinds the reserved location until a location that is
+ in real source code is reached.
+
+ Otherwise, if the spelling location for LOC is not reserved or if
+ LOC doesn't come from the expansion of a macro, the function
+ returns LOC as is and *MAP is not touched.
+
+ *MAP is set to the map of the returned location if the later is
+ different from LOC. */
+source_location linemap_unwind_to_first_non_reserved_loc (struct line_maps *,
+ source_location loc,
+ const struct line_map **map);
+
/* Expand source code location LOC and return a user readable source
code location. LOC must be a spelling (non-virtual) location. If
it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 106a4b515a7..6e514e5531a 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -1114,6 +1114,55 @@ linemap_unwind_toward_expansion (struct line_maps *set,
return resolved_location;
}
+/* If LOC is the virtual location of a token coming from the expansion
+ of a macro M and if its spelling location is reserved (e.g, a
+ location for a built-in token), then this function unwinds (using
+ linemap_unwind_toward_expansion) the location until a location that
+ is not reserved and is not in a sytem header is reached. In other
+ words, this unwinds the reserved location until a location that is
+ in real source code is reached.
+
+ Otherwise, if the spelling location for LOC is not reserved or if
+ LOC doesn't come from the expansion of a macro, the function
+ returns LOC as is and *MAP is not touched.
+
+ *MAP is set to the map of the returned location if the later is
+ different from LOC. */
+source_location
+linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
+ source_location loc,
+ const struct line_map **map)
+{
+ source_location resolved_loc;
+ const struct line_map *map0 = NULL, *map1 = NULL;
+
+ map0 = linemap_lookup (set, loc);
+ if (!linemap_macro_expansion_map_p (map0))
+ return loc;
+
+ resolved_loc = linemap_resolve_location (set, loc,
+ LRK_SPELLING_LOCATION,
+ &map1);
+
+ if (resolved_loc >= RESERVED_LOCATION_COUNT
+ && !LINEMAP_SYSP (map1))
+ return loc;
+
+ while (linemap_macro_expansion_map_p (map0)
+ && (resolved_loc < RESERVED_LOCATION_COUNT
+ || LINEMAP_SYSP (map1)))
+ {
+ loc = linemap_unwind_toward_expansion (set, loc, &map0);
+ resolved_loc = linemap_resolve_location (set, loc,
+ LRK_SPELLING_LOCATION,
+ &map1);
+ }
+
+ if (map != NULL)
+ *map = map0;
+ return loc;
+}
+
/* Expand source code location LOC and return a user readable source
code location. LOC must be a spelling (non-virtual) location. If
it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source