diff mbox series

C++ PATCH for c++/65043, missing narrowing warning with bool

Message ID 20180814233001.GI7399@redhat.com
State New
Headers show
Series C++ PATCH for c++/65043, missing narrowing warning with bool | expand

Commit Message

Marek Polacek Aug. 14, 2018, 11:30 p.m. UTC
We weren't complaining about narrowing when converting to bool because
standard_conversion wasn't setting check_narrowing for the converting to bool
case; it only sets it at the end of the function.  Moreover, check_narrowing
wasn't catching real_type -> boolean_type at all, which is wrong;
[dcl.init.list] says that a narrowing conversion is an implicit conversion from
a floating-point type to an integer type, and bool is an integer type.

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

2018-08-14  Marek Polacek  <polacek@redhat.com>

	PR c++/65043
	* call.c (standard_conversion): Set check_narrowing.
	* typeck2.c (check_narrowing): Use CP_INTEGRAL_TYPE_P rather
	than comparing with INTEGER_TYPE.

	* g++.dg/concepts/pr67595.C: Add dg-warning.
	* g++.dg/cpp0x/Wnarrowing11.C: New test.
	* g++.dg/cpp0x/Wnarrowing12.C: New test.
	* g++.dg/cpp0x/rv-cast5.C: Add static_cast.

Comments

Jason Merrill Aug. 21, 2018, 11:49 a.m. UTC | #1
On Wed, Aug 15, 2018 at 11:30 AM, Marek Polacek <polacek@redhat.com> wrote:
> We weren't complaining about narrowing when converting to bool because
> standard_conversion wasn't setting check_narrowing for the converting to bool
> case; it only sets it at the end of the function.  Moreover, check_narrowing
> wasn't catching real_type -> boolean_type at all, which is wrong;
> [dcl.init.list] says that a narrowing conversion is an implicit conversion from
> a floating-point type to an integer type, and bool is an integer type.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2018-08-14  Marek Polacek  <polacek@redhat.com>
>
>         PR c++/65043
>         * call.c (standard_conversion): Set check_narrowing.
>         * typeck2.c (check_narrowing): Use CP_INTEGRAL_TYPE_P rather
>         than comparing with INTEGER_TYPE.
>
>         * g++.dg/concepts/pr67595.C: Add dg-warning.
>         * g++.dg/cpp0x/Wnarrowing11.C: New test.
>         * g++.dg/cpp0x/Wnarrowing12.C: New test.
>         * g++.dg/cpp0x/rv-cast5.C: Add static_cast.
>
> diff --git gcc/cp/call.c gcc/cp/call.c
> index 62654a9e407..ded279a0f43 100644
> --- gcc/cp/call.c
> +++ gcc/cp/call.c
> @@ -1387,6 +1387,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
>             conv->rank = cr_pbool;
>           if (NULLPTR_TYPE_P (from) && (flags & LOOKUP_ONLYCONVERTING))
>             conv->bad_p = true;
> +         if (flags & LOOKUP_NO_NARROWING)
> +           conv->check_narrowing = true;
>           return conv;
>         }

Hmm, it might be better to fix this section to properly fall through
to the common check_narrowing code below.  OK either way.

Jason
diff mbox series

Patch

diff --git gcc/cp/call.c gcc/cp/call.c
index 62654a9e407..ded279a0f43 100644
--- gcc/cp/call.c
+++ gcc/cp/call.c
@@ -1387,6 +1387,8 @@  standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
 	    conv->rank = cr_pbool;
 	  if (NULLPTR_TYPE_P (from) && (flags & LOOKUP_ONLYCONVERTING))
 	    conv->bad_p = true;
+	  if (flags & LOOKUP_NO_NARROWING)
+	    conv->check_narrowing = true;
 	  return conv;
 	}
 
diff --git gcc/cp/typeck2.c gcc/cp/typeck2.c
index 674d08762b5..b521f79e8c3 100644
--- gcc/cp/typeck2.c
+++ gcc/cp/typeck2.c
@@ -912,7 +912,7 @@  check_narrowing (tree type, tree init, tsubst_flags_t complain, bool const_only)
   if (const_only && !TREE_CONSTANT (init))
     return ok;
 
