public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ warnings vs. errors
@ 2008-06-11 14:12 Volker Reichelt
  2008-06-11 14:48 ` Ian Lance Taylor
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Volker Reichelt @ 2008-06-11 14:12 UTC (permalink / raw)
  To: gcc

Hi,

since Manuel's patch http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00962.html
a lot of C++ code is now accepted on mainline (when compiling without
special flags like -fpermissive and -pedantic), that used to be rejected.
Instead of getting closer to the standard we get away from it, which is a
bad idea IMHO - especially since the standard should be widely adopted by
now, given that it's about 10 years old. So here's a collection of some
warnings that I'd rather see as errors:


* Scopes in for-loops:

  void foo()
  {
    for (int i=0; i<10; ++i) {}
    i = 0;
  }

  warn.cc: In function 'void foo()':
  warn.cc:4: warning: name lookup of 'i' changed for new ISO 'for' scoping
  warn.cc:3: warning:   using obsolete binding at 'i'

  Btw, because the compiler tries to be smart to track new scoping and old
  scoping at once it rejects valid code, accepts invalid code and even
  generates wrong code in some cases (see PR10852).


* Declaration with no type:

  foo() {}

  warn.cc:1: warning: ISO C++ forbids declaration of 'foo' with no type


  Or even worse IMHO:

  struct A
  {
    i;
  };

  warn.cc:3: warning: ISO C++ forbids declaration of 'i' with no type


* Invalid use of 'template':

  struct A
  {
    static void foo();
  };

  template<int> void bar()
  {
    A::template foo();
  }

  warn.cc: In function 'void bar()':
  warn.cc:8: warning: 'A::foo()' is not a template

  Btw, I don't know why we should accept this even with -fpermissive.


* Using 'struct' for a union:

  union A {};
  struct A a;

  warn.cc:2: warning: 'struct' tag used in naming 'union A'


* Static members of local classes:

  void foo()
  {
    struct A
    {
      static int i;
    };
  }

  warn.cc: In function 'void foo()':
  warn.cc:5: warning: local class 'struct foo()::A' shall not have static data member 'int foo()::A::i'


* Return without value:

  int foo()
  {
    return;
  }

  warn.cc: In function 'int foo()':
  warn.cc:1: warning: return-statement with no value, in function returning 'int'


* Definition in wrong namespace:

  struct A
  {
    void foo();
  };

  namespace N
  {
    void A::foo() {}
  }

  warn.cc:8: warning: definition of 'void A::foo()' is not in namespace enclosing 'A'


* Operator new:

  struct A
  {
    void* operator new(char);
  };

  warn.cc:3: warning: 'operator new' takes type 'size_t' ('unsigned int') as first parameter


* Sizeof for function types:

  void foo() { sizeof(foo); }

  warn.cc: In member function 'void A::foo()':
  warn.cc:1: warning: ISO C++ forbids applying 'sizeof' to an expression of function type


What do you think?

Regards,
Volker

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-11 14:12 C++ warnings vs. errors Volker Reichelt
@ 2008-06-11 14:48 ` Ian Lance Taylor
  2008-06-11 18:48   ` Manuel López-Ibáñez
  2008-06-11 20:24 ` Joe Buck
  2008-06-11 23:06 ` Jonathan Wakely
  2 siblings, 1 reply; 19+ messages in thread
From: Ian Lance Taylor @ 2008-06-11 14:48 UTC (permalink / raw)
  To: Volker Reichelt; +Cc: gcc

Volker Reichelt <v.reichelt@netcologne.de> writes:

> since Manuel's patch http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00962.html
> a lot of C++ code is now accepted on mainline (when compiling without
> special flags like -fpermissive and -pedantic), that used to be rejected.
> Instead of getting closer to the standard we get away from it, which is a
> bad idea IMHO - especially since the standard should be widely adopted by
> now, given that it's about 10 years old. So here's a collection of some
> warnings that I'd rather see as errors:

It sounds like you want to change some pedwarns to permerrors.  Go for
it.

Ian

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-11 14:48 ` Ian Lance Taylor
@ 2008-06-11 18:48   ` Manuel López-Ibáñez
  0 siblings, 0 replies; 19+ messages in thread
From: Manuel López-Ibáñez @ 2008-06-11 18:48 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Volker Reichelt, gcc

2008/6/11 Ian Lance Taylor <iant@google.com>:
> Volker Reichelt <v.reichelt@netcologne.de> writes:
>
>> since Manuel's patch http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00962.html
>> a lot of C++ code is now accepted on mainline (when compiling without
>> special flags like -fpermissive and -pedantic), that used to be rejected.
>> Instead of getting closer to the standard we get away from it, which is a
>> bad idea IMHO - especially since the standard should be widely adopted by
>> now, given that it's about 10 years old. So here's a collection of some
>> warnings that I'd rather see as errors:
>
> It sounds like you want to change some pedwarns to permerrors.  Go for
> it.

Absolutely. Thanks to Jonathan Wakely, we did change quite a few.
However, right now, I don't have neither the free time nor the
knowledge of the ISO C++ standard to go through all of them and
evaluate whether they should be pedwarns or permerrors.

So, just grep pedwarn gcc/cp/*.c and s/pedwarn/permerror/ as you see fit.

A tip: if it is guarded by "if (pedantic)" it should probably stay as
pedwarn. It doesn't make sense for a permerror to be guarded by the
"pedantic" flag.

Moreover, you will probably find things that we don't handle well when
using fpermissive, so they should be just errors.

Thanks,

Manuel.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-11 14:12 C++ warnings vs. errors Volker Reichelt
  2008-06-11 14:48 ` Ian Lance Taylor
@ 2008-06-11 20:24 ` Joe Buck
  2008-06-11 23:06 ` Jonathan Wakely
  2 siblings, 0 replies; 19+ messages in thread
From: Joe Buck @ 2008-06-11 20:24 UTC (permalink / raw)
  To: Volker Reichelt; +Cc: gcc

On Wed, Jun 11, 2008 at 04:12:18PM +0200, Volker Reichelt wrote:
> * Scopes in for-loops:
> 
>   void foo()
>   {
>     for (int i=0; i<10; ++i) {}
>     i = 0;
>   }
> 
>   warn.cc: In function 'void foo()':
>   warn.cc:4: warning: name lookup of 'i' changed for new ISO 'for' scoping
>   warn.cc:3: warning:   using obsolete binding at 'i'
> 
>   Btw, because the compiler tries to be smart to track new scoping and old
>   scoping at once it rejects valid code, accepts invalid code and even
>   generates wrong code in some cases (see PR10852).

That was originally there because, around the time the standard was
first adopted, there was a lot of old code that used the original
cfront scoping rule.  But people have had a decade now to get their
code right.  It might even be better to toss the support for the
alternative parsing entirely, so the compiler just reports the final
use of i as a reference to an undefined symbol.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-11 14:12 C++ warnings vs. errors Volker Reichelt
  2008-06-11 14:48 ` Ian Lance Taylor
  2008-06-11 20:24 ` Joe Buck
@ 2008-06-11 23:06 ` Jonathan Wakely
  2008-06-13 19:48   ` Mark Mitchell
  2008-06-17 19:48   ` Jonathan Wakely
  2 siblings, 2 replies; 19+ messages in thread
From: Jonathan Wakely @ 2008-06-11 23:06 UTC (permalink / raw)
  To: Volker Reichelt; +Cc: gcc

Hi Volker, thanks for picking these issues up. I told Manuel I'd
review the rest of the remaining pedwarns, but haven't had time to do
it either.

2008/6/11 Volker Reichelt:
> * Scopes in for-loops:
>
>  void foo()
>  {
>    for (int i=0; i<10; ++i) {}
>    i = 0;
>  }
>
>  warn.cc: In function 'void foo()':
>  warn.cc:4: warning: name lookup of 'i' changed for new ISO 'for' scoping
>  warn.cc:3: warning:   using obsolete binding at 'i'

I suggest making this a permerror and changing the text slightly, see
http://gcc.gnu.org/ml/gcc/2008-01/msg00192.html

> * Declaration with no type:
>
>  foo() {}
>
>  warn.cc:1: warning: ISO C++ forbids declaration of 'foo' with no type

See the part about special handling of 'main' in
http://gcc.gnu.org/ml/gcc/2008-01/msg00189.html


> * Invalid use of 'template':
> * Using 'struct' for a union:

These two can both be fixed by changes in cp/parser.c - all cases of
pedwarn that are not guarded by testing 'pedantic' should be
permerrors.

I'm reviewing the mails linked above, as well as the other cases you
listed. I haven't updated my gcc tree in weeks, so it will take me a
while to bootstrap and test. If you get a patch ready first, please CC
me as I'm not subscribed to gcc-patches.

Thanks,

Jon

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-11 23:06 ` Jonathan Wakely
@ 2008-06-13 19:48   ` Mark Mitchell
  2008-06-13 21:20     ` Manuel López-Ibáñez
  2008-06-15 23:06     ` Jonathan Wakely
  2008-06-17 19:48   ` Jonathan Wakely
  1 sibling, 2 replies; 19+ messages in thread
From: Mark Mitchell @ 2008-06-13 19:48 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Volker Reichelt, gcc

Jonathan Wakely wrote:
> Hi Volker, thanks for picking these issues up. I told Manuel I'd
> review the rest of the remaining pedwarns, but haven't had time to do
> it either.

Just to chime in here: Volker, I agree with your comments.

Jonathan, Manuel, if you would please make the time to finish this 
project, that would be very much appreciated.  We don't want this to be 
a case where we improved the infrastructure of the compiler -- but made 
the user experience worse.

Thanks,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-13 19:48   ` Mark Mitchell
@ 2008-06-13 21:20     ` Manuel López-Ibáñez
  2008-06-15 23:06     ` Jonathan Wakely
  1 sibling, 0 replies; 19+ messages in thread
From: Manuel López-Ibáñez @ 2008-06-13 21:20 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Jonathan Wakely, Volker Reichelt, gcc

2008/6/13 Mark Mitchell <mark@codesourcery.com>:
> Jonathan Wakely wrote:
>>
>> Hi Volker, thanks for picking these issues up. I told Manuel I'd
>> review the rest of the remaining pedwarns, but haven't had time to do
>> it either.
>
> Just to chime in here: Volker, I agree with your comments.
>
> Jonathan, Manuel, if you would please make the time to finish this project,
> that would be very much appreciated.  We don't want this to be a case where
> we improved the infrastructure of the compiler -- but made the user
> experience worse.

Mark, I also agree with Volker comments. But I am respectfully not
going to tackle this.

First, because I have very little free time and I have many other
things half-backed that I would like to finish. And second and more
importantly, to "finish the project" as you say, just involves to
"grep -n -e "pedwarn" cp/*.c and s/pedwarn/permerror/ whatever you
think must be an error by default.

The only "difficulty" of this process is to know whether something
must be a warning or an error by default and I don't have the
knowledge to decide this. And, honestly, the idea of discovering it by
trial and error is not very exciting.  That may take a long time and a
lot of iterations. This job would be done better and faster by someone
knowledgeable in the C++ standard, who could also add a comment in
each warning/error stating why it is given.

(In fact, you don't even need to bootstrap and run the regression
testsuite: I bet there won't be any testsuite errors since the C++
testsuite can't distinguish between warnings and errors unless you
included "warning: " or "error: " in the dg-* statement. And those we
fixed already when we submitted the patch. Of course, bonus points
would be to add those tests for each permerror so we don't regress in
the future.)

I am deeply sorry if I dissapoint you. But I think it is better to be
honest than to silently ignore this issue.

Manuel.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-13 19:48   ` Mark Mitchell
  2008-06-13 21:20     ` Manuel López-Ibáñez
@ 2008-06-15 23:06     ` Jonathan Wakely
  2008-06-16  2:32       ` Mark Mitchell
  2008-06-16 10:13       ` Manuel López-Ibáñez
  1 sibling, 2 replies; 19+ messages in thread
From: Jonathan Wakely @ 2008-06-15 23:06 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Volker Reichelt, gcc

2008/6/13 Mark Mitchell:
> Jonathan Wakely wrote:
>>
>> Hi Volker, thanks for picking these issues up. I told Manuel I'd
>> review the rest of the remaining pedwarns, but haven't had time to do
>> it either.
>
> Just to chime in here: Volker, I agree with your comments.

