c++: Avoid informs without a warning [PR109278]
Checks
Commit Message
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
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
>
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
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
>
@@ -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);
@@ -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);
+}