-  if (TREE_CODE (type) == INTEGER_TYPE
+  if (CP_INTEGRAL_TYPE_P (type)
       && TREE_CODE (ftype) == REAL_TYPE)
     ok = false;
   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
diff --git gcc/testsuite/g++.dg/concepts/pr67595.C gcc/testsuite/g++.dg/concepts/pr67595.C
index 63162fb4c72..76d1fe62132 100644
--- gcc/testsuite/g++.dg/concepts/pr67595.C
+++ gcc/testsuite/g++.dg/concepts/pr67595.C
@@ -4,7 +4,7 @@  template <class X> concept bool allocatable = requires{{new X}->X * };
 template <class X> concept bool semiregular = allocatable<X>;
 template <class X> concept bool readable = requires{requires semiregular<X>};
 template <class> int weak_input_iterator = requires{{0}->readable};
-template <class X> bool input_iterator{weak_input_iterator<X>};
+template <class X> bool input_iterator{weak_input_iterator<X>}; // { dg-warning "narrowing conversion" }
 template <class X> bool forward_iterator{input_iterator<X>};
 template <class X> bool bidirectional_iterator{forward_iterator<X>};
 template <class X>
diff --git gcc/testsuite/g++.dg/cpp0x/Wnarrowing11.C gcc/testsuite/g++.dg/cpp0x/Wnarrowing11.C
index e69de29bb2d..5b7323633c7 100644
--- gcc/testsuite/g++.dg/cpp0x/Wnarrowing11.C
+++ gcc/testsuite/g++.dg/cpp0x/Wnarrowing11.C
@@ -0,0 +1,30 @@ 
+// PR c++/65043
+// { dg-do compile { target c++11 } }
+
+struct X
+{
+  X(bool) { }
+};
+
+struct Y
+{
+  Y(char) { }
+};
+
+struct Z
+{
+  Z(char16_t) { }
+};
+
+struct W
+{
+  W(char32_t) { }
+};
+
+int main() 
+{
+  X x{1.2}; // { dg-error "narrowing conversion" }
+  Y y{1.2}; // { dg-error "narrowing conversion" }
+  Z z{1.2}; // { dg-error "narrowing conversion" }
+  W w{1.2}; // { dg-error "narrowing conversion" }
+}
diff --git gcc/testsuite/g++.dg/cpp0x/Wnarrowing12.C gcc/testsuite/g++.dg/cpp0x/Wnarrowing12.C
index e69de29bb2d..83b4d3a58c6 100644
--- gcc/testsuite/g++.dg/cpp0x/Wnarrowing12.C
+++ gcc/testsuite/g++.dg/cpp0x/Wnarrowing12.C
@@ -0,0 +1,32 @@ 
+// PR c++/65043
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wnarrowing" }
+
+struct X
+{
+  X(bool) { }
+};
+
+struct Y
+{
+  Y(char) { }
+};
+
+struct Z
+{
+  Z(char16_t) { }
+};
+
+struct W
+{
+  W(char32_t) { }
+};
+
+int main() 
+{
+  double d = 1.2;
+  X x{d}; // { dg-warning "narrowing conversion" }
+  Y y{d}; // { dg-warning "narrowing conversion" }
+  Z z{d}; // { dg-warning "narrowing conversion" }
+  W w{d}; // { dg-warning "narrowing conversion" }
+}
diff --git gcc/testsuite/g++.dg/cpp0x/rv-cast5.C gcc/testsuite/g++.dg/cpp0x/rv-cast5.C
index c2473e266b6..5233078f7b4 100644
--- gcc/testsuite/g++.dg/cpp0x/rv-cast5.C
+++ gcc/testsuite/g++.dg/cpp0x/rv-cast5.C
@@ -8,5 +8,5 @@  struct hold {
 
 int main()
 {
-  hold<bool&&>{42}();
+  hold<bool&&>{static_cast<bool>(42)}();
 }