I think we all do :-)

> Jonathan, Manuel, if you would please make the time to finish this project,
> that would be very much appreciated.  We don't want this to be a case where
> we improved the infrastructure of the compiler -- but made the user
> experience worse.

Absolutely agreed. I'm working on it. Sorry for the delay, until
Volker's mail I didn't realise most of the pedwarns hadn't changed to
permerrors already.

Jon

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-15 23:06     ` Jonathan Wakely
@ 2008-06-16  2:32       ` Mark Mitchell
  2008-06-16 10:13       ` Manuel López-Ibáñez
  1 sibling, 0 replies; 19+ messages in thread
From: Mark Mitchell @ 2008-06-16  2:32 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Volker Reichelt, gcc

Jonathan --

Thanks for pushing this forward!

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

On Jun 15, 2008, at 7:06 PM, "Jonathan Wakely" <jwakely.gcc@gmail.com>  
wrote:

> 2008/6/13 Mark Mitchell:
>> Jonathan Wakely wrote:
>>>
>>> Hi Volker, thanks for picking these issues up. I told Manuel I'd
>>> review the rest of the remaining pedwarns, but haven't had time to  
>>> do
>>> it either.
>>
>> Just to chime in here: Volker, I agree with your comments.
>
> I think we all do :-)
>
>> Jonathan, Manuel, if you would please make the time to finish this  
>> project,
>> that would be very much appreciated.  We don't want this to be a  
>> case where
>> we improved the infrastructure of the compiler -- but made the user
>> experience worse.
>
> Absolutely agreed. I'm working on it. Sorry for the delay, until
> Volker's mail I didn't realise most of the pedwarns hadn't changed to
> permerrors already.
>
> Jon

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-15 23:06     ` Jonathan Wakely
  2008-06-16  2:32       ` Mark Mitchell
@ 2008-06-16 10:13       ` Manuel López-Ibáñez
  1 sibling, 0 replies; 19+ messages in thread
From: Manuel López-Ibáñez @ 2008-06-16 10:13 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Mark Mitchell, Volker Reichelt, gcc

2008/6/16 Jonathan Wakely <jwakely.gcc@gmail.com>:
> 2008/6/13 Mark Mitchell:
>> Jonathan Wakely wrote:
>>>
>>> Hi Volker, thanks for picking these issues up. I told Manuel I'd
>>> review the rest of the remaining pedwarns, but haven't had time to do
>>> it either.
>>
>> Just to chime in here: Volker, I agree with your comments.
>
> I think we all do :-)
>
>> Jonathan, Manuel, if you would please make the time to finish this project,
>> that would be very much appreciated.  We don't want this to be a case where
>> we improved the infrastructure of the compiler -- but made the user
>> experience worse.
>
> Absolutely agreed. I'm working on it. Sorry for the delay, until
> Volker's mail I didn't realise most of the pedwarns hadn't changed to
> permerrors already.

If you make a list of pedwarns that should be permerrors and you get a
C++ maintainer to review it and agree with it. I will write the patch,
bootstrap+test it, adjust any failing testcases, and commit it in your
name.

Cheers,

Manuel.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-11 23:06 ` Jonathan Wakely
  2008-06-13 19:48   ` Mark Mitchell
@ 2008-06-17 19:48   ` Jonathan Wakely
  2008-06-19  0:27     ` Mark Mitchell
  1 sibling, 1 reply; 19+ messages in thread
From: Jonathan Wakely @ 2008-06-17 19:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc, Volker Reichelt, Manuel López-Ibáñez

[-- Attachment #1: Type: text/plain, Size: 2870 bytes --]

2008/6/12 Jonathan Wakely:
> 2008/6/11 Volker Reichelt:
>> * Scopes in for-loops:
>>
>>  void foo()
>>  {
>>    for (int i=0; i<10; ++i) {}
>>    i = 0;
>>  }
>>
>>  warn.cc: In function 'void foo()':
>>  warn.cc:4: warning: name lookup of 'i' changed for new ISO 'for' scoping
>>  warn.cc:3: warning:   using obsolete binding at 'i'
>
> I suggest making this a permerror and changing the text slightly, see
> http://gcc.gnu.org/ml/gcc/2008-01/msg00192.html
>
>> * Declaration with no type:
>>
>>  foo() {}
>>
>>  warn.cc:1: warning: ISO C++ forbids declaration of 'foo' with no type
>
> See the part about special handling of 'main' in
> http://gcc.gnu.org/ml/gcc/2008-01/msg00189.html
>
>
>> * Invalid use of 'template':
>> * Using 'struct' for a union:
>
> These two can both be fixed by changes in cp/parser.c - all cases of
> pedwarn that are not guarded by testing 'pedantic' should be
> permerrors.

Could a C++ maintainer please review this patch to turn most pedwarns
into permerrors.

This restores the previous behaviour without any switches: most
diagnostics are errors. The permerrors can be relaxed with
-fpermissive.  When a warning was guarded by a test for the 'pedantic'
flag I left it as a pedwarn.

The interesting cases are:
* when 'main' is declared without a return type. I split one case into
a permerror and pedwarn.
* 'for' scoping.   I removed the "new" from "new ISO 'for' scoping"
since the ISO standard is not new, and when C++0x arrives it would be
misleading.
* Should it really be a hard error for a class to declare itself as a
friend? I don't think it's expressly forbidden
e.g. class A { friend class A; };
I changed this to a permerror, restoring the old  behaviour.
* I don't think the pedwarn in joust() in cp/call.c should be a
permerror, is this a GNU extension?
	  if (warn)
	    {
	      pedwarn ("\
ISO C++ says that these are ambiguous, even \
though the worst conversion for the first is better than \
the worst conversion for the second:");
	      print_z_candidate (_("candidate 1:"), w);
	      print_z_candidate (_("candidate 2:"), l);
	    }

* I don't know if these in cp/typeck.c should be permerrors, DTRT
implies not, but should tf_error be changed to tf_warning?

  /* DTRT if one side is an overloaded function, but complain about it.  */
  if (type_unknown_p (op0))
    {
      tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none);
      if (t != error_mark_node)
	{
	  if (complain & tf_error)
	    pedwarn ("assuming cast to type %qT from overloaded function",
		     TREE_TYPE (t));
	  op0 = t;
	}
    }
  if (type_unknown_p (op1))
    {
      tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none);
      if (t != error_mark_node)
	{
	  if (complain & tf_error)
	    pedwarn ("assuming cast to type %qT from overloaded function",
		     TREE_TYPE (t));
	  op1 = t;
	}
    }

tested linux/x86-64

Jon

[-- Attachment #2: permerrors.patch --]
[-- Type: application/octet-stream, Size: 32021 bytes --]

Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 136847)
+++ gcc/cp/typeck.c	(working copy)
@@ -435,9 +435,9 @@
   else
     {
       if (complain & tf_error)
-	pedwarn ("%s between distinct pointer types %qT and %qT "
-		 "lacks a cast",
-		 location, t1, t2);
+	permerror ("%s between distinct pointer types %qT and %qT "
+		   "lacks a cast",
+		   location, t1, t2);
       result_type = void_type_node;
     }
   result_type = cp_build_qualified_type (result_type,
@@ -450,9 +450,9 @@
       if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
 			TYPE_PTRMEM_CLASS_TYPE (t2))
 	  && (complain & tf_error))
-	pedwarn ("%s between distinct pointer types %qT and %qT "
-		 "lacks a cast",
-		 location, t1, t2);
+	permerror ("%s between distinct pointer types %qT and %qT "
+		   "lacks a cast",
+		   location, t1, t2);
       result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
 				       result_type);
     }
@@ -1355,8 +1355,8 @@
   else if (is_overloaded_fn (e))
     {
       if (complain & tf_error)
-        pedwarn ("ISO C++ forbids applying %<sizeof%> to an expression of "
-                 "function type");
+        permerror ("ISO C++ forbids applying %<sizeof%> to an expression of "
+                   "function type");
       else
         return error_mark_node;
       e = char_type_node;
@@ -1415,8 +1415,8 @@
   else if (is_overloaded_fn (e))
     {
       if (complain & tf_error)
-        pedwarn ("ISO C++ forbids applying %<__alignof%> to an expression of "
-                 "function type");
+        permerror ("ISO C++ forbids applying %<__alignof%> to an expression of "
+                   "function type");
       else
         return error_mark_node;
       if (TREE_CODE (e) == FUNCTION_DECL)
@@ -2146,7 +2146,7 @@
       && TREE_CODE (decl) != TEMPLATE_ID_EXPR)
     {
       if (!is_overloaded_fn (decl))
-	pedwarn ("%qD is not a template", decl);
+	permerror ("%qD is not a template", decl);
       else
 	{
 	  tree fns;
@@ -2166,7 +2166,7 @@
 	      fns = OVL_NEXT (fns);
 	    }
 	  if (!fns)
-	    pedwarn ("%qD is not a template", decl);
+	    permerror ("%qD is not a template", decl);
 	}
     }
 }
