c++: Avoid informs without a warning [PR109278]

Message ID ZB7IBe1ytkKihzTP@tucnak
State New
Headers
Series c++: Avoid informs without a warning [PR109278] |

Commit Message

Jakub Jelinek March 25, 2023, 10:10 a.m. UTC
  Hi!

On the following testcase we emit notes in
maybe_inform_about_fndecl_for_bogus_argument_init
despite no warning/error being printed before it.
This is for the extended floating point type conversions where pedwarn
is used, and complained is used there for 2 different purposes,
one is whether an unspecific error should be emitted if we haven't
complained otherwise, and one whether
maybe_inform_about_fndecl_for_bogus_argument_init should be called.
For the 2 pedwarns, currently it sets complained to true regardless of
whether pedwarn succeeded, which results in the undesirable notes printed
with -w.  If complained is initialized to result of pedwarn, we would
emit an error later on.

So, the following patch makes complained a tristate, the additional
error isn't printed if complained != 0, and
maybe_inform_about_fndecl_for_bogus_argument_init is called only if
complained == 1, so if pedwarn returns false, we can use complained = -1
to tell later code not to emit an error and not to call
maybe_inform_about_fndecl_for_bogus_argument_init.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2023-03-25  Jakub Jelinek  <jakub@redhat.com>

	PR c++/109278
	* call.cc (convert_like_internal): If pedwarn for extended float
	type conversions doesn't report anything, avoid calling
	maybe_inform_about_fndecl_for_bogus_argument_init.

	* g++.dg/cpp23/ext-floating15.C: New test.


	Jakub
  

Comments

Jason Merrill March 29, 2023, 8:35 p.m. UTC | #1
On 3/25/23 06:08, Jakub Jelinek wrote:
> Hi!
> 
> On the following testcase we emit notes in
> maybe_inform_about_fndecl_for_bogus_argument_init
> despite no warning/error being printed before it.
> This is for the extended floating point type conversions where pedwarn
> is used, and complained is used there for 2 different purposes,
> one is whether an unspecific error should be emitted if we haven't
> complained otherwise, and one whether
> maybe_inform_about_fndecl_for_bogus_argument_init should be called.
> For the 2 pedwarns, currently it sets complained to true regardless of
> whether pedwarn succeeded, which results in the undesirable notes printed
> with -w.  If complained is initialized to result of pedwarn, we would
> emit an error later on.
> 
> So, the following patch makes complained a tristate, the additional
> error isn't printed if complained != 0, and
> maybe_inform_about_fndecl_for_bogus_argument_init is called only if
> complained == 1, so if pedwarn returns false, we can use complained = -1
> to tell later code not to emit an error and not to call
> maybe_inform_about_fndecl_for_bogus_argument_init.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2023-03-25  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/109278
> 	* call.cc (convert_like_internal): If pedwarn for extended float
> 	type conversions doesn't report anything, avoid calling
> 	maybe_inform_about_fndecl_for_bogus_argument_init.

I think we want the same handling for all the complained = permerror 
cases as well.

> 	* g++.dg/cpp23/ext-floating15.C: New test.
> 
> --- gcc/cp/call.cc.jj	2023-03-23 15:24:33.074801422 +0100
> +++ gcc/cp/call.cc	2023-03-24 22:29:06.328140170 +0100
> @@ -8296,7 +8296,7 @@ convert_like_internal (conversion *convs
>   	  || SCALAR_TYPE_P (totype))
>         && convs->kind != ck_base)
>       {
> -      bool complained = false;
> +      int complained = 0;
>         conversion *t = convs;
>   
>         /* Give a helpful error if this is bad because of excess braces.  */
> @@ -8328,14 +8328,18 @@ convert_like_internal (conversion *convs
>   							    totype))
>   	  {
>   	  case 2:
> -	    pedwarn (loc, 0, "converting to %qH from %qI with greater "
> -			     "conversion rank", totype, TREE_TYPE (expr));
> -	    complained = true;
> +	    if (pedwarn (loc, 0, "converting to %qH from %qI with greater "
> +				 "conversion rank", totype, TREE_TYPE (expr)))
> +	      complained = 1;
> +	    else if (!complained)
> +	      complained = -1;
>   	    break;
>   	  case 3:
> -	    pedwarn (loc, 0, "converting to %qH from %qI with unordered "
> -			     "conversion ranks", totype, TREE_TYPE (expr));
> -	    complained = true;
> +	    if (pedwarn (loc, 0, "converting to %qH from %qI with unordered "
> +				 "conversion ranks", totype, TREE_TYPE (expr)))
> +	      complained = 1;
> +	    else if (!complained)
> +	      complained = -1;
>   	    break;
>   	  default:
>   	    break;
> @@ -8389,7 +8393,7 @@ convert_like_internal (conversion *convs
>   				  "invalid conversion from %qH to %qI",
>   				  TREE_TYPE (expr), totype);
>   	}
> -      if (complained)
> +      if (complained == 1)
>   	maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
>   
>         return cp_convert (totype, expr, complain);
> --- gcc/testsuite/g++.dg/cpp23/ext-floating15.C.jj	2023-03-24 22:38:40.358890548 +0100
> +++ gcc/testsuite/g++.dg/cpp23/ext-floating15.C	2023-03-24 22:38:18.484204916 +0100
> @@ -0,0 +1,11 @@
> +// PR c++/109278
> +// { dg-do compile { target float128 } }
> +// { dg-options "-w" }
> +
> +void foo (long double);	// { dg-bogus "initializing argument 1 of" }
> +
> +void
> +bar (_Float128 x)
> +{
> +  foo (x);
> +}
> 
> 	Jakub
>
  
