For built-in macros, the patch is now stepping up until it sees a
location that is not for a built-in macro, and at point, checks if we
are in a system header.

It also uses the location of the '=' operator as the location for
assignment expressions.  I had to adjust a couple of tests due to that change.

Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.

OK for trunk?

libcpp/

        * line-map.c (linemap_location_in_system_header_p): For built-in
        macro tokens, check the first expansion point location for that is
        not for a token coming from a built-in macro.

gcc/cp/

        * parser.c (cp_parser_assignment_expression): Use the location
        for the LHS as the default location for the expression.

gcc/testsuite/

        * g++.dg/cpp/limits.C: New test.
        * g++.dg/parse/error19.C: Adjust.
        * g++.dg/warn/Wconversion-real-integer2.C: Likewise.
        * g++.dg/warn/pr35635.C: Likewise.
        * g++.old-deja/g++.pt/assign1.C: Likewise.
---
 gcc/cp/parser.c                                    |    4 ++-
 gcc/testsuite/g++.dg/cpp/limits.C                  |   21 ++++++++++++++
 gcc/testsuite/g++.dg/parse/error19.C               |    2 +-
 .../g++.dg/warn/Wconversion-real-integer2.C        |    4 +-
 gcc/testsuite/g++.dg/warn/pr35635.C                |    4 +-
 gcc/testsuite/g++.old-deja/g++.pt/assign1.C        |    5 ++-
 libcpp/line-map.c                                  |   30 +++++++++++++++++--
 7 files changed, 58 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp/limits.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 9fd8c84..e393f48 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7491,7 +7491,9 @@ cp_parser_assignment_expression (cp_parser* parser, bool 
cast_p,
              if (cp_parser_non_integral_constant_expression (parser,
                                                              NIC_ASSIGNMENT))
                return error_mark_node;
-             /* Build the assignment expression.  */
+             /* Build the assignment expression.  Its default
+                location is the location of the '=' token.  */
+             input_location = loc;
              expr = build_x_modify_expr (loc, expr,
                                          assignment_operator,
                                          rhs,
diff --git a/gcc/testsuite/g++.dg/cpp/limits.C 
b/gcc/testsuite/g++.dg/cpp/limits.C
new file mode 100644
index 0000000..b64e1e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp/limits.C
@@ -0,0 +1,21 @@
+// { dg-options "-pedantic" }
+// { dg-do compile }
+
+#include <limits>
+
+// Compiling this with -pedantic was wrongly triggering this error:
+// libstdc++-v3/include/limits:1269:45: warning : use of C++0x long long 
integer constant [-Wlong-long]
+//       min() _GLIBCXX_USE_NOEXCEPT { return -__LONG_LONG_MAX__ - 1; }
+//                                             ^
+// libstdc++-v3/include/limits:1272:44: warning : use of C++0x long long 
integer constant [-Wlong-long]
+//       max() _GLIBCXX_USE_NOEXCEPT { return __LONG_LONG_MAX__; }
+//                                            ^
+// libstdc++-v3/include/limits:1342:44: warning : use of C++0x long long 
integer constant [-Wlong-long]
+//       max() _GLIBCXX_USE_NOEXCEPT { return __LONG_LONG_MAX__ * 2ULL + 1
+//                                            ^
+
+int
+main ()
+{
+    return 0;
+}
diff --git a/gcc/testsuite/g++.dg/parse/error19.C 
b/gcc/testsuite/g++.dg/parse/error19.C
index 010a403..6d84f71 100644
--- a/gcc/testsuite/g++.dg/parse/error19.C
+++ b/gcc/testsuite/g++.dg/parse/error19.C
@@ -10,6 +10,6 @@ const A& foo();
 
 void bar()
 {
-  foo()=A(0); // { dg-error "12:no match for 'operator='" }
+  foo()=A(0); // { dg-error "8:no match for 'operator='" }
   // { dg-message "candidate" "candidate note" { target *-*-* } 13 }
 }
diff --git a/gcc/testsuite/g++.dg/warn/Wconversion-real-integer2.C 
b/gcc/testsuite/g++.dg/warn/Wconversion-real-integer2.C
index 6a95b0e..0494588 100644
--- a/gcc/testsuite/g++.dg/warn/Wconversion-real-integer2.C
+++ b/gcc/testsuite/g++.dg/warn/Wconversion-real-integer2.C
@@ -23,11 +23,11 @@
 //
 // That is more useful.
 
-#define INT_MAX __INT_MAX__ // { dg-warning "conversion to .float. alters 
.int. constant value" }
+#define INT_MAX __INT_MAX__ 
 
 float  vfloat;
 
 void h (void)
 {
-    vfloat = INT_MAX; // { dg-message "in expansion of macro 'INT_MAX'" }
+    vfloat = INT_MAX; // { dg-warning "conversion to .float. alters .int. 
constant value" }
 }
diff --git a/gcc/testsuite/g++.dg/warn/pr35635.C 
b/gcc/testsuite/g++.dg/warn/pr35635.C
index 66ade8b..de68ceb 100644
--- a/gcc/testsuite/g++.dg/warn/pr35635.C
+++ b/gcc/testsuite/g++.dg/warn/pr35635.C
@@ -62,9 +62,9 @@ void func3()
   /* At least one branch of ? does not fit in the destination, thus
      warn.  */
   uchar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */
-  uchar_x = bar != 0 
+  uchar_x = bar != 0  /* { dg-warning "negative integer implicitly converted 
to unsigned type" } */
     ? (unsigned char) 1024 
-    : -1; /* { dg-warning "negative integer implicitly converted to unsigned 
type" } */
+    : -1; 
 }
 
 void func4()
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/assign1.C 
b/gcc/testsuite/g++.old-deja/g++.pt/assign1.C
index 854d8ee..951d882 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/assign1.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/assign1.C
@@ -2,7 +2,8 @@
 // Origin: Mark Mitchell <m...@codesourcery.com>
 
 template <class T>
-struct S {                     // { dg-error "const|operator=" }
+struct S {  // { dg-message "operator=\[\n\r\]*is implicitly deleted" { target 
c++11 } 5 }
+            // { dg-error "const|operator=" "" { target *-*-* } 5 }
   S();
   T t;
 };