@@ -3544,7 +3544,7 @@
 	{
 	  result_type = type0;
 	  if (complain & tf_error) 
-            pedwarn ("ISO C++ forbids comparison between pointer and integer");
+            permerror ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
@@ -3552,7 +3552,7 @@
 	{
 	  result_type = type1;
 	  if (complain & tf_error)
-	    pedwarn ("ISO C++ forbids comparison between pointer and integer");
+	    permerror ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
@@ -3732,7 +3732,7 @@
 	{
 	  result_type = type0;
 	  if (complain & tf_error)
-	    pedwarn ("ISO C++ forbids comparison between pointer and integer");
+	    permerror ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
@@ -3740,7 +3740,7 @@
 	{
 	  result_type = type1;
 	  if (complain & tf_error)
-	    pedwarn ("ISO C++ forbids comparison between pointer and integer");
+	    permerror ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
@@ -4111,11 +4111,11 @@
   if (pedantic || warn_pointer_arith)
     {
       if (TREE_CODE (target_type) == VOID_TYPE)
-	pedwarn ("ISO C++ forbids using pointer of type %<void *%> in subtraction");
+	permerror ("ISO C++ forbids using pointer of type %<void *%> in subtraction");
       if (TREE_CODE (target_type) == FUNCTION_TYPE)
-	pedwarn ("ISO C++ forbids using pointer to a function in subtraction");
+	permerror ("ISO C++ forbids using pointer to a function in subtraction");
       if (TREE_CODE (target_type) == METHOD_TYPE)
-	pedwarn ("ISO C++ forbids using pointer to a method in subtraction");
+	permerror ("ISO C++ forbids using pointer to a method in subtraction");
     }
 
   /* First do the subtraction as integers;
@@ -4481,9 +4481,9 @@
 	if (TREE_CODE (argtype) == ENUMERAL_TYPE)
           {
             if (complain & tf_error)
-              pedwarn ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
-                       ? G_("ISO C++ forbids incrementing an enum")
-                       : G_("ISO C++ forbids decrementing an enum"));
+              permerror ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
+                         ? G_("ISO C++ forbids incrementing an enum")
+                         : G_("ISO C++ forbids decrementing an enum"));
             else
               return error_mark_node;
           }
@@ -4509,11 +4509,11 @@
 		     && !TYPE_PTROB_P (argtype)) 
               {
                 if (complain & tf_error)
-                  pedwarn ((code == PREINCREMENT_EXPR
-                            || code == POSTINCREMENT_EXPR)
-                           ? G_("ISO C++ forbids incrementing a pointer of type %qT")
-                           : G_("ISO C++ forbids decrementing a pointer of type %qT"),
-                           argtype);
+                  permerror ((code == PREINCREMENT_EXPR
+                              || code == POSTINCREMENT_EXPR)
+                             ? G_("ISO C++ forbids incrementing a pointer of type %qT")
+                             : G_("ISO C++ forbids decrementing a pointer of type %qT"),
+                             argtype);
                 else
                   return error_mark_node;
               }
@@ -4570,7 +4570,7 @@
         {
           /* ARM $3.4 */
           if (complain & tf_error)
-            pedwarn ("ISO C++ forbids taking address of function %<::main%>");
+            permerror ("ISO C++ forbids taking address of function %<::main%>");
           else
             return error_mark_node;
         }
@@ -4631,15 +4631,15 @@
 	      else if (current_class_type
                        && TREE_OPERAND (arg, 0) == current_class_ref)
                   /* An expression like &memfn.  */
-                pedwarn ("ISO C++ forbids taking the address of an unqualified"
-                         " or parenthesized non-static member function to form"
-                         " a pointer to member function.  Say %<&%T::%D%>",
-                         base, name);
+                permerror ("ISO C++ forbids taking the address of an unqualified"
+                           " or parenthesized non-static member function to form"
+                           " a pointer to member function.  Say %<&%T::%D%>",
+                           base, name);
 	      else
-		pedwarn ("ISO C++ forbids taking the address of a bound member"
-			 " function to form a pointer to member function."
-			 "  Say %<&%T::%D%>",
-			 base, name);
+		permerror ("ISO C++ forbids taking the address of a bound member"
+			   " function to form a pointer to member function."
+			   "  Say %<&%T::%D%>",
+			   base, name);
 	    }
 	  arg = build_offset_ref (base, fn, /*address_p=*/true);
 	}
@@ -4665,7 +4665,7 @@
 	  if (! lvalue_p (arg) && (pedantic || complain == tf_none))
             {
               if (complain & tf_error)
-                pedwarn ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
+                permerror ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
               else
                 return error_mark_node;
             }
@@ -5010,7 +5010,7 @@
   if (TREE_CHAIN (list))
     {
       if (msg)
-	pedwarn ("%s expression list treated as compound expression", msg);
+	permerror ("%s expression list treated as compound expression", msg);
 
       for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
 	expr = build_x_compound_expr (expr, TREE_VALUE (list), 
@@ -5561,8 +5561,8 @@
       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
         {
           if (complain & tf_error)
-            pedwarn ("cast from %qT to %qT loses precision",
-                     intype, type);
+            permerror ("cast from %qT to %qT loses precision",
+                       intype, type);
           else
             return error_mark_node;
         }
@@ -5838,7 +5838,7 @@
       if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
 	{
           if (complain & tf_error)
-            pedwarn ("ISO C++ forbids casting to an array type %qT", type);
+            permerror ("ISO C++ forbids casting to an array type %qT", type);
           else
             return error_mark_node;
 	  type = build_pointer_type (TREE_TYPE (type));
@@ -6964,8 +6964,8 @@
      that's supposed to return a value.  */
   if (!retval && fn_returns_value_p)
     {
-      pedwarn ("return-statement with no value, in function returning %qT",
-	       valtype);
+      permerror ("return-statement with no value, in function returning %qT",
+	         valtype);
       /* Clear this, so finish_function won't say that we reach the
 	 end of a non-void function (which we don't, we gave a
 	 return!).  */
@@ -6985,8 +6985,8 @@
 	   its side-effects.  */
 	  finish_expr_stmt (retval);
       else
-	pedwarn ("return-statement with a value, in function "
-		 "returning 'void'");
+	permerror ("return-statement with a value, in function "
+		   "returning 'void'");
 
       current_function_returns_null = 1;
 
Index: gcc/cp/init.c
===================================================================
--- gcc/cp/init.c	(revision 136847)
+++ gcc/cp/init.c	(working copy)
@@ -533,11 +533,11 @@
 	    }
 	  /* member traversal: note it leaves init NULL */
 	  else if (TREE_CODE (type) == REFERENCE_TYPE)
-	    pedwarn ("%Juninitialized reference member %qD",
-		     current_function_decl, member);
+	    permerror ("%Juninitialized reference member %qD",
+		       current_function_decl, member);
 	  else if (CP_TYPE_CONST_P (type))
-	    pedwarn ("%Juninitialized member %qD with %<const%> type %qT",
-		     current_function_decl, member, type);
+	    permerror ("%Juninitialized member %qD with %<const%> type %qT",
+		       current_function_decl, member, type);
 	}
       else if (TREE_CODE (init) == TREE_LIST)
 	/* There was an explicit member initialization.  Do some work
@@ -2158,7 +2158,7 @@
 	  else if (init)
             {
               if (complain & tf_error)
-                pedwarn ("ISO C++ forbids initialization in array new");
+                permerror ("ISO C++ forbids initialization in array new");
               else
                 return error_mark_node;
             }
@@ -2370,7 +2370,7 @@
       if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, nelts, false))
         {
           if (complain & tf_error)
-            pedwarn ("size in array new must have integral type");
+            permerror ("size in array new must have integral type");
           else
             return error_mark_node;
         }
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 136847)
+++ gcc/cp/decl.c	(working copy)
@@ -1055,8 +1055,8 @@
     return;
 
   name = DECL_ASSEMBLER_NAME (newdecl);
-  pedwarn ("%qD was declared %<extern%> and later %<static%>", newdecl);
-  pedwarn ("previous declaration of %q+D", olddecl);
+  permerror ("%qD was declared %<extern%> and later %<static%>", newdecl);
+  permerror ("previous declaration of %q+D", olddecl);
 }
 
 /* NEW_DECL is a redeclaration of OLD_DECL; both are functions or
@@ -1539,9 +1539,9 @@
 		if (1 == simple_cst_equal (TREE_PURPOSE (t1),
 					   TREE_PURPOSE (t2)))
 		  {
-		    pedwarn ("default argument given for parameter %d of %q#D",
-			     i, newdecl);
-		    pedwarn ("after previous specification in %q+#D", olddecl);
+		    permerror ("default argument given for parameter %d of %q#D",
+			       i, newdecl);
+		    permerror ("after previous specification in %q+#D", olddecl);
 		  }
 		else
 		  {
@@ -2458,11 +2458,11 @@
 identify_goto (tree decl, const location_t *locus)
 {
   if (decl)
-    pedwarn ("jump to label %qD", decl);
+    permerror ("jump to label %qD", decl);
   else
-    pedwarn ("jump to case label");
+    permerror ("jump to case label");
   if (locus)
-    pedwarn ("%H  from here", locus);
+    permerror ("%H  from here", locus);
 }
 
 /* Check that a single previously seen jump to a newly defined label
@@ -2504,7 +2504,7 @@
 	  if (problem > 1)
 	    error ("  crosses initialization of %q+#D", new_decls);
 	  else
-	    pedwarn ("  enters scope of non-POD %q+#D", new_decls);
+	    permerror ("  enters scope of non-POD %q+#D", new_decls);
 	}
 
       if (b == level)
@@ -2600,8 +2600,8 @@
   if (ent->in_try_scope || ent->in_catch_scope
       || ent->in_omp_scope || ent->bad_decls)
     {
-      pedwarn ("jump to label %q+D", decl);
-      pedwarn ("  from here");
+      permerror ("jump to label %q+D", decl);
+      permerror ("  from here");
       identified = true;
     }
 
@@ -2619,7 +2619,7 @@
       else if (u > 1)
 	error ("  skips initialization of %q+#D", b);
       else
-	pedwarn ("  enters scope of non-POD %q+#D", b);
+	permerror ("  enters scope of non-POD %q+#D", b);
     }
 
   if (ent->in_try_scope)
@@ -2640,8 +2640,8 @@
 	    {
 	      if (!identified)
 		{
-		  pedwarn ("jump to label %q+D", decl);
-		  pedwarn ("  from here");
+		  permerror ("jump to label %q+D", decl);
+		  permerror ("  from here");
 		  identified = true;
 		}
 	      error ("  exits OpenMP structured block");
@@ -2693,7 +2693,7 @@
     p->more_cleanups_ok = 0;
 
   if (name == get_identifier ("wchar_t"))
-    pedwarn ("label named wchar_t");
+    permerror ("label named wchar_t");
 
   if (DECL_INITIAL (decl) != NULL_TREE)
     {
@@ -3767,8 +3767,8 @@
   else if (declspecs->redefined_builtin_type)
     {
       if (!in_system_header)
-	pedwarn ("redeclaration of C++ built-in type %qT",
-		 declspecs->redefined_builtin_type);
+	permerror ("redeclaration of C++ built-in type %qT",
+		   declspecs->redefined_builtin_type);
       return NULL_TREE;
     }
 
@@ -3781,7 +3781,7 @@
   else if (declspecs->type == error_mark_node)
     error_p = true;
   if (declared_type == NULL_TREE && ! saw_friend && !error_p)
-    pedwarn ("declaration does not declare anything");
+    permerror ("declaration does not declare anything");
   /* Check for an anonymous union.  */
   else if (declared_type && RECORD_OR_UNION_CODE_P (TREE_CODE (declared_type))
 	   && TYPE_ANONYMOUS_P (declared_type))
@@ -4054,10 +4054,10 @@
 	      if (DECL_CONTEXT (field) != context)
 		{
 		  if (!same_type_p (DECL_CONTEXT (field), context))
-		    pedwarn ("ISO C++ does not permit %<%T::%D%> "
-			     "to be defined as %<%T::%D%>",
-			     DECL_CONTEXT (field), DECL_NAME (decl),
-			     context, DECL_NAME (decl));
+		    permerror ("ISO C++ does not permit %<%T::%D%> "
+			       "to be defined as %<%T::%D%>",
+			       DECL_CONTEXT (field), DECL_NAME (decl),
+			       context, DECL_NAME (decl));
 		  DECL_CONTEXT (decl) = DECL_CONTEXT (field);
 		}
 	      if (processing_specialization
@@ -4110,8 +4110,8 @@
 	}
 
       if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
-	pedwarn ("declaration of %q#D outside of class is not definition",
-		 decl);
+	permerror ("declaration of %q#D outside of class is not definition",
+		   decl);
     }
 
   was_public = TREE_PUBLIC (decl);
@@ -6319,8 +6319,8 @@
      The definition for a static data member shall appear in a
      namespace scope enclosing the member's class definition.  */
   if (!is_ancestor (current_namespace, DECL_CONTEXT (decl)))
-    pedwarn ("definition of %qD is not in namespace enclosing %qT",
-	     decl, DECL_CONTEXT (decl));
+    permerror ("definition of %qD is not in namespace enclosing %qT",
+	       decl, DECL_CONTEXT (decl));
 }
 
 /* Build a PARM_DECL for the "this" parameter.  TYPE is the
@@ -6553,16 +6553,16 @@
 		/* Allow this; it's pretty common in C.  */;
 	      else
 		{
-		  pedwarn ("non-local function %q#D uses anonymous type",
+		  permerror ("non-local function %q#D uses anonymous type",
 			      decl);
 		  if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
-		    pedwarn ("%q+#D does not refer to the unqualified "
-			     "type, so it is not used for linkage",
-			     TYPE_NAME (t));
+		    permerror ("%q+#D does not refer to the unqualified "
+			       "type, so it is not used for linkage",
+			       TYPE_NAME (t));
 		}
 	    }
 	  else
-	    pedwarn ("non-local function %q#D uses local type %qT", decl, t);
+	    permerror ("non-local function %q#D uses local type %qT", decl, t);
 	}
     }
 
@@ -7706,7 +7706,9 @@
 	/* We've already issued an error, don't complain more.  */;
       else if (in_system_header || flag_ms_extensions)
 	/* Allow it, sigh.  */;
