lichray updated this revision to Diff 232752.
lichray added a comment.

Regenerate the diff in Git, update description, link to paper.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64034/new/

https://reviews.llvm.org/D64034

Files:
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
  clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp

Index: clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
===================================================================
--- clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
+++ clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
@@ -20,6 +20,7 @@
   int ii = {2.0};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
   float f1 { x };  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
   float f2 { 7 };  // OK: 7 can be exactly represented as a float
+  bool b = {"meow"};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
   int f(int);
   int a[] =
     { 2, f(2), f(2.0) };  // OK: the double-to-int conversion is not at the top level
@@ -131,7 +132,7 @@
 //   cannot represent all the values of the original type, except where the
 //   source is a constant expression and the actual value after conversion will
 //   fit into the target type and will produce the original value when converted
-//   back to the original type.
+//   back to the original type, or
 void shrink_int() {
   // Not a constant expression.
   short s = 1;
@@ -163,14 +164,24 @@
   Agg<bool> b2 = {1};  // OK
   Agg<bool> b3 = {-1};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
 
-  // Conversions from pointers to booleans aren't narrowing conversions.
-  Agg<bool>* ptr = &b1;
-  Agg<bool> b = {ptr};  // OK
-
   Agg<short> ce1 = { Convert<int>(100000) }; // expected-warning {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{silence}} expected-warning {{changes value from 100000 to -31072}}
   Agg<char> ce2 = { ConvertVar<short>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{silence}}
 }
 
+// * from a pointer type or a pointer-to-member type to bool.
+void pointer_to_bool() {
+  Agg<int> obj;
+  Agg<int> *p1 = &obj;
+  constexpr void *p2 = nullptr;
+
+  Agg<bool> b1 = {p1};           // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<bool> b2 = {p2};           // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<bool> b3 = {&Agg<int>::t}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+
+  Agg<bool> b4 = {ConvertVar<int *>()};           // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<bool> b5 = {ConvertVar<int Agg<int>::*>()}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+}
+
 // Be sure that type- and value-dependent expressions in templates get the warning
 // too.
 
Index: clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
===================================================================
--- clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
+++ clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
@@ -19,6 +19,7 @@
   int ii = {2.0};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
   float f1 { x };  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
   float f2 { 7 };  // OK: 7 can be exactly represented as a float
+  bool b = {"meow"};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
   int f(int);
   int a[] =
     { 2, f(2), f(2.0) };  // OK: the double-to-int conversion is not at the top level
@@ -143,7 +144,7 @@
 //   cannot represent all the values of the original type, except where the
 //   source is a constant expression and the actual value after conversion will
 //   fit into the target type and will produce the original value when converted
-//   back to the original type.
+//   back to the original type, or
 void shrink_int() {
   // Not a constant expression.
   short s = 1;
@@ -180,10 +181,6 @@
   Agg<bool> b2 = {1};  // OK
   Agg<bool> b3 = {-1};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
 
-  // Conversions from pointers to booleans aren't narrowing conversions.
-  Agg<bool>* ptr = &b1;
-  Agg<bool> b = {ptr};  // OK
-
   Agg<short> ce1 = { Convert<int>(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{silence}} expected-warning {{changes value from 100000 to -31072}}
   Agg<char> ce2 = { ConvertVar<short>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{silence}}
 
@@ -202,6 +199,20 @@
   unsigned short usc3 = { (signed char)-1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{silence}}
 }
 
+// * from a pointer type or a pointer-to-member type to bool.
+void pointer_to_bool() {
+  Agg<int> obj;
+  Agg<int> *p1 = &obj;
+  constexpr void *p2 = nullptr;
+
+  Agg<bool> b1 = {p1};           // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<bool> b2 = {p2};           // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<bool> b3 = {&Agg<int>::t}; // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+
+  Agg<bool> b4 = {ConvertVar<int *>()};           // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<bool> b5 = {ConvertVar<int Agg<int>::*>()}; // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+}
+
 // Be sure that type- and value-dependent expressions in templates get the error
 // too.
 
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -324,8 +324,8 @@
     if (FromType->isIntegralOrUnscopedEnumerationType())
       goto IntegralConversion;
     // Boolean conversions can be from pointers and pointers to members
-    // [conv.bool], and those aren't considered narrowing conversions.
-    return NK_Not_Narrowing;
+    // [conv.bool], which are considered narrowing conversions.
+    return NK_Type_Narrowing;
 
   // -- from a floating-point type to an integer type, or
   //
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -9533,9 +9533,9 @@
     return;
 
   case NK_Type_Narrowing:
-    // This was a floating-to-integer conversion, which is always considered a
-    // narrowing conversion even if the value is a constant and can be
-    // represented exactly as an integer.
+    // This was a floating-to-integer conversion or a boolean conversion from a
+    // pointer, which is always considered a narrowing conversion even if the
+    // value is a constant and can be represented exactly as an integer.
     S.Diag(PostInit->getBeginLoc(), NarrowingErrs(S.getLangOpts())
                                         ? diag::ext_init_list_type_narrowing
                                         : diag::warn_init_list_type_narrowing)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to