@@ -10,5 +11,5 @@ struct S {                    // { dg-error "const|operator=" 
}
 void f()
 {
   S<const int> s;
-  s = s; // { dg-message "synthesized|deleted" }
+  s = s;
 }
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 8a368ee..e6a344f 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -755,13 +755,35 @@ linemap_location_in_system_header_p (struct line_maps 
*set,
 {
   const struct line_map *map = NULL;
 
-  location =
-    linemap_resolve_location (set, location, LRK_SPELLING_LOCATION, &map);
-
   if (location < RESERVED_LOCATION_COUNT)
     return false;
 
-  return LINEMAP_SYSP (map);
+  /* Let's look at where the token for LOCATION comes from.  */
+  while (true)
+    {
+      map = linemap_lookup (set, location);
+      if (map != NULL)
+       {
+         if (!linemap_macro_expansion_map_p (map))
+           /* It's a normal token.  */
+           return LINEMAP_SYSP (map);
+         else
+           {
+             /* It's a token resulting from a macro expansion.  */
+             source_location loc =
+               linemap_macro_map_loc_unwind_toward_spelling (map, location);
+             if (loc < RESERVED_LOCATION_COUNT)
+               /* This token might come from a built-in macro.  Let's
+                  look at where that macro got expanded.  */
+               location = linemap_macro_map_loc_to_exp_point (map, location);
+             else
+               location = loc;
+           }
+       }
+      else
+       break;
+    }
+  return false;
 }
 
 /* Return TRUE if LOCATION is a source code location of a token coming
-- 
                Dodji

Reply via email to