-      else if (pedantic || ! is_main)
+      else if (! is_main)
+	permerror ("ISO C++ forbids declaration of %qs with no type", name);
+      else if (pedantic)
 	pedwarn ("ISO C++ forbids declaration of %qs with no type", name);
       else
 	warning (OPT_Wreturn_type,
@@ -8157,7 +8159,7 @@
 		      explicitp = 2;
 		    if (virtualp)
 		      {
-			pedwarn ("constructors cannot be declared virtual");
+			permerror ("constructors cannot be declared virtual");
 			virtualp = 0;
 		      }
 		    if (decl_context == FIELD
@@ -8380,12 +8382,12 @@
 	{
 	  if (friendp)
 	    {
-	      pedwarn ("member functions are implicitly friends of their class");
+	      permerror ("member functions are implicitly friends of their class");
 	      friendp = 0;
 	    }
 	  else
-	    pedwarn ("extra qualification %<%T::%> on member %qs",
-		     ctype, name);
+	    permerror ("extra qualification %<%T::%> on member %qs",
+		       ctype, name);
 	}
       else if (/* If the qualifying type is already complete, then we
 		  can skip the following checks.  */
@@ -8569,9 +8571,9 @@
 	    DECL_ABSTRACT (decl) = 1;
 	}
       else if (constructor_name_p (unqualified_id, current_class_type))
-	pedwarn ("ISO C++ forbids nested type %qD with same name "
-		 "as enclosing class",
-		 unqualified_id);
+	permerror ("ISO C++ forbids nested type %qD with same name "
+		   "as enclosing class",
+		   unqualified_id);
 
       /* If the user declares "typedef struct {...} foo" then the
 	 struct will have an anonymous name.  Fill that name in now.
@@ -8694,15 +8696,15 @@
 	    {
 	      /* Don't allow friend declaration without a class-key.  */
 	      if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
-		pedwarn ("template parameters cannot be friends");
+		permerror ("template parameters cannot be friends");
 	      else if (TREE_CODE (type) == TYPENAME_TYPE)
-		pedwarn ("friend declaration requires class-key, "
-			 "i.e. %<friend class %T::%D%>",
-			 TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
+		permerror ("friend declaration requires class-key, "
+			   "i.e. %<friend class %T::%D%>",
+			   TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
 	      else
-		pedwarn ("friend declaration requires class-key, "
-			 "i.e. %<friend %#T%>",
-			 type);
+		permerror ("friend declaration requires class-key, "
+			   "i.e. %<friend %#T%>",
+			   type);
 	    }
 
 	  /* Only try to do this stuff if we didn't already give up.  */
@@ -8987,7 +8989,7 @@
 	  {
 	    /* Friends are treated specially.  */
 	    if (ctype == current_class_type)
-	      ;  /* We already issued a pedwarn.  */
+	      ;  /* We already issued a permerror.  */
 	    else if (decl && DECL_NAME (decl))
 	      {
 		if (template_class_depth (current_class_type) == 0)
@@ -9028,9 +9030,9 @@
 		       the rest of the compiler does not correctly
 		       handle the initialization unless the member is
 		       static so we make it static below.  */
-		    pedwarn ("ISO C++ forbids initialization of member %qD",
-			     unqualified_id);
-		    pedwarn ("making %qD static", unqualified_id);
+		    permerror ("ISO C++ forbids initialization of member %qD",
+			       unqualified_id);
+		    permerror ("making %qD static", unqualified_id);
 		    staticp = 1;
 		  }
 
@@ -9152,8 +9154,8 @@
 	       declaring main to be static.  */
 	    if (TREE_CODE (type) == METHOD_TYPE)
 	      {
-		pedwarn ("cannot declare member function %qD to have "
-			 "static linkage", decl);
+		permerror ("cannot declare member function %qD to have "
+			   "static linkage", decl);
 		invalid_static = 1;
 	      }
 	    else if (current_function_decl)
@@ -9189,8 +9191,8 @@
 	    DECL_CONTEXT (decl) = ctype;
 	    if (staticp == 1)
 	      {
-		pedwarn ("%<static%> may not be used when defining "
-			 "(as opposed to declaring) a static data member");
+		permerror ("%<static%> may not be used when defining "
+			   "(as opposed to declaring) a static data member");
 		staticp = 0;
 		storage_class = sc_none;
 	      }
Index: gcc/cp/except.c
===================================================================
--- gcc/cp/except.c	(revision 136847)
+++ gcc/cp/except.c	(working copy)
@@ -1015,8 +1015,8 @@
 	if (tsi_end_p (i))
 	  break;
 	if (TREE_TYPE (handler) == NULL_TREE)
-	  pedwarn ("%H%<...%> handler must be the last handler for"
-		   " its try block", EXPR_LOCUS (handler));
+	  permerror ("%H%<...%> handler must be the last handler for"
+		     " its try block", EXPR_LOCUS (handler));
 	else
 	  check_handlers_1 (handler, i);
       }
Index: gcc/cp/friend.c
===================================================================
--- gcc/cp/friend.c	(revision 136847)
+++ gcc/cp/friend.c	(working copy)
@@ -253,8 +253,8 @@
   else if (same_type_p (type, friend_type))
     {
       if (complain)
-	pedwarn ("class %qT is implicitly friends with itself",
-		 type);
+	permerror ("class %qT is implicitly friends with itself",
+		   type);
       return;
     }
 
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 136847)
+++ gcc/cp/typeck2.c	(working copy)
@@ -694,7 +694,7 @@
 		 counted in the length of the constant, but in C++ this would
 		 be invalid.  */
 	      if (size < TREE_STRING_LENGTH (init))
-		pedwarn ("initializer-string for array of chars is too long");
+		permerror ("initializer-string for array of chars is too long");
 	    }
 	  return init;
 	}
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 136847)
+++ gcc/cp/pt.c	(working copy)
@@ -710,8 +710,8 @@
     return true;
   else
     {
-      pedwarn ("specialization of %qD in different namespace", tmpl);
-      pedwarn ("  from definition of %q+#D", tmpl);
+      permerror ("specialization of %qD in different namespace", tmpl);
+      permerror ("  from definition of %q+#D", tmpl);
       return false;
     }
 }
@@ -728,9 +728,9 @@
      namespace of its template.  */
   ns = decl_namespace_context (spec);
   if (!is_ancestor (current_namespace, ns))
-    pedwarn ("explicit instantiation of %qD in namespace %qD "
-	     "(which does not enclose namespace %qD)",
-	     spec, current_namespace, ns);
+    permerror ("explicit instantiation of %qD in namespace %qD "
+	       "(which does not enclose namespace %qD)",
+	       spec, current_namespace, ns);
 }
 
 /* The TYPE is being declared.  If it is a template type, that means it
@@ -811,9 +811,9 @@
 	  if (current_namespace
 	      != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
 	    {
-	      pedwarn ("specializing %q#T in different namespace", type);
-	      pedwarn ("  from definition of %q+#D",
-		       CLASSTYPE_TI_TEMPLATE (type));
+	      permerror ("specializing %q#T in different namespace", type);
+	      permerror ("  from definition of %q+#D",
+		         CLASSTYPE_TI_TEMPLATE (type));
 	    }
 
 	  /* Check for invalid specialization after instantiation:
@@ -2006,7 +2006,7 @@
       for (; t; t = TREE_CHAIN (t))
 	if (TREE_PURPOSE (t))
 	  {
-	    pedwarn
+	    permerror
 	      ("default argument specified in explicit specialization");
 	    break;
 	  }
@@ -4942,8 +4942,8 @@
   if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
       && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
     {
-      pedwarn ("to refer to a type member of a template parameter, "
-	       "use %<typename %E%>", orig_arg);
+      permerror ("to refer to a type member of a template parameter, "
+	         "use %<typename %E%>", orig_arg);
 
       orig_arg = make_typename_type (TREE_OPERAND (arg, 0),
 				     TREE_OPERAND (arg, 1),
@@ -14567,7 +14567,7 @@
 	 the first instantiation was `extern' and the second is not,
 	 and EXTERN_P for the opposite case.  */
       if (DECL_NOT_REALLY_EXTERN (result) && !extern_p)
-	pedwarn ("duplicate explicit instantiation of %q#D", result);
+	permerror ("duplicate explicit instantiation of %q#D", result);
       /* If an "extern" explicit instantiation follows an ordinary
 	 explicit instantiation, the template is instantiated.  */
       if (extern_p)
@@ -14580,7 +14580,7 @@
     }
   else if (!DECL_TEMPLATE_INFO (result))
     {
-      pedwarn ("explicit instantiation of non-template %q#D", result);
+      permerror ("explicit instantiation of non-template %q#D", result);
       return;
     }
 
@@ -14721,7 +14721,7 @@
 
       if (!previous_instantiation_extern_p && !extern_p
 	  && (complain & tf_error))
-	pedwarn ("duplicate explicit instantiation of %q#T", t);
+	permerror ("duplicate explicit instantiation of %q#T", t);
 
       /* If we've already instantiated the template, just return now.  */
       if (!CLASSTYPE_INTERFACE_ONLY (t))
@@ -15168,7 +15168,7 @@
 	   member function or static data member of a class template
 	   shall be present in every translation unit in which it is
 	   explicitly instantiated.  */
-	pedwarn
+	permerror
 	  ("explicit instantiation of %qD but no definition available", d);
 
       /* ??? Historically, we have instantiated inline functions, even
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 136847)
+++ gcc/cp/semantics.c	(working copy)
@@ -2170,7 +2170,7 @@
 {
   if (aggr != class_type_node)
     {
-      pedwarn ("template type parameters must use the keyword %<class%> or %<typename%>");
+      permerror ("template type parameters must use the keyword %<class%> or %<typename%>");
       aggr = class_type_node;
     }
 
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 136847)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -846,8 +846,8 @@
 	      && TREE_CODE (decl) == TREE_CODE (x)
 	      && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl)))
 	    {
-	      pedwarn ("type mismatch with previous external decl of %q#D", x);
-	      pedwarn ("previous external decl of %q+#D", decl);
+	      permerror ("type mismatch with previous external decl of %q#D", x);
+	      permerror ("previous external decl of %q+#D", decl);
 	    }
 	}
 
@@ -1165,7 +1165,7 @@
 
   if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
     {
-      error ("name lookup of %qD changed for new ISO %<for%> scoping",
+      error ("name lookup of %qD changed for ISO %<for%> scoping",
 	     DECL_NAME (decl));
       error ("  cannot use obsolete binding at %q+D because "
 	     "it has a destructor", decl);
@@ -1173,9 +1173,19 @@
     }
   else
     {
-      pedwarn ("name lookup of %qD changed for new ISO %<for%> scoping",
-	       DECL_NAME (decl));
-      pedwarn ("  using obsolete binding at %q+D", decl);
+      permerror ("name lookup of %qD changed for ISO %<for%> scoping",
+	         DECL_NAME (decl));
+      if (flag_permissive)
+        permerror ("  using obsolete binding at %q+D", decl);
+      else
+	{
+	  static bool hint;
+	  if (!hint)
+	    {
+	      inform ("(if you use %<-fpermissive%> G++ will accept your code)");
+	      hint = true;
+	    }
+	}
     }
 
   return decl;
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c	(revision 136847)
+++ gcc/cp/decl2.c	(working copy)
@@ -716,8 +716,8 @@
     VEC_safe_push (tree, gc, pending_statics, decl);
 
   if (LOCAL_CLASS_P (current_class_type))
-    pedwarn ("local class %q#T shall not have static data member %q#D",
-	     current_class_type, decl);
+    permerror ("local class %q#T shall not have static data member %q#D",
+	       current_class_type, decl);
 
   /* Static consts need not be initialized in the class definition.  */
   if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
@@ -1233,15 +1233,15 @@
 	continue;
       if (TREE_CODE (field) != FIELD_DECL)
 	{
-	  pedwarn ("%q+#D invalid; an anonymous union can only "
-		   "have non-static data members", field);
+	  permerror ("%q+#D invalid; an anonymous union can only "
+		     "have non-static data members", field);
 	  continue;
 	}
 
       if (TREE_PRIVATE (field))
-	pedwarn ("private member %q+#D in anonymous union", field);
+	permerror ("private member %q+#D in anonymous union", field);
       else if (TREE_PROTECTED (field))
-	pedwarn ("protected member %q+#D in anonymous union", field);
+	permerror ("protected member %q+#D in anonymous union", field);
 
       if (processing_template_decl)
 	ref = build_min_nt (COMPONENT_REF, object,
@@ -1376,8 +1376,8 @@
     e = 2;
 
   if (e == 2)
-    pedwarn ("%<operator new%> takes type %<size_t%> (%qT) "
-	     "as first parameter", size_type_node);
+    permerror ("%<operator new%> takes type %<size_t%> (%qT) "
+	       "as first parameter", size_type_node);
 
   switch (e)
   {
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 136847)
+++ gcc/cp/parser.c	(working copy)
@@ -4111,10 +4111,10 @@
 	  && !(TREE_CODE (new_scope) == TYPENAME_TYPE
 	       && (TREE_CODE (TYPENAME_TYPE_FULLNAME (new_scope))
 		   == TEMPLATE_ID_EXPR)))
