OSDN Git Service

2009-04-21 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
authormanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 20 Apr 2009 22:12:52 +0000 (22:12 +0000)
committermanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 20 Apr 2009 22:12:52 +0000 (22:12 +0000)
PR c++/13358
* doc/invoke.texi (-Wlong-long): Update description.
* c-lex (interpret_integer): Only warn if there was no previous
overflow and -Wlong-long is enabled.
* c-decl.c (declspecs_add_type): Drop redundant flags.
* c.opt (Wlong-long): Init to -1.
* c-opts.c (sanitize_cpp_opts): Synchronize cpp's warn_long_long
and front-end warn_long_long. Wlong-long only depends on other
flags if it is uninitialized.
* c-parser.c (disable_extension_diagnostics): warn_long_long is
the same for CPP and FE.
(restore_extension_diagnostics): Likewise.
libcpp/
* init.c (cpp_create_reader): Wlong_long is disabled by default.
* expr.c (cpp_classify_number): Give different messages for C and
C++ front-ends.
cp/
* parser.c (cp_parser_check_decl_spec): Drop redundant flags.
* error.c (pedwarn_cxx98): New.
* cp-tree.h (pedwarn_cxx98): Declare.
testsuite/
* gcc.dg/wtr-int-type-1.c: Use two dg-warning to match two
messages. Test for "long long" in system headers.
* gcc.dg/c99-longlong-2.c: New.
* g++.dg/warn/pr13358.C: New.
* g++.dg/warn/pr13358-2.C: New.
* g++.dg/warn/pr13358-3.C: New.
* g++.dg/warn/pr13358-4.C: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146459 138bc75d-0d04-0410-961f-82ee72b054a4

22 files changed:
gcc/ChangeLog
gcc/c-decl.c
gcc/c-lex.c
gcc/c-opts.c
gcc/c-parser.c
gcc/c.opt
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/error.c
gcc/cp/parser.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/pr13358-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/pr13358-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/pr13358-4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/pr13358.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/c90-longlong-1.c
gcc/testsuite/gcc.dg/c99-longlong-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/wtr-int-type-1.c
libcpp/ChangeLog
libcpp/expr.c
libcpp/init.c

index 16a34f4..a609506 100644 (file)
@@ -1,3 +1,18 @@
+2009-04-21  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+       PR c++/13358
+       * doc/invoke.texi (-Wlong-long): Update description.
+       * c-lex (interpret_integer): Only warn if there was no previous
+       overflow and -Wlong-long is enabled.
+       * c-decl.c (declspecs_add_type): Drop redundant flags.
+       * c.opt (Wlong-long): Init to -1.
+       * c-opts.c (sanitize_cpp_opts): Synchronize cpp's warn_long_long
+       and front-end warn_long_long. Wlong-long only depends on other
+       flags if it is uninitialized.
+       * c-parser.c (disable_extension_diagnostics): warn_long_long is
+       the same for CPP and FE.
+       (restore_extension_diagnostics): Likewise.
+
 2009-04-20  Ian Lance Taylor  <iant@google.com>
 
        Fix enum conversions which are invalid in C++:
index 6dc2a6a..7efb826 100644 (file)
@@ -7309,8 +7309,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
                             "declaration specifiers");
                      break;
                    }
-                 if (pedantic && !flag_isoc99 && !in_system_header)
-                   pedwarn (input_location, OPT_Wlong_long, "ISO C90 does not support %<long long%>");
+                 pedwarn_c90 (input_location, OPT_Wlong_long, 
+                              "ISO C90 does not support %<long long%>");
                  specs->long_long_p = 1;
                  break;
                }
index 9fe29df..df63548 100644 (file)
@@ -582,13 +582,18 @@ interpret_integer (const cpp_token *token, unsigned int flags)
            ? widest_unsigned_literal_type_node
            : widest_integer_literal_type_node);
   else
