PR preprocessor/53463 - Fix system header detection for built-in macro tokens
authorDodji Seketeli <dodji@redhat.com>
Mon, 4 Jun 2012 19:19:58 +0000 (19:19 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Mon, 4 Jun 2012 19:19:58 +0000 (21:19 +0200)
The location for a built-in macro token is BUILTIN_LOCATION.  When we
see that location value, we cannot know if that token was used in a
system header or not.  And that can trigger some unwanted warnings on
e.g, the use of __LONG_LONG_MAX__ built-in macro in system headers
when we compile with -pedantic, like in the test case accompanying
this patch.

In that case, I think we ought to step-up to see where the built-in
macro has been expanded, until we see a location that is not for a
built-in macro.  Then we can check if the resulting location is in a
system header or not.

Now that we step up to the location of first non-built-in-macro token,
it appeared that for
testsuite/c-c++-common/dfp/convert-int-saturate.c, G++ then fails to
emit the warning in:

    volatile unsigned int usi;
    int
    main ()
    {
      usi = DEC32_MAX;  /* { dg-warning "overflow in implicit constant conversion" } */
     ...
    }

Because DEC32_MAX is defined in the system header float.h as a
built-in macro:

    #define DEC32_MAX __DEC32_MAX__

And during the parsing of the assignment expression that should have
led to the warning above, input_location is set to the location for
the DEC32_MAX, which is actually the location for the built-in
__DECL32_MAX_EXP.

A possible fix is to use the location of the "=" operator as the
default location for assignment expressions.  This is what the patch
does.

I had to adjust a couple of tests to arrange for this.

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

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.

From-SVN: r188203

gcc/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp/limits.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/error19.C
gcc/testsuite/g++.dg/warn/Wconversion-real-integer2.C
gcc/testsuite/g++.dg/warn/pr35635.C
gcc/testsuite/g++.old-deja/g++.pt/assign1.C
libcpp/ChangeLog
libcpp/line-map.c

index 2cf78684a9212ec4bc310ea0153ad5f157a0e22c..9448591306ebe1a2b4615c8031a8fd3d5fe5b15a 100644 (file)
@@ -1,3 +1,9 @@
+2012-06-04  Dodji Seketeli  <dodji@redhat.com>
+
+       PR preprocessor/53463
+       * parser.c (cp_parser_assignment_expression): Use the location
+       for the '=' as the default location for the expression.
+
 2012-06-04  Edmar Wienskoski  <edmar@freescale.com>
 
        PR target/53559
index 16139d619aa73224b974222631c2e4565aefd72a..2afcbc0639a427b3ebe58cdf78a5a055e3f871e4 100644 (file)
@@ -7481,6 +7481,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
          if (assignment_operator != ERROR_MARK)
            {
              bool non_constant_p;
+             location_t saved_input_location;
 
              /* Parse the right-hand side of the assignment.  */
              tree rhs = cp_parser_initializer_clause (parser, &non_constant_p);
@@ -7493,11 +7494,15 @@ 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.  */
+             saved_input_location = input_location;
+             input_location = loc;
              expr = build_x_modify_expr (loc, expr,
                                          assignment_operator,
                                          rhs,
                                          tf_warning_or_error);
+             input_location = saved_input_location;
            }
        }
     }
index f9d5e93a6073db9448f3867aff408923453f5551..2d125fcebea6e75953e8493a891ae98be19fb587 100644 (file)
@@ -1,3 +1,12 @@
+2012-06-04  Dodji Seketeli  <dodji@redhat.com>
+
+       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.
+
 2012-06-04  Edmar Wienskoski  <edmar@freescale.com>
 
        PR target/53559
diff --git a/gcc/testsuite/g++.dg/cpp/limits.C b/gcc/testsuite/g++.dg/cpp/limits.C
new file mode 100644 (file)
index 0000000..b64e1e2
--- /dev/null
@@ -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;
+}
index 010a4032e76aae137316260a16e2ba1a720cc022..6d84f7142463e0a559b157eee493adff29c09a83 100644 (file)
@@ -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 }
 }
index 6a95b0e3a8c2c3aca10c6dec9c6615cac2d95f26..0494588c15b7bd158a2ac25e176faa5246941712 100644 (file)
 //
 // 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" }
 }
index 66ade8b28e12b5397463c60a1e2cea05525edf37..de68ceb484c49bf104032d850ccca49618ec0b83 100644 (file)
@@ -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()
index 854d8ee27a9d3787cb8d111f0d5876b9ea17c686..95cbee0daddf676712507b49ea45f7a8c99258fb 100644 (file)
@@ -2,7 +2,7 @@
 // Origin: Mark Mitchell <mark@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;
 };
index e526af243424b352ea64d4915bf64fe68e277565..1a5c1462da13dd21f66b5e2e9ae5aa94ba6cd7f9 100644 (file)
@@ -1,3 +1,10 @@
+2012-06-04  Dodji Seketeli  <dodji@redhat.com>
+
+       PR preprocessor/53463
+       * line-map.c (linemap_location_in_system_header_p): For built-in
+       macro tokens, check the first expansion point location that is not
+       for a token coming from a built-in macro.
+
 2012-05-29  Joseph Myers  <joseph@codesourcery.com>
 
        * directives.c: Fix typos.
index 8a368eec2cbe3071a1bacefe5e8b4730e97a8b71..e6a344f0afab4a5314545190ddb998931e93ec02 100644 (file)
@@ -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