-	pedwarn (TYPE_P (new_scope)
-		 ? "%qT is not a template"
-		 : "%qD is not a template",
-		 new_scope);
+	permerror (TYPE_P (new_scope)
+		   ? "%qT is not a template"
+		   : "%qD is not a template",
+		   new_scope);
       /* If it is a class scope, try to complete it; we are about to
 	 be looking up names inside the class.  */
       if (TYPE_P (new_scope)
@@ -8928,7 +8928,7 @@
   /* Find out what is being initialized.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
     {
-      pedwarn ("anachronistic old-style base class initializer");
+      permerror ("anachronistic old-style base class initializer");
       mem_initializer_id = NULL_TREE;
     }
   else
@@ -9845,7 +9845,7 @@
 	  static bool hint;
 	  if (!hint)
 	    {
-	      inform ("(if you use -fpermissive G++ will accept your code)");
+	      inform ("(if you use %<-fpermissive%> G++ will accept your code)");
 	      hint = true;
 	    }
 	}
@@ -11186,7 +11186,7 @@
       tag_type = typename_type;
       /* The `typename' keyword is only allowed in templates.  */
       if (!processing_template_decl)
-	pedwarn ("using %<typename%> outside of template");
+	permerror ("using %<typename%> outside of template");
     }
   /* Otherwise it must be a class-key.  */
   else