Jakub Jelinek March 29, 2023, 8:57 p.m. UTC | #2
On Wed, Mar 29, 2023 at 04:35:15PM -0400, Jason Merrill wrote:
> > On the following testcase we emit notes in
> > maybe_inform_about_fndecl_for_bogus_argument_init
> > despite no warning/error being printed before it.
> > This is for the extended floating point type conversions where pedwarn
> > is used, and complained is used there for 2 different purposes,
> > one is whether an unspecific error should be emitted if we haven't
> > complained otherwise, and one whether
> > maybe_inform_about_fndecl_for_bogus_argument_init should be called.
> > For the 2 pedwarns, currently it sets complained to true regardless of
> > whether pedwarn succeeded, which results in the undesirable notes printed
> > with -w.  If complained is initialized to result of pedwarn, we would
> > emit an error later on.
> > 
> > So, the following patch makes complained a tristate, the additional
> > error isn't printed if complained != 0, and
> > maybe_inform_about_fndecl_for_bogus_argument_init is called only if
> > complained == 1, so if pedwarn returns false, we can use complained = -1
> > to tell later code not to emit an error and not to call
> > maybe_inform_about_fndecl_for_bogus_argument_init.
> > 
> > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> > 
> > 2023-03-25  Jakub Jelinek  <jakub@redhat.com>
> > 
> > 	PR c++/109278
> > 	* call.cc (convert_like_internal): If pedwarn for extended float
> > 	type conversions doesn't report anything, avoid calling
> > 	maybe_inform_about_fndecl_for_bogus_argument_init.
> 
> I think we want the same handling for all the complained = permerror cases
> as well.

I think it isn't really needed in those cases.
If I have say:
int foo (int);
int a = foo ({ { 1 } });
int bar (bool);
decltype (nullptr) n;
int b = bar (n);
and compile with -fpermissive -w (which is I think the only way how to get
permerror return false), then it will later reach that:
      if (!complained && expr != error_mark_node)
        {
          range_label_for_type_mismatch label (TREE_TYPE (expr), totype);
          gcc_rich_location richloc (loc, &label);
          complained = permerror (&richloc,
                                  "invalid conversion from %qH to %qI",
                                  TREE_TYPE (expr), totype);
        }
      if (complained)
        maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
in current trunk or complained == 1 in the latter condition with the
patch.  !complained is true, so it will call permerror, but because
of -fpermissive -w neither that permerror will emit anything and will set
complained to false, so maybe_inform_about_fndecl_for_bogus_argument_init
is not called.  If I compile the above just with -fpermissive, it prints
the 2 warnings and 2 informs, if without -fpermissive, it prints the 2
errors and 2 informs.

If you want, I can add the above snippet as 3 testcases (normal,
-fpermissive and -fpermissive -w).

	Jakub
  
