This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Changes in C++ FE regarding pedwarns to be errors are harmful


On 12/01/2008, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> On 11/01/2008, Mark Mitchell wrote:
> >
> > Exactly so.  I think that we have two kinds of pedwarns: those that are
> > pedantic in the sense we use for C (like, that there cannot be a naked
> > semicolon at the top-level of a file, or that "long long" is not in
> > C++98) and those that refer to semantically reasonable constructs that
> > we previously accepted, often because they were allowed by cfront or the
> > ARM.  With flag_permissive, we probably want the latter category to be
> > warnings at most; without flag_permissive, we want them to be errors.
>
> I'll start the ball rolling with cp/call.c, cp/class.c and cp/cvt.c
> I'll call the latter category isowarns for the purpose of this mail,
> they are technically illegal constructs that are errors without
> -fpermissive.  My suggestion of pedwarn/isowarn given in capitals on
> each entry.
>

Here is an initial patch implementing some of your proposals. I used
pederror as the name of the function. That is, it is an error unless
fpermissive is given.

Let me know your opinion. (Not bootstrapped, not tested, not complete patch).

Cheers,

Manuel.
Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 131405)
+++ gcc/diagnostic.c	(working copy)
@@ -538,15 +538,36 @@ pedwarn (const char *gmsgid, ...)
   diagnostic_info diagnostic;
   va_list ap;
 
   va_start (ap, gmsgid);
   diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
+		       pedantic_warning_kind ());
+  report_diagnostic (&diagnostic);
+  va_end (ap);
+}
+
+/* A "pedantic" error: issues an error unless -fpermissive was
+   given on the command line, in which case it issues a warning.  Use
+   this for things that really should be errors but we want to support legacy code.
+
+   Note that these diagnostics are issued independent of the setting
+   of the -pedantic command-line switch.  To get an error enabled
+   only with that switch, write "if (pedantic) pederror (...);"  */
+void
+pederror (const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
 		       pedantic_error_kind ());
   report_diagnostic (&diagnostic);
   va_end (ap);
 }
 
+
 /* A hard error: the code is definitely ill-formed, and an object file
    will not be produced.  */
 void
 error (const char *gmsgid, ...)
 {
Index: gcc/diagnostic.h
===================================================================
--- gcc/diagnostic.h	(revision 131405)
+++ gcc/diagnostic.h	(working copy)
@@ -48,11 +48,12 @@ typedef struct diagnostic_info
   diagnostic_t kind;
   /* Which OPT_* directly controls this diagnostic.  */
   int option_index;
 } diagnostic_info;
 