-    type = integer_types[itk];
-
-  if (itk > itk_unsigned_long
-      && (flags & CPP_N_WIDTH) != CPP_N_LARGE
-      && !in_system_header && !flag_isoc99)
-    pedwarn (input_location, 0, "integer constant is too large for %qs type",
-            (flags & CPP_N_UNSIGNED) ? "unsigned long" : "long");
+    {
+      type = integer_types[itk];
+      if (itk > itk_unsigned_long
+         && (flags & CPP_N_WIDTH) != CPP_N_LARGE)
+       emit_diagnostic 
+         ((c_dialect_cxx () ? cxx_dialect == cxx98 : !flag_isoc99)
+          ? DK_PEDWARN : DK_WARNING,
+          input_location, OPT_Wlong_long,
+          (flags & CPP_N_UNSIGNED) 
+          ? "integer constant is too large for %<unsigned long%> type"
+          : "integer constant is too large for %<long%> type");
+    }
 
   value = build_int_cst_wide (type, integer.low, integer.high);
 
index ece4d7f..4dffc78 100644 (file)
@@ -1433,14 +1433,15 @@ sanitize_cpp_opts (void)
   cpp_opts->unsigned_char = !flag_signed_char;
   cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS;
 
-  /* We want -Wno-long-long to override -pedantic -std=non-c99
-     and/or -Wtraditional, whatever the ordering.  */
-  cpp_opts->warn_long_long
-    = warn_long_long && ((pedantic
-                         && (c_dialect_cxx ()
-                             ? cxx_dialect == cxx98
-                             : !flag_isoc99))
-                         || warn_traditional);
+  /* Wlong-long is disabled by default. It is enabled by:
+      [-pedantic | -Wtraditional] -std=[gnu|c]++98 ; or
+      [-pedantic | -Wtraditional] -std=non-c99 . 
+
+      Either -Wlong-long or -Wno-long-long override any other settings.  */
+  if (warn_long_long == -1)
+    warn_long_long = ((pedantic || warn_traditional)
+                     && (c_dialect_cxx () ? cxx_dialect == cxx98 : !flag_isoc99));
+  cpp_opts->warn_long_long = warn_long_long;
 
   /* Similarly with -Wno-variadic-macros.  No check for c99 here, since
      this also turns off warnings about GCCs extension.  */
index e5129dc..ca51d95 100644 (file)
@@ -818,14 +818,12 @@ disable_extension_diagnostics (void)
             | (warn_pointer_arith << 1)
             | (warn_traditional << 2)
             | (flag_iso << 3)
-            | (warn_long_long << 4)
-            | (cpp_opts->warn_long_long << 5));
+            | (warn_long_long << 4));
   cpp_opts->pedantic = pedantic = 0;
   warn_pointer_arith = 0;
   cpp_opts->warn_traditional = warn_traditional = 0;
   flag_iso = 0;
-  warn_long_long = 0;
-  cpp_opts->warn_long_long = 0;
+  cpp_opts->warn_long_long = warn_long_long = 0;
   return ret;
 }
 
@@ -839,8 +837,7 @@ restore_extension_diagnostics (int flags)
   warn_pointer_arith = (flags >> 1) & 1;
   cpp_opts->warn_traditional = warn_traditional = (flags >> 2) & 1;
   flag_iso = (flags >> 3) & 1;
-  warn_long_long = (flags >> 4) & 1;
-  cpp_opts->warn_long_long = (flags >> 5) & 1;
+  cpp_opts->warn_long_long = warn_long_long = (flags >> 4) & 1;
 }
 
 /* Possibly kinds of declarator to parse.  */
index b3e7dd7..7f71699 100644 (file)
--- a/gcc/c.opt
+++ b/gcc/c.opt
@@ -289,7 +289,7 @@ C ObjC C++ ObjC++ Var(warn_logical_op) Init(-1) Warning
 Warn when a logical operator is suspiciously always evaluating to true or false
 
 Wlong-long
-C ObjC C++ ObjC++ Var(warn_long_long) Init(1) Warning
+C ObjC C++ ObjC++ Var(warn_long_long) Init(-1) Warning
 Do not warn about using \"long long\" when -pedantic
 
 Wmain
index 15f83d9..df0a91a 100644 (file)
@@ -1,3 +1,10 @@
+2009-04-21  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+       PR c++/13358
+       * parser.c (cp_parser_check_decl_spec): Drop redundant flags.
+       * error.c (pedwarn_cxx98): New.
+       * cp-tree.h (pedwarn_cxx98): Declare.
+
 2009-04-20  Le-Chun Wu  <lcwu@google.com>
 
        PR c++/39803
