> > -  s = s; // { dg-message "synthesized|deleted" }
> > +  s = s;
> 
> Why do we lose this error?

Good question.

This is the result of a weird behaviour of DejaGNU, I think.

For the record, here is the whole test:

     1  // { dg-do compile  }
     2  // Origin: Mark Mitchell <m...@codesourcery.com>
     3  
     4  template <class T>
     5  struct S {                      // { dg-error "const|operator=" }
     6    S();
     7    T t;
     8  };
     9  
    10  void f()
    11  {
    12    S<const int> s;
    13    s = s; // { dg-message "synthesized|deleted" }
    14  }

And here is the output of the test, when run in trunk, without my
patch: http://people.redhat.com/dseketel/gcc/master-g++.log

Then, look at the output with the patch:
http://people.redhat.com/dseketel/gcc/PR53463-g++.log.

It says:

    FAIL: g++.old-deja/g++.pt/assign1.C -std=c++98  (test for warnings, line 13)

But in the compiler output, we duly have:

    assign1.C:13:5: note: synthesized method 'S<const int>& S<const 
int>::operator=(const
    S<const int>&)' first required here 

which seems correct and shouldn't have triggered a FAIL there, IMHO.
Which, after much punching in my TCL darkness, brings me to this
theory:

It seems the { dg-error "const|operator=" } at line 5 is "swallowing"
somehow the compiler output above.  Why exactly? I have no idea.

One thing I noted though, is that there is no error emitted by g++ on
line 5 that has the string "operator=".  There is just one "note" with
that string.  So the "|operator=" seems superfluous there.  Note
however that the note above, on line 13, has the string "operator=".

Incidentally, changing that DejaGNU directive at line 5 with the more
specific:

    // { dg-error "const member\[^\n\r\]*can't use default assignment operator" 
}

makes the whole shebang work.

And of course, I sent you the wrong patch.  The one I sent you does
pass testing, but it was just an attempt for me to understand the
issue.  The patch below is the one that uses the more specific DejaGNU
directive above.

libcpp/

        PR preprocessor/53463
        * 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/

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

gcc/testsuite/

        PR preprocessor/53463
        * 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        |    2 +-
 libcpp/line-map.c                                  |   30 +++++++++++++++++--
 7 files changed, 56 insertions(+), 11 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..95cbee0 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/assign1.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/assign1.C
@@ -2,7 +2,7 @@
 // Origin: Mark Mitchell <m...@codesourcery.com>
 
 template <class T>
-struct S {                     // { dg-error "const|operator=" }
+struct S {  // { dg-error "const member\[^\n\r\]*can't use default assignment 
operator" }
   S();
   T t;
 };
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