-#define pedantic_error_kind() (flag_pedantic_errors ? DK_ERROR : DK_WARNING)
+#define pedantic_warning_kind() (flag_pedantic_errors ? DK_ERROR : DK_WARNING)
+#define pedantic_error_kind() (flag_permissive ? DK_WARNING : DK_ERROR)
 
 
 /*  Forward declarations.  */
 typedef struct diagnostic_context diagnostic_context;
 typedef void (*diagnostic_starter_fn) (diagnostic_context *,
Index: gcc/toplev.h
===================================================================
--- gcc/toplev.h	(revision 131405)
+++ gcc/toplev.h	(working copy)
@@ -60,10 +60,11 @@ extern void warning0 (const char *, ...)
 extern void warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
      ATTRIBUTE_NORETURN;
 extern void pedwarn (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
+extern void pederror (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void inform (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 
 extern void rest_of_decl_compilation (tree, int, int);
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 131405)
+++ gcc/cp/decl.c	(working copy)
@@ -6981,16 +6981,11 @@ compute_array_index_type (tree name, tre
   /* Normally, the array-bound will be a constant.  */
   if (TREE_CODE (size) == INTEGER_CST)
     {
       /* Check to see if the array bound overflowed.  Make that an
 	 error, no matter how generous we're being.  */
-      int old_flag_pedantic_errors = flag_pedantic_errors;
-      int old_pedantic = pedantic;
-      pedantic = flag_pedantic_errors = 1;
-      constant_expression_warning (size);
-      pedantic = old_pedantic;
-      flag_pedantic_errors = old_flag_pedantic_errors;
+      constant_expression_error (size);
 
       /* An array must have a positive number of elements.  */
       if (INT_CST_LT (size, integer_zero_node))
 	{
 	  if (name)
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 131405)
+++ gcc/cp/call.c	(working copy)
@@ -3862,11 +3862,11 @@ build_new_op (enum tree_code code, int f
 	case POSTINCREMENT_EXPR:
 	case POSTDECREMENT_EXPR:
 	  /* Look for an `operator++ (int)'.  If they didn't have
 	     one, then we fall back to the old way of doing things.  */
 	  if (flags & LOOKUP_COMPLAIN)
-	    pedwarn ("no %<%D(int)%> declared for postfix %qs, "
+	    pederror ("no %<%D(int)%> declared for postfix %qs, "
 		     "trying prefix operator instead",
 		     fnname,
 		     operator_name_info[code].name);
 	  if (code == POSTINCREMENT_EXPR)
 	    code = PREINCREMENT_EXPR;
@@ -4347,13 +4347,13 @@ convert_like_real (conversion *convs, tr
 				      /*issue_conversion_warnings=*/false,
 				      /*c_cast_p=*/false);
 	  else if (t->kind == ck_identity)
 	    break;
 	}
-      pedwarn ("invalid conversion from %qT to %qT", TREE_TYPE (expr), totype);
+      pederror ("invalid conversion from %qT to %qT", TREE_TYPE (expr), totype);
       if (fn)
-	pedwarn ("  initializing argument %P of %qD", argnum, fn);
+	pederror ("  initializing argument %P of %qD", argnum, fn);
       return cp_convert (totype, expr);
     }
 
   if (issue_conversion_warnings)
     conversion_null_warnings (totype, expr, fn, argnum);
@@ -4948,11 +4948,11 @@ build_over_call (struct z_candidate *can
       tree argtype = TREE_TYPE (TREE_VALUE (arg));
       tree converted_arg;
       tree base_binfo;
 
       if (convs[i]->bad_p)
-	pedwarn ("passing %qT as %<this%> argument of %q#D discards qualifiers",
+	pederror ("passing %qT as %<this%> argument of %q#D discards qualifiers",
 		 TREE_TYPE (argtype), fn);
 
       /* [class.mfct.nonstatic]: If a nonstatic member function of a class
 	 X is called for an object that is not of type X, or of a type
 	 derived from X, the behavior is undefined.
Index: gcc/cp/error.c
===================================================================
--- gcc/cp/error.c	(revision 131405)
+++ gcc/cp/error.c	(working copy)
@@ -2653,11 +2653,11 @@ cp_cpp_error (cpp_reader *pfile ATTRIBUT
     case CPP_DL_WARNING:
     case CPP_DL_WARNING_SYSHDR:
       dlevel = DK_WARNING;
       break;
     case CPP_DL_PEDWARN:
-      dlevel = pedantic_error_kind ();
+      dlevel = pedantic_warning_kind ();
       break;
     case CPP_DL_ERROR:
       dlevel = DK_ERROR;
       break;
     case CPP_DL_ICE:
Index: gcc/cp/lex.c
===================================================================
--- gcc/cp/lex.c	(revision 131405)
+++ gcc/cp/lex.c	(working copy)
@@ -658,20 +658,20 @@ unqualified_fn_lookup_error (tree name)
 	 is going wrong.
 
 	 Note that we have the exact wording of the following message in
 	 the manual (trouble.texi, node "Name lookup"), so they need to
 	 be kept in synch.  */
-      pedwarn ("there are no arguments to %qD that depend on a template "
+      pederror ("there are no arguments to %qD that depend on a template "
 	       "parameter, so a declaration of %qD must be available",
 	       name, name);
 
       if (!flag_permissive)
 	{
 	  static bool hint;
 	  if (!hint)
 	    {
-	      error ("(if you use %<-fpermissive%>, G++ will accept your "
+	      inform ("(if you use %<-fpermissive%>, G++ will accept your "
 		     "code, but allowing the use of an undeclared name is "
 		     "deprecated)");
 	      hint = true;
 	    }
 	}
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 131405)
+++ gcc/cp/parser.c	(working copy)
@@ -9724,11 +9724,11 @@ cp_parser_template_id (cp_parser *parser
 	  pop_deferring_access_checks ();
 	  return error_mark_node;
 	}
       /* Otherwise, emit an error about the invalid digraph, but continue
 	 parsing because we got our argument list.  */
-      pedwarn ("%<<::%> cannot begin a template-argument list");
+      pederror ("%<<::%> cannot begin a template-argument list");
       inform ("%<<:%> is an alternate spelling for %<[%>. Insert whitespace "
 	      "between %<<%> and %<::%>");
       if (!flag_permissive)
 	{
 	  static bool hint;
Index: gcc/c-errors.c
===================================================================
--- gcc/c-errors.c	(revision 131405)
+++ gcc/c-errors.c	(working copy)
@@ -36,11 +36,11 @@ pedwarn_c99 (const char *gmsgid, ...)
   diagnostic_info diagnostic;
   va_list ap;
 
   va_start (ap, gmsgid);
   diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
-		       flag_isoc99 ? pedantic_error_kind () : DK_WARNING);
+		       flag_isoc99 ? pedantic_warning_kind () : DK_WARNING);
   report_diagnostic (&diagnostic);
   va_end (ap);
 }
 
 /* Issue an ISO C90 pedantic warning MSGID.  This function is supposed to
@@ -54,9 +54,9 @@ pedwarn_c90 (const char *gmsgid, ...)
   diagnostic_info diagnostic;
   va_list ap;
 
   va_start (ap, gmsgid);
   diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
-		       flag_isoc99 ? DK_WARNING : pedantic_error_kind ());
+		       flag_isoc99 ? DK_WARNING : pedantic_warning_kind ());
   report_diagnostic (&diagnostic);
   va_end (ap);
 }
Index: gcc/c-opts.c
===================================================================
--- gcc/c-opts.c	(revision 131405)
+++ gcc/c-opts.c	(working copy)
@@ -1095,15 +1095,10 @@ c_common_post_options (const char **pfil
     warn_overlength_strings = 0;
 
   /* Adjust various flags for C++ based on command-line settings.  */
   if (c_dialect_cxx ())
     {
-      if (!flag_permissive)
-	{
-	  flag_pedantic_errors = 1;
-	  cpp_opts->pedantic_errors = 1;
-	}
       if (!flag_no_inline)
 	{
 	  flag_inline_trees = 1;
 	  flag_no_inline = 1;
 	}
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c	(revision 131405)
+++ gcc/c-common.c	(working copy)
@@ -929,18 +929,28 @@ fix_string_type (tree value)
    constant expression to overflow.  */
 
 void
 constant_expression_warning (tree value)
 {
-  if ((TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
-       || TREE_CODE (value) == FIXED_CST
-       || TREE_CODE (value) == VECTOR_CST
-       || TREE_CODE (value) == COMPLEX_CST)
-      && TREE_OVERFLOW (value)
-      && warn_overflow
-      && pedantic)
-    pedwarn ("overflow in constant expression");
+  if (warn_overflow && pedantic && TREE_OVERFLOW (value) 
+      && (TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
+	  || TREE_CODE (value) == FIXED_CST
+	  || TREE_CODE (value) == VECTOR_CST
+	  || TREE_CODE (value) == COMPLEX_CST))
+      pedwarn ("overflow in constant expression");
+}
+
+/* The same as above but print an unconditional error.  */
+void
+constant_expression_error (tree value)
+{
+  if (TREE_OVERFLOW (value) 
+      && (TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
+	  || TREE_CODE (value) == FIXED_CST
+	  || TREE_CODE (value) == VECTOR_CST
+	  || TREE_CODE (value) == COMPLEX_CST))
+      error ("overflow in constant expression");
 }
 
 /* Print a warning if an expression had overflow in folding and its
    operands hadn't.
 
Index: gcc/c-common.h
===================================================================
--- gcc/c-common.h	(revision 131405)
+++ gcc/c-common.h	(working copy)
@@ -686,10 +686,11 @@ extern tree c_alignof_expr (tree);
    NOP_EXPR is used as a special case (see truthvalue_conversion).  */
 extern void binary_op_error (enum tree_code, tree, tree);
 extern tree fix_string_type (tree);
 struct varray_head_tag;
 extern void constant_expression_warning (tree);
+extern void constant_expression_error (tree);
 extern bool strict_aliasing_warning (tree, tree, tree);
 extern void empty_if_body_warning (tree, tree);
 extern void warnings_for_convert_and_check (tree, tree, tree);
 extern tree convert_and_check (tree, tree);
 extern void overflow_warning (tree);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]