index e3fed77..c80037d 100644 (file)
@@ -4462,6 +4462,7 @@ extern const char *class_key_or_enum_as_string    (tree);
 extern void print_instantiation_context                (void);
 extern void maybe_warn_variadic_templates       (void);
 extern void maybe_warn_cpp0x                   (const char *);
+extern bool pedwarn_cxx98                       (location_t, int, const char *, ...) ATTRIBUTE_GCC_CXXDIAG(3,4);
 
 /* in except.c */
 extern void init_exception_processing          (void);
index 9c2e7e5..4e7e9ec 100644 (file)
@@ -2804,3 +2804,22 @@ maybe_warn_variadic_templates (void)
 {
   maybe_warn_cpp0x ("variadic templates");
 }
+
+
+/* Issue an ISO C++98 pedantic warning at LOCATION, conditional on
+   option OPT with text GMSGID.  Use this function to report
+   diagnostics for constructs that are invalid C++98, but valid
+   C++0x.  */
+bool
+pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, location,
+                      (cxx_dialect == cxx98) ? DK_PEDWARN : DK_WARNING);
+  diagnostic.option_index = opt;
+  va_end (ap);
+  return report_diagnostic (&diagnostic);
+}
index b640033..b6b8bf5 100644 (file)
@@ -2167,10 +2167,9 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs,
        {
          if (count > 2)
            error ("%H%<long long long%> is too long for GCC", &location);
-         else if (pedantic && !in_system_header && warn_long_long
-                   && cxx_dialect == cxx98)
-           pedwarn (location, OPT_Wlong_long, 
-                    "ISO C++ 1998 does not support %<long long%>");
+         else 
+           pedwarn_cxx98 (location, OPT_Wlong_long, 
+                          "ISO C++ 1998 does not support %<long long%>");
        }
       else if (count > 1)
        {
index e1dd0e0..05f02ed 100644 (file)
@@ -4147,10 +4147,9 @@ the search path but can't be used.
 @item -Wlong-long
 @opindex Wlong-long
 @opindex Wno-long-long
-Warn if @samp{long long} type is used.  This is default.  To inhibit
-the warning messages, use @option{-Wno-long-long}.  Flags
-@option{-Wlong-long} and @option{-Wno-long-long} are taken into account
-only when @option{-pedantic} flag is used.
+Warn if @samp{long long} type is used.  This is enabled by either
+@option{-pedantic} or @option{-Wtraditional} in ISO C90 and C++98
+modes.  To inhibit the warning messages, use @option{-Wno-long-long}.
 
 @item -Wvariadic-macros
 @opindex Wvariadic-macros
index 548314c..1b0914c 100644 (file)
@@ -1,3 +1,14 @@
+2009-04-21  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+       PR c++/13358
+       * gcc.dg/wtr-int-type-1.c: Use two dg-warning to match two
+       messages. Test for "long long" in system headers.
+       * gcc.dg/c99-longlong-2.c: New.
+       * g++.dg/warn/pr13358.C: New.
+       * g++.dg/warn/pr13358-2.C: New.
+       * g++.dg/warn/pr13358-3.C: New.
+       * g++.dg/warn/pr13358-4.C: New.
+
 2009-04-20  Andrew Pinski <andrew_pinski@playstation.sony.com>
 
        * gcc.dg/framework-2.c: Fix up for non existent includes
diff --git a/gcc/testsuite/g++.dg/warn/pr13358-2.C b/gcc/testsuite/g++.dg/warn/pr13358-2.C
new file mode 100644 (file)
index 0000000..f547f19
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/13358: g++ should accept a long long constant sans LL suffix
+// if -Wno-long-long is in use.
+// { dg-do compile }
+// { dg-require-effective-target int32plus }
+// { dg-options "-std=c++98 -pedantic-errors" }
+
+
+void use_longlong ()
+{
+  unsigned long long x1, x2, x3; // { dg-error "ISO C\\+\\+ 1998 does not support 'long long'" }
+  // make sure we error with hex, decimal and octal
+  x1 = 0x1b27da572ef3cd86; // { dg-error "integer constant is too large for 'long' type" "long long" { target ilp32 } }
+  x2 = 1956772631100509574; // { dg-error "integer constant is too large for 'long' type" "long long" { target ilp32 } }
+  x3 = 0154476645345674746606; // { dg-error "integer constant is too large for 'long' type" "long long" { target ilp32 } }
+}
+
+void use_longlong2 ()
+{
+  unsigned long long x1, x2, x3; // { dg-error "ISO C\\+\\+ 1998 does not support 'long long'" }
+  // make sure we error with hex, decimal and octal
+  x1 = 0x1b27da572ef3cd86LL; // { dg-error "long long" }
+  x2 = 1956772631100509574LL; // { dg-error "long long" }
+  x3 = 0154476645345674746606LL; // { dg-error "long long" }
+}
diff --git a/gcc/testsuite/g++.dg/warn/pr13358-3.C b/gcc/testsuite/g++.dg/warn/pr13358-3.C
new file mode 100644 (file)
index 0000000..f23e7d9
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/13358: g++ should accept a long long constant sans LL suffix
+// if -Wno-long-long is in use
+// { dg-do compile }
+// { dg-require-effective-target int32plus } 
+// { dg-options "-std=c++0x -pedantic-errors" }
+
+
+void use_longlong ()
+{
+  unsigned long long x1, x2, x3; 
+  // make sure it's ok with hex, decimal and octal
+  x1 = 0x1b27da572ef3cd86;
+  x2 = 1956772631100509574;
+  x3 = 0154476645345674746606;
+}
+
+void use_longlong2 ()
+{
+  unsigned long long x1, x2, x3; 
+  // make sure it's ok with hex, decimal and octal
+  x1 = 0x1b27da572ef3cd86LL;
+  x2 = 1956772631100509574LL;
+  x3 = 0154476645345674746606LL;
+}
diff --git a/gcc/testsuite/g++.dg/warn/pr13358-4.C b/gcc/testsuite/g++.dg/warn/pr13358-4.C
new file mode 100644 (file)
index 0000000..b652bb4
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/13358: g++ should accept a long long constant sans LL suffix
+// if -Wno-long-long is in use.
+// { dg-do compile }
+// { dg-require-effective-target int32plus } 
+// { dg-options "-std=c++0x -pedantic-errors -Wlong-long" }
+
+
+void use_longlong ()
+{
+  unsigned long long x1, x2, x3; // { dg-warning "ISO C\\+\\+ 1998 does not support 'long long'" }
+  // make sure we warn with hex, decimal and octal
+  x1 = 0x1b27da572ef3cd86; // { dg-warning "integer constant is too large for 'long' type" "long long" { target ilp32 } }
+  x2 = 1956772631100509574; // { dg-warning "integer constant is too large for 'long' type" "long long" { target ilp32 } }
+  x3 = 0154476645345674746606; // { dg-warning "integer constant is too large for 'long' type" "long long" { target ilp32 } }
+}
+
+void use_longlong2 ()
+{
+  unsigned long long x1, x2, x3; // { dg-warning "ISO C\\+\\+ 1998 does not support 'long long'" }
+  // make sure we warn with hex, decimal and octal
+  x1 = 0x1b27da572ef3cd86LL; // { dg-warning "long long" }
+  x2 = 1956772631100509574LL; // { dg-warning "long long" }
+  x3 = 0154476645345674746606LL; // { dg-warning "long long" }
+}
diff --git a/gcc/testsuite/g++.dg/warn/pr13358.C b/gcc/testsuite/g++.dg/warn/pr13358.C
new file mode 100644 (file)
index 0000000..257616d
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/13358: g++ should accept a long long constant sans LL suffix
+// if -Wno-long-long is in use.
+// { dg-do compile }
+// { dg-require-effective-target int32plus } 
+// { dg-options "-std=c++98 -Wno-long-long -pedantic-errors" }
+
+
+void use_longlong ()
+{
+  unsigned long long x1, x2, x3; 
+  // make sure it's ok with hex, decimal and octal
+  x1 = 0x1b27da572ef3cd86;
+  x2 = 1956772631100509574;
+  x3 = 0154476645345674746606;
+}
+
+void use_longlong2 ()
+{
+  unsigned long long x1, x2, x3; 
+  // make sure it's ok with hex, decimal and octal
+  x1 = 0x1b27da572ef3cd86LL;
+  x2 = 1956772631100509574LL;
+  x3 = 0154476645345674746606LL;
+}
index e91e39e..3594d4b 100644 (file)
@@ -3,5 +3,4 @@
 /* { dg-do compile } */
 /* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
 
-long long foo; /* { dg-bogus "warning" "warning in place of error" } */
-/* { dg-error "long long" "long long not in C90" { target *-*-* } 6 } */
+long long foo; /* { dg-error "long long" "long long not in C90" } */
diff --git a/gcc/testsuite/gcc.dg/c99-longlong-2.c b/gcc/testsuite/gcc.dg/c99-longlong-2.c
new file mode 100644 (file)
index 0000000..fc6c8a5
--- /dev/null
@@ -0,0 +1,6 @@
+/* Test for long long: if explicit Wlong-long, in C99 only warn, not
+   pedwarn.  */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors -Wlong-long" } */
+
+long long foo; /* { dg-warning "long long" } */
index d44165d..c0abb44 100644 (file)
@@ -25,9 +25,17 @@ testfunc ()
 
   /* But this one should, since it doesn't fit in long (long), but
      does fit in unsigned long (long).  */
-  i = 18446744073709551615; /* { dg-warning "decimal constant|unsigned" "decimal constant" } */
-  
+  i = 18446744073709551615; /* { dg-warning "integer constant is so large that it is unsigned" "decimal constant" } */
+  /* { dg-warning "this decimal constant would be unsigned in ISO C90" "decimal constant" { target *-*-* } 28 } */
+
 # 29 "sys-header.h" 3
+}
+
+void
+testfunc2( ) 
+{ 
+  long long i;
+
 /* We are in system headers now, no -Wtraditional warnings should issue.  */
 
   i = 0x80000000;
@@ -41,3 +49,4 @@ testfunc ()
   i = 9223372036854775807;
   i = 18446744073709551615;
 }
