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  <pola...@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;
        }
 
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)}();
 }

Reply via email to