c++: Link extended FP conversion pedwarns to -Wnarrowing [PR111842]

Message ID 20231113190401.759232-1-jwakely@redhat.com
State Accepted
Headers
Series c++: Link extended FP conversion pedwarns to -Wnarrowing [PR111842] |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Jonathan Wakely Nov. 13, 2023, 7:01 p.m. UTC
  Tested x86_64-linux. Does this make sense for trunk?

These forbidden conversions are defined as narrowing conversions, and we
already use -Wnarrowing to control other "ill-formed, but only warn by
default" diagnostics required by the standard.

-- >8 --

Several users have been confused by the status of these warnings,
which can be misunderstood as "this might not be what you want",
rather than diagnostics required by the C++ standard. Add the text "ISO
C++ does not allow" to make this clear.

Also link them to -Wnarrowing so that they can be disabled or promoted
to errors independently of other pedwarns.

gcc/cp/ChangeLog:

	PR c++/111842
	PR c++/112498
	* call.cc (convert_like_internal): Use OPT_Wnarrowing for
	pedwarns about illformed conversions involving extended
	floating-point types. Clarify that ISO C++ requires these
	diagnostics.
	* g++.dg/cpp23/ext-floating16.C: New test.
	* g++.dg/cpp23/ext-floating17.C: New test.
---
 gcc/cp/call.cc                              | 10 +++--
 gcc/testsuite/g++.dg/cpp23/ext-floating16.C | 40 ++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp23/ext-floating17.C | 42 +++++++++++++++++++++
 3 files changed, 88 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp23/ext-floating16.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/ext-floating17.C
  

Comments

Jason Merrill Nov. 14, 2023, 2:10 a.m. UTC | #1
On 11/13/23 14:01, Jonathan Wakely wrote:
> Tested x86_64-linux. Does this make sense for trunk?

OK, thanks.