+
index 74979a2..7fdc737 100644 (file)
@@ -1,3 +1,10 @@
+2009-04-21  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+       PR c++/13358
+       * init.c (cpp_create_reader): Wlong_long is disabled by default.
+       * expr.c (cpp_classify_number): Give different messages for C and
+       C++ front-ends.
+
 2009-04-19  Joseph Myers  <joseph@codesourcery.com>
 
        PR preprocessor/20078
index 56945d9..b9a17db 100644 (file)
@@ -419,10 +419,12 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
        }
 
       if ((result & CPP_N_WIDTH) == CPP_N_LARGE
-         && ! CPP_OPTION (pfile, c99)
          && CPP_OPTION (pfile, warn_long_long))
-       cpp_error (pfile, CPP_DL_PEDWARN,
-                  "use of C99 long long integer constant");
+       cpp_error (pfile, 
+                  CPP_OPTION (pfile, c99) ? CPP_DL_WARNING : CPP_DL_PEDWARN,
+                  CPP_OPTION (pfile, cplusplus) 
+                  ? "use of C++0x long long integer constant"
+                  : "use of C99 long long integer constant");
 
       result |= CPP_N_INTEGER;
     }
index d251f19..c211217 100644 (file)
@@ -160,7 +160,7 @@ cpp_create_reader (enum c_lang lang, hash_table *table,
   CPP_OPTION (pfile, warn_trigraphs) = 2;
   CPP_OPTION (pfile, warn_endif_labels) = 1;
   CPP_OPTION (pfile, warn_deprecated) = 1;
-  CPP_OPTION (pfile, warn_long_long) = !CPP_OPTION (pfile, c99);
+  CPP_OPTION (pfile, warn_long_long) = 0;
   CPP_OPTION (pfile, dollars_in_ident) = 1;
   CPP_OPTION (pfile, warn_dollars) = 1;
   CPP_OPTION (pfile, warn_variadic_macros) = 1;