@@ -13865,7 +13865,7 @@
 
       if (!parser->default_arg_ok_p)
 	{
-	  if (!flag_pedantic_errors)
+	  if (flag_permissive)
 	    warning (0, "deprecated use of default argument for parameter of non-function");
 	  else
 	    {
@@ -14758,7 +14758,7 @@
 	 class member of a namespace outside of its namespace.  */
       if (scope == nested_name_specifier)
 	{
-	  pedwarn ("extra qualification ignored");
+	  permerror ("extra qualification not allowed");
 	  nested_name_specifier = NULL_TREE;
 	  num_templates = 0;
 	}
@@ -18121,7 +18121,7 @@
 cp_parser_check_class_key (enum tag_types class_key, tree type)
 {
   if ((TREE_CODE (type) == UNION_TYPE) != (class_key == union_type))
-    pedwarn ("%qs tag used in naming %q#T",
+    permerror ("%qs tag used in naming %q#T",
 	    class_key == union_type ? "union"
 	     : class_key == record_type ? "struct" : "class",
 	     type);

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-17 19:48   ` Jonathan Wakely
@ 2008-06-19  0:27     ` Mark Mitchell
  2008-06-19  8:17       ` Jonathan Wakely
                         ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Mark Mitchell @ 2008-06-19  0:27 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: gcc-patches, gcc, Volker Reichelt, Manuel López-Ibáñez

Jonathan Wakely wrote:

> Could a C++ maintainer please review this patch to turn most pedwarns
> into permerrors.

This patch is OK, with minor nits below.  Thanks for working on this!

> The interesting cases are:
> * when 'main' is declared without a return type. I split one case into
> a permerror and pedwarn.

I think that's OK.

> * Should it really be a hard error for a class to declare itself as a
> friend? I don't think it's expressly forbidden
> e.g. class A { friend class A; };
> I changed this to a permerror, restoring the old  behaviour.

I think this should just be a warning.  I can't find anything in the WP 
that says this is invalid.  (That's why I try to cite the WP when making 
changes -- so that we can go back and check later!)  Please change it to 
a warning.

> * I don't think the pedwarn in joust() in cp/call.c should be a
> permerror, is this a GNU extension?
> 	  if (warn)
> 	    {
> 	      pedwarn ("\
> ISO C++ says that these are ambiguous, even \
> though the worst conversion for the first is better than \
> the worst conversion for the second:");
> 	      print_z_candidate (_("candidate 1:"), w);
> 	      print_z_candidate (_("candidate 2:"), l);
> 	    }

Yes, that is a historical GNU extension.  I think this should just be a 
warning, given that the whole section of code is guarded with !pedantic.

> * I don't know if these in cp/typeck.c should be permerrors, DTRT
> implies not, but should tf_error be changed to tf_warning?

I think "DTRT" here means "do what whoever wrote this code thinks the 
standard should say" not "do what the standard says".  Please make these 
permerrors.

Thanks,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-19  0:27     ` Mark Mitchell
@ 2008-06-19  8:17       ` Jonathan Wakely
  2008-06-19 22:08       ` Jonathan Wakely
  2008-06-19 23:47       ` Jonathan Wakely
  2 siblings, 0 replies; 19+ messages in thread
From: Jonathan Wakely @ 2008-06-19  8:17 UTC (permalink / raw)
  To: Mark Mitchell
  Cc: gcc-patches, gcc, Volker Reichelt, Manuel López-Ibáñez

2008/6/18 Mark Mitchell:
> Jonathan Wakely wrote:
>
>> Could a C++ maintainer please review this patch to turn most pedwarns
>> into permerrors.
>
> This patch is OK, with minor nits below.  Thanks for working on this!

Thanks Mark, I'll submit a revised patch this evening.

Jonathan

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-19  0:27     ` Mark Mitchell
  2008-06-19  8:17       ` Jonathan Wakely
@ 2008-06-19 22:08       ` Jonathan Wakely
  2008-06-19 22:21         ` Mark Mitchell
  2008-06-20  7:26         ` Gabriel Dos Reis
  2008-06-19 23:47       ` Jonathan Wakely
  2 siblings, 2 replies; 19+ messages in thread
From: Jonathan Wakely @ 2008-06-19 22:08 UTC (permalink / raw)
  To: Mark Mitchell
  Cc: gcc-patches, gcc, Volker Reichelt, Manuel López-Ibáñez

2008/6/18 Mark Mitchell:
>> * I don't think the pedwarn in joust() in cp/call.c should be a
>> permerror, is this a GNU extension?
>>          if (warn)
>>            {
>>              pedwarn ("\
>> ISO C++ says that these are ambiguous, even \
>> though the worst conversion for the first is better than \
>> the worst conversion for the second:");
>>              print_z_candidate (_("candidate 1:"), w);
>>              print_z_candidate (_("candidate 2:"), l);
>>            }
>
> Yes, that is a historical GNU extension.  I think this should just be a
> warning, given that the whole section of code is guarded with !pedantic.

OK. Should I also get rid of the escaped newlines and rely on string
concatenation for the text?

Jon




>> * I don't know if these in cp/typeck.c should be permerrors, DTRT
>> implies not, but should tf_error be changed to tf_warning?
>
> I think "DTRT" here means "do what whoever wrote this code thinks the
> standard should say" not "do what the standard says".  Please make these
> permerrors.
>
> Thanks,
>
> --
> Mark Mitchell
> CodeSourcery
> mark@codesourcery.com
> (650) 331-3385 x713
>
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-19 22:08       ` Jonathan Wakely
@ 2008-06-19 22:21         ` Mark Mitchell
  2008-06-20  7:26         ` Gabriel Dos Reis
  1 sibling, 0 replies; 19+ messages in thread
From: Mark Mitchell @ 2008-06-19 22:21 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: gcc-patches, gcc, Volker Reichelt, Manuel López-Ibáñez

Jonathan Wakely wrote:
> 2008/6/18 Mark Mitchell:
>>> * I don't think the pedwarn in joust() in cp/call.c should be a
>>> permerror, is this a GNU extension?
>>>          if (warn)
>>>            {
>>>              pedwarn ("\
>>> ISO C++ says that these are ambiguous, even \
>>> though the worst conversion for the first is better than \
>>> the worst conversion for the second:");
>>>              print_z_candidate (_("candidate 1:"), w);
>>>              print_z_candidate (_("candidate 2:"), l);
>>>            }
>> Yes, that is a historical GNU extension.  I think this should just be a
>> warning, given that the whole section of code is guarded with !pedantic.
> 
> OK. Should I also get rid of the escaped newlines and rely on string
> concatenation for the text?

It's fine if you want to do that, but I don't think it's important 
either way.

Thanks,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-19  0:27     ` Mark Mitchell
  2008-06-19  8:17       ` Jonathan Wakely
  2008-06-19 22:08       ` Jonathan Wakely
@ 2008-06-19 23:47       ` Jonathan Wakely
  2008-06-20 10:29         ` Mark Mitchell
  2 siblings, 1 reply; 19+ messages in thread
From: Jonathan Wakely @ 2008-06-19 23:47 UTC (permalink / raw)
  To: Mark Mitchell
  Cc: gcc-patches, gcc, Volker Reichelt, Manuel López-Ibáñez

[-- Attachment #1: Type: text/plain, Size: 1662 bytes --]

Thanks for the review, here's another patch ...

2008/6/18 Mark Mitchell:
>
>> * Should it really be a hard error for a class to declare itself as a
>> friend? I don't think it's expressly forbidden
>> e.g. class A { friend class A; };
>> I changed this to a permerror, restoring the old  behaviour.
>
> I think this should just be a warning.  I can't find anything in the WP that
> says this is invalid.  (That's why I try to cite the WP when making changes
> -- so that we can go back and check later!)  Please change it to a warning.

Done, plain old warning now.
Declaring a member function a friend of its own class is still a
permerror, which is consistent with comeau.

>> * I don't think the pedwarn in joust() in cp/call.c should be a
>> permerror, is this a GNU extension?
>>          if (warn)
>>            {
>>              pedwarn ("\
>> ISO C++ says that these are ambiguous, even \
>> though the worst conversion for the first is better than \
>> the worst conversion for the second:");
>>              print_z_candidate (_("candidate 1:"), w);
>>              print_z_candidate (_("candidate 2:"), l);
>>            }
>
> Yes, that is a historical GNU extension.  I think this should just be a
> warning, given that the whole section of code is guarded with !pedantic.

Done, plain old warning.

>> * I don't know if these in cp/typeck.c should be permerrors, DTRT
>> implies not, but should tf_error be changed to tf_warning?
>
> I think "DTRT" here means "do what whoever wrote this code thinks the
> standard should say" not "do what the standard says".  Please make these
> permerrors.

Done.

tested linux/x86-64

Shall I commit this?

Jon

[-- Attachment #2: ChangeLog --]
[-- Type: application/octet-stream, Size: 1547 bytes --]

2008-06-20  Jonathan Wakely  <...>

	* typeck.c (composite_pointer_type_r, cxx_sizeof_expr,
	cxx_alignof_expr, check_template_keyword, cp_build_binary_op,
	pointer_diff, cp_build_unary_op, build_x_compound_expr_from_list,
	build_reinterpret_cast_1, cp_build_c_cast, check_return_expr): Change
	pedwarn to permerror.
	* init.c (perform_member_init, build_new_1, build_new): Likewise.
	* decl.c (warn_extern_redeclared_static, duplicate_decls,
	* identify_goto, check_previous_goto_1, check_goto, define_label,
	check_tag_decl, start_decl, check_class_member_definition_namespace,
	grokfndecl, grokdeclarator): Likewise.
	* except.c (check_handlers): Likewise.
	* typeck2.c (digest_init): Likewise.
	* pt.c (check_specialization_namespace,
	check_explicit_instantiation_namespace,
	maybe_process_partial_specialization, check_explicit_specialization,
	convert_template_argument, do_decl_instantiation,
	do_type_instantiation, instantiate_decl): Likewise.
	* semantics.c (finish_template_type_parm): Likewise.
	* name-lookup.c (pushdecl_maybe_friend,
	check_for_out_of_scope_variable): Likewise.
	* decl2.c (finish_static_data_member_decl, build_anon_union_vars,
	coerce_new_type): Likewise.
	* parser.c (cp_parser_nested_name_specifier_opt,
	cp_parser_mem_initializer, cp_parser_elaborated_type_specifier,
	cp_parser_class_head, cp_parser_check_class_key): Likewise.
	(cp_parser_parameter_declaration): Check flag_permissive instead of
	flag_pedantic_errors.
	* call.c (joust): Change pedwarn to warning.
	* friend.c (make_friend_class): Likewise.


[-- Attachment #3: permerrors-2.patch --]
[-- Type: application/octet-stream, Size: 33287 bytes --]

Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 136968)
+++ gcc/cp/typeck.c	(working copy)
@@ -435,9 +435,9 @@
   else
     {
       if (complain & tf_error)
-	pedwarn ("%s between distinct pointer types %qT and %qT "
-		 "lacks a cast",
-		 location, t1, t2);
+	permerror ("%s between distinct pointer types %qT and %qT "
+		   "lacks a cast",
+		   location, t1, t2);
       result_type = void_type_node;
     }
   result_type = cp_build_qualified_type (result_type,
@@ -450,9 +450,9 @@
       if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
 			TYPE_PTRMEM_CLASS_TYPE (t2))
 	  && (complain & tf_error))
-	pedwarn ("%s between distinct pointer types %qT and %qT "
-		 "lacks a cast",
-		 location, t1, t2);
+	permerror ("%s between distinct pointer types %qT and %qT "
+		   "lacks a cast",
+		   location, t1, t2);
       result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
 				       result_type);
     }
@@ -1355,8 +1355,8 @@
   else if (is_overloaded_fn (e))
     {
       if (complain & tf_error)
-        pedwarn ("ISO C++ forbids applying %<sizeof%> to an expression of "
-                 "function type");
+        permerror ("ISO C++ forbids applying %<sizeof%> to an expression of "
+                   "function type");
       else
         return error_mark_node;
       e = char_type_node;
@@ -1415,8 +1415,8 @@
   else if (is_overloaded_fn (e))
     {
       if (complain & tf_error)
-        pedwarn ("ISO C++ forbids applying %<__alignof%> to an expression of "
-                 "function type");
+        permerror ("ISO C++ forbids applying %<__alignof%> to an expression of "
+                   "function type");
       else
         return error_mark_node;
       if (TREE_CODE (e) == FUNCTION_DECL)
@@ -2146,7 +2146,7 @@
       && TREE_CODE (decl) != TEMPLATE_ID_EXPR)
     {
       if (!is_overloaded_fn (decl))
-	pedwarn ("%qD is not a template", decl);
+	permerror ("%qD is not a template", decl);
       else
 	{
 	  tree fns;
@@ -2166,7 +2166,7 @@
 	      fns = OVL_NEXT (fns);
 	    }
 	  if (!fns)
-	    pedwarn ("%qD is not a template", decl);
+	    permerror ("%qD is not a template", decl);
 	}
     }
 }
@@ -3258,8 +3258,8 @@
       if (t != error_mark_node)
 	{
 	  if (complain & tf_error)
-	    pedwarn ("assuming cast to type %qT from overloaded function",
-		     TREE_TYPE (t));
+	    permerror ("assuming cast to type %qT from overloaded function",
+		       TREE_TYPE (t));
 	  op0 = t;
 	}
     }
@@ -3269,8 +3269,8 @@
       if (t != error_mark_node)
 	{
 	  if (complain & tf_error)
-	    pedwarn ("assuming cast to type %qT from overloaded function",
-		     TREE_TYPE (t));
+	    permerror ("assuming cast to type %qT from overloaded function",
+		       TREE_TYPE (t));
 	  op1 = t;
 	}
     }
@@ -3544,7 +3544,7 @@
 	{
 	  result_type = type0;
 	  if (complain & tf_error) 
-            pedwarn ("ISO C++ forbids comparison between pointer and integer");
+            permerror ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
@@ -3552,7 +3552,7 @@
 	{
 	  result_type = type1;
 	  if (complain & tf_error)
-	    pedwarn ("ISO C++ forbids comparison between pointer and integer");
+	    permerror ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
@@ -3732,7 +3732,7 @@
 	{
 	  result_type = type0;
 	  if (complain & tf_error)
-	    pedwarn ("ISO C++ forbids comparison between pointer and integer");
+	    permerror ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
@@ -3740,7 +3740,7 @@
 	{
 	  result_type = type1;
 	  if (complain & tf_error)
-	    pedwarn ("ISO C++ forbids comparison between pointer and integer");
+	    permerror ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
@@ -4111,11 +4111,11 @@
   if (pedantic || warn_pointer_arith)
     {
       if (TREE_CODE (target_type) == VOID_TYPE)
-	pedwarn ("ISO C++ forbids using pointer of type %<void *%> in subtraction");
+	permerror ("ISO C++ forbids using pointer of type %<void *%> in subtraction");
       if (TREE_CODE (target_type) == FUNCTION_TYPE)
-	pedwarn ("ISO C++ forbids using pointer to a function in subtraction");
+	permerror ("ISO C++ forbids using pointer to a function in subtraction");
       if (TREE_CODE (target_type) == METHOD_TYPE)
-	pedwarn ("ISO C++ forbids using pointer to a method in subtraction");
+	permerror ("ISO C++ forbids using pointer to a method in subtraction");
     }
 
   /* First do the subtraction as integers;
@@ -4481,9 +4481,9 @@
 	if (TREE_CODE (argtype) == ENUMERAL_TYPE)
           {
             if (complain & tf_error)
-              pedwarn ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
-                       ? G_("ISO C++ forbids incrementing an enum")
-                       : G_("ISO C++ forbids decrementing an enum"));
+              permerror ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
+                         ? G_("ISO C++ forbids incrementing an enum")
+                         : G_("ISO C++ forbids decrementing an enum"));
             else
               return error_mark_node;
           }
@@ -4509,11 +4509,11 @@
 		     && !TYPE_PTROB_P (argtype)) 
               {
                 if (complain & tf_error)
-                  pedwarn ((code == PREINCREMENT_EXPR
-                            || code == POSTINCREMENT_EXPR)
-                           ? G_("ISO C++ forbids incrementing a pointer of type %qT")
-                           : G_("ISO C++ forbids decrementing a pointer of type %qT"),
-                           argtype);
+                  permerror ((code == PREINCREMENT_EXPR
+                              || code == POSTINCREMENT_EXPR)
+                             ? G_("ISO C++ forbids incrementing a pointer of type %qT")
+                             : G_("ISO C++ forbids decrementing a pointer of type %qT"),
+                             argtype);
                 else
                   return error_mark_node;
               }
@@ -4570,7 +4570,7 @@
         {
           /* ARM $3.4 */
           if (complain & tf_error)
-            pedwarn ("ISO C++ forbids taking address of function %<::main%>");
+            permerror ("ISO C++ forbids taking address of function %<::main%>");
           else
             return error_mark_node;
         }
@@ -4631,15 +4631,15 @@
 	      else if (current_class_type
                        && TREE_OPERAND (arg, 0) == current_class_ref)
                   /* An expression like &memfn.  */
-                pedwarn ("ISO C++ forbids taking the address of an unqualified"
-                         " or parenthesized non-static member function to form"
-                         " a pointer to member function.  Say %<&%T::%D%>",
-                         base, name);
+                permerror ("ISO C++ forbids taking the address of an unqualified"
+                           " or parenthesized non-static member function to form"
+                           " a pointer to member function.  Say %<&%T::%D%>",
+                           base, name);
 	      else
-		pedwarn ("ISO C++ forbids taking the address of a bound member"
-			 " function to form a pointer to member function."
-			 "  Say %<&%T::%D%>",
-			 base, name);
+		permerror ("ISO C++ forbids taking the address of a bound member"
+			   " function to form a pointer to member function."
+			   "  Say %<&%T::%D%>",
+			   base, name);
 	    }
 	  arg = build_offset_ref (base, fn, /*address_p=*/true);
 	}
@@ -4665,7 +4665,7 @@
 	  if (! lvalue_p (arg) && (pedantic || complain == tf_none))
             {
               if (complain & tf_error)
-                pedwarn ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
+                permerror ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
               else
                 return error_mark_node;
             }
@@ -5010,7 +5010,7 @@
   if (TREE_CHAIN (list))
     {
       if (msg)
-	pedwarn ("%s expression list treated as compound expression", msg);
+	permerror ("%s expression list treated as compound expression", msg);
 
       for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
 	expr = build_x_compound_expr (expr, TREE_VALUE (list), 
@@ -5561,8 +5561,8 @@
       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
         {
           if (complain & tf_error)
-            pedwarn ("cast from %qT to %qT loses precision",
-                     intype, type);
+            permerror ("cast from %qT to %qT loses precision",
+                       intype, type);
           else
             return error_mark_node;
         }
@@ -5838,7 +5838,7 @@
       if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
 	{
           if (complain & tf_error)
-            pedwarn ("ISO C++ forbids casting to an array type %qT", type);
+            permerror ("ISO C++ forbids casting to an array type %qT", type);
           else
             return error_mark_node;
 	  type = build_pointer_type (TREE_TYPE (type));
@@ -6964,8 +6964,8 @@
      that's supposed to return a value.  */
   if (!retval && fn_returns_value_p)
     {
-      pedwarn ("return-statement with no value, in function returning %qT",
-	       valtype);
+      permerror ("return-statement with no value, in function returning %qT",
+	         valtype);
       /* Clear this, so finish_function won't say that we reach the
 	 end of a non-void function (which we don't, we gave a
 	 return!).  */
@@ -6985,8 +6985,8 @@
 	   its side-effects.  */
 	  finish_expr_stmt (retval);
       else
-	pedwarn ("return-statement with a value, in function "
-		 "returning 'void'");
+	permerror ("return-statement with a value, in function "
+		   "returning 'void'");
 
       current_function_returns_null = 1;
 
Index: gcc/cp/init.c
===================================================================
--- gcc/cp/init.c	(revision 136968)
+++ gcc/cp/init.c	(working copy)
@@ -533,11 +533,11 @@
 	    }
 	  /* member traversal: note it leaves init NULL */
 	  else if (TREE_CODE (type) == REFERENCE_TYPE)
-	    pedwarn ("%Juninitialized reference member %qD",
-		     current_function_decl, member);
+	    permerror ("%Juninitialized reference member %qD",
+		       current_function_decl, member);
 	  else if (CP_TYPE_CONST_P (type))
-	    pedwarn ("%Juninitialized member %qD with %<const%> type %qT",
-		     current_function_decl, member, type);
+	    permerror ("%Juninitialized member %qD with %<const%> type %qT",
+		       current_function_decl, member, type);
 	}
       else if (TREE_CODE (init) == TREE_LIST)
 	/* There was an explicit member initialization.  Do some work
@@ -2158,7 +2158,7 @@
 	  else if (init)
             {
               if (complain & tf_error)
-                pedwarn ("ISO C++ forbids initialization in array new");
+                permerror ("ISO C++ forbids initialization in array new");
               else
                 return error_mark_node;
             }
@@ -2370,7 +2370,7 @@
       if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, nelts, false))
         {
           if (complain & tf_error)
-            pedwarn ("size in array new must have integral type");
+            permerror ("size in array new must have integral type");
           else
             return error_mark_node;
         }
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 136968)
+++ gcc/cp/decl.c	(working copy)
@@ -1055,8 +1055,8 @@
     return;
 
   name = DECL_ASSEMBLER_NAME (newdecl);
-  pedwarn ("%qD was declared %<extern%> and later %<static%>", newdecl);
-  pedwarn ("previous declaration of %q+D", olddecl);
+  permerror ("%qD was declared %<extern%> and later %<static%>", newdecl);
+  permerror ("previous declaration of %q+D", olddecl);
 }
 
 /* NEW_DECL is a redeclaration of OLD_DECL; both are functions or
@@ -1539,9 +1539,9 @@
 		if (1 == simple_cst_equal (TREE_PURPOSE (t1),
 					   TREE_PURPOSE (t2)))
 		  {
-		    pedwarn ("default argument given for parameter %d of %q#D",
-			     i, newdecl);
-		    pedwarn ("after previous specification in %q+#D", olddecl);
+		    permerror ("default argument given for parameter %d of %q#D",
+			       i, newdecl);
+		    permerror ("after previous specification in %q+#D", olddecl);
 		  }
 		else
 		  {
@@ -2458,11 +2458,11 @@
 identify_goto (tree decl, const location_t *locus)
 {
   if (decl)
-    pedwarn ("jump to label %qD", decl);
+    permerror ("jump to label %qD", decl);
   else
-    pedwarn ("jump to case label");
+    permerror ("jump to case label");
   if (locus)
-    pedwarn ("%H  from here", locus);
+    permerror ("%H  from here", locus);
 }
 
 /* Check that a single previously seen jump to a newly defined label
@@ -2504,7 +2504,7 @@
 	  if (problem > 1)
 	    error ("  crosses initialization of %q+#D", new_decls);
 	  else
-	    pedwarn ("  enters scope of non-POD %q+#D", new_decls);
+	    permerror ("  enters scope of non-POD %q+#D", new_decls);
 	}
 
       if (b == level)
@@ -2600,8 +2600,8 @@
   if (ent->in_try_scope || ent->in_catch_scope
       || ent->in_omp_scope || ent->bad_decls)
     {
-      pedwarn ("jump to label %q+D", decl);
-      pedwarn ("  from here");
+      permerror ("jump to label %q+D", decl);
+      permerror ("  from here");
       identified = true;
     }
 
@@ -2619,7 +2619,7 @@
       else if (u > 1)
 	error ("  skips initialization of %q+#D", b);
       else
-	pedwarn ("  enters scope of non-POD %q+#D", b);
+	permerror ("  enters scope of non-POD %q+#D", b);
     }
 
   if (ent->in_try_scope)
@@ -2640,8 +2640,8 @@
 	    {
 	      if (!identified)
 		{
-		  pedwarn ("jump to label %q+D", decl);
-		  pedwarn ("  from here");
+		  permerror ("jump to label %q+D", decl);
+		  permerror ("  from here");
 		  identified = true;
 		}
 	      error ("  exits OpenMP structured block");
@@ -2693,7 +2693,7 @@
     p->more_cleanups_ok = 0;
 
   if (name == get_identifier ("wchar_t"))
-    pedwarn ("label named wchar_t");
+    permerror ("label named wchar_t");
 
   if (DECL_INITIAL (decl) != NULL_TREE)
     {
@@ -3767,8 +3767,8 @@
   else if (declspecs->redefined_builtin_type)
     {
       if (!in_system_header)
-	pedwarn ("redeclaration of C++ built-in type %qT",
-		 declspecs->redefined_builtin_type);
+	permerror ("redeclaration of C++ built-in type %qT",
+		   declspecs->redefined_builtin_type);
       return NULL_TREE;
     }
 
@@ -3781,7 +3781,7 @@
   else if (declspecs->type == error_mark_node)
     error_p = true;
   if (declared_type == NULL_TREE && ! saw_friend && !error_p)
-    pedwarn ("declaration does not declare anything");
+    permerror ("declaration does not declare anything");
   /* Check for an anonymous union.  */
   else if (declared_type && RECORD_OR_UNION_CODE_P (TREE_CODE (declared_type))
 	   && TYPE_ANONYMOUS_P (declared_type))
@@ -4054,10 +4054,10 @@
 	      if (DECL_CONTEXT (field) != context)
 		{
 		  if (!same_type_p (DECL_CONTEXT (field), context))
-		    pedwarn ("ISO C++ does not permit %<%T::%D%> "
-			     "to be defined as %<%T::%D%>",
-			     DECL_CONTEXT (field), DECL_NAME (decl),
-			     context, DECL_NAME (decl));
+		    permerror ("ISO C++ does not permit %<%T::%D%> "
+			       "to be defined as %<%T::%D%>",
+			       DECL_CONTEXT (field), DECL_NAME (decl),
+			       context, DECL_NAME (decl));
 		  DECL_CONTEXT (decl) = DECL_CONTEXT (field);
 		}
 	      if (processing_specialization
@@ -4110,8 +4110,8 @@
 	}
 
       if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
-	pedwarn ("declaration of %q#D outside of class is not definition",
-		 decl);
+	permerror ("declaration of %q#D outside of class is not definition",
+		   decl);
     }
 
   was_public = TREE_PUBLIC (decl);
@@ -6319,8 +6319,8 @@
      The definition for a static data member shall appear in a
      namespace scope enclosing the member's class definition.  */
   if (!is_ancestor (current_namespace, DECL_CONTEXT (decl)))
-    pedwarn ("definition of %qD is not in namespace enclosing %qT",
-	     decl, DECL_CONTEXT (decl));
+    permerror ("definition of %qD is not in namespace enclosing %qT",
+	       decl, DECL_CONTEXT (decl));
 }
 
 /* Build a PARM_DECL for the "this" parameter.  TYPE is the
@@ -6553,16 +6553,16 @@
 		/* Allow this; it's pretty common in C.  */;
 	      else
 		{
-		  pedwarn ("non-local function %q#D uses anonymous type",
+		  permerror ("non-local function %q#D uses anonymous type",
 			      decl);
 		  if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
-		    pedwarn ("%q+#D does not refer to the unqualified "
-			     "type, so it is not used for linkage",
-			     TYPE_NAME (t));
+		    permerror ("%q+#D does not refer to the unqualified "
+			       "type, so it is not used for linkage",
+			       TYPE_NAME (t));
 		}
 	    }
 	  else
-	    pedwarn ("non-local function %q#D uses local type %qT", decl, t);
+	    permerror ("non-local function %q#D uses local type %qT", decl, t);
 	}
     }
 
@@ -7706,7 +7706,9 @@
 	/* We've already issued an error, don't complain more.  */;
       else if (in_system_header || flag_ms_extensions)
 	/* Allow it, sigh.  */;
-      else if (pedantic || ! is_main)
+      else if (! is_main)
+	permerror ("ISO C++ forbids declaration of %qs with no type", name);
+      else if (pedantic)
 	pedwarn ("ISO C++ forbids declaration of %qs with no type", name);
       else
 	warning (OPT_Wreturn_type,
@@ -8157,7 +8159,7 @@
 		      explicitp = 2;
 		    if (virtualp)
 		      {
-			pedwarn ("constructors cannot be declared virtual");
+			permerror ("constructors cannot be declared virtual");
 			virtualp = 0;
 		      }
 		    if (decl_context == FIELD
@@ -8380,12 +8382,12 @@
 	{
 	  if (friendp)
 	    {
-	      pedwarn ("member functions are implicitly friends of their class");
+	      permerror ("member functions are implicitly friends of their class");
 	      friendp = 0;
 	    }
 	  else
-	    pedwarn ("extra qualification %<%T::%> on member %qs",
-		     ctype, name);
+	    permerror ("extra qualification %<%T::%> on member %qs",
+		       ctype, name);
 	}
       else if (/* If the qualifying type is already complete, then we
 		  can skip the following checks.  */
@@ -8569,9 +8571,9 @@
 	    DECL_ABSTRACT (decl) = 1;
 	}
       else if (constructor_name_p (unqualified_id, current_class_type))
-	pedwarn ("ISO C++ forbids nested type %qD with same name "
-		 "as enclosing class",
-		 unqualified_id);
+	permerror ("ISO C++ forbids nested type %qD with same name "
+		   "as enclosing class",
+		   unqualified_id);
 
       /* If the user declares "typedef struct {...} foo" then the
 	 struct will have an anonymous name.  Fill that name in now.
@@ -8694,15 +8696,15 @@
 	    {
 	      /* Don't allow friend declaration without a class-key.  */
 	      if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
-		pedwarn ("template parameters cannot be friends");
+		permerror ("template parameters cannot be friends");
 	      else if (TREE_CODE (type) == TYPENAME_TYPE)
-		pedwarn ("friend declaration requires class-key, "
-			 "i.e. %<friend class %T::%D%>",
-			 TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
+		permerror ("friend declaration requires class-key, "
+			   "i.e. %<friend class %T::%D%>",
+			   TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
 	      else
-		pedwarn ("friend declaration requires class-key, "
-			 "i.e. %<friend %#T%>",
-			 type);
+		permerror ("friend declaration requires class-key, "
+			   "i.e. %<friend %#T%>",
+			   type);
 	    }
 
 	  /* Only try to do this stuff if we didn't already give up.  */
@@ -8987,7 +8989,7 @@
 	  {
 	    /* Friends are treated specially.  */
 	    if (ctype == current_class_type)
-	      ;  /* We already issued a pedwarn.  */
+	      ;  /* We already issued a permerror.  */
 	    else if (decl && DECL_NAME (decl))
 	      {
 		if (template_class_depth (current_class_type) == 0)
@@ -9028,9 +9030,9 @@
 		       the rest of the compiler does not correctly
 		       handle the initialization unless the member is
 		       static so we make it static below.  */
-		    pedwarn ("ISO C++ forbids initialization of member %qD",
-			     unqualified_id);
-		    pedwarn ("making %qD static", unqualified_id);
+		    permerror ("ISO C++ forbids initialization of member %qD",
+			       unqualified_id);
+		    permerror ("making %qD static", unqualified_id);
 		    staticp = 1;
 		  }
 
@@ -9152,8 +9154,8 @@
 	       declaring main to be static.  */
 	    if (TREE_CODE (type) == METHOD_TYPE)
 	      {
-		pedwarn ("cannot declare member function %qD to have "
-			 "static linkage", decl);
+		permerror ("cannot declare member function %qD to have "
+			   "static linkage", decl);
 		invalid_static = 1;
 	      }
 	    else if (current_function_decl)
@@ -9189,8 +9191,8 @@
 	    DECL_CONTEXT (decl) = ctype;
 	    if (staticp == 1)
 	      {
-		pedwarn ("%<static%> may not be used when defining "
-			 "(as opposed to declaring) a static data member");
+		permerror ("%<static%> may not be used when defining "
+			   "(as opposed to declaring) a static data member");
 		staticp = 0;
 		storage_class = sc_none;
 	      }
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 136968)
+++ gcc/cp/call.c	(working copy)
@@ -6563,10 +6563,10 @@
 	{
 	  if (warn)
 	    {
-	      pedwarn ("\
-ISO C++ says that these are ambiguous, even \
-though the worst conversion for the first is better than \
-the worst conversion for the second:");
+	      warning (0,
+	      "ISO C++ says that these are ambiguous, even "
+	      "though the worst conversion for the first is better than "
+	      "the worst conversion for the second:");
 	      print_z_candidate (_("candidate 1:"), w);
 	      print_z_candidate (_("candidate 2:"), l);
 	    }
Index: gcc/cp/except.c
===================================================================
--- gcc/cp/except.c	(revision 136968)
+++ gcc/cp/except.c	(working copy)
@@ -1015,8 +1015,8 @@
 	if (tsi_end_p (i))
 	  break;
 	if (TREE_TYPE (handler) == NULL_TREE)
-	  pedwarn ("%H%<...%> handler must be the last handler for"
-		   " its try block", EXPR_LOCUS (handler));
+	  permerror ("%H%<...%> handler must be the last handler for"
+		     " its try block", EXPR_LOCUS (handler));
 	else
 	  check_handlers_1 (handler, i);
       }
Index: gcc/cp/friend.c
===================================================================
--- gcc/cp/friend.c	(revision 136968)
+++ gcc/cp/friend.c	(working copy)
@@ -253,7 +253,7 @@
   else if (same_type_p (type, friend_type))
     {
       if (complain)
-	pedwarn ("class %qT is implicitly friends with itself",
+	warning (0, "class %qT is implicitly friends with itself",
 		 type);
       return;
     }
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 136968)
+++ gcc/cp/typeck2.c	(working copy)
@@ -694,7 +694,7 @@
 		 counted in the length of the constant, but in C++ this would
 		 be invalid.  */
 	      if (size < TREE_STRING_LENGTH (init))
-		pedwarn ("initializer-string for array of chars is too long");
+		permerror ("initializer-string for array of chars is too long");
 	    }
 	  return init;
 	}
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 136968)
+++ gcc/cp/pt.c	(working copy)
@@ -710,8 +710,8 @@
     return true;
   else
     {
-      pedwarn ("specialization of %qD in different namespace", tmpl);
-      pedwarn ("  from definition of %q+#D", tmpl);
+      permerror ("specialization of %qD in different namespace", tmpl);
+      permerror ("  from definition of %q+#D", tmpl);
       return false;
     }
 }
@@ -728,9 +728,9 @@
      namespace of its template.  */
   ns = decl_namespace_context (spec);
   if (!is_ancestor (current_namespace, ns))
-    pedwarn ("explicit instantiation of %qD in namespace %qD "
-	     "(which does not enclose namespace %qD)",
-	     spec, current_namespace, ns);
+    permerror ("explicit instantiation of %qD in namespace %qD "
+	       "(which does not enclose namespace %qD)",
+	       spec, current_namespace, ns);
 }
 
 /* The TYPE is being declared.  If it is a template type, that means it
@@ -811,9 +811,9 @@
 	  if (current_namespace
 	      != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
 	    {
-	      pedwarn ("specializing %q#T in different namespace", type);
-	      pedwarn ("  from definition of %q+#D",
-		       CLASSTYPE_TI_TEMPLATE (type));
+	      permerror ("specializing %q#T in different namespace", type);
+	      permerror ("  from definition of %q+#D",
+		         CLASSTYPE_TI_TEMPLATE (type));
 	    }
 
 	  /* Check for invalid specialization after instantiation:
@@ -2006,7 +2006,7 @@
       for (; t; t = TREE_CHAIN (t))
 	if (TREE_PURPOSE (t))
 	  {
-	    pedwarn
+	    permerror
 	      ("default argument specified in explicit specialization");
 	    break;
 	  }
@@ -4942,8 +4942,8 @@
   if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
       && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
     {
-      pedwarn ("to refer to a type member of a template parameter, "
-	       "use %<typename %E%>", orig_arg);
+      permerror ("to refer to a type member of a template parameter, "
+	         "use %<typename %E%>", orig_arg);
 
       orig_arg = make_typename_type (TREE_OPERAND (arg, 0),
 				     TREE_OPERAND (arg, 1),
@@ -14567,7 +14567,7 @@
 	 the first instantiation was `extern' and the second is not,
 	 and EXTERN_P for the opposite case.  */
       if (DECL_NOT_REALLY_EXTERN (result) && !extern_p)
-	pedwarn ("duplicate explicit instantiation of %q#D", result);
+	permerror ("duplicate explicit instantiation of %q#D", result);
       /* If an "extern" explicit instantiation follows an ordinary
 	 explicit instantiation, the template is instantiated.  */
       if (extern_p)
@@ -14580,7 +14580,7 @@
     }
   else if (!DECL_TEMPLATE_INFO (result))
     {
-      pedwarn ("explicit instantiation of non-template %q#D", result);
+      permerror ("explicit instantiation of non-template %q#D", result);
       return;
     }
 
@@ -14721,7 +14721,7 @@
 
       if (!previous_instantiation_extern_p && !extern_p
 	  && (complain & tf_error))
-	pedwarn ("duplicate explicit instantiation of %q#T", t);
+	permerror ("duplicate explicit instantiation of %q#T", t);
 
       /* If we've already instantiated the template, just return now.  */
       if (!CLASSTYPE_INTERFACE_ONLY (t))
@@ -15168,7 +15168,7 @@
 	   member function or static data member of a class template
 	   shall be present in every translation unit in which it is
 	   explicitly instantiated.  */
-	pedwarn
+	permerror
 	  ("explicit instantiation of %qD but no definition available", d);
 
       /* ??? Historically, we have instantiated inline functions, even
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 136968)
+++ gcc/cp/semantics.c	(working copy)
@@ -2170,7 +2170,7 @@
 {
   if (aggr != class_type_node)
     {
-      pedwarn ("template type parameters must use the keyword %<class%> or %<typename%>");
+      permerror ("template type parameters must use the keyword %<class%> or %<typename%>");
       aggr = class_type_node;
     }
 
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 136968)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -846,8 +846,8 @@
 	      && TREE_CODE (decl) == TREE_CODE (x)
 	      && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl)))
 	    {
-	      pedwarn ("type mismatch with previous external decl of %q#D", x);
-	      pedwarn ("previous external decl of %q+#D", decl);
+	      permerror ("type mismatch with previous external decl of %q#D", x);
+	      permerror ("previous external decl of %q+#D", decl);
 	    }
 	}
 
@@ -1165,7 +1165,7 @@
 
   if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
     {
-      error ("name lookup of %qD changed for new ISO %<for%> scoping",
+      error ("name lookup of %qD changed for ISO %<for%> scoping",
 	     DECL_NAME (decl));
       error ("  cannot use obsolete binding at %q+D because "
 	     "it has a destructor", decl);
@@ -1173,9 +1173,19 @@
     }
   else
     {
-      pedwarn ("name lookup of %qD changed for new ISO %<for%> scoping",
-	       DECL_NAME (decl));
-      pedwarn ("  using obsolete binding at %q+D", decl);
+      permerror ("name lookup of %qD changed for ISO %<for%> scoping",
+	         DECL_NAME (decl));
+      if (flag_permissive)
+        permerror ("  using obsolete binding at %q+D", decl);
+      else
+	{
+	  static bool hint;
+	  if (!hint)
+	    {
+	      inform ("(if you use %<-fpermissive%> G++ will accept your code)");
+	      hint = true;
+	    }
+	}
     }
 
   return decl;
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c	(revision 136968)
+++ gcc/cp/decl2.c	(working copy)
@@ -716,8 +716,8 @@
     VEC_safe_push (tree, gc, pending_statics, decl);
 
   if (LOCAL_CLASS_P (current_class_type))
-    pedwarn ("local class %q#T shall not have static data member %q#D",
-	     current_class_type, decl);
+    permerror ("local class %q#T shall not have static data member %q#D",
+	       current_class_type, decl);
 
   /* Static consts need not be initialized in the class definition.  */
   if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
@@ -1233,15 +1233,15 @@
 	continue;
       if (TREE_CODE (field) != FIELD_DECL)
 	{
-	  pedwarn ("%q+#D invalid; an anonymous union can only "
-		   "have non-static data members", field);
+	  permerror ("%q+#D invalid; an anonymous union can only "
+		     "have non-static data members", field);
 	  continue;
 	}
 
       if (TREE_PRIVATE (field))
-	pedwarn ("private member %q+#D in anonymous union", field);
+	permerror ("private member %q+#D in anonymous union", field);
       else if (TREE_PROTECTED (field))
-	pedwarn ("protected member %q+#D in anonymous union", field);
+	permerror ("protected member %q+#D in anonymous union", field);
 
       if (processing_template_decl)
 	ref = build_min_nt (COMPONENT_REF, object,
@@ -1376,8 +1376,8 @@
     e = 2;
 
   if (e == 2)
-    pedwarn ("%<operator new%> takes type %<size_t%> (%qT) "
-	     "as first parameter", size_type_node);
+    permerror ("%<operator new%> takes type %<size_t%> (%qT) "
+	       "as first parameter", size_type_node);
 
   switch (e)
   {
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 136968)
+++ gcc/cp/parser.c	(working copy)
@@ -4111,10 +4111,10 @@
 	  && !(TREE_CODE (new_scope) == TYPENAME_TYPE
 	       && (TREE_CODE (TYPENAME_TYPE_FULLNAME (new_scope))
 		   == TEMPLATE_ID_EXPR)))
-	pedwarn (TYPE_P (new_scope)
-		 ? "%qT is not a template"
-		 : "%qD is not a template",
-		 new_scope);
+	permerror (TYPE_P (new_scope)
+		   ? "%qT is not a template"
+		   : "%qD is not a template",
+		   new_scope);
       /* If it is a class scope, try to complete it; we are about to
 	 be looking up names inside the class.  */
       if (TYPE_P (new_scope)
@@ -8928,7 +8928,7 @@
   /* Find out what is being initialized.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
     {
-      pedwarn ("anachronistic old-style base class initializer");
+      permerror ("anachronistic old-style base class initializer");
       mem_initializer_id = NULL_TREE;
     }
   else
@@ -9845,7 +9845,7 @@
 	  static bool hint;
 	  if (!hint)
 	    {
-	      inform ("(if you use -fpermissive G++ will accept your code)");
+	      inform ("(if you use %<-fpermissive%> G++ will accept your code)");
 	      hint = true;
 	    }
 	}
@@ -11186,7 +11186,7 @@
       tag_type = typename_type;
       /* The `typename' keyword is only allowed in templates.  */
       if (!processing_template_decl)
-	pedwarn ("using %<typename%> outside of template");
+	permerror ("using %<typename%> outside of template");
     }
   /* Otherwise it must be a class-key.  */
   else
@@ -13865,7 +13865,7 @@
 
       if (!parser->default_arg_ok_p)
 	{
-	  if (!flag_pedantic_errors)
+	  if (flag_permissive)
 	    warning (0, "deprecated use of default argument for parameter of non-function");
 	  else
 	    {
@@ -14758,7 +14758,7 @@
 	 class member of a namespace outside of its namespace.  */
       if (scope == nested_name_specifier)
 	{
-	  pedwarn ("extra qualification ignored");
+	  permerror ("extra qualification not allowed");
 	  nested_name_specifier = NULL_TREE;
 	  num_templates = 0;
 	}
@@ -18121,7 +18121,7 @@
 cp_parser_check_class_key (enum tag_types class_key, tree type)
 {
   if ((TREE_CODE (type) == UNION_TYPE) != (class_key == union_type))
-    pedwarn ("%qs tag used in naming %q#T",
+    permerror ("%qs tag used in naming %q#T",
 	    class_key == union_type ? "union"
 	     : class_key == record_type ? "struct" : "class",
 	     type);

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-19 22:08       ` Jonathan Wakely
  2008-06-19 22:21         ` Mark Mitchell
@ 2008-06-20  7:26         ` Gabriel Dos Reis
  1 sibling, 0 replies; 19+ messages in thread
From: Gabriel Dos Reis @ 2008-06-20  7:26 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: Mark Mitchell, gcc-patches, gcc, Volker Reichelt,
	Manuel López-Ibáñez

On Thu, Jun 19, 2008 at 5:08 PM, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> 2008/6/18 Mark Mitchell:
>>> * I don't think the pedwarn in joust() in cp/call.c should be a
>>> permerror, is this a GNU extension?
>>>          if (warn)
>>>            {
>>>              pedwarn ("\
>>> ISO C++ says that these are ambiguous, even \
>>> though the worst conversion for the first is better than \
>>> the worst conversion for the second:");
>>>              print_z_candidate (_("candidate 1:"), w);
>>>              print_z_candidate (_("candidate 2:"), l);
>>>            }
>>
>> Yes, that is a historical GNU extension.  I think this should just be a
>> warning, given that the whole section of code is guarded with !pedantic.
>
> OK. Should I also get rid of the escaped newlines and rely on string
> concatenation for the text?

yes, please.

>
> Jon
>
>
>
>
>>> * I don't know if these in cp/typeck.c should be permerrors, DTRT
>>> implies not, but should tf_error be changed to tf_warning?
>>
>> I think "DTRT" here means "do what whoever wrote this code thinks the
>> standard should say" not "do what the standard says".  Please make these
>> permerrors.
>>
>> Thanks,
>>
>> --
>> Mark Mitchell
>> CodeSourcery
>> mark@codesourcery.com
>> (650) 331-3385 x713
>>
>>
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-19 23:47       ` Jonathan Wakely
@ 2008-06-20 10:29         ` Mark Mitchell
  2008-06-21 11:13           ` Jonathan Wakely
  0 siblings, 1 reply; 19+ messages in thread
From: Mark Mitchell @ 2008-06-20 10:29 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: gcc-patches, gcc, Volker Reichelt, Manuel López-Ibáñez

Jonathan Wakely wrote:
> Thanks for the review, here's another patch ...

> Shall I commit this?

Yes, please.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ warnings vs. errors
  2008-06-20 10:29         ` Mark Mitchell
@ 2008-06-21 11:13           ` Jonathan Wakely
  0 siblings, 0 replies; 19+ messages in thread
From: Jonathan Wakely @ 2008-06-21 11:13 UTC (permalink / raw)
  To: Mark Mitchell
  Cc: gcc-patches, gcc, Volker Reichelt, Manuel López-Ibáñez

2008/6/20 Mark Mitchell:
>
>> Shall I commit this?
>
> Yes, please.

Thanks, Mark, I've  committed it.
Volker, all the problems you noticed should be fixed, if you find any
other cases that seem wrong please let me know.

Cheers,

Jonathan

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2008-06-21 11:13 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-11 14:12 C++ warnings vs. errors Volker Reichelt
2008-06-11 14:48 ` Ian Lance Taylor
2008-06-11 18:48   ` Manuel López-Ibáñez
2008-06-11 20:24 ` Joe Buck
2008-06-11 23:06 ` Jonathan Wakely
2008-06-13 19:48   ` Mark Mitchell
2008-06-13 21:20     ` Manuel López-Ibáñez
2008-06-15 23:06     ` Jonathan Wakely
2008-06-16  2:32       ` Mark Mitchell
2008-06-16 10:13       ` Manuel López-Ibáñez
2008-06-17 19:48   ` Jonathan Wakely
2008-06-19  0:27     ` Mark Mitchell
2008-06-19  8:17       ` Jonathan Wakely
2008-06-19 22:08       ` Jonathan Wakely
2008-06-19 22:21         ` Mark Mitchell
2008-06-20  7:26         ` Gabriel Dos Reis
2008-06-19 23:47       ` Jonathan Wakely
2008-06-20 10:29         ` Mark Mitchell
2008-06-21 11:13           ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).