> These forbidden conversions are defined as narrowing conversions, and we
> already use -Wnarrowing to control other "ill-formed, but only warn by
> default" diagnostics required by the standard.
> 
> -- >8 --
> 
> Several users have been confused by the status of these warnings,
> which can be misunderstood as "this might not be what you want",
> rather than diagnostics required by the C++ standard. Add the text "ISO
> C++ does not allow" to make this clear.
> 
> Also link them to -Wnarrowing so that they can be disabled or promoted
> to errors independently of other pedwarns.
> 
> gcc/cp/ChangeLog:
> 
> 	PR c++/111842
> 	PR c++/112498
> 	* call.cc (convert_like_internal): Use OPT_Wnarrowing for
> 	pedwarns about illformed conversions involving extended
> 	floating-point types. Clarify that ISO C++ requires these
> 	diagnostics.
> 	* g++.dg/cpp23/ext-floating16.C: New test.
> 	* g++.dg/cpp23/ext-floating17.C: New test.
> ---
>   gcc/cp/call.cc                              | 10 +++--
>   gcc/testsuite/g++.dg/cpp23/ext-floating16.C | 40 ++++++++++++++++++++
>   gcc/testsuite/g++.dg/cpp23/ext-floating17.C | 42 +++++++++++++++++++++
>   3 files changed, 88 insertions(+), 4 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp23/ext-floating16.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp23/ext-floating17.C
> 
> diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
> index 4516677bcab..4b0c6c42f01 100644
> --- a/gcc/cp/call.cc
> +++ b/gcc/cp/call.cc
> @@ -8303,15 +8303,17 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
>   							    totype))
>   	  {
>   	  case 2:
> -	    if (pedwarn (loc, 0, "converting to %qH from %qI with greater "
> -				 "conversion rank", totype, TREE_TYPE (expr)))
> +	    if (pedwarn (loc, OPT_Wnarrowing, "ISO C++ does not allow "
> +			 "converting to %qH from %qI with greater "
> +			 "conversion rank", totype, TREE_TYPE (expr)))
>   	      complained = 1;
>   	    else if (!complained)
>   	      complained = -1;
>   	    break;
>   	  case 3:
> -	    if (pedwarn (loc, 0, "converting to %qH from %qI with unordered "
> -				 "conversion ranks", totype, TREE_TYPE (expr)))
> +	    if (pedwarn (loc, OPT_Wnarrowing, "ISO C++ does not allow "
> +			 "converting to %qH from %qI with unordered "
> +			 "conversion rank", totype, TREE_TYPE (expr)))
>   	      complained = 1;
>   	    else if (!complained)
>   	      complained = -1;
> diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating16.C b/gcc/testsuite/g++.dg/cpp23/ext-floating16.C
> new file mode 100644
> index 00000000000..d6a562d5cb0
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp23/ext-floating16.C
> @@ -0,0 +1,40 @@
> +// P1467R9 - Extended floating-point types and standard names.
> +// { dg-do compile { target c++23 } }
> +// { dg-options "-pedantic-errors -Wno-narrowing" }
> +// { dg-add-options float16 }
> +// { dg-add-options float32 }
> +// { dg-add-options float64 }
> +// { dg-add-options float128 }
> +
> +#include "ext-floating.h"
> +
> +#ifdef __STRICT_ANSI__
> +#undef __SIZEOF_FLOAT128__
> +#endif
> +
> +using namespace std;
> +
> +#ifdef __STDCPP_FLOAT16_T__
> +#ifdef __STDCPP_FLOAT32_T__
> +float16_t f16c = 1.0F32;		// { dg-bogus "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float32' with greater conversion rank" "" { target { float16 && float32 } } }
> +#endif
> +#ifdef __STDCPP_FLOAT64_T__
> +float16_t f16e = 1.0F64;		// { dg-bogus "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float64' with greater conversion rank" "" { target { float16 && float64 } } }
> +#endif
> +#ifdef __STDCPP_FLOAT128_T__
> +float16_t f16g = 1.0F128;		// { dg-bogus "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float128' with greater conversion rank" "" { target { float16 && float128 } } }
> +#endif
> +#endif
> +#ifdef __STDCPP_FLOAT32_T__
> +#ifdef __STDCPP_FLOAT64_T__
> +float32_t f32e = 1.0F64;		// { dg-bogus "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '_Float64' with greater conversion rank" "" { target { float32 && float64 } } }
> +#endif
> +#ifdef __STDCPP_FLOAT128_T__
> +float32_t f32g = 1.0F128;		// { dg-bogus "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '_Float128' with greater conversion rank" "" { target { float32 && float128 } } }
> +#endif
> +#endif
> +#ifdef __STDCPP_FLOAT64_T__
> +#ifdef __STDCPP_FLOAT128_T__
> +float64_t f64g = 1.0F128;		// { dg-bogus "converting to 'std::float64_t' \\\{aka '_Float64'\\\} from '_Float128' with greater conversion rank" "" { target { float64 && float128 } } }
> +#endif
> +#endif
> diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating17.C b/gcc/testsuite/g++.dg/cpp23/ext-floating17.C
> new file mode 100644
> index 00000000000..796e045537a
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp23/ext-floating17.C
> @@ -0,0 +1,42 @@
> +// P1467R9 - Extended floating-point types and standard names.
> +// { dg-do compile { target c++23 } }
> +// { dg-options "-Werror=narrowing" }
> +// { dg-add-options float16 }
> +// { dg-add-options float32 }
> +// { dg-add-options float64 }
> +// { dg-add-options float128 }
> +// { dg-prune-output "some warnings being treated as errors" }
> +
> +#include "ext-floating.h"
> +
> +#ifdef __STRICT_ANSI__
> +#undef __SIZEOF_FLOAT128__
> +#endif
> +
> +using namespace std;
> +
> +#ifdef __STDCPP_FLOAT16_T__
> +#ifdef __STDCPP_FLOAT32_T__
> +float16_t f16c = 1.0F32;		// { dg-error "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float32' with greater conversion rank" "" { target { float16 && float32 } } }
> +#endif
> +#ifdef __STDCPP_FLOAT64_T__
> +float16_t f16e = 1.0F64;		// { dg-error "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float64' with greater conversion rank" "" { target { float16 && float64 } } }
> +#endif
> +#ifdef __STDCPP_FLOAT128_T__
> +float16_t f16g = 1.0F128;		// { dg-error "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float128' with greater conversion rank" "" { target { float16 && float128 } } }
> +#endif
> +#endif
> +#ifdef __STDCPP_FLOAT32_T__
> +#ifdef __STDCPP_FLOAT64_T__
> +float32_t f32e = 1.0F64;		// { dg-error "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '_Float64' with greater conversion rank" "" { target { float32 && float64 } } }
> +#endif
> +#ifdef __STDCPP_FLOAT128_T__
> +float32_t f32g = 1.0F128;		// { dg-error "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '_Float128' with greater conversion rank" "" { target { float32 && float128 } } }
> +#endif
> +#endif
> +#ifdef __STDCPP_FLOAT64_T__
> +#ifdef __STDCPP_FLOAT128_T__
> +float64_t f64g = 1.0F128;		// { dg-error "converting to 'std::float64_t' \\\{aka '_Float64'\\\} from '_Float128' with greater conversion rank" "" { target { float64 && float128 } } }
> +#endif
> +#endif
> +
  

Patch

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 4516677bcab..4b0c6c42f01 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -8303,15 +8303,17 @@  convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
 							    totype))
 	  {
 	  case 2:
-	    if (pedwarn (loc, 0, "converting to %qH from %qI with greater "
-				 "conversion rank", totype, TREE_TYPE (expr)))
+	    if (pedwarn (loc, OPT_Wnarrowing, "ISO C++ does not allow "
+			 "converting to %qH from %qI with greater "
+			 "conversion rank", totype, TREE_TYPE (expr)))
 	      complained = 1;
 	    else if (!complained)
 	      complained = -1;
 	    break;
 	  case 3:
-	    if (pedwarn (loc, 0, "converting to %qH from %qI with unordered "
-				 "conversion ranks", totype, TREE_TYPE (expr)))
+	    if (pedwarn (loc, OPT_Wnarrowing, "ISO C++ does not allow "
+			 "converting to %qH from %qI with unordered "
+			 "conversion rank", totype, TREE_TYPE (expr)))
 	      complained = 1;
 	    else if (!complained)
 	      complained = -1;
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating16.C b/gcc/testsuite/g++.dg/cpp23/ext-floating16.C
new file mode 100644
index 00000000000..d6a562d5cb0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating16.C
@@ -0,0 +1,40 @@ 
+// P1467R9 - Extended floating-point types and standard names.
+// { dg-do compile { target c++23 } }
+// { dg-options "-pedantic-errors -Wno-narrowing" }
+// { dg-add-options float16 }
+// { dg-add-options float32 }
+// { dg-add-options float64 }
+// { dg-add-options float128 }
+
+#include "ext-floating.h"
+
+#ifdef __STRICT_ANSI__
+#undef __SIZEOF_FLOAT128__
+#endif
+
+using namespace std;
+
+#ifdef __STDCPP_FLOAT16_T__
+#ifdef __STDCPP_FLOAT32_T__
+float16_t f16c = 1.0F32;		// { dg-bogus "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float32' with greater conversion rank" "" { target { float16 && float32 } } }
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+float16_t f16e = 1.0F64;		// { dg-bogus "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float64' with greater conversion rank" "" { target { float16 && float64 } } }
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+float16_t f16g = 1.0F128;		// { dg-bogus "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float128' with greater conversion rank" "" { target { float16 && float128 } } }
+#endif
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+#ifdef __STDCPP_FLOAT64_T__
+float32_t f32e = 1.0F64;		// { dg-bogus "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '_Float64' with greater conversion rank" "" { target { float32 && float64 } } }
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+float32_t f32g = 1.0F128;		// { dg-bogus "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '_Float128' with greater conversion rank" "" { target { float32 && float128 } } }
+#endif
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+#ifdef __STDCPP_FLOAT128_T__
+float64_t f64g = 1.0F128;		// { dg-bogus "converting to 'std::float64_t' \\\{aka '_Float64'\\\} from '_Float128' with greater conversion rank" "" { target { float64 && float128 } } }
+#endif
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating17.C b/gcc/testsuite/g++.dg/cpp23/ext-floating17.C
new file mode 100644
index 00000000000..796e045537a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating17.C
@@ -0,0 +1,42 @@ 
+// P1467R9 - Extended floating-point types and standard names.
+// { dg-do compile { target c++23 } }
+// { dg-options "-Werror=narrowing" }
+// { dg-add-options float16 }
+// { dg-add-options float32 }
+// { dg-add-options float64 }
+// { dg-add-options float128 }
+// { dg-prune-output "some warnings being treated as errors" }
+
+#include "ext-floating.h"
+
+#ifdef __STRICT_ANSI__
+#undef __SIZEOF_FLOAT128__
+#endif
+
+using namespace std;
+
+#ifdef __STDCPP_FLOAT16_T__
+#ifdef __STDCPP_FLOAT32_T__
+float16_t f16c = 1.0F32;		// { dg-error "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float32' with greater conversion rank" "" { target { float16 && float32 } } }
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+float16_t f16e = 1.0F64;		// { dg-error "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float64' with greater conversion rank" "" { target { float16 && float64 } } }
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+float16_t f16g = 1.0F128;		// { dg-error "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float128' with greater conversion rank" "" { target { float16 && float128 } } }
+#endif
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+#ifdef __STDCPP_FLOAT64_T__
+float32_t f32e = 1.0F64;		// { dg-error "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '_Float64' with greater conversion rank" "" { target { float32 && float64 } } }
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+float32_t f32g = 1.0F128;		// { dg-error "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '_Float128' with greater conversion rank" "" { target { float32 && float128 } } }
+#endif
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+#ifdef __STDCPP_FLOAT128_T__
+float64_t f64g = 1.0F128;		// { dg-error "converting to 'std::float64_t' \\\{aka '_Float64'\\\} from '_Float128' with greater conversion rank" "" { target { float64 && float128 } } }
+#endif
+#endif
+