Jason Merrill March 30, 2023, 2:53 a.m. UTC | #3
On 3/29/23 16:57, Jakub Jelinek wrote:
> On Wed, Mar 29, 2023 at 04:35:15PM -0400, Jason Merrill wrote:
>>> On the following testcase we emit notes in
>>> maybe_inform_about_fndecl_for_bogus_argument_init
>>> despite no warning/error being printed before it.
>>> This is for the extended floating point type conversions where pedwarn
>>> is used, and complained is used there for 2 different purposes,
>>> one is whether an unspecific error should be emitted if we haven't
>>> complained otherwise, and one whether
>>> maybe_inform_about_fndecl_for_bogus_argument_init should be called.
>>> For the 2 pedwarns, currently it sets complained to true regardless of
>>> whether pedwarn succeeded, which results in the undesirable notes printed
>>> with -w.  If complained is initialized to result of pedwarn, we would
>>> emit an error later on.
>>>
>>> So, the following patch makes complained a tristate, the additional
>>> error isn't printed if complained != 0, and
>>> maybe_inform_about_fndecl_for_bogus_argument_init is called only if
>>> complained == 1, so if pedwarn returns false, we can use complained = -1
>>> to tell later code not to emit an error and not to call
>>> maybe_inform_about_fndecl_for_bogus_argument_init.
>>>
>>> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>>>
>>> 2023-03-25  Jakub Jelinek  <jakub@redhat.com>
>>>
>>> 	PR c++/109278
>>> 	* call.cc (convert_like_internal): If pedwarn for extended float
>>> 	type conversions doesn't report anything, avoid calling
>>> 	maybe_inform_about_fndecl_for_bogus_argument_init.
>>
>> I think we want the same handling for all the complained = permerror cases
>> as well.
> 
> I think it isn't really needed in those cases.
> If I have say:
> int foo (int);
> int a = foo ({ { 1 } });
> int bar (bool);
> decltype (nullptr) n;
> int b = bar (n);
> and compile with -fpermissive -w (which is I think the only way how to get
> permerror return false), then it will later reach that:
>        if (!complained && expr != error_mark_node)
>          {
>            range_label_for_type_mismatch label (TREE_TYPE (expr), totype);
>            gcc_rich_location richloc (loc, &label);
>            complained = permerror (&richloc,
>                                    "invalid conversion from %qH to %qI",
>                                    TREE_TYPE (expr), totype);
>          }
>        if (complained)
>          maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
> in current trunk or complained == 1 in the latter condition with the
> patch.  !complained is true, so it will call permerror, but because
> of -fpermissive -w neither that permerror will emit anything and will set
> complained to false, so maybe_inform_about_fndecl_for_bogus_argument_init
> is not called.  If I compile the above just with -fpermissive, it prints
> the 2 warnings and 2 informs, if without -fpermissive, it prints the 2
> errors and 2 informs.

Ah, makes sense.  The patch is OK.

> If you want, I can add the above snippet as 3 testcases (normal,
> -fpermissive and -fpermissive -w).
> 
> 	Jakub
>
  

Patch

--- gcc/cp/call.cc.jj	2023-03-23 15:24:33.074801422 +0100
+++ gcc/cp/call.cc	2023-03-24 22:29:06.328140170 +0100
@@ -8296,7 +8296,7 @@  convert_like_internal (conversion *convs
 	  || SCALAR_TYPE_P (totype))
       && convs->kind != ck_base)
     {
-      bool complained = false;
+      int complained = 0;
       conversion *t = convs;
 
       /* Give a helpful error if this is bad because of excess braces.  */
@@ -8328,14 +8328,18 @@  convert_like_internal (conversion *convs
 							    totype))
 	  {
 	  case 2:
-	    pedwarn (loc, 0, "converting to %qH from %qI with greater "
-			     "conversion rank", totype, TREE_TYPE (expr));
-	    complained = true;
+	    if (pedwarn (loc, 0, "converting to %qH from %qI with greater "
+				 "conversion rank", totype, TREE_TYPE (expr)))
+	      complained = 1;
+	    else if (!complained)
+	      complained = -1;
 	    break;
 	  case 3:
-	    pedwarn (loc, 0, "converting to %qH from %qI with unordered "
-			     "conversion ranks", totype, TREE_TYPE (expr));
-	    complained = true;
+	    if (pedwarn (loc, 0, "converting to %qH from %qI with unordered "
+				 "conversion ranks", totype, TREE_TYPE (expr)))
+	      complained = 1;
+	    else if (!complained)
+	      complained = -1;
 	    break;
 	  default:
 	    break;
@@ -8389,7 +8393,7 @@  convert_like_internal (conversion *convs
 				  "invalid conversion from %qH to %qI",
 				  TREE_TYPE (expr), totype);
 	}
-      if (complained)
+      if (complained == 1)
 	maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
 
       return cp_convert (totype, expr, complain);
--- gcc/testsuite/g++.dg/cpp23/ext-floating15.C.jj	2023-03-24 22:38:40.358890548 +0100
+++ gcc/testsuite/g++.dg/cpp23/ext-floating15.C	2023-03-24 22:38:18.484204916 +0100
@@ -0,0 +1,11 @@ 
+// PR c++/109278
+// { dg-do compile { target float128 } }
+// { dg-options "-w" }
+
+void foo (long double);	// { dg-bogus "initializing argument 1 of" }
+
+void
+bar (_Float128 x)
+{
+  foo (x);
+}