From 5d5dcc65aae1024da31e0e9cae6a8966461037e8 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Sun, 19 Apr 2020 18:46:40 -0400 Subject: [PATCH] c++: Detect long double -> double narrowing [PR94590] This PR points out that we don't detect long double -> double narrowing when long double happens to have the same precision as double; on x86_64 this can be achieved by -mlong-double-64. [dcl.init.list]#7.2 specifically says "from long double to double or float, or from double to float", but check_narrowing only checks TYPE_PRECISION (type) < TYPE_PRECISION (ftype) so we need to handle the other cases too, e.g. by same_type_p as in the following patch. PR c++/94590 - Detect long double -> double narrowing. * typeck2.c (check_narrowing): Detect long double -> double narrowing even when double and long double have the same precision. Make it handle conversions to float too. * g++.dg/cpp0x/Wnarrowing18.C: New test. --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/typeck2.c | 9 ++++++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp0x/Wnarrowing18.C | 15 +++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/Wnarrowing18.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7454352020e..031741e2264 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2020-05-07 Marek Polacek + + PR c++/94590 - Detect long double -> double narrowing. + * typeck2.c (check_narrowing): Detect long double -> double + narrowing even when double and long double have the same + precision. Make it handle conversions to float too. + 2020-05-07 Marek Polacek PR c++/94255 diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index acf4414980c..d407e4cbfa4 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1008,10 +1008,17 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain, || !int_fits_type_p (init, type))) ok = false; } + /* [dcl.init.list]#7.2: "from long double to double or float, or from + double to float". */ else if (TREE_CODE (ftype) == REAL_TYPE && TREE_CODE (type) == REAL_TYPE) { - if (TYPE_PRECISION (type) < TYPE_PRECISION (ftype)) + if ((same_type_p (ftype, long_double_type_node) + && (same_type_p (type, double_type_node) + || same_type_p (type, float_type_node))) + || (same_type_p (ftype, double_type_node) + && same_type_p (type, float_type_node)) + || (TYPE_PRECISION (type) < TYPE_PRECISION (ftype))) { if (TREE_CODE (init) == REAL_CST) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bed2d90fb02..6712c1dfbb2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-05-07 Marek Polacek + + PR c++/94590 - Detect long double -> double narrowing. + * g++.dg/cpp0x/Wnarrowing18.C: New test. + 2020-05-07 Marek Polacek PR c++/94255 diff --git a/gcc/testsuite/g++.dg/cpp0x/Wnarrowing18.C b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing18.C new file mode 100644 index 00000000000..0dc7075cd62 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing18.C @@ -0,0 +1,15 @@ +// PR c++/94590 - Detect long double -> double narrowing. +// { dg-do compile { target c++11 } } +// { dg-additional-options "-mlong-double-64" { target x86_64-*-* i?86-*-* } } + +int +main () +{ + using T = long double; + extern long double ld; + extern T ld2; + extern const T ld3; + double d{ld}; // { dg-error "narrowing conversion" } + double d2{ld2}; // { dg-error "narrowing conversion" } + double d3{ld3}; // { dg-error "narrowing conversion" } +} -- 2.30.2