[PATCH] D50543: [libcxx] Mark charconv tests as failing for previous libcxx versions.

2018-08-09 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

LGTM.  @ldionne 's job to confirm.


https://reviews.llvm.org/D50543



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41347: [libc++] Lift std::errc into a separated header

2018-05-22 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

In https://reviews.llvm.org/D41347#1099842, @mclow.lists wrote:

> Sorry this took so long. Please update `test/libcxx/double_include.sh.cpp` 
> and commit.


Are you sure?  `double_include.sh.cpp` doesn't seem to be testing any 
intermediate headers.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41347



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-05-22 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: include/charconv:89
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+enum class _LIBCPP_ENUM_VIS chars_format

mclow.lists wrote:
> lichray wrote:
> > EricWF wrote:
> > > We need to hide these names when `_LIBCPP_STD_VER < 17`, since we're not 
> > > allowed to introduce new names into namespace `std` in older dialects.
> > But this header is backported to C++11, so I intended to not to guard it.
> > But this header is backported to C++11, so I intended to not to guard it.
> 
> In general, we don't provide new features for old language versions.
> 
> The only time we've ever done that is for `string_view`, and I'm **still** 
> not sure I did the right thing there.
We need to decide on this... From my point of view this header will be widely 
used by formatting and logging libraries, and it doesn't add much to the 
community by enforcing C++17 here, especially when the interface we specified 
are very simple and not using any features beyond C++11.



Comment at: src/charconv.cpp:34
+
+#define APPEND1(i)  \
+do  \

mclow.lists wrote:
> I'd really like to see some numbers here showing how this (somewhat awkward) 
> code performs better than the straightforward versions.
> 
> Because maintenance is forever.
> 
> Note: I'm sure that this was true on older compilers - but is it true today?
One thing I could try may be using return values rather than output parameters, 
like
```
buffer = append3(buffer, b); 
```
But I really don't think doing these makes the code any bit more maintainable 
comparing to
```
APPEND3(b);
```
, which looks very straightforward and expressive to me...


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39162: [test] Fix clang-test for FreeBSD

2017-10-21 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray created this revision.
Herald added subscribers: krytarowski, emaste.

Lit tries to inject the shared library paths, but no action is taken when 
`platform.system()` is not recognized, results in an environment variable with 
an empty name, which is illegal.

The patch fixes this mechanism for FreeBSD, and throws an exception on other 
platforms, so that the latecomers don't have to spend time on debugging lit.


https://reviews.llvm.org/D39162

Files:
  test/Unit/lit.cfg.py


Index: test/Unit/lit.cfg.py
===
--- test/Unit/lit.cfg.py
+++ test/Unit/lit.cfg.py
@@ -36,12 +36,14 @@
 config.environment[symbolizer] = os.environ[symbolizer]
 
 shlibpath_var = ''
-if platform.system() == 'Linux':
+if platform.system() in ['Linux', 'FreeBSD']:
 shlibpath_var = 'LD_LIBRARY_PATH'
 elif platform.system() == 'Darwin':
 shlibpath_var = 'DYLD_LIBRARY_PATH'
 elif platform.system() == 'Windows':
 shlibpath_var = 'PATH'
+else:
+raise EnvironmentError('unknown platform.system()')
 
 # in stand-alone builds, shlibdir is clang's build tree
 # while llvm_libs_dir is installed LLVM (and possibly older clang)


Index: test/Unit/lit.cfg.py
===
--- test/Unit/lit.cfg.py
+++ test/Unit/lit.cfg.py
@@ -36,12 +36,14 @@
 config.environment[symbolizer] = os.environ[symbolizer]
 
 shlibpath_var = ''
-if platform.system() == 'Linux':
+if platform.system() in ['Linux', 'FreeBSD']:
 shlibpath_var = 'LD_LIBRARY_PATH'
 elif platform.system() == 'Darwin':
 shlibpath_var = 'DYLD_LIBRARY_PATH'
 elif platform.system() == 'Windows':
 shlibpath_var = 'PATH'
+else:
+raise EnvironmentError('unknown platform.system()')
 
 # in stand-alone builds, shlibdir is clang's build tree
 # while llvm_libs_dir is installed LLVM (and possibly older clang)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39162: [test] Fix clang-test for FreeBSD and NetBSD

2017-10-21 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 119772.
lichray retitled this revision from "[test] Fix clang-test for FreeBSD" to 
"[test] Fix clang-test for FreeBSD and NetBSD".
lichray edited the summary of this revision.

https://reviews.llvm.org/D39162

Files:
  test/Unit/lit.cfg.py


Index: test/Unit/lit.cfg.py
===
--- test/Unit/lit.cfg.py
+++ test/Unit/lit.cfg.py
@@ -36,12 +36,14 @@
 config.environment[symbolizer] = os.environ[symbolizer]
 
 shlibpath_var = ''
-if platform.system() == 'Linux':
+if platform.system() in ['Linux', 'FreeBSD', 'NetBSD']:
 shlibpath_var = 'LD_LIBRARY_PATH'
 elif platform.system() == 'Darwin':
 shlibpath_var = 'DYLD_LIBRARY_PATH'
 elif platform.system() == 'Windows':
 shlibpath_var = 'PATH'
+else:
+raise EnvironmentError('unknown platform.system()')
 
 # in stand-alone builds, shlibdir is clang's build tree
 # while llvm_libs_dir is installed LLVM (and possibly older clang)


Index: test/Unit/lit.cfg.py
===
--- test/Unit/lit.cfg.py
+++ test/Unit/lit.cfg.py
@@ -36,12 +36,14 @@
 config.environment[symbolizer] = os.environ[symbolizer]
 
 shlibpath_var = ''
-if platform.system() == 'Linux':
+if platform.system() in ['Linux', 'FreeBSD', 'NetBSD']:
 shlibpath_var = 'LD_LIBRARY_PATH'
 elif platform.system() == 'Darwin':
 shlibpath_var = 'DYLD_LIBRARY_PATH'
 elif platform.system() == 'Windows':
 shlibpath_var = 'PATH'
+else:
+raise EnvironmentError('unknown platform.system()')
 
 # in stand-alone builds, shlibdir is clang's build tree
 # while llvm_libs_dir is installed LLVM (and possibly older clang)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39166: [NFC] Add some assertions to placate my paranoia about sharing a variant bit across FunctionDecl and CXXDeductionGuideDecl - should I do this?

2017-10-22 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

Isn't it already an UB if someone set `WillHaveBody` and but later 
`IsCopyDeductionCandidate` being read, vice versa?


Repository:
  rL LLVM

https://reviews.llvm.org/D39166



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39162: [test] Fix clang-test for FreeBSD and NetBSD

2017-10-22 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked an inline comment as done.
lichray added a comment.

In https://reviews.llvm.org/D39162#903179, @zturner wrote:

> Please don't throw an exception here.  Instead, write this as:
>
>   lit_config.warning('Unable to determine shared library path variable for 
> platform {}'.format(platform.system()))
>
>  


Why a warning rather than fatal?


https://reviews.llvm.org/D39162



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39162: [test] Fix clang-test for FreeBSD and NetBSD

2017-10-22 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

In https://reviews.llvm.org/D39162#903186, @joerg wrote:

> I think we should special case Darwin and Windows and fall-back to 
> LD_LIBRARY_PATH for the rest. Can't remember if there is a UNIX-like platform 
> left where it doesn't work.


If those developers come to us, I would say.  The script is for LLVM developers 
only, and to developers, a missed guess wastes more time than pointing out 
where it doesn't work.


https://reviews.llvm.org/D39162



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39162: [test] Fix clang-test for FreeBSD and NetBSD

2017-10-22 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 119800.

https://reviews.llvm.org/D39162

Files:
  test/Unit/lit.cfg.py


Index: test/Unit/lit.cfg.py
===
--- test/Unit/lit.cfg.py
+++ test/Unit/lit.cfg.py
@@ -35,13 +35,15 @@
 if symbolizer in os.environ:
 config.environment[symbolizer] = os.environ[symbolizer]
 
-shlibpath_var = ''
-if platform.system() == 'Linux':
+if platform.system() in ['Linux', 'FreeBSD', 'NetBSD']:
 shlibpath_var = 'LD_LIBRARY_PATH'
 elif platform.system() == 'Darwin':
 shlibpath_var = 'DYLD_LIBRARY_PATH'
 elif platform.system() == 'Windows':
 shlibpath_var = 'PATH'
+else:
+lit_config.fatal("unable to inject shared library path on '{}'"
+ .format(platform.system()))
 
 # in stand-alone builds, shlibdir is clang's build tree
 # while llvm_libs_dir is installed LLVM (and possibly older clang)


Index: test/Unit/lit.cfg.py
===
--- test/Unit/lit.cfg.py
+++ test/Unit/lit.cfg.py
@@ -35,13 +35,15 @@
 if symbolizer in os.environ:
 config.environment[symbolizer] = os.environ[symbolizer]
 
-shlibpath_var = ''
-if platform.system() == 'Linux':
+if platform.system() in ['Linux', 'FreeBSD', 'NetBSD']:
 shlibpath_var = 'LD_LIBRARY_PATH'
 elif platform.system() == 'Darwin':
 shlibpath_var = 'DYLD_LIBRARY_PATH'
 elif platform.system() == 'Windows':
 shlibpath_var = 'PATH'
+else:
+lit_config.fatal("unable to inject shared library path on '{}'"
+ .format(platform.system()))
 
 # in stand-alone builds, shlibdir is clang's build tree
 # while llvm_libs_dir is installed LLVM (and possibly older clang)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39162: [test] Fix clang-test for FreeBSD and NetBSD

2017-10-22 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 119803.
lichray edited the summary of this revision.
lichray added a comment.

Changed to an warning given @zturner 's comments and experiments.


https://reviews.llvm.org/D39162

Files:
  test/Unit/lit.cfg.py


Index: test/Unit/lit.cfg.py
===
--- test/Unit/lit.cfg.py
+++ test/Unit/lit.cfg.py
@@ -35,17 +35,23 @@
 if symbolizer in os.environ:
 config.environment[symbolizer] = os.environ[symbolizer]
 
-shlibpath_var = ''
-if platform.system() == 'Linux':
-shlibpath_var = 'LD_LIBRARY_PATH'
-elif platform.system() == 'Darwin':
-shlibpath_var = 'DYLD_LIBRARY_PATH'
-elif platform.system() == 'Windows':
-shlibpath_var = 'PATH'
-
-# in stand-alone builds, shlibdir is clang's build tree
-# while llvm_libs_dir is installed LLVM (and possibly older clang)
-shlibpath = os.path.pathsep.join((config.shlibdir, config.llvm_libs_dir,
- config.environment.get(shlibpath_var,'')))
-
-config.environment[shlibpath_var] = shlibpath
+def find_shlibpath_var():
+if platform.system() in ['Linux', 'FreeBSD', 'NetBSD']:
+yield 'LD_LIBRARY_PATH'
+elif platform.system() == 'Darwin':
+yield 'DYLD_LIBRARY_PATH'
+elif platform.system() == 'Windows':
+yield 'PATH'
+
+for shlibpath_var in find_shlibpath_var():
+# in stand-alone builds, shlibdir is clang's build tree
+# while llvm_libs_dir is installed LLVM (and possibly older clang)
+shlibpath = os.path.pathsep.join(
+(config.shlibdir,
+ config.llvm_libs_dir,
+ config.environment.get(shlibpath_var, '')))
+config.environment[shlibpath_var] = shlibpath
+break
+else:
+lit_config.warning("unable to inject shared library path on '{}'"
+   .format(platform.system()))


Index: test/Unit/lit.cfg.py
===
--- test/Unit/lit.cfg.py
+++ test/Unit/lit.cfg.py
@@ -35,17 +35,23 @@
 if symbolizer in os.environ:
 config.environment[symbolizer] = os.environ[symbolizer]
 
-shlibpath_var = ''
-if platform.system() == 'Linux':
-shlibpath_var = 'LD_LIBRARY_PATH'
-elif platform.system() == 'Darwin':
-shlibpath_var = 'DYLD_LIBRARY_PATH'
-elif platform.system() == 'Windows':
-shlibpath_var = 'PATH'
-
-# in stand-alone builds, shlibdir is clang's build tree
-# while llvm_libs_dir is installed LLVM (and possibly older clang)
-shlibpath = os.path.pathsep.join((config.shlibdir, config.llvm_libs_dir,
- config.environment.get(shlibpath_var,'')))
-
-config.environment[shlibpath_var] = shlibpath
+def find_shlibpath_var():
+if platform.system() in ['Linux', 'FreeBSD', 'NetBSD']:
+yield 'LD_LIBRARY_PATH'
+elif platform.system() == 'Darwin':
+yield 'DYLD_LIBRARY_PATH'
+elif platform.system() == 'Windows':
+yield 'PATH'
+
+for shlibpath_var in find_shlibpath_var():
+# in stand-alone builds, shlibdir is clang's build tree
+# while llvm_libs_dir is installed LLVM (and possibly older clang)
+shlibpath = os.path.pathsep.join(
+(config.shlibdir,
+ config.llvm_libs_dir,
+ config.environment.get(shlibpath_var, '')))
+config.environment[shlibpath_var] = shlibpath
+break
+else:
+lit_config.warning("unable to inject shared library path on '{}'"
+   .format(platform.system()))
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39162: [test] Fix clang-test for FreeBSD and NetBSD

2017-10-23 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

ping?


https://reviews.llvm.org/D39162



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39220: [Analyzer] Store BodyFarm in std::unique_ptr

2017-10-23 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: lib/Analysis/AnalysisDeclContext.cpp:606
 
-AnalysisDeclContextManager::~AnalysisDeclContextManager() {
-  if (BdyFrm)
-delete BdyFrm;
-}
+AnalysisDeclContextManager::~AnalysisDeclContextManager() {}
 

Why having empty user-defined dtor?  This class has no vtbl; deleting the dtor 
declaration in `AnalysisDeclContext.h` should work.


https://reviews.llvm.org/D39220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39220: [Analyzer] Store BodyFarm in std::unique_ptr

2017-10-24 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray accepted this revision.
lichray added a comment.
This revision is now accepted and ready to land.

LGTM


https://reviews.llvm.org/D39220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39284: [c++2a] Decomposed _condition_

2017-10-25 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray created this revision.

This feature was discussed but not yet proposed.  It allows a structured 
binding to appear as a //condition//

  if (auto [ok, val] = f(...))

So the user can save an extra //condition// if the statement can query the 
value to-be-decomposed instead.  Formally, it makes the value of the underlying 
object of the structured binding declaration also the value of a //condition// 
that is an initialized declaration.

Considering its logicality which is entirely evident from its trivial 
implementation, I think it might be acceptable to land it as an extension for 
now before I write the paper.


https://reviews.llvm.org/D39284

Files:
  include/clang/Sema/DeclSpec.h
  lib/Parse/ParseExprCXX.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/Parser/cxx2a-decomposition.cpp
  test/SemaCXX/cxx2a-decomposition.cpp

Index: test/SemaCXX/cxx2a-decomposition.cpp
===
--- /dev/null
+++ test/SemaCXX/cxx2a-decomposition.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+struct X {
+  bool flag;
+  int data;
+  constexpr explicit operator bool() const {
+return flag;
+  }
+  constexpr operator int() const {
+return data;
+  }
+};
+
+namespace CondInIf {
+constexpr int f(X x) {
+  if (auto [ok, d] = x)
+return d + int(ok);
+  else
+return d * int(ok);
+  ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
+  d = {};  // expected-error {{use of undeclared identifier 'd'}}
+}
+
+static_assert(f({true, 2}) == 3);
+static_assert(f({false, 2}) == 0);
+
+constexpr char g(char const (&x)[2]) {
+  if (auto &[a, b] = x)
+return a;
+  else
+return b;
+}
+
+static_assert(g("x") == 'x');
+} // namespace CondInIf
+
+namespace CondInSwitch {
+constexpr int f(int n) {
+  switch (X s = {true, n}; auto [ok, d] = s) {
+s = {};
+  case 0:
+return int(ok);
+  case 1:
+return d * 10;
+  case 2:
+return d * 40;
+  default:
+return 0;
+  }
+  ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
+  d = {};  // expected-error {{use of undeclared identifier 'd'}}
+  s = {};  // expected-error {{use of undeclared identifier 's'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 10);
+static_assert(f(2) == 80);
+} // namespace CondInSwitch
+
+namespace CondInWhile {
+constexpr int f(int n) {
+  int m = 1;
+  while (auto [ok, d] = X{n > 1, n}) {
+m *= d;
+--n;
+  }
+  return m;
+  return ok; // expected-error {{use of undeclared identifier 'ok'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 1);
+static_assert(f(4) == 24);
+} // namespace CondInWhile
+
+namespace CondInFor {
+constexpr int f(int n) {
+  int a = 1, b = 1;
+  for (X x = {true, n}; auto &[ok, d] = x; --d) {
+if (d < 2)
+  ok = false;
+else {
+  int x = b;
+  b += a;
+  a = x;
+}
+  }
+  return b;
+  return d; // expected-error {{use of undeclared identifier 'd'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 1);
+static_assert(f(2) == 2);
+static_assert(f(5) == 8);
+} // namespace CondInFor
Index: test/Parser/cxx2a-decomposition.cpp
===
--- /dev/null
+++ test/Parser/cxx2a-decomposition.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++2a %s -verify
+
+struct Na {
+  bool flag;
+  float data;
+};
+
+struct Rst {
+  bool flag;
+  float data;
+  explicit operator bool() const {
+return flag;
+  }
+};
+
+Rst f();
+Na g();
+
+namespace CondInIf {
+void h() {
+  if (auto [ok, d] = f())
+;
+  if (auto [ok, d] = g()) // expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInIf
+
+namespace CondInWhile {
+void h() {
+  while (auto [ok, d] = f())
+;
+  while (auto [ok, d] = g()) // expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInWhile
+
+namespace CondInFor {
+void h() {
+  for (; auto [ok, d] = f();)
+;
+  for (; auto [ok, d] = g();) // expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInFor
+
+struct IntegerLike {
+  bool flag;
+  float data;
+  operator int() const {
+return int(data);
+  }
+};
+
+namespace CondInSwitch {
+void h(IntegerLike x) {
+  switch (auto [ok, d] = x)
+;
+  switch (auto [ok, d] = g()) // expected-error {{statement requires expression of integer type ('Na' invalid)}}
+;
+}
+} // namespace CondInSwitch
Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -692,9 +692,10 @@
   assert(D.isDecompositionDeclarator());
   const DecompositionDeclarator &Decomp = D.getDecompositionDeclarator();
 
-  // The syntax only allows a decomposition declarator as a simple-declaration
-  // or a for-range-declaration, but we parse it in more cases than that.
-  if (!D.mayHaveDecompositionDeclarat

[PATCH] D51268: [libc++] Implement P0487R1 - Fixing operator>>(basic_istream&, CharT*)

2018-08-25 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray created this revision.
lichray added reviewers: mclow.lists, ldionne.
Herald added a reviewer: EricWF.
Herald added a subscriber: christof.

Avoid buffer overflow by replacing the pointer interface with an array 
reference interface in C++2a.
Tentatively ready on Batavia2018.

https://wg21.link/lwg2499
 https://wg21.link/p0487


Repository:
  rCXX libc++

https://reviews.llvm.org/D51268

Files:
  include/istream
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp

Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
===
--- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
+++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
@@ -50,6 +50,17 @@
 assert(!is.fail());
 assert(std::string(s) == "abcdefghijk");
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+char s[4];
+is >> s;
+assert(!is.eof());
+assert(!is.fail());
+assert(std::string(s) == "abc");
+}
+#endif
 {
 testbuf sb(L"   abcdefghijk");
 std::wistream is(&sb);
@@ -71,6 +82,17 @@
 assert(std::wstring(s) == L"abcdefghijk");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb(L"   abcdefghijk");
+std::wistream is(&sb);
+wchar_t s[4];
+is >> s;
+assert(!is.eof());
+assert(!is.fail());
+assert(std::wstring(s) == L"abc");
+}
+#endif
 {
 testbuf sb("   abcdefghijk");
 std::istream is(&sb);
@@ -82,4 +104,15 @@
 assert(std::string(s) == "");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+char s[1];
+is >> s;
+assert(!is.eof());
+assert( is.fail());
+assert(std::string(s) == "");
+}
+#endif
 }
Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
===
--- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
+++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
@@ -61,6 +61,17 @@
 assert(std::string((char*)s) == "abc");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+unsigned char s[4];
+is >> s;
+assert(!is.eof());
+assert(!is.fail());
+assert(std::string((char*)s) == "abc");
+}
+#endif
 {
 testbuf sb("   abcdefghijk");
 std::istream is(&sb);
@@ -82,4 +93,15 @@
 assert(std::string((char*)s) == "");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+unsigned char s[1];
+is >> s;
+assert(!is.eof());
+assert( is.fail());
+assert(std::string((char*)s) == "");
+}
+#endif
 }
Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
===
--- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
+++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
@@ -61,6 +61,17 @@
 assert(std::string((char*)s) == "abc");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+signed char s[4];
+is >> s;
+assert(!is.eof());
+assert(!is.fail());
+assert(std::string((char*)s) == "abc");
+}
+#endif
 {
 testbuf sb("   abcdefghijk");
 std::istream is(&sb);
@@ -82,4 +93,15 @@
 assert(std::string((char*)s) == "");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+signed char s[1];
+is >> s;
+assert(!is.eof());
+assert( is.fail());
+assert(std::string((char*)s) == "");
+}
+#endif
 }
Inde

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-20 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

Ping.  Any more comments?


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-30 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked an inline comment as done.
lichray added inline comments.



Comment at: include/charconv:158
+
+#if !defined(_LIBCPP_COMPILER_MSVC)
+static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)

mclow.lists wrote:
> In general, we don't put `_LIBCPP_COMPILER_XXX` in header files in libc++.
> Instead, we declare a feature macro `_LIBCPP_HAS_` in `<__config>` and 
> then use that everywhere.
> 
> I see that most of the uses of `_LIBCPP_COMPILER_MSVC` are in ``, 
> and center around the builtins for `__builtin_clz`, etc.
> 
> We can clean this up later. (/me makes note).
> 
MSVC has the intrinsics we need, but I did not plan to put too much in this 
patch.  The suggested `` header sounds like a good place for grouping up 
those intrinsics in the future.



Comment at: include/charconv:285
+inline _LIBCPP_INLINE_VISIBILITY auto
+__to_unsigned(_Tp __x)
+{

mclow.lists wrote:
> in libc++, we put the return type on the left.
> 
> template 
> inline _LIBCPP_INLINE_VISIBILITY
> auto __to_unsigned(_Tp __x)
> 
> (and then ask 'why auto'?)
> 
```
template 
inline _LIBCPP_INLINE_VISIBILITY
auto __to_unsigned(_Tp __x)
```

I want this as well, but ClangFormat doesn't support it... The style which I'm 
using is close to FreeBSD style(9), please forgive.  I don't mind if you send 
me a `.clang-format` file (the one I used is 
http://paste.openstack.org/show/726883/), but I won't manually adjust the 
code...

About why `auto` -- this file requires C++14 already, so I don't need to repeat 
my self (by writing `make_unsigned_t<_Tp>` again).



Comment at: test/support/charconv_test_helpers.h:226
+void
+run(type_list)
+{

mclow.lists wrote:
> This name `run` concerns me. I'd feel better if it was `run_integral_tests` 
> or something a bit less general.
> 
> On the other hand, it's in a test, so we can change it whenever we want.
> 
The callsites look like
```
run(all_signed);
```
That's why I named it "run".  Not an issue for now I think.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-31 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 158404.
lichray added a comment.

Dropping a lambda


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  include/CMakeLists.txt
  include/charconv
  include/module.modulemap
  src/charconv.cpp
  test/libcxx/double_include.sh.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,232 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+#if TEST_STD_VER <= 11
+#error This file requires C++14
+#endif
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && std::make_unsigned_t(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= std::make_unsigned_t((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+assert(r.ptr == buf + len - 1);
+assert(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+assert(r.ptr == buf + len);
+assert(r.ec == std::errc{});
+assert(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+assert(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+assert(r.ptr == ep);
+assert(r.ec == std::errc::value_too_large);
+}
+
+private:
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+{
+char* last;
+auto r = strtoll(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+{
+char* last;
+auto r = strtoull(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10)
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, r.ptr, x, args...);
+assert(r2.ptr == r.ptr);
+assert(x == X(v));
+}
+else
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, r.ptr,

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-31 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL338479: [libc++][C++17] Elementary string conversions for 
integral types (authored by lichray, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D41458?vs=158404&id=158455#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D41458

Files:
  libcxx/trunk/include/CMakeLists.txt
  libcxx/trunk/include/charconv
  libcxx/trunk/include/module.modulemap
  libcxx/trunk/src/charconv.cpp
  libcxx/trunk/test/libcxx/double_include.sh.cpp
  
libcxx/trunk/test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  libcxx/trunk/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  
libcxx/trunk/test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  libcxx/trunk/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  libcxx/trunk/test/support/charconv_test_helpers.h

Index: libcxx/trunk/src/charconv.cpp
===
--- libcxx/trunk/src/charconv.cpp
+++ libcxx/trunk/src/charconv.cpp
@@ -0,0 +1,233 @@
+//===- charconv.cpp ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "charconv"
+#include 
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __itoa
+{
+
+static constexpr char cDigitsLut[200] = {
+'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0',
+'7', '0', '8', '0', '9', '1', '0', '1', '1', '1', '2', '1', '3', '1', '4',
+'1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '2', '0', '2', '1', '2',
+'2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
+'3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3',
+'7', '3', '8', '3', '9', '4', '0', '4', '1', '4', '2', '4', '3', '4', '4',
+'4', '5', '4', '6', '4', '7', '4', '8', '4', '9', '5', '0', '5', '1', '5',
+'2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
+'6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6',
+'7', '6', '8', '6', '9', '7', '0', '7', '1', '7', '2', '7', '3', '7', '4',
+'7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '8', '0', '8', '1', '8',
+'2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
+'9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9',
+'7', '9', '8', '9', '9'};
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY char*
+append1(char* buffer, T i)
+{
+*buffer = '0' + static_cast(i);
+return buffer + 1;
+}
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY char*
+append2(char* buffer, T i)
+{
+memcpy(buffer, &cDigitsLut[(i)*2], 2);
+return buffer + 2;
+}
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY char*
+append3(char* buffer, T i)
+{
+return append2(append1(buffer, (i) / 100), (i) % 100);
+}
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY char*
+append4(char* buffer, T i)
+{
+return append2(append2(buffer, (i) / 100), (i) % 100);
+}
+
+char*
+__u32toa(uint32_t value, char* buffer)
+{
+if (value < 1)
+{
+if (value < 100)
+{
+if (value < 10)
+buffer = append1(buffer, value);
+else
+buffer = append2(buffer, value);
+}
+else
+{
+if (value < 1000)
+buffer = append3(buffer, value);
+else
+buffer = append4(buffer, value);
+}
+}
+else if (value < 1)
+{
+// value = 
+const uint32_t b = value / 1;
+const uint32_t c = value % 1;
+
+if (value < 100)
+{
+if (value < 10)
+buffer = append1(buffer, b);
+else
+buffer = append2(buffer, b);
+}
+else
+{
+if (value < 1000)
+buffer = append3(buffer, b);
+else
+buffer = append4(buffer, b);
+}
+
+buffer = append4(buffer, c);
+}
+else
+{
+// value = aa in decimal
+const uint32_t a = value / 1;  // 1 to 42
+value %= 1;
+
+if (a < 10)
+buffer = append1(buffer, a);
+else
+buffer = append2(buffer, a);
+
+buffer = append4(buffer, value / 1);
+buffer = append4(buffer, value % 1);
+}
+
+return buffer;
+}
+
+char*
+__u64toa(uint64_t value, char* buffer)
+{
+if (value < 1)
+{
+uint32_t v = static_cast(value);
+if (v < 1)
+{
+if (v < 100)
+{
+   

[PATCH] D50130: [libc++] Fix build failures after merging

2018-07-31 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray created this revision.
Herald added a reviewer: EricWF.
Herald added subscribers: cfe-commits, ldionne, christof.

- fix a stupid unit test typo
- add  symbols to Linux abilist


Repository:
  rCXX libc++

https://reviews.llvm.org/D50130

Files:
  lib/abi/x86_64-unknown-linux-gnu.v1.abilist
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h


Index: test/support/charconv_test_helpers.h
===
--- test/support/charconv_test_helpers.h
+++ test/support/charconv_test_helpers.h
@@ -178,7 +178,7 @@
 {
 assert(x == 0xc);
 assert(r2.ptr == buf);
-assert(r.ec == std::errc::invalid_argument);
+assert(r2.ec == std::errc::invalid_argument);
 }
 else
 {
Index: test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
===
--- test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
+++ test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
@@ -37,6 +37,7 @@
 using xl = std::numeric_limits;
 
 test(1, b);
+test(-1, b);
 test(xl::lowest(), b);
 test((xl::max)(), b);
 test((xl::max)() / 2, b);
Index: lib/abi/x86_64-unknown-linux-gnu.v1.abilist
===
--- lib/abi/x86_64-unknown-linux-gnu.v1.abilist
+++ lib/abi/x86_64-unknown-linux-gnu.v1.abilist
@@ -1192,6 +1192,8 @@
 {'name': '_ZNSt3__15wclogE', 'is_defined': True, 'type': 'OBJECT', 'size': 160}
 {'name': '_ZNSt3__15wcoutE', 'is_defined': True, 'type': 'OBJECT', 'size': 160}
 {'name': '_ZNSt3__16__clocEv', 'is_defined': True, 'type': 'FUNC'}
+{'name': '_ZNSt3__16__itoa8__u64toaEmPc', 'is_defined': True, 'type': 'FUNC'}
+{'name': '_ZNSt3__16__itoa8__u32toaEjPc', 'is_defined': True, 'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIaaEEPaEEvT0_S5_T_', 'is_defined': True, 
'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIccEEPcEEvT0_S5_T_', 'is_defined': True, 
'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIddEEPdEEvT0_S5_T_', 'is_defined': True, 
'type': 'FUNC'}


Index: test/support/charconv_test_helpers.h
===
--- test/support/charconv_test_helpers.h
+++ test/support/charconv_test_helpers.h
@@ -178,7 +178,7 @@
 {
 assert(x == 0xc);
 assert(r2.ptr == buf);
-assert(r.ec == std::errc::invalid_argument);
+assert(r2.ec == std::errc::invalid_argument);
 }
 else
 {
Index: test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
===
--- test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
+++ test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
@@ -37,6 +37,7 @@
 using xl = std::numeric_limits;
 
 test(1, b);
+test(-1, b);
 test(xl::lowest(), b);
 test((xl::max)(), b);
 test((xl::max)() / 2, b);
Index: lib/abi/x86_64-unknown-linux-gnu.v1.abilist
===
--- lib/abi/x86_64-unknown-linux-gnu.v1.abilist
+++ lib/abi/x86_64-unknown-linux-gnu.v1.abilist
@@ -1192,6 +1192,8 @@
 {'name': '_ZNSt3__15wclogE', 'is_defined': True, 'type': 'OBJECT', 'size': 160}
 {'name': '_ZNSt3__15wcoutE', 'is_defined': True, 'type': 'OBJECT', 'size': 160}
 {'name': '_ZNSt3__16__clocEv', 'is_defined': True, 'type': 'FUNC'}
+{'name': '_ZNSt3__16__itoa8__u64toaEmPc', 'is_defined': True, 'type': 'FUNC'}
+{'name': '_ZNSt3__16__itoa8__u32toaEjPc', 'is_defined': True, 'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIaaEEPaEEvT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIccEEPcEEvT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIddEEPdEEvT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50130: [libc++] Fix build failures after merging

2018-07-31 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rCXX338486: [libc++] Fix build failures after merging 
 (authored by lichray, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D50130?vs=158464&id=158465#toc

Repository:
  rCXX libc++

https://reviews.llvm.org/D50130

Files:
  lib/abi/x86_64-unknown-linux-gnu.v1.abilist
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h


Index: test/support/charconv_test_helpers.h
===
--- test/support/charconv_test_helpers.h
+++ test/support/charconv_test_helpers.h
@@ -178,7 +178,7 @@
 {
 assert(x == 0xc);
 assert(r2.ptr == buf);
-assert(r.ec == std::errc::invalid_argument);
+assert(r2.ec == std::errc::invalid_argument);
 }
 else
 {
Index: test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
===
--- test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
+++ test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
@@ -37,6 +37,7 @@
 using xl = std::numeric_limits;
 
 test(1, b);
+test(-1, b);
 test(xl::lowest(), b);
 test((xl::max)(), b);
 test((xl::max)() / 2, b);
Index: lib/abi/x86_64-unknown-linux-gnu.v1.abilist
===
--- lib/abi/x86_64-unknown-linux-gnu.v1.abilist
+++ lib/abi/x86_64-unknown-linux-gnu.v1.abilist
@@ -1192,6 +1192,8 @@
 {'name': '_ZNSt3__15wclogE', 'is_defined': True, 'type': 'OBJECT', 'size': 160}
 {'name': '_ZNSt3__15wcoutE', 'is_defined': True, 'type': 'OBJECT', 'size': 160}
 {'name': '_ZNSt3__16__clocEv', 'is_defined': True, 'type': 'FUNC'}
+{'name': '_ZNSt3__16__itoa8__u64toaEmPc', 'is_defined': True, 'type': 'FUNC'}
+{'name': '_ZNSt3__16__itoa8__u32toaEjPc', 'is_defined': True, 'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIaaEEPaEEvT0_S5_T_', 'is_defined': True, 
'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIccEEPcEEvT0_S5_T_', 'is_defined': True, 
'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIddEEPdEEvT0_S5_T_', 'is_defined': True, 
'type': 'FUNC'}


Index: test/support/charconv_test_helpers.h
===
--- test/support/charconv_test_helpers.h
+++ test/support/charconv_test_helpers.h
@@ -178,7 +178,7 @@
 {
 assert(x == 0xc);
 assert(r2.ptr == buf);
-assert(r.ec == std::errc::invalid_argument);
+assert(r2.ec == std::errc::invalid_argument);
 }
 else
 {
Index: test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
===
--- test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
+++ test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
@@ -37,6 +37,7 @@
 using xl = std::numeric_limits;
 
 test(1, b);
+test(-1, b);
 test(xl::lowest(), b);
 test((xl::max)(), b);
 test((xl::max)() / 2, b);
Index: lib/abi/x86_64-unknown-linux-gnu.v1.abilist
===
--- lib/abi/x86_64-unknown-linux-gnu.v1.abilist
+++ lib/abi/x86_64-unknown-linux-gnu.v1.abilist
@@ -1192,6 +1192,8 @@
 {'name': '_ZNSt3__15wclogE', 'is_defined': True, 'type': 'OBJECT', 'size': 160}
 {'name': '_ZNSt3__15wcoutE', 'is_defined': True, 'type': 'OBJECT', 'size': 160}
 {'name': '_ZNSt3__16__clocEv', 'is_defined': True, 'type': 'FUNC'}
+{'name': '_ZNSt3__16__itoa8__u64toaEmPc', 'is_defined': True, 'type': 'FUNC'}
+{'name': '_ZNSt3__16__itoa8__u32toaEjPc', 'is_defined': True, 'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIaaEEPaEEvT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIccEEPcEEvT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
 {'name': '_ZNSt3__16__sortIRNS_6__lessIddEEPdEEvT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-02-09 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

I will pick up the changes later next week.




Comment at: include/charconv:89
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+enum class _LIBCPP_ENUM_VIS chars_format

EricWF wrote:
> We need to hide these names when `_LIBCPP_STD_VER < 17`, since we're not 
> allowed to introduce new names into namespace `std` in older dialects.
But this header is backported to C++11, so I intended to not to guard it.



Comment at: include/charconv:122
+template 
+inline _LIBCPP_INLINE_VISIBILITY auto
+__to_unsigned(_Tp __x) -> typename make_unsigned<_Tp>::type

EricWF wrote:
> Same as above. There's no reason to deviate from the typical libc++ style and 
> use trailing return types here.
libc++ doesn't have one uniformed style.  For some reason I found this style 
formats better with clang-format.



Comment at: include/charconv:151
+
+#if __has_builtin(__builtin_clzll)
+if (__tx::digits <= __diff || __tx::width(__value) <= __diff)

EricWF wrote:
> `` already has a `__clz` wrapper for `__builtin_clz` et al. We 
> should use that instead. That also allows us to get rid of the fallback 
> implementation, and it correctly uses the builtin for compilers like GCC 
> which don't provide `__has_builtin`.
I saw that, and I agree this can be improved, however `` would be 
too heavy to include here.  Thoughts?



Comment at: include/support/itoa/itoa.h:81
+#if __has_builtin(__builtin_clzll)
+static _LIBCPP_INLINE_VISIBILITY auto width(_Tp __v) -> int
+{

EricWF wrote:
> `width`, `convert` and `pow` need to be reserved names.
These names are standard names (functions), so users can't provide function 
style macros to override them.  Am I wrong on that?



Comment at: include/support/itoa/itoa.h:123
+inline _LIBCPP_INLINE_VISIBILITY bool
+__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
+{

EricWF wrote:
> `__builtin_mul_overflow` works for `char` and `short`, so can't we just call 
> that?
I don't think so, it "works" after promotion.



Comment at: include/support/itoa/itoa.h:161
+template 
+struct _LIBCPP_HIDDEN traits : __traits<_Tp>
+{

EricWF wrote:
> `traits` needs to be a reserved name, and preferably a more descriptive one.
Similarly It's a standard name (std::string typedef), so user can't use a 
non-function style macro name to override it, IIUC.



Comment at: include/support/itoa/itoa.h:188
+
+template 
+static _LIBCPP_INLINE_VISIBILITY auto

EricWF wrote:
> What's wrong with using `std::inner_product`?
`__first != __last1` instead of `<`



Comment at: src/support/itoa/itoa.cpp:1
+// -*- C++ -*-
+//===--===//

EricWF wrote:
> This file should be renamed `charconv.cpp` and moved into the main source 
> directory.
We are going to have floating point cpp files so I don't think that one 
charconv.cpp is enough.



Comment at: src/support/itoa/itoa.cpp:35
+
+#define APPEND1(i)  \
+do  \

EricWF wrote:
> Any reason these can't be `static` functions? The compiler should optimize 
> them away nicely.
Although yes, but that's what the author provides.  It's an implementation 
file, so it doesn't matter I guess.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33776: [libcxx] LWG2221: No formatted output operator for nullptr

2017-12-13 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: include/ostream:225
+basic_ostream& operator<<(nullptr_t)
+{ return *this << (const void*)0; }
+

K-ballo wrote:
> Quuxplusone wrote:
> > mclow.lists wrote:
> > > lichray wrote:
> > > > Oh, common, I persuaded the committee to allow you to print a `(null)`  
> > > > and you don't do it...
> > > I think that `(null)` is a better thing to output here than `0x0`.
> > Are you two implying that
> > 
> > *this << (const void *)0;
> > 
> > does *not* print `(null)`? It certainly should, IMO. (I mean, it'll call 
> > `num_put` for `void*` in the current locale, but I would naturally expect 
> > that to print `(null)`.)
> > Anyway, whether the current locale prints null as `(null)` or not, there is 
> > great potential utility in using the same format for all pointers, as 
> > K-ballo is doing here. I'd really like to be able to
> > 
> > std::ostringstream oss;
> > oss << nullptr;  // equivalently: oss << (void*)0;
> > void *p;
> > std::istringstream(oss.str()) >> p;  // should read in a null pointer, 
> > not derp out
> > 
> > FWIW, it looks like libc++ currently *does* print null pointers as `(nil)`, 
> > which is not quite the same thing as `(null)`. libstdc++ prints them as `0`.
> > https://wandbox.org/permlink/yAM6tjMzvEX9HhhE
> It's been a while now, but I seem to recall that the reason we settled on 
> `(*this) << (const void*)0` was precisely so that it would go through 
> `num_put`, as the rest of the pointers do. As I read back on the 
> specification, however, I am no longer sure that such an implementation is 
> conforming. Maybe if we were to call the facet directly...
> 
> I am no longer interested in this issue. If anyone wants to take over control 
> I would be happy to yield it; otherwise, I'll implement whatever I'm 
> instructed to.
Your test code prints 0x0 0x0 on FreeBSD though.
If reliable round-tripping is the goal, maybe we can enforce printing `(nil)`?  
fmtlib does this as well:

https://github.com/fmtlib/fmt/commit/b5fda1c90d94aeaf96081477c9bfe13789c00e03


https://reviews.llvm.org/D33776



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41223: [libc++] Fix PR35491 - std::array of zero-size doesn't work with non-default constructible types.

2017-12-14 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: include/array:135
+  _LIBCPP_INLINE_VISIBILITY
+  static void __swap(_StorageT& __lhs, _StorageT& __rhs) {
+std::swap_ranges(__lhs, __lhs + _Size, __rhs);

Just asking: no compiler is dumb enough to not inline this entirely trivial 
wrapper so that it's okay to not to propagate `noexcept` here to avoid 
try...capture...terminate codegen in its caller side?


https://reviews.llvm.org/D41223



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41223: [libc++] Fix PR35491 - std::array of zero-size doesn't work with non-default constructible types.

2017-12-15 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

BTW, this is https://cplusplus.github.io/LWG/issue2157 , so please update `www` 
accordingly, and also test `{{}}` cases.


https://reviews.llvm.org/D41223



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41347: [libc++] Lift std::errc into a separated header

2017-12-18 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray created this revision.
lichray added reviewers: mclow.lists, EricWF.

This is needed to implement ``.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41347

Files:
  include/__errc
  include/system_error

Index: include/system_error
===
--- include/system_error
+++ include/system_error
@@ -120,88 +120,6 @@
 const char* what() const noexcept;
 };
 
-enum class errc
-{
-address_family_not_supported,   // EAFNOSUPPORT
-address_in_use, // EADDRINUSE
-address_not_available,  // EADDRNOTAVAIL
-already_connected,  // EISCONN
-argument_list_too_long, // E2BIG
-argument_out_of_domain, // EDOM
-bad_address,// EFAULT
-bad_file_descriptor,// EBADF
-bad_message,// EBADMSG
-broken_pipe,// EPIPE
-connection_aborted, // ECONNABORTED
-connection_already_in_progress, // EALREADY
-connection_refused, // ECONNREFUSED
-connection_reset,   // ECONNRESET
-cross_device_link,  // EXDEV
-destination_address_required,   // EDESTADDRREQ
-device_or_resource_busy,// EBUSY
-directory_not_empty,// ENOTEMPTY
-executable_format_error,// ENOEXEC
-file_exists,// EEXIST
-file_too_large, // EFBIG
-filename_too_long,  // ENAMETOOLONG
-function_not_supported, // ENOSYS
-host_unreachable,   // EHOSTUNREACH
-identifier_removed, // EIDRM
-illegal_byte_sequence,  // EILSEQ
-inappropriate_io_control_operation, // ENOTTY
-interrupted,// EINTR
-invalid_argument,   // EINVAL
-invalid_seek,   // ESPIPE
-io_error,   // EIO
-is_a_directory, // EISDIR
-message_size,   // EMSGSIZE
-network_down,   // ENETDOWN
-network_reset,  // ENETRESET
-network_unreachable,// ENETUNREACH
-no_buffer_space,// ENOBUFS
-no_child_process,   // ECHILD
-no_link,// ENOLINK
-no_lock_available,  // ENOLCK
-no_message_available,   // ENODATA
-no_message, // ENOMSG
-no_protocol_option, // ENOPROTOOPT
-no_space_on_device, // ENOSPC
-no_stream_resources,// ENOSR
-no_such_device_or_address,  // ENXIO
-no_such_device, // ENODEV
-no_such_file_or_directory,  // ENOENT
-no_such_process,// ESRCH
-not_a_directory,// ENOTDIR
-not_a_socket,   // ENOTSOCK
-not_a_stream,   // ENOSTR
-not_connected,  // ENOTCONN
-not_enough_memory,  // ENOMEM
-not_supported,  // ENOTSUP
-operation_canceled, // ECANCELED
-operation_in_progress,  // EINPROGRESS
-operation_not_permitted,// EPERM
-operation_not_supported,// EOPNOTSUPP
-operation_would_block,  // EWOULDBLOCK
-owner_dead, // EOWNERDEAD
-permission_denied,  // EACCES
-protocol_error, // EPROTO
-protocol_not_supported, // EPROTONOSUPPORT
-read_only_file_system,  // EROFS
-resource_deadlock_would_occur,  // EDEADLK
-resource_unavailable_try_again, // EAGAIN
-result_out_of_range,// ERANGE
-state_not_recoverable,  // ENOTRECOVERABLE
-stream_timeout, // ETIME
-text_file_busy, // ETXTBSY
-timed_out,  // ETIMEDOUT
-too_many_files_open_in_system,  // ENFILE
-too_many_files_open,// EMFILE
-too_many_links, // EMLINK
-too_many_symbolic_link_levels,  // ELOOP
-value_too_large,// EOVERFLOW
-wrong_protocol_type // EPROTOTYPE
-};
-
 template <> struct is_error_condition_enum
 : true_type { }
 
@@ -225,8 +143,7 @@
 
 */
 
-#include <__config>
-#include 
+#include <__errc>
 #include 
 #include 
 #include <__functional_base>
@@ -260,109 +177,6 @@
 constexpr size_t is_error_condition_enum_v = is_error_condition_enum<_Tp>::value;
 #endif
 
-// Some error codes are not present on all platforms, so we provide equivalents
-// for them:
-
-//enum class errc
-_LIBCPP_DECLARE_

[PATCH] D41458: WIP: [libc++][C++17] Elementary string conversions for integral types

2017-12-20 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray created this revision.
lichray added reviewers: mclow.lists, EricWF.
Herald added a subscriber: mgorny.

Progress: std::to_chars for integers
Missing: std::from_chars

References:
 https://wg21.link/p0067r5
 https://wg21.link/p0682r1


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  .gitignore
  include/charconv
  include/support/itoa/
  include/support/itoa/itoa.h
  lib/CMakeLists.txt
  src/support/itoa/
  src/support/itoa/itoa.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp

Index: test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
===
--- /dev/null
+++ test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
@@ -0,0 +1,87 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+// 
+
+// to_chars_result to_chars(char* first, char* last, Integral value,
+//  int base = 10)
+
+#include "charconv_test_helpers.h"
+
+template 
+struct test_basics : to_chars_test_base
+{
+using to_chars_test_base::test;
+using to_chars_test_base::test_value;
+
+void operator()()
+{
+
+test(0, "0");
+test(42, "42");
+test(32768, "32768");
+test(0, "0", 10);
+test(42, "42", 10);
+test(32768, "32768", 10);
+test(0xf, "f", 16);
+test(0xdeadbeaf, "deadbeaf", 16);
+test(0755, "755", 8);
+
+for (int b = 2; b < 37; ++b)
+{
+using xl = std::numeric_limits;
+
+test_value(1, b);
+test_value(xl::lowest(), b);
+test_value((xl::max)(), b);
+test_value((xl::max)() / 2, b);
+}
+}
+};
+
+template 
+struct test_signed : to_chars_test_base
+{
+using to_chars_test_base::test;
+using to_chars_test_base::test_value;
+
+void operator()()
+{
+test(-1, "-1");
+test(-12, "-12");
+test(-1, "-1", 10);
+test(-12, "-12", 10);
+test(-21734634, "-21734634", 10);
+test(-2647, "-101001010111", 2);
+test(-0xcc1, "-cc1", 16);
+
+for (int b = 2; b < 37; ++b)
+{
+using xl = std::numeric_limits;
+
+test_value(0, b);
+test_value(xl::lowest(), b);
+test_value((xl::max)(), b);
+}
+}
+};
+
+int
+main()
+{
+auto all_signed =
+type_list();
+auto all_unsigned = type_list();
+auto integrals = concat(all_signed, all_unsigned);
+
+run(integrals);
+run(all_signed);
+}
Index: test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
===
--- /dev/null
+++ test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
@@ -0,0 +1,30 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+// 
+
+// In
+//
+// to_chars_result to_chars(char* first, char* last, Integral value,
+//  int base = 10)
+//
+// Integral cannot be bool.
+
+#include 
+
+int main()
+{
+using std::to_chars;
+char buf[10];
+bool lv = true;
+
+to_chars(buf, buf + sizeof(buf), false);   // expected-error {{call to deleted function}}
+to_chars(buf, buf + sizeof(buf), lv, 16);  // expected-error {{call to deleted function}}
+}
Index: src/support/itoa/itoa.cpp
===
--- /dev/null
+++ src/support/itoa/itoa.cpp
@@ -0,0 +1,296 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limi

[PATCH] D41458: WIP: [libc++][C++17] Elementary string conversions for integral types

2017-12-22 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 127996.
lichray added a comment.

Added std::from_chars


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  .gitignore
  include/charconv
  include/support/itoa/
  include/support/itoa/itoa.h
  lib/CMakeLists.txt
  src/support/itoa/
  src/support/itoa/itoa.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,233 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && typename std::make_unsigned::type(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= typename std::make_unsigned::type((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+LIBCPP_ASSERT(r.ptr == buf + len - 1);
+LIBCPP_ASSERT(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+LIBCPP_ASSERT(r.ptr == buf + len);
+LIBCPP_ASSERT(r.ec == std::errc{});
+LIBCPP_ASSERT(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+LIBCPP_ASSERT(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+LIBCPP_ASSERT(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+LIBCPP_ASSERT(r.ptr == ep);
+LIBCPP_ASSERT(r.ec == std::errc::value_too_large);
+}
+
+private:
+using max_t = typename std::conditional::value, long long,
+unsigned long long>::type;
+
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+-> long long
+{
+char* last;
+auto r = strtoll(p, &last, base);
+LIBCPP_ASSERT(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+-> unsigned long long
+{
+char* last;
+auto r = strtoull(p, &last, base);
+LIBCPP_ASSERT(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10) -> max_t
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+LIBCPP_ASSERT(r.ec == std::errc{});
+
+r2 = from_chars(bu

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2017-12-23 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 128071.
lichray added a comment.

Use Marshall's method to generate digits in reversed order in generic to_chars.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  .gitignore
  include/charconv
  include/support/itoa/
  include/support/itoa/itoa.h
  lib/CMakeLists.txt
  src/support/itoa/
  src/support/itoa/itoa.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,233 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && typename std::make_unsigned::type(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= typename std::make_unsigned::type((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+LIBCPP_ASSERT(r.ptr == buf + len - 1);
+LIBCPP_ASSERT(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+LIBCPP_ASSERT(r.ptr == buf + len);
+LIBCPP_ASSERT(r.ec == std::errc{});
+LIBCPP_ASSERT(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+LIBCPP_ASSERT(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+LIBCPP_ASSERT(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+LIBCPP_ASSERT(r.ptr == ep);
+LIBCPP_ASSERT(r.ec == std::errc::value_too_large);
+}
+
+private:
+using max_t = typename std::conditional::value, long long,
+unsigned long long>::type;
+
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+-> long long
+{
+char* last;
+auto r = strtoll(p, &last, base);
+LIBCPP_ASSERT(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+-> unsigned long long
+{
+char* last;
+auto r = strtoull(p, &last, base);
+LIBCPP_ASSERT(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10) -> max_t
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+LIBCPP_ASSE

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-01-01 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 128393.
lichray added a comment.

Just include math.h


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  .gitignore
  include/charconv
  include/support/itoa/
  include/support/itoa/itoa.h
  lib/CMakeLists.txt
  src/support/itoa/
  src/support/itoa/itoa.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,233 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && typename std::make_unsigned::type(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= typename std::make_unsigned::type((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+LIBCPP_ASSERT(r.ptr == buf + len - 1);
+LIBCPP_ASSERT(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+LIBCPP_ASSERT(r.ptr == buf + len);
+LIBCPP_ASSERT(r.ec == std::errc{});
+LIBCPP_ASSERT(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+LIBCPP_ASSERT(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+LIBCPP_ASSERT(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+LIBCPP_ASSERT(r.ptr == ep);
+LIBCPP_ASSERT(r.ec == std::errc::value_too_large);
+}
+
+private:
+using max_t = typename std::conditional::value, long long,
+unsigned long long>::type;
+
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+-> long long
+{
+char* last;
+auto r = strtoll(p, &last, base);
+LIBCPP_ASSERT(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+-> unsigned long long
+{
+char* last;
+auto r = strtoull(p, &last, base);
+LIBCPP_ASSERT(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10) -> max_t
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+LIBCPP_ASSERT(r.ec == std::errc{});
+
+r2 = from_chars(buf,

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-03-11 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked 7 inline comments as done.
lichray added a comment.
Herald added a subscriber: christof.

Pending patch update due to poor network.




Comment at: include/charconv:90
+
+enum class _LIBCPP_ENUM_VIS chars_format
+{

EricWF wrote:
> enum types should have their underlying integer type explicitly specified. 
> Otherwise their size and ABI can break when users specify `-short-enums`
The standard requires `enum class` to default to `int`; IIUC `enum class` is 
not affected by `-fshort-enums`.



Comment at: include/support/itoa/itoa.h:1
+// -*- C++ -*-
+//===- support/itoa/itoa.h 
===//

EricWF wrote:
> I would rather not introduce another header for this. I think it should go 
> directly in the `charconv` header.
We may have separated floating point headers coming as well...



Comment at: include/support/itoa/itoa.h:47
+
+static constexpr uint32_t __pow10_32[] = {
+UINT32_C(0),  UINT32_C(10),   UINT32_C(100),

EricWF wrote:
> I suspect we can use `__pow10_64` in the 32 bit case as well to avoid 
> emitting another static global.
I have functions returning them as array references.



Comment at: include/support/itoa/itoa.h:54
+
+#if __has_builtin(__builtin_clzll)
+

EricWF wrote:
> Use `__clz` from ``. You can assume we always have that.
Factor `__clz` out of `algorithm` may be too much for this review.  I would 
like to see a subsequent patch to take care of all the related portability 
fixes.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44534: Fix codegen for structured binding binding in conditions

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC327780: Fix codegen for structured binding binding in 
conditions (authored by lichray, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D44534

Files:
  lib/CodeGen/CGStmt.cpp
  test/Parser/decomposed-condition.cpp

Index: lib/CodeGen/CGStmt.cpp
===
--- lib/CodeGen/CGStmt.cpp
+++ lib/CodeGen/CGStmt.cpp
@@ -608,7 +608,7 @@
 EmitStmt(S.getInit());
 
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
 
   // If the condition constant folds and can be elided, try to avoid emitting
   // the condition and the dead arm of the if/else.
@@ -705,7 +705,7 @@
   RunCleanupsScope ConditionScope(*this);
 
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
 
   // Evaluate the conditional in the while header.  C99 6.8.5.1: The
   // evaluation of the controlling expression takes place before each
@@ -865,7 +865,7 @@
 // If the for statement has a condition scope, emit the local variable
 // declaration.
 if (S.getConditionVariable()) {
-  EmitAutoVarDecl(*S.getConditionVariable());
+  EmitDecl(*S.getConditionVariable());
 }
 
 llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
@@ -1574,7 +1574,7 @@
   // Emit the condition variable if needed inside the entire cleanup scope
   // used by this special case for constant folded switches.
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
 
   // At this point, we are no longer "within" a switch instance, so
   // we can temporarily enforce this to ensure that any embedded case
@@ -1603,7 +1603,7 @@
 EmitStmt(S.getInit());
 
   if (S.getConditionVariable())
-EmitAutoVarDecl(*S.getConditionVariable());
+EmitDecl(*S.getConditionVariable());
   llvm::Value *CondV = EmitScalarExpr(S.getCond());
 
   // Create basic block to hold stuff that comes after switch
Index: test/Parser/decomposed-condition.cpp
===
--- test/Parser/decomposed-condition.cpp
+++ test/Parser/decomposed-condition.cpp
@@ -1,5 +1,20 @@
 // RUN: %clang_cc1 -std=c++1z %s -verify
 
+namespace std {
+  template struct tuple_size;
+  template struct tuple_element;
+}
+
+struct Get {
+  template int get() { return 0; }
+  operator bool() { return true; }
+};
+
+namespace std {
+  template<> struct tuple_size { static constexpr int value = 1; };
+  template<> struct tuple_element<0, Get> { using type = int; };
+}
+
 struct Na {
   bool flag;
   float data;
@@ -17,29 +32,35 @@
 Na g();
 
 namespace CondInIf {
-void h() {
+int h() {
   if (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
 ;
   if (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
 ;
+  if (auto [value] = Get()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+return value;
 }
 } // namespace CondInIf
 
 namespace CondInWhile {
-void h() {
+int h() {
   while (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
 ;
   while (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
 ;
+  while (auto [value] = Get()) // expected-warning{{ISO C++17 does not permit structured binding declaration in a condition}}
+return value;
 }
 } // namespace CondInWhile
 
 namespace CondInFor {
-void h() {
+int h() {
   for (; auto [ok, d] = f();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
 ;
   for (; auto [ok, d] = g();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
 ;
+  for (; auto [value] = Get();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+return value;
 }
 } // namespace CondInFor
 
@@ -52,10 +73,15 @@
 };
 
 namespace CondInSwitch {
-void h(IntegerLike x) {
+int h(IntegerLike x) {
   switch (auto [ok, d] = x) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
 ;
   switch (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('Na' invalid)}}
 ;
+ 

[PATCH] D40445: [C++17] Allow an empty expression in an if init statement

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC327782: [C++17] Allow an empty expression in an if init 
statement (authored by lichray, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D40445

Files:
  lib/Parse/ParseExprCXX.cpp
  test/CXX/stmt.stmt/stmt.select/p3.cpp

Index: test/CXX/stmt.stmt/stmt.select/p3.cpp
===
--- test/CXX/stmt.stmt/stmt.select/p3.cpp
+++ test/CXX/stmt.stmt/stmt.select/p3.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++14-compat -verify %s -DCPP17
 
 int f();
 
@@ -10,10 +11,67 @@
   }
 }
 
-
 void h() {
   if (int x = f()) // expected-note 2{{previous definition}}
 int x; // expected-error{{redefinition of 'x'}}
   else
 int x; // expected-error{{redefinition of 'x'}}
 }
+
+void ifInitStatement() {
+  int Var = 0;
+
+  if (int I = 0; true) {}
+  if (Var + Var; true) {}
+  if (; true) {}
+#ifdef CPP17
+  // expected-warning@-4 {{if initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{if initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{if initialization statements are incompatible with C++ standards before C++17}}
+#else
+  // expected-warning@-8 {{'if' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'if' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'if' initialization statements are a C++17 extension}}
+#endif
+}
+
+void switchInitStatement() {
+  int Var = 0;
+
+  switch (int I = 0; Var) {}
+  switch (Var + Var; Var) {}
+  switch (; Var) {}
+#ifdef CPP17
+  // expected-warning@-4 {{switch initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{switch initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{switch initialization statements are incompatible with C++ standards before C++17}}
+#else
+  // expected-warning@-8 {{'switch' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'switch' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'switch' initialization statements are a C++17 extension}}
+#endif
+}
+
+// TODO: Better diagnostics for while init statements.
+void whileInitStatement() {
+  while (int I = 10; I--); // expected-error {{expected ')'}}
+  // expected-note@-1 {{to match this '('}}
+  // expected-error@-2 {{use of undeclared identifier 'I'}}
+
+  int Var = 10;
+  while (Var + Var; Var--) {} // expected-error {{expected ')'}}
+  // expected-note@-1 {{to match this '('}}
+  // expected-error@-2 {{expected ';' after expression}}
+  // expected-error@-3 {{expected expression}}
+  // expected-warning@-4 {{while loop has empty body}}
+  // expected-note@-5 {{put the semicolon on a separate line to silence this warning}}
+}
+
+// TODO: This is needed because clang can't seem to diagnose invalid syntax after the
+// last loop above. It would be nice to remove this.
+void whileInitStatement2() {
+  while (; false) {} // expected-error {{expected expression}}
+  // expected-warning@-1 {{expression result unused}}
+  // expected-error@-2 {{expected ';' after expression}}
+  // expected-error@-3 {{expected expression}}
+}
Index: lib/Parse/ParseExprCXX.cpp
===
--- lib/Parse/ParseExprCXX.cpp
+++ lib/Parse/ParseExprCXX.cpp
@@ -1744,17 +1744,34 @@
   ParsedAttributesWithRange attrs(AttrFactory);
   MaybeParseCXX11Attributes(attrs);
 
+  const auto WarnOnInit = [this, &CK] {
+Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
+? diag::warn_cxx14_compat_init_statement
+: diag::ext_init_statement)
+<< (CK == Sema::ConditionKind::Switch);
+  };
+
   // Determine what kind of thing we have.
   switch (isCXXConditionDeclarationOrInitStatement(InitStmt)) {
   case ConditionOrInitStatement::Expression: {
 ProhibitAttributes(attrs);
 
+// We can have an empty expression here.
+//   if (; true);
+if (InitStmt && Tok.is(tok::semi)) {
+  WarnOnInit();
+  SourceLocation SemiLoc = ConsumeToken();
+  *InitStmt = Actions.ActOnNullStmt(SemiLoc);
+  return ParseCXXCondition(nullptr, Loc, CK);
+}
+
 // Parse the expression.
 ExprResult Expr = ParseExpression(); // expression
 if (Expr.isInvalid())
   return Sema::ConditionError();
 
 if (InitStmt && Tok.is(tok::semi)) {
+  WarnOnInit();
   *InitStmt = Actions.ActOnExprStmt(Expr.get());
   ConsumeToken();
   return ParseCXXCondition(nullptr, Loc, CK);
@@ -1764,10 +1781,7 @@
   }
 
   case ConditionOrInitStatement::InitStmtDecl: {
-Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
-? diag::war

[PATCH] D38216: [C++17] Fix class template argument deduction for default constructors without an initializer

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

LGTM




Comment at: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp:17
 };
 extern A x; // expected-error {{requires an initializer}}

Please add one more test to the end of the file saying
```
static A y;
```
as a remainder to the readers.


https://reviews.llvm.org/D38216



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked an inline comment as not done.
lichray added inline comments.



Comment at: include/support/itoa/itoa.h:29
+UINT64_C(1000),
+UINT64_C(1),
+UINT64_C(10),

EricWF wrote:
> The `UINT64_C` and `UINT32_C` macros are non-standard, so I would rather not 
> use them in a header.
> 
> Additionally, the compiler should correctly convert the integer type to the 
> array's element type, no?
They are from C standard, and I included the corresponding C header.  Dropping 
them gave me `-Wimplicitly-unsigned-literal` warning.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 138841.
lichray marked an inline comment as not done.
lichray added a comment.

Addressing 'Done' comments


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  .gitignore
  include/__errc
  include/charconv
  include/support/itoa/
  include/support/itoa/itoa.h
  include/system_error
  lib/CMakeLists.txt
  src/support/itoa/
  src/support/itoa/itoa.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,233 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && typename std::make_unsigned::type(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= typename std::make_unsigned::type((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+assert(r.ptr == buf + len - 1);
+assert(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+assert(r.ptr == buf + len);
+assert(r.ec == std::errc{});
+assert(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+assert(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+assert(r.ptr == ep);
+assert(r.ec == std::errc::value_too_large);
+}
+
+private:
+using max_t = typename std::conditional::value, long long,
+unsigned long long>::type;
+
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+-> long long
+{
+char* last;
+auto r = strtoll(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+-> unsigned long long
+{
+char* last;
+auto r = strtoull(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10) -> max_t
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_c

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-03-17 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 138842.
lichray added a comment.

Keep patches split


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  .gitignore
  include/charconv
  include/support/itoa/
  include/support/itoa/itoa.h
  lib/CMakeLists.txt
  src/support/itoa/
  src/support/itoa/itoa.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,233 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && typename std::make_unsigned::type(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= typename std::make_unsigned::type((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+assert(r.ptr == buf + len - 1);
+assert(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+assert(r.ptr == buf + len);
+assert(r.ec == std::errc{});
+assert(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+assert(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+assert(r.ptr == ep);
+assert(r.ec == std::errc::value_too_large);
+}
+
+private:
+using max_t = typename std::conditional::value, long long,
+unsigned long long>::type;
+
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+-> long long
+{
+char* last;
+auto r = strtoll(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+-> unsigned long long
+{
+char* last;
+auto r = strtoull(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10) -> max_t
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, r.ptr, x, args...);
+assert(r2.ptr == r.ptr);
+assert(x == X

[PATCH] D44865: [libc++] Implement P0608R2 - A sane variant converting constructor

2018-06-04 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 149824.
lichray added a comment.

Preserve value category in narrowing test.


Repository:
  rCXX libc++

https://reviews.llvm.org/D44865

Files:
  include/variant
  test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
  test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp

Index: test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "test_convertible.hpp"
 #include "test_macros.h"
@@ -40,6 +41,11 @@
 struct AnyConstructible { template  AnyConstructible(T&&) {} };
 struct NoConstructible { NoConstructible() = delete; };
 
+template 
+struct RValueConvertibleFrom {
+RValueConvertibleFrom(T&&) {}
+};
+
 void test_T_ctor_noexcept() {
   {
 using V = std::variant;
@@ -53,7 +59,7 @@
 
 void test_T_ctor_sfinae() {
   {
-using V = std::variant;
+using V = std::variant;
 static_assert(!std::is_constructible::value, "ambiguous");
   }
   {
@@ -66,6 +72,16 @@
   "no matching constructor");
   }
   {
+using V = std::variant;
+static_assert(!std::is_constructible::value,
+  "no matching constructor");
+  }
+  {
+using V = std::variant, bool>;
+static_assert(!std::is_constructible>::value,
+  "no explicit bool in constructor");
+  }
+  {
 using V = std::variant;
 static_assert(
 !std::is_constructible>::value,
@@ -99,6 +115,34 @@
 static_assert(v.index() == 1, "");
 static_assert(std::get<1>(v) == 42, "");
   }
+  {
+constexpr std::variant v(42);
+static_assert(v.index() == 1, "");
+static_assert(std::get<1>(v) == 42, "");
+  }
+  {
+std::variant v = "foo";
+assert(v.index() == 0);
+assert(std::get<0>(v) == "foo");
+  }
+  {
+std::variant> v = nullptr;
+assert(v.index() == 1);
+assert(std::get<1>(v) == nullptr);
+  }
+  {
+std::variant v = true;
+assert(v.index() == 0);
+assert(std::get<0>(v));
+  }
+  {
+std::variant> v1 = 42;
+assert(v1.index() == 0);
+
+int x = 42;
+std::variant, AnyConstructible> v2 = x;
+assert(v2.index() == 1);
+  }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
 using V = std::variant;
Index: test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "test_macros.h"
 #include "variant_test_helpers.hpp"
@@ -128,7 +129,7 @@
 
 void test_T_assignment_sfinae() {
   {
-using V = std::variant;
+using V = std::variant;
 static_assert(!std::is_assignable::value, "ambiguous");
   }
   {
@@ -139,6 +140,15 @@
 using V = std::variant;
 static_assert(!std::is_assignable::value, "no matching operator=");
   }
+  {
+using V = std::variant;
+static_assert(!std::is_assignable::value, "no matching operator=");
+  }
+  {
+using V = std::variant, bool>;
+static_assert(!std::is_assignable>::value,
+  "no explicit bool in operator=");
+  }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
 using V = std::variant;
@@ -167,6 +177,44 @@
 assert(v.index() == 1);
 assert(std::get<1>(v) == 43);
   }
+  {
+std::variant v;
+v = 42;
+assert(v.index() == 1);
+assert(std::get<1>(v) == 42);
+v = 43u;
+assert(v.index() == 0);
+assert(std::get<0>(v) == 43);
+  }
+  {
+std::variant v = true;
+v = std::false_type();
+assert(v.index() == 1);
+assert(std::get<1>(v) == false);
+v = "bar";
+assert(v.index() == 0);
+assert(std::get<0>(v) == "bar");
+  }
+  {
+std::variant> v;
+v = nullptr;
+assert(v.index() == 1);
+assert(std::get<1>(v) == nullptr);
+v = std::true_type();
+assert(v.index() == 0);
+assert(std::get<0>(v));
+  }
+  {
+std::variant v = 42;
+assert(v.index() == 1);
+assert(std::get<1>(v) == 42);
+v = std::false_type();
+assert(v.index() == 0);
+assert(!std::get<0>(v));
+v = true;
+assert(v.index() == 0);
+assert(std::get<0>(v));
+  }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
 using V = std::variant;
Index: include/variant
===
--- include/variant
+++ include/variant
@@ -1097,11 +1097,40 @@
 template 
 struct __overload<_Tp, _Types...> : __overload<_Types...> {
   using __overload<_Types...>::operator();
-  __identity<_Tp> operator()(_Tp) const;
+
+  template 
+  auto operator()(_Tp, _Up&& __t) const
+  -> decltype(_Tp{_VSTD::forward<_U

[PATCH] D44865: [libc++] Implement P0608R2 - A sane variant converting constructor

2018-06-04 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 149825.
lichray added a comment.

Refine coding style


Repository:
  rCXX libc++

https://reviews.llvm.org/D44865

Files:
  include/variant
  test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
  test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp

Index: test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "test_convertible.hpp"
 #include "test_macros.h"
@@ -39,6 +40,8 @@
 
 struct AnyConstructible { template  AnyConstructible(T&&) {} };
 struct NoConstructible { NoConstructible() = delete; };
+template 
+struct RValueConvertibleFrom { RValueConvertibleFrom(T&&) {} };
 
 void test_T_ctor_noexcept() {
   {
@@ -53,7 +56,7 @@
 
 void test_T_ctor_sfinae() {
   {
-using V = std::variant;
+using V = std::variant;
 static_assert(!std::is_constructible::value, "ambiguous");
   }
   {
@@ -66,6 +69,16 @@
   "no matching constructor");
   }
   {
+using V = std::variant;
+static_assert(!std::is_constructible::value,
+  "no matching constructor");
+  }
+  {
+using V = std::variant, bool>;
+static_assert(!std::is_constructible>::value,
+  "no explicit bool in constructor");
+  }
+  {
 using V = std::variant;
 static_assert(
 !std::is_constructible>::value,
@@ -99,6 +112,34 @@
 static_assert(v.index() == 1, "");
 static_assert(std::get<1>(v) == 42, "");
   }
+  {
+constexpr std::variant v(42);
+static_assert(v.index() == 1, "");
+static_assert(std::get<1>(v) == 42, "");
+  }
+  {
+std::variant v = "foo";
+assert(v.index() == 0);
+assert(std::get<0>(v) == "foo");
+  }
+  {
+std::variant> v = nullptr;
+assert(v.index() == 1);
+assert(std::get<1>(v) == nullptr);
+  }
+  {
+std::variant v = true;
+assert(v.index() == 0);
+assert(std::get<0>(v));
+  }
+  {
+std::variant> v1 = 42;
+assert(v1.index() == 0);
+
+int x = 42;
+std::variant, AnyConstructible> v2 = x;
+assert(v2.index() == 1);
+  }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
 using V = std::variant;
Index: test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "test_macros.h"
 #include "variant_test_helpers.hpp"
@@ -128,7 +129,7 @@
 
 void test_T_assignment_sfinae() {
   {
-using V = std::variant;
+using V = std::variant;
 static_assert(!std::is_assignable::value, "ambiguous");
   }
   {
@@ -139,6 +140,15 @@
 using V = std::variant;
 static_assert(!std::is_assignable::value, "no matching operator=");
   }
+  {
+using V = std::variant;
+static_assert(!std::is_assignable::value, "no matching operator=");
+  }
+  {
+using V = std::variant, bool>;
+static_assert(!std::is_assignable>::value,
+  "no explicit bool in operator=");
+  }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
 using V = std::variant;
@@ -167,6 +177,44 @@
 assert(v.index() == 1);
 assert(std::get<1>(v) == 43);
   }
+  {
+std::variant v;
+v = 42;
+assert(v.index() == 1);
+assert(std::get<1>(v) == 42);
+v = 43u;
+assert(v.index() == 0);
+assert(std::get<0>(v) == 43);
+  }
+  {
+std::variant v = true;
+v = std::false_type();
+assert(v.index() == 1);
+assert(std::get<1>(v) == false);
+v = "bar";
+assert(v.index() == 0);
+assert(std::get<0>(v) == "bar");
+  }
+  {
+std::variant> v;
+v = nullptr;
+assert(v.index() == 1);
+assert(std::get<1>(v) == nullptr);
+v = std::true_type();
+assert(v.index() == 0);
+assert(std::get<0>(v));
+  }
+  {
+std::variant v = 42;
+assert(v.index() == 1);
+assert(std::get<1>(v) == 42);
+v = std::false_type();
+assert(v.index() == 0);
+assert(!std::get<0>(v));
+v = true;
+assert(v.index() == 0);
+assert(std::get<0>(v));
+  }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
 using V = std::variant;
Index: include/variant
===
--- include/variant
+++ include/variant
@@ -1097,11 +1097,40 @@
 template 
 struct __overload<_Tp, _Types...> : __overload<_Types...> {
   using __overload<_Types...>::operator();
-  __identity<_Tp> operator()(_Tp) const;
+
+  template 
+  auto operator()(_Tp, _Up&& __t) const
+  -> decltype(_Tp{_VSTD::forward<_Up>(__t)}, __identity<_Tp>());
+};
+
+template 
+struct __ov

[PATCH] D51268: [libc++] Implement P0487R1 - Fixing operator>>(basic_istream&, CharT*)

2018-11-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 172497.
lichray added a comment.
Herald added a subscriber: libcxx-commits.

Rebased


Repository:
  rCXX libc++

https://reviews.llvm.org/D51268

Files:
  include/istream
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp

Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
===
--- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
+++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
@@ -50,6 +50,17 @@
 assert(!is.fail());
 assert(std::string(s) == "abcdefghijk");
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+char s[4];
+is >> s;
+assert(!is.eof());
+assert(!is.fail());
+assert(std::string(s) == "abc");
+}
+#endif
 {
 testbuf sb(L"   abcdefghijk");
 std::wistream is(&sb);
@@ -71,6 +82,17 @@
 assert(std::wstring(s) == L"abcdefghijk");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb(L"   abcdefghijk");
+std::wistream is(&sb);
+wchar_t s[4];
+is >> s;
+assert(!is.eof());
+assert(!is.fail());
+assert(std::wstring(s) == L"abc");
+}
+#endif
 {
 testbuf sb("   abcdefghijk");
 std::istream is(&sb);
@@ -82,4 +104,15 @@
 assert(std::string(s) == "");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+char s[1];
+is >> s;
+assert(!is.eof());
+assert( is.fail());
+assert(std::string(s) == "");
+}
+#endif
 }
Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
===
--- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
+++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
@@ -61,6 +61,17 @@
 assert(std::string((char*)s) == "abc");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+unsigned char s[4];
+is >> s;
+assert(!is.eof());
+assert(!is.fail());
+assert(std::string((char*)s) == "abc");
+}
+#endif
 {
 testbuf sb("   abcdefghijk");
 std::istream is(&sb);
@@ -82,4 +93,15 @@
 assert(std::string((char*)s) == "");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+unsigned char s[1];
+is >> s;
+assert(!is.eof());
+assert( is.fail());
+assert(std::string((char*)s) == "");
+}
+#endif
 }
Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
===
--- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
+++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
@@ -61,6 +61,17 @@
 assert(std::string((char*)s) == "abc");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+signed char s[4];
+is >> s;
+assert(!is.eof());
+assert(!is.fail());
+assert(std::string((char*)s) == "abc");
+}
+#endif
 {
 testbuf sb("   abcdefghijk");
 std::istream is(&sb);
@@ -82,4 +93,15 @@
 assert(std::string((char*)s) == "");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+signed char s[1];
+is >> s;
+assert(!is.eof());
+assert( is.fail());
+assert(std::string((char*)s) == "");
+}
+#endif
 }
Index: include/istream
===
--- include/istream
+++ include/istream
@@ -517,23 +517,21 @@
 }
 
 template
+_LIBCPP_INLINE_VISIBILITY
 basic_istream<_CharT, 

[PATCH] D44865: [libc++] Implement P0608R2 - A sane variant converting constructor

2018-11-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 172514.
lichray added a comment.
Herald added subscribers: libcxx-commits, ldionne.

Updated implementation for https://reviews.llvm.org/source/clang/


Repository:
  rCXX libc++

https://reviews.llvm.org/D44865

Files:
  include/variant
  test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
  test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp

Index: test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
@@ -20,8 +20,8 @@
 #include 
 #include 
 #include 
+#include 
 
-#include "test_convertible.hpp"
 #include "test_macros.h"
 #include "variant_test_helpers.hpp"
 
@@ -39,6 +39,8 @@
 
 struct AnyConstructible { template  AnyConstructible(T&&) {} };
 struct NoConstructible { NoConstructible() = delete; };
+template 
+struct RValueConvertibleFrom { RValueConvertibleFrom(T&&) {} };
 
 void test_T_ctor_noexcept() {
   {
@@ -53,7 +55,7 @@
 
 void test_T_ctor_sfinae() {
   {
-using V = std::variant;
+using V = std::variant;
 static_assert(!std::is_constructible::value, "ambiguous");
   }
   {
@@ -66,6 +68,32 @@
   "no matching constructor");
   }
   {
+using V = std::variant;
+static_assert(!std::is_constructible::value,
+  "no matching constructor");
+  }
+  {
+using V = std::variant, bool>;
+static_assert(!std::is_constructible>::value,
+  "no explicit bool in constructor");
+struct X {
+  operator void*();
+};
+static_assert(!std::is_constructible::value,
+  "no boolean conversion in constructor");
+static_assert(!std::is_constructible::value,
+  "no converted to bool in constructor");
+  }
+  {
+struct X {};
+struct Y {
+  operator X();
+};
+using V = std::variant;
+static_assert(std::is_constructible::value,
+  "regression on user-defined conversions in constructor");
+  }
+  {
 using V = std::variant;
 static_assert(
 !std::is_constructible>::value,
@@ -99,6 +127,34 @@
 static_assert(v.index() == 1, "");
 static_assert(std::get<1>(v) == 42, "");
   }
+  {
+constexpr std::variant v(42);
+static_assert(v.index() == 1, "");
+static_assert(std::get<1>(v) == 42, "");
+  }
+  {
+std::variant v = "foo";
+assert(v.index() == 0);
+assert(std::get<0>(v) == "foo");
+  }
+  {
+std::variant> v = nullptr;
+assert(v.index() == 1);
+assert(std::get<1>(v) == nullptr);
+  }
+  {
+std::variant v = true;
+assert(v.index() == 0);
+assert(std::get<0>(v));
+  }
+  {
+std::variant> v1 = 42;
+assert(v1.index() == 0);
+
+int x = 42;
+std::variant, AnyConstructible> v2 = x;
+assert(v2.index() == 1);
+  }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
 using V = std::variant;
Index: test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "test_macros.h"
 #include "variant_test_helpers.hpp"
@@ -128,7 +129,7 @@
 
 void test_T_assignment_sfinae() {
   {
-using V = std::variant;
+using V = std::variant;
 static_assert(!std::is_assignable::value, "ambiguous");
   }
   {
@@ -139,6 +140,31 @@
 using V = std::variant;
 static_assert(!std::is_assignable::value, "no matching operator=");
   }
+  {
+using V = std::variant;
+static_assert(!std::is_assignable::value, "no matching operator=");
+  }
+  {
+using V = std::variant, bool>;
+static_assert(!std::is_assignable>::value,
+  "no explicit bool in operator=");
+struct X {
+  operator void*();
+};
+static_assert(!std::is_assignable::value,
+  "no boolean conversion in operator=");
+static_assert(!std::is_assignable::value,
+  "no converted to bool in operator=");
+  }
+  {
+struct X {};
+struct Y {
+  operator X();
+};
+using V = std::variant;
+static_assert(std::is_assignable::value,
+  "regression on user-defined conversions in operator=");
+  }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
 using V = std::variant;
@@ -167,6 +193,37 @@
 assert(v.index() == 1);
 assert(std::get<1>(v) == 43);
   }
+  {
+std::variant v;
+v = 42;
+assert(v.index() == 1);
+assert(std::get<1>(v) == 42);
+v = 43u;
+assert(v.index() == 0);
+assert(std::get<0>(v) == 43);
+  }
+  {
+std::variant v = true;
+v = "bar";
+assert(v.index() == 0);
+assert(std::get<0>(v) == "bar");

[PATCH] D49863: [istream] Fix error flags and exceptions propagated from input stream operations

2018-11-08 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray accepted this revision.
lichray added inline comments.
This revision is now accepted and ready to land.
Herald added a subscriber: libcxx-commits.



Comment at: libcxx/include/istream:365
 __input_arithmetic(basic_istream<_CharT, _Traits>& __is, _Tp& __n) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-try
+ios_base::iostate __state = ios_base::goodbit;
+typename basic_istream<_CharT, _Traits>::sentry __s(__is);

I like `auto` just FYI :)



Comment at: libcxx/include/istream:1005
 default:
-read(__s, _VSTD::min(__c, __n));
 break;

LOL


Repository:
  rCXX libc++

https://reviews.llvm.org/D49863



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51268: [libc++] Implement P0487R1 - Fixing operator>>(basic_istream&, CharT*)

2018-11-19 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

In https://reviews.llvm.org/D51268#1303217, @ldionne wrote:

> Please also update https://libcxx.llvm.org/cxx2a_status.html.


Done.




Comment at: include/istream:601
+streamsize __n = __is.width();
+if (__n <= 0)
+__n = numeric_limits::max() / sizeof(_CharT) - 1;

ldionne wrote:
> Should this instead be `if (__n == 0)`? Can `width()` ever return a negative 
> number? cppreference says this about `streamsize`:
> 
> > Except in the constructors of `std::strstreambuf`, negative values of 
> > `std::streamsize` are never used.
> 
> I couldn't find a matching statement in the standard, however there's this 
> footnote in `30.5.2`:
> 
> > `streamsize` is used in most places where ISO C would use `size_t`. Most of 
> > the uses of `streamsize` could use `size_t`, except for the `strstreambuf` 
> > constructors, which require negative values. It should probably be the 
> > signed type corresponding to `size_t` (which is what Posix.2 calls 
> > `ssize_t`).
> 
> This does not clearly say that negative values are never used, but it does 
> suggest it. Maybe it's safer to still use `__n <= 0`.
> 
My interpretation of 27.5.3.2 is that you can retrieve the value you set 
through `width(streamsize)`.  And the wording here (unmodified) says "If 
`width()` is greater than zero, [...]," so the opposite should be `width() <= 
0`.


Repository:
  rCXX libc++

https://reviews.llvm.org/D51268



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51268: [libc++] Implement P0487R1 - Fixing operator>>(basic_istream&, CharT*)

2018-11-19 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 174722.
lichray added a comment.

Update cxx2a status.


Repository:
  rCXX libc++

https://reviews.llvm.org/D51268

Files:
  include/istream
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
  www/cxx2a_status.html

Index: www/cxx2a_status.html
===
--- www/cxx2a_status.html
+++ www/cxx2a_status.html
@@ -112,7 +112,7 @@
 	https://wg21.link/P0356R5";>P0356R5LWGSimplified partial function applicationSan Diego 
 	https://wg21.link/P0357R3";>P0357R3LWGreference_wrapper for incomplete typesSan Diego 
 	https://wg21.link/P0482R6";>P0482R6CWGchar8_t: A type for UTF-8 characters and stringsSan Diego 
-	https://wg21.link/P0487R1";>P0487R1LWGFixing operator>>(basic_istream&, CharT*) (LWG 2499)San Diego 
+	https://wg21.link/P0487R1";>P0487R1LWGFixing operator>>(basic_istream&, CharT*) (LWG 2499)San DiegoComplete8.0
 	https://wg21.link/P0591R4";>P0591R4LWGUtility functions to implement uses-allocator constructionSan Diego 
 	https://wg21.link/P0595R2";>P0595R2CWGP0595R2 std::is_constant_evaluated()San Diego 
 	https://wg21.link/P0602R4";>P0602R4LWGvariant and optional should propagate copy/move trivialitySan Diego 
Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
===
--- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
+++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
@@ -50,6 +50,17 @@
 assert(!is.fail());
 assert(std::string(s) == "abcdefghijk");
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+char s[4];
+is >> s;
+assert(!is.eof());
+assert(!is.fail());
+assert(std::string(s) == "abc");
+}
+#endif
 {
 testbuf sb(L"   abcdefghijk");
 std::wistream is(&sb);
@@ -71,6 +82,17 @@
 assert(std::wstring(s) == L"abcdefghijk");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb(L"   abcdefghijk");
+std::wistream is(&sb);
+wchar_t s[4];
+is >> s;
+assert(!is.eof());
+assert(!is.fail());
+assert(std::wstring(s) == L"abc");
+}
+#endif
 {
 testbuf sb("   abcdefghijk");
 std::istream is(&sb);
@@ -82,4 +104,15 @@
 assert(std::string(s) == "");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+char s[1];
+is >> s;
+assert(!is.eof());
+assert( is.fail());
+assert(std::string(s) == "");
+}
+#endif
 }
Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
===
--- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
+++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
@@ -61,6 +61,17 @@
 assert(std::string((char*)s) == "abc");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+unsigned char s[4];
+is >> s;
+assert(!is.eof());
+assert(!is.fail());
+assert(std::string((char*)s) == "abc");
+}
+#endif
 {
 testbuf sb("   abcdefghijk");
 std::istream is(&sb);
@@ -82,4 +93,15 @@
 assert(std::string((char*)s) == "");
 assert(is.width() == 0);
 }
+#if TEST_STD_VER > 17
+{
+testbuf sb("   abcdefghijk");
+std::istream is(&sb);
+unsigned char s[1];
+is >> s;
+assert(!is.eof());
+assert( is.fail());
+assert(std::string((char*)s) == "");
+}
+#endif
 }
Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
===
--- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
+++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
@@ -61,6 +61,17 @@
 assert(std::string((char*)s) == "abc");
 assert(

[PATCH] D51268: [libc++] Implement P0487R1 - Fixing operator>>(basic_istream&, CharT*)

2018-11-20 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rCXX347377: [libc++] Implement P0487R1 - Fixing 
operator>>(basic_istream&, CharT*) (authored by lichray, committed by 
).

Changed prior to commit:
  https://reviews.llvm.org/D51268?vs=174722&id=174864#toc

Repository:
  rCXX libc++

https://reviews.llvm.org/D51268

Files:
  include/istream
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
  
test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
  www/cxx2a_status.html

Index: www/cxx2a_status.html
===
--- www/cxx2a_status.html
+++ www/cxx2a_status.html
@@ -112,7 +112,7 @@
 	https://wg21.link/P0356R5";>P0356R5LWGSimplified partial function applicationSan Diego 
 	https://wg21.link/P0357R3";>P0357R3LWGreference_wrapper for incomplete typesSan Diego 
 	https://wg21.link/P0482R6";>P0482R6CWGchar8_t: A type for UTF-8 characters and stringsSan Diego 
-	https://wg21.link/P0487R1";>P0487R1LWGFixing operator>>(basic_istream&, CharT*) (LWG 2499)San Diego 
+	https://wg21.link/P0487R1";>P0487R1LWGFixing operator>>(basic_istream&, CharT*) (LWG 2499)San DiegoComplete8.0
 	https://wg21.link/P0591R4";>P0591R4LWGUtility functions to implement uses-allocator constructionSan Diego 
 	https://wg21.link/P0595R2";>P0595R2CWGP0595R2 std::is_constant_evaluated()San Diego 
 	https://wg21.link/P0602R4";>P0602R4LWGvariant and optional should propagate copy/move trivialitySan Diego 
Index: include/istream
===
--- include/istream
+++ include/istream
@@ -517,23 +517,21 @@
 }
 
 template
+_LIBCPP_INLINE_VISIBILITY
 basic_istream<_CharT, _Traits>&
-operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
+__input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
 {
 #ifndef _LIBCPP_NO_EXCEPTIONS
 try
 {
 #endif  // _LIBCPP_NO_EXCEPTIONS
 typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
 if (__sen)
 {
-streamsize __n = __is.width();
-if (__n <= 0)
-__n = numeric_limits::max() / sizeof(_CharT) - 1;
-streamsize __c = 0;
+auto __s = __p;
 const ctype<_CharT>& __ct = use_facet >(__is.getloc());
 ios_base::iostate __err = ios_base::goodbit;
-while (__c < __n-1)
+while (__s != __p + (__n-1))
 {
 typename _Traits::int_type __i = __is.rdbuf()->sgetc();
 if (_Traits::eq_int_type(__i, _Traits::eof()))
@@ -545,12 +543,11 @@
 if (__ct.is(__ct.space, __ch))
 break;
 *__s++ = __ch;
-++__c;
  __is.rdbuf()->sbumpc();
 }
 *__s = _CharT();
 __is.width(0);
-if (__c == 0)
+if (__s == __p)
__err |= ios_base::failbit;
 __is.setstate(__err);
 }
@@ -564,6 +561,48 @@
 return __is;
 }
 
+#if _LIBCPP_STD_VER > 17
+
+template
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, _CharT (&__buf)[_Np])
+{
+auto __n = _Np;
+if (__is.width() > 0)
+__n = _VSTD::min(size_t(__is.width()), _Np);
+return _VSTD::__input_c_string(__is, __buf, __n);
+}
+
+template
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream&
+operator>>(basic_istream& __is, unsigned char (&__buf)[_Np])
+{
+return __is >> (char(&)[_Np])__buf;
+}
+
+template
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream&
+operator>>(basic_istream& __is, signed char (&__buf)[_Np])
+{
+return __is >> (char(&)[_Np])__buf;
+}
+
+#else
+
+template
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
+{
+streamsize __n = __is.width();
+if (__n <= 0)
+__n = numeric_limits::max() / sizeof(_CharT) - 1;
+return _VSTD::__input_c_string(__is, __s, size_t(__n));
+}
+
 template
 inline _LIBCPP_INLINE_VISIBILITY
 basic_istream&
@@ -580,6 +619,8 @@
 return __is >> (char*)__s;
 }
 
+#endif  // _LIBCPP_STD_VER > 17
+
 template
 basic_istream<_CharT, _Traits>&
 operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)
Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
===
--- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
+++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigne

[PATCH] D52391: Document new symbols for __u64toa and __u32toa

2018-09-22 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray created this revision.
lichray added a reviewer: EricWF.
Herald added subscribers: libcxx-commits, ldionne, christof.

They are introduced in r338479; their Linux ABI changes are recorded in r338486.

TODO: Record the Mac OS X ABI changes.


Repository:
  rCXX libc++

https://reviews.llvm.org/D52391

Files:
  lib/abi/CHANGELOG.TXT


Index: lib/abi/CHANGELOG.TXT
===
--- lib/abi/CHANGELOG.TXT
+++ lib/abi/CHANGELOG.TXT
@@ -16,6 +16,18 @@
 Version 7.0
 ---
 
+* r338479 - Elementary string conversions for integral types
+
+  The change emits __u64toa and __u32toa under std::__1::__itoa.
+
+  x86_64-linux-gnu
+  
+  Symbol added: _ZNSt3__16__itoa8__u64toaEmPc
+  Symbol added: _ZNSt3__16__itoa8__u32toaEjPc
+
+  x86_64-apple-darwin16.0
+  ---
+
 * r333467 - Fix embarrasing typo in uncaught_exceptions.
 
   This bug caused __uncaught_exception to be ODR used instead of


Index: lib/abi/CHANGELOG.TXT
===
--- lib/abi/CHANGELOG.TXT
+++ lib/abi/CHANGELOG.TXT
@@ -16,6 +16,18 @@
 Version 7.0
 ---
 
+* r338479 - Elementary string conversions for integral types
+
+  The change emits __u64toa and __u32toa under std::__1::__itoa.
+
+  x86_64-linux-gnu
+  
+  Symbol added: _ZNSt3__16__itoa8__u64toaEmPc
+  Symbol added: _ZNSt3__16__itoa8__u32toaEjPc
+
+  x86_64-apple-darwin16.0
+  ---
+
 * r333467 - Fix embarrasing typo in uncaught_exceptions.
 
   This bug caused __uncaught_exception to be ODR used instead of
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52391: Document new symbols for __u64toa and __u32toa

2018-09-22 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rCXX342810: Document new symbols for __u64toa and __u32toa 
(authored by lichray, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D52391?vs=166605&id=166610#toc

Repository:
  rCXX libc++

https://reviews.llvm.org/D52391

Files:
  lib/abi/CHANGELOG.TXT


Index: lib/abi/CHANGELOG.TXT
===
--- lib/abi/CHANGELOG.TXT
+++ lib/abi/CHANGELOG.TXT
@@ -16,6 +16,18 @@
 Version 7.0
 ---
 
+* r338479 - Elementary string conversions for integral types
+
+  The change emits __u64toa and __u32toa under std::__1::__itoa.
+
+  x86_64-linux-gnu
+  
+  Symbol added: _ZNSt3__16__itoa8__u64toaEmPc
+  Symbol added: _ZNSt3__16__itoa8__u32toaEjPc
+
+  x86_64-apple-darwin16.0
+  ---
+
 * r333467 - Fix embarrasing typo in uncaught_exceptions.
 
   This bug caused __uncaught_exception to be ODR used instead of


Index: lib/abi/CHANGELOG.TXT
===
--- lib/abi/CHANGELOG.TXT
+++ lib/abi/CHANGELOG.TXT
@@ -16,6 +16,18 @@
 Version 7.0
 ---
 
+* r338479 - Elementary string conversions for integral types
+
+  The change emits __u64toa and __u32toa under std::__1::__itoa.
+
+  x86_64-linux-gnu
+  
+  Symbol added: _ZNSt3__16__itoa8__u64toaEmPc
+  Symbol added: _ZNSt3__16__itoa8__u32toaEjPc
+
+  x86_64-apple-darwin16.0
+  ---
+
 * r333467 - Fix embarrasing typo in uncaught_exceptions.
 
   This bug caused __uncaught_exception to be ODR used instead of
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52401: Remove redundant null pointer check in operator delete

2018-09-28 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray reopened this revision.
lichray added a comment.
This revision is now accepted and ready to land.

LGTM as well, unless @mclow.lists can tell us some history like interactions 
with K&R libc :)


Repository:
  rL LLVM

https://reviews.llvm.org/D52401



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44609: [Clang-Format] New option BeforeLambdaBody to manage lambda line break inside function parameter call (in Allman style)

2018-09-28 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

In https://reviews.llvm.org/D44609#1059675, @Wawha wrote:

> In my case, the main requirement is to be able **avoid** a lambda in one line.


That doesn't work for me.  I would like short lambdas still be formatted in one 
line, when `AllowShortFunctionsOnASingleLine` or a new option is on.


Repository:
  rC Clang

https://reviews.llvm.org/D44609



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52401: Remove redundant null pointer check in operator delete

2018-09-30 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

In https://reviews.llvm.org/D52401#1250551, @MaskRay wrote:

> `__free_hook` (defaults to NULL) is a user-supplied hook 
> (https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html).


Very interesting, that means if we don't apply this patch, we essentially 
breaks glic `__free_hook`, because that one expects to be able to observe null 
pointers.


Repository:
  rL LLVM

https://reviews.llvm.org/D52401



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44865: [libc++] Implement P0608R3 - A sane variant converting constructor

2019-02-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

Ping @mclow.lists @EricWF  ; the patch still applies, is there any other thing 
I need to address?


Repository:
  rCXX libc++

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

https://reviews.llvm.org/D44865



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44865: [libc++] Implement P0608R3 - A sane variant converting constructor

2019-06-09 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 203733.
lichray added a comment.

Trivial rebase


Repository:
  rCXX libc++

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

https://reviews.llvm.org/D44865

Files:
  include/variant
  test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
  test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp

Index: test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
@@ -20,8 +20,8 @@
 #include 
 #include 
 #include 
+#include 
 
-#include "test_convertible.hpp"
 #include "test_macros.h"
 #include "variant_test_helpers.hpp"
 
@@ -39,6 +39,8 @@
 
 struct AnyConstructible { template  AnyConstructible(T&&) {} };
 struct NoConstructible { NoConstructible() = delete; };
+template 
+struct RValueConvertibleFrom { RValueConvertibleFrom(T&&) {} };
 
 void test_T_ctor_noexcept() {
   {
@@ -53,7 +55,7 @@
 
 void test_T_ctor_sfinae() {
   {
-using V = std::variant;
+using V = std::variant;
 static_assert(!std::is_constructible::value, "ambiguous");
   }
   {
@@ -66,6 +68,32 @@
   "no matching constructor");
   }
   {
+using V = std::variant;
+static_assert(!std::is_constructible::value,
+  "no matching constructor");
+  }
+  {
+using V = std::variant, bool>;
+static_assert(!std::is_constructible>::value,
+  "no explicit bool in constructor");
+struct X {
+  operator void*();
+};
+static_assert(!std::is_constructible::value,
+  "no boolean conversion in constructor");
+static_assert(!std::is_constructible::value,
+  "no converted to bool in constructor");
+  }
+  {
+struct X {};
+struct Y {
+  operator X();
+};
+using V = std::variant;
+static_assert(std::is_constructible::value,
+  "regression on user-defined conversions in constructor");
+  }
+  {
 using V = std::variant;
 static_assert(
 !std::is_constructible>::value,
@@ -99,6 +127,34 @@
 static_assert(v.index() == 1, "");
 static_assert(std::get<1>(v) == 42, "");
   }
+  {
+constexpr std::variant v(42);
+static_assert(v.index() == 1, "");
+static_assert(std::get<1>(v) == 42, "");
+  }
+  {
+std::variant v = "foo";
+assert(v.index() == 0);
+assert(std::get<0>(v) == "foo");
+  }
+  {
+std::variant> v = nullptr;
+assert(v.index() == 1);
+assert(std::get<1>(v) == nullptr);
+  }
+  {
+std::variant v = true;
+assert(v.index() == 0);
+assert(std::get<0>(v));
+  }
+  {
+std::variant> v1 = 42;
+assert(v1.index() == 0);
+
+int x = 42;
+std::variant, AnyConstructible> v2 = x;
+assert(v2.index() == 1);
+  }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
 using V = std::variant;
Index: test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "test_macros.h"
 #include "variant_test_helpers.hpp"
@@ -122,7 +123,7 @@
 
 void test_T_assignment_sfinae() {
   {
-using V = std::variant;
+using V = std::variant;
 static_assert(!std::is_assignable::value, "ambiguous");
   }
   {
@@ -133,6 +134,31 @@
 using V = std::variant;
 static_assert(!std::is_assignable::value, "no matching operator=");
   }
+  {
+using V = std::variant;
+static_assert(!std::is_assignable::value, "no matching operator=");
+  }
+  {
+using V = std::variant, bool>;
+static_assert(!std::is_assignable>::value,
+  "no explicit bool in operator=");
+struct X {
+  operator void*();
+};
+static_assert(!std::is_assignable::value,
+  "no boolean conversion in operator=");
+static_assert(!std::is_assignable::value,
+  "no converted to bool in operator=");
+  }
+  {
+struct X {};
+struct Y {
+  operator X();
+};
+using V = std::variant;
+static_assert(std::is_assignable::value,
+  "regression on user-defined conversions in operator=");
+  }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
 using V = std::variant;
@@ -161,6 +187,37 @@
 assert(v.index() == 1);
 assert(std::get<1>(v) == 43);
   }
+  {
+std::variant v;
+v = 42;
+assert(v.index() == 1);
+assert(std::get<1>(v) == 42);
+v = 43u;
+assert(v.index() == 0);
+assert(std::get<0>(v) == 43);
+  }
+  {
+std::variant v = true;
+v = "bar";
+assert(v.index() == 0);
+assert(std::get<0>(v) == "bar");
+  }
+  {
+std::variant> v;
+  

[PATCH] D44865: [libc++] Implement P0608R3 - A sane variant converting constructor

2019-06-09 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked an inline comment as done.
lichray added a comment.

In D44865#1535823 , @zoecarver wrote:

> - the spacing is different from the rest of libc++ (a lot of it was that way 
> before).


That's not something I can "fix" in this patch :(

> - since this is a paper it should probably be guarded with `#if 
> _LIBCPP_STD_VER > 17`

Marshall and me agreed that we are going to apply the paper as a "bugfix." We 
don't want to make the constructor behave differently under different language 
versions.

> - update the status in `www`.

Done.




Comment at: include/variant:1110
+template 
+struct __overload_bool : _Base {
+  using _Base::operator();

zoecarver wrote:
> Is this structure 100% necessary? Couldn't `__overload` add an overload to 
> take care of `bool`s? Maybe something like this:
>  
> ```
>   template
>   auto operator()(_Tp, _Up&&) const
> ->  enable_if_t<
> is_same_v<__uncvref_t<_Up>, bool>,
> __identity<_Tp>
> >;
> ```
I'm trying to reduce the compile time cost of SFINAE by putting the bool 
handling logic in specializations.


Repository:
  rCXX libc++

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

https://reviews.llvm.org/D44865



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44865: [libc++] Implement P0608R3 - A sane variant converting constructor

2019-06-09 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 203766.
lichray added a comment.

Update www


Repository:
  rCXX libc++

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

https://reviews.llvm.org/D44865

Files:
  include/variant
  test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
  test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
  www/cxx2a_status.html

Index: www/cxx2a_status.html
===
--- www/cxx2a_status.html
+++ www/cxx2a_status.html
@@ -115,7 +115,7 @@
 	https://wg21.link/P0591R4";>P0591R4LWGUtility functions to implement uses-allocator constructionSan Diego 
 	https://wg21.link/P0595R2";>P0595R2CWGP0595R2 std::is_constant_evaluated()San DiegoComplete9.0
 	https://wg21.link/P0602R4";>P0602R4LWGvariant and optional should propagate copy/move trivialitySan DiegoComplete8.0
-	https://wg21.link/P0608R3";>P0608R3LWGA sane variant converting constructorSan Diego 
+	https://wg21.link/P0608R3";>P0608R3LWGA sane variant converting constructorSan DiegoComplete9.0
 	https://wg21.link/P0655R1";>P0655R1LWGvisit: Explicit Return Type for visitSan Diego 
 	https://wg21.link/P0771R1";>P0771R1LWGstd::function move constructor should be noexceptSan DiegoComplete6.0
 	https://wg21.link/P0896R4";>P0896R4LWGThe One Ranges ProposalSan Diego 
Index: test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
@@ -20,8 +20,8 @@
 #include 
 #include 
 #include 
+#include 
 
-#include "test_convertible.hpp"
 #include "test_macros.h"
 #include "variant_test_helpers.hpp"
 
@@ -39,6 +39,8 @@
 
 struct AnyConstructible { template  AnyConstructible(T&&) {} };
 struct NoConstructible { NoConstructible() = delete; };
+template 
+struct RValueConvertibleFrom { RValueConvertibleFrom(T&&) {} };
 
 void test_T_ctor_noexcept() {
   {
@@ -53,7 +55,7 @@
 
 void test_T_ctor_sfinae() {
   {
-using V = std::variant;
+using V = std::variant;
 static_assert(!std::is_constructible::value, "ambiguous");
   }
   {
@@ -66,6 +68,32 @@
   "no matching constructor");
   }
   {
+using V = std::variant;
+static_assert(!std::is_constructible::value,
+  "no matching constructor");
+  }
+  {
+using V = std::variant, bool>;
+static_assert(!std::is_constructible>::value,
+  "no explicit bool in constructor");
+struct X {
+  operator void*();
+};
+static_assert(!std::is_constructible::value,
+  "no boolean conversion in constructor");
+static_assert(!std::is_constructible::value,
+  "no converted to bool in constructor");
+  }
+  {
+struct X {};
+struct Y {
+  operator X();
+};
+using V = std::variant;
+static_assert(std::is_constructible::value,
+  "regression on user-defined conversions in constructor");
+  }
+  {
 using V = std::variant;
 static_assert(
 !std::is_constructible>::value,
@@ -99,6 +127,34 @@
 static_assert(v.index() == 1, "");
 static_assert(std::get<1>(v) == 42, "");
   }
+  {
+constexpr std::variant v(42);
+static_assert(v.index() == 1, "");
+static_assert(std::get<1>(v) == 42, "");
+  }
+  {
+std::variant v = "foo";
+assert(v.index() == 0);
+assert(std::get<0>(v) == "foo");
+  }
+  {
+std::variant> v = nullptr;
+assert(v.index() == 1);
+assert(std::get<1>(v) == nullptr);
+  }
+  {
+std::variant v = true;
+assert(v.index() == 0);
+assert(std::get<0>(v));
+  }
+  {
+std::variant> v1 = 42;
+assert(v1.index() == 0);
+
+int x = 42;
+std::variant, AnyConstructible> v2 = x;
+assert(v2.index() == 1);
+  }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
 using V = std::variant;
Index: test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "test_macros.h"
 #include "variant_test_helpers.hpp"
@@ -122,7 +123,7 @@
 
 void test_T_assignment_sfinae() {
   {
-using V = std::variant;
+using V = std::variant;
 static_assert(!std::is_assignable::value, "ambiguous");
   }
   {
@@ -133,6 +134,31 @@
 using V = std::variant;
 static_assert(!std::is_assignable::value, "no matching operator=");
   }
+  {
+using V = std::variant;
+static_assert(!std::is_assignable::value, "no matching operator=");
+  }
+  {
+using V = std::variant, bool>;
+static_assert(!std::is_assignable>::value,
+  "no explicit bool in operator=");
+struct X {
+ 

[PATCH] D44865: [libc++] Implement P0608R3 - A sane variant converting constructor

2019-06-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 203966.
lichray added a comment.

Add fail tests


Repository:
  rCXX libc++

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

https://reviews.llvm.org/D44865

Files:
  include/variant
  test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
  test/std/utilities/variant/variant.variant/variant.assign/conv.fail.cpp
  test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
  test/std/utilities/variant/variant.variant/variant.ctor/conv.fail.cpp
  www/cxx2a_status.html

Index: www/cxx2a_status.html
===
--- www/cxx2a_status.html
+++ www/cxx2a_status.html
@@ -115,7 +115,7 @@
 	https://wg21.link/P0591R4";>P0591R4LWGUtility functions to implement uses-allocator constructionSan Diego 
 	https://wg21.link/P0595R2";>P0595R2CWGP0595R2 std::is_constant_evaluated()San DiegoComplete9.0
 	https://wg21.link/P0602R4";>P0602R4LWGvariant and optional should propagate copy/move trivialitySan DiegoComplete8.0
-	https://wg21.link/P0608R3";>P0608R3LWGA sane variant converting constructorSan Diego 
+	https://wg21.link/P0608R3";>P0608R3LWGA sane variant converting constructorSan DiegoComplete9.0
 	https://wg21.link/P0655R1";>P0655R1LWGvisit: Explicit Return Type for visitSan Diego 
 	https://wg21.link/P0771R1";>P0771R1LWGstd::function move constructor should be noexceptSan DiegoComplete6.0
 	https://wg21.link/P0896R4";>P0896R4LWGThe One Ranges ProposalSan Diego 
Index: test/std/utilities/variant/variant.variant/variant.ctor/conv.fail.cpp
===
--- /dev/null
+++ test/std/utilities/variant/variant.variant/variant.ctor/conv.fail.cpp
@@ -0,0 +1,39 @@
+// -*- C++ -*-
+//===--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// 
+
+// template  class variant;
+
+// template  constexpr variant(T&&) noexcept(see below);
+
+#include 
+#include 
+#include 
+
+int main(int, char**)
+{
+  std::variant v1 = 1; // expected-error {{no viable conversion}}
+  std::variant v2 = 1; // expected-error {{no viable conversion}}
+  std::variant v3 = 1; // expected-error {{no viable conversion}}
+
+  std::variant v4 = 1; // expected-error {{no viable conversion}}
+  std::variant v5 = 1; // expected-error {{no viable conversion}}
+  std::variant v6 = 1; // expected-error {{no viable conversion}}
+
+  std::variant v7 = "meow"; // expected-error {{no viable conversion}}
+  std::variant v8 = "meow"; // expected-error {{no viable conversion}}
+  std::variant v9 = "meow"; // expected-error {{no viable conversion}}
+
+  std::variant v10 = std::true_type(); // expected-error {{no viable conversion}}
+  std::variant v11 = std::unique_ptr(); // expected-error {{no viable conversion}}
+  std::variant v12 = nullptr; // expected-error {{no viable conversion}}
+}
Index: test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
===
--- test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
+++ test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
@@ -20,8 +20,8 @@
 #include 
 #include 
 #include 
+#include 
 
-#include "test_convertible.hpp"
 #include "test_macros.h"
 #include "variant_test_helpers.hpp"
 
@@ -39,6 +39,8 @@
 
 struct AnyConstructible { template  AnyConstructible(T&&) {} };
 struct NoConstructible { NoConstructible() = delete; };
+template 
+struct RValueConvertibleFrom { RValueConvertibleFrom(T&&) {} };
 
 void test_T_ctor_noexcept() {
   {
@@ -53,7 +55,7 @@
 
 void test_T_ctor_sfinae() {
   {
-using V = std::variant;
+using V = std::variant;
 static_assert(!std::is_constructible::value, "ambiguous");
   }
   {
@@ -66,6 +68,32 @@
   "no matching constructor");
   }
   {
+using V = std::variant;
+static_assert(!std::is_constructible::value,
+  "no matching constructor");
+  }
+  {
+using V = std::variant, bool>;
+static_assert(!std::is_constructible>::value,
+  "no explicit bool in constructor");
+struct X {
+  operator void*();
+};
+static_assert(!std::is_constructible::value,
+  "no boolean conversion in constructor");
+static_assert(!std::is_constructible::value,
+  "no converted to bool in constructor");
+  }
+  {
+struct X {};
+struct Y {
+  operator X();
+};
+using V = std::variant;
+static_assert(std::is_constructible::value,
+  "regression on user-defined conversions in constructor");
+  }
+  {
 using V = std::variant;

[PATCH] D44865: [libc++] Implement P0608R3 - A sane variant converting constructor

2019-06-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked 2 inline comments as done.
lichray added inline comments.



Comment at: 
test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp:130
   {
 using V = std::variant;
 static_assert(!std::is_assignable::value, "ambiguous");

mclow.lists wrote:
> If you really want to check that these are "ambiguous" , or "no matching 
> operator=", etc, the way to do that is to define a fail.cpp test, and check 
> the error messages.
>  
(the messages in static_assert are just notes to people who read this code)

I added additional fail.cpp tests.


Repository:
  rCXX libc++

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

https://reviews.llvm.org/D44865



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44865: [libc++] Implement P0608R3 - A sane variant converting constructor

2019-06-18 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
lichray marked an inline comment as done.
Closed by commit rL363692: [libc++] Implement P0608R3 - A sane variant 
converting constructor (authored by lichray, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

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

https://reviews.llvm.org/D44865

Files:
  libcxx/trunk/include/variant
  
libcxx/trunk/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
  
libcxx/trunk/test/std/utilities/variant/variant.variant/variant.assign/conv.fail.cpp
  
libcxx/trunk/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
  
libcxx/trunk/test/std/utilities/variant/variant.variant/variant.ctor/conv.fail.cpp
  libcxx/trunk/www/cxx2a_status.html

Index: libcxx/trunk/www/cxx2a_status.html
===
--- libcxx/trunk/www/cxx2a_status.html
+++ libcxx/trunk/www/cxx2a_status.html
@@ -115,7 +115,7 @@
 	https://wg21.link/P0591R4";>P0591R4LWGUtility functions to implement uses-allocator constructionSan Diego 
 	https://wg21.link/P0595R2";>P0595R2CWGP0595R2 std::is_constant_evaluated()San DiegoComplete9.0
 	https://wg21.link/P0602R4";>P0602R4LWGvariant and optional should propagate copy/move trivialitySan DiegoComplete8.0
-	https://wg21.link/P0608R3";>P0608R3LWGA sane variant converting constructorSan Diego 
+	https://wg21.link/P0608R3";>P0608R3LWGA sane variant converting constructorSan DiegoComplete9.0
 	https://wg21.link/P0655R1";>P0655R1LWGvisit: Explicit Return Type for visitSan Diego 
 	https://wg21.link/P0771R1";>P0771R1LWGstd::function move constructor should be noexceptSan DiegoComplete6.0
 	https://wg21.link/P0896R4";>P0896R4LWGThe One Ranges ProposalSan Diego 
Index: libcxx/trunk/include/variant
===
--- libcxx/trunk/include/variant
+++ libcxx/trunk/include/variant
@@ -1098,11 +1098,39 @@
 template 
 struct __overload<_Tp, _Types...> : __overload<_Types...> {
   using __overload<_Types...>::operator();
-  __identity<_Tp> operator()(_Tp) const;
+
+  static auto __test(_Tp (&&)[1]) -> __identity<_Tp>;
+
+  template 
+  auto operator()(_Tp, _Up&& __t) const
+  -> decltype(__test({ _VSTD::forward<_Up>(__t) }));
 };
 
+template 
+struct __overload_bool : _Base {
+  using _Base::operator();
+
+  template >
+  auto operator()(bool, _Up&&) const
+  -> enable_if_t, __identity<_Tp>>;
+};
+
+template 
+struct __overload
+: __overload_bool<__overload<_Types...>, bool> {};
+template 
+struct __overload
+: __overload_bool<__overload<_Types...>, bool const> {};
+template 
+struct __overload
+: __overload_bool<__overload<_Types...>, bool volatile> {};
+template 
+struct __overload
+: __overload_bool<__overload<_Types...>, bool const volatile> {};
+
 template 
-using __best_match_t = typename result_of_t<__overload<_Types...>(_Tp&&)>::type;
+using __best_match_t =
+typename invoke_result_t<__overload<_Types...>, _Tp, _Tp>::type;
 
 } // __variant_detail
 
Index: libcxx/trunk/test/std/utilities/variant/variant.variant/variant.ctor/conv.fail.cpp
===
--- libcxx/trunk/test/std/utilities/variant/variant.variant/variant.ctor/conv.fail.cpp
+++ libcxx/trunk/test/std/utilities/variant/variant.variant/variant.ctor/conv.fail.cpp
@@ -0,0 +1,39 @@
+// -*- C++ -*-
+//===--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// 
+
+// template  class variant;
+
+// template  constexpr variant(T&&) noexcept(see below);
+
+#include 
+#include 
+#include 
+
+int main(int, char**)
+{
+  std::variant v1 = 1; // expected-error {{no viable conversion}}
+  std::variant v2 = 1; // expected-error {{no viable conversion}}
+  std::variant v3 = 1; // expected-error {{no viable conversion}}
+
+  std::variant v4 = 1; // expected-error {{no viable conversion}}
+  std::variant v5 = 1; // expected-error {{no viable conversion}}
+  std::variant v6 = 1; // expected-error {{no viable conversion}}
+
+  std::variant v7 = "meow"; // expected-error {{no viable conversion}}
+  std::variant v8 = "meow"; // expected-error {{no viable conversion}}
+  std::variant v9 = "meow"; // expected-error {{no viable conversion}}
+
+  std::variant v10 = std::true_type(); // expected-error {{no viable conversion}}
+  std::variant v11 = std::unique_ptr(); // expected-error {{no viable conversion}}
+  std::variant v12 = nullptr; // expected-error {{no viable conversion}}
+}
Index: libcxx/trunk/test/std/utilit

[PATCH] D64034: [c++] Implement categorizing pointer-to-bool as narrowing conversions

2019-07-01 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray created this revision.
lichray added reviewers: rsmith, EricWF.
lichray added a project: clang.
Herald added a subscriber: cfe-commits.

This change implements an upcoming Core issue to categorize boolean conversions 
from pointer and pointer-to-member as (always) narrowing conversion (you can 
tell the wording from this diff).  MSVC does it slightly differently, for 
example, array-to-pointer conversion isn't applied before the test -- suspected 
a bug.


Repository:
  rC Clang

https://reviews.llvm.org/D64034

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

Index: test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
===
--- test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
+++ 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 b2 = {1};  // OK
   Agg b3 = {-1};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
 
-  // Conversions from pointers to booleans aren't narrowing conversions.
-  Agg* ptr = &b1;
-  Agg b = {ptr};  // OK
-
   Agg ce1 = { Convert(10) }; // expected-warning {{constant expression evaluates to 10 which cannot be narrowed to type 'short'}} expected-note {{silence}} expected-warning {{changes value from 10 to -31072}}
   Agg ce2 = { ConvertVar() }; // 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 obj;
+  Agg *p1 = &obj;
+  constexpr void *p2 = nullptr;
+
+  Agg b1 = {p1};   // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg b2 = {p2};   // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg b3 = {&Agg::t}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+
+  Agg b4 = {ConvertVar()};   // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg b5 = {ConvertVar::*>()}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+}
+
 // Be sure that type- and value-dependent expressions in templates get the warning
 // too.
 
Index: test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
===
--- test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
+++ 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 b2 = {1};  // OK
   Agg b3 = {-1};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
 
-  // Conversions from pointers to booleans aren't narrowing conversions.
-  Agg* ptr = &b1;
-  Agg b = {ptr};  // OK
-
   Agg ce1 = { Convert(10) }; // expected-error {{constant expression evaluates to 10 which cannot be narrowed to type 'short'}} expected-note {{silence}} expected-warning {{changes value from 10 to -31072}}
   Agg ce2 = { ConvertVar() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{silence}}
 
@@ -202,6 +199,20 @@
   un

[PATCH] D41347: [libc++] Lift std::errc into a separated header

2018-07-02 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rCXX336164: [libc++] Lift std::errc into a separated header 
(authored by lichray, committed by ).
Herald added a subscriber: ldionne.

Changed prior to commit:
  https://reviews.llvm.org/D41347?vs=141109&id=153852#toc

Repository:
  rCXX libc++

https://reviews.llvm.org/D41347

Files:
  include/__errc
  include/module.modulemap
  include/system_error

Index: include/__errc
===
--- include/__errc
+++ include/__errc
@@ -0,0 +1,218 @@
+// -*- C++ -*-
+//=== __errc --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef _LIBCPP___ERRC
+#define _LIBCPP___ERRC
+
+/*
+system_error synopsis
+
+namespace std
+{
+
+enum class errc
+{
+address_family_not_supported,   // EAFNOSUPPORT
+address_in_use, // EADDRINUSE
+address_not_available,  // EADDRNOTAVAIL
+already_connected,  // EISCONN
+argument_list_too_long, // E2BIG
+argument_out_of_domain, // EDOM
+bad_address,// EFAULT
+bad_file_descriptor,// EBADF
+bad_message,// EBADMSG
+broken_pipe,// EPIPE
+connection_aborted, // ECONNABORTED
+connection_already_in_progress, // EALREADY
+connection_refused, // ECONNREFUSED
+connection_reset,   // ECONNRESET
+cross_device_link,  // EXDEV
+destination_address_required,   // EDESTADDRREQ
+device_or_resource_busy,// EBUSY
+directory_not_empty,// ENOTEMPTY
+executable_format_error,// ENOEXEC
+file_exists,// EEXIST
+file_too_large, // EFBIG
+filename_too_long,  // ENAMETOOLONG
+function_not_supported, // ENOSYS
+host_unreachable,   // EHOSTUNREACH
+identifier_removed, // EIDRM
+illegal_byte_sequence,  // EILSEQ
+inappropriate_io_control_operation, // ENOTTY
+interrupted,// EINTR
+invalid_argument,   // EINVAL
+invalid_seek,   // ESPIPE
+io_error,   // EIO
+is_a_directory, // EISDIR
+message_size,   // EMSGSIZE
+network_down,   // ENETDOWN
+network_reset,  // ENETRESET
+network_unreachable,// ENETUNREACH
+no_buffer_space,// ENOBUFS
+no_child_process,   // ECHILD
+no_link,// ENOLINK
+no_lock_available,  // ENOLCK
+no_message_available,   // ENODATA
+no_message, // ENOMSG
+no_protocol_option, // ENOPROTOOPT
+no_space_on_device, // ENOSPC
+no_stream_resources,// ENOSR
+no_such_device_or_address,  // ENXIO
+no_such_device, // ENODEV
+no_such_file_or_directory,  // ENOENT
+no_such_process,// ESRCH
+not_a_directory,// ENOTDIR
+not_a_socket,   // ENOTSOCK
+not_a_stream,   // ENOSTR
+not_connected,  // ENOTCONN
+not_enough_memory,  // ENOMEM
+not_supported,  // ENOTSUP
+operation_canceled, // ECANCELED
+operation_in_progress,  // EINPROGRESS
+operation_not_permitted,// EPERM
+operation_not_supported,// EOPNOTSUPP
+operation_would_block,  // EWOULDBLOCK
+owner_dead, // EOWNERDEAD
+permission_denied,  // EACCES
+protocol_error, // EPROTO
+protocol_not_supported, // EPROTONOSUPPORT
+read_only_file_system,  // EROFS
+resource_deadlock_would_occur,  // EDEADLK
+resource_unavailable_try_again, // EAGAIN
+result_out_of_range,// ERANGE
+state_not_recoverable,  // ENOTRECOVERABLE
+stream_timeout, // ETIME
+text_file_busy, // ETXTBSY
+timed_out,  // ETIMEDOUT
+too_many_files_open_in_system,  // ENFILE
+too_many_files_open,// EMFILE
+too_many_link

[PATCH] D48864: [libc++] Install the missing header __errc

2018-07-02 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray created this revision.
Herald added subscribers: cfe-commits, ldionne, christof, mgorny.
Herald added a reviewer: EricWF.

Omitted from https://reviews.llvm.org/D41347.


Repository:
  rCXX libc++

https://reviews.llvm.org/D48864

Files:
  include/CMakeLists.txt


Index: include/CMakeLists.txt
===
--- include/CMakeLists.txt
+++ include/CMakeLists.txt
@@ -2,6 +2,7 @@
   __bit_reference
   __bsd_locale_defaults.h
   __bsd_locale_fallbacks.h
+  __errc
   __debug
   __functional_03
   __functional_base


Index: include/CMakeLists.txt
===
--- include/CMakeLists.txt
+++ include/CMakeLists.txt
@@ -2,6 +2,7 @@
   __bit_reference
   __bsd_locale_defaults.h
   __bsd_locale_fallbacks.h
+  __errc
   __debug
   __functional_03
   __functional_base
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48864: [libc++] Install the missing header __errc

2018-07-02 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rCXX336165: [libc++] Install the missing header __errc 
(authored by lichray, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D48864?vs=153853&id=153854#toc

Repository:
  rCXX libc++

https://reviews.llvm.org/D48864

Files:
  include/CMakeLists.txt


Index: include/CMakeLists.txt
===
--- include/CMakeLists.txt
+++ include/CMakeLists.txt
@@ -2,6 +2,7 @@
   __bit_reference
   __bsd_locale_defaults.h
   __bsd_locale_fallbacks.h
+  __errc
   __debug
   __functional_03
   __functional_base


Index: include/CMakeLists.txt
===
--- include/CMakeLists.txt
+++ include/CMakeLists.txt
@@ -2,6 +2,7 @@
   __bit_reference
   __bsd_locale_defaults.h
   __bsd_locale_fallbacks.h
+  __errc
   __debug
   __functional_03
   __functional_base
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 153868.
lichray added a comment.
Herald added a subscriber: ldionne.

A macro-free implementation


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  .gitignore
  include/charconv
  include/module.modulemap
  src/charconv.cpp
  test/libcxx/double_include.sh.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,233 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && typename std::make_unsigned::type(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= typename std::make_unsigned::type((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+assert(r.ptr == buf + len - 1);
+assert(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+assert(r.ptr == buf + len);
+assert(r.ec == std::errc{});
+assert(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+assert(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+assert(r.ptr == ep);
+assert(r.ec == std::errc::value_too_large);
+}
+
+private:
+using max_t = typename std::conditional::value, long long,
+unsigned long long>::type;
+
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+-> long long
+{
+char* last;
+auto r = strtoll(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+-> unsigned long long
+{
+char* last;
+auto r = strtoull(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10) -> max_t
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, r.ptr, x, args...);
+assert(r2.ptr == r.ptr);
+assert(x 

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked an inline comment as done.
lichray added inline comments.



Comment at: src/charconv.cpp:34
+
+#define APPEND1(i)  \
+do  \

lichray wrote:
> mclow.lists wrote:
> > I'd really like to see some numbers here showing how this (somewhat 
> > awkward) code performs better than the straightforward versions.
> > 
> > Because maintenance is forever.
> > 
> > Note: I'm sure that this was true on older compilers - but is it true today?
> One thing I could try may be using return values rather than output 
> parameters, like
> ```
> buffer = append3(buffer, b); 
> ```
> But I really don't think doing these makes the code any bit more maintainable 
> comparing to
> ```
> APPEND3(b);
> ```
> , which looks very straightforward and expressive to me...
OK, after several attempts, I figured out that by eliminating side-effects to 
the `buffer` pointer in the helper functions, Clang now generates code of the 
same quality, and runs statistically faster.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 153888.
lichray added a comment.

Install the header file


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  .gitignore
  include/CMakeLists.txt
  include/charconv
  include/module.modulemap
  src/charconv.cpp
  test/libcxx/double_include.sh.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,233 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && typename std::make_unsigned::type(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= typename std::make_unsigned::type((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+assert(r.ptr == buf + len - 1);
+assert(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+assert(r.ptr == buf + len);
+assert(r.ec == std::errc{});
+assert(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+assert(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+assert(r.ptr == ep);
+assert(r.ec == std::errc::value_too_large);
+}
+
+private:
+using max_t = typename std::conditional::value, long long,
+unsigned long long>::type;
+
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+-> long long
+{
+char* last;
+auto r = strtoll(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+-> unsigned long long
+{
+char* last;
+auto r = strtoull(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10) -> max_t
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, r.ptr, x, args...);
+assert(r2.ptr == r.ptr);
+assert(x == X(v));
+

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-09 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: test/support/charconv_test_helpers.h:24
+
+template 
+constexpr auto

mclow.lists wrote:
> If this is supposed to be a C++17 or later header (and I'm pretty sure it 
> is), you should add a `static_assert(TEST_STD_VER > 14, "");` to this header.
> 
I can run it with `--param=std=c++11`.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 154804.
lichray marked an inline comment as done.
lichray added a comment.

Respond to the 2nd round review


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  include/CMakeLists.txt
  include/charconv
  include/module.modulemap
  src/charconv.cpp
  test/libcxx/double_include.sh.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,233 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && typename std::make_unsigned::type(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= typename std::make_unsigned::type((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+assert(r.ptr == buf + len - 1);
+assert(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+assert(r.ptr == buf + len);
+assert(r.ec == std::errc{});
+assert(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+assert(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+assert(r.ptr == ep);
+assert(r.ec == std::errc::value_too_large);
+}
+
+private:
+using max_t = typename std::conditional::value, long long,
+unsigned long long>::type;
+
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+-> long long
+{
+char* last;
+auto r = strtoll(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+-> unsigned long long
+{
+char* last;
+auto r = strtoull(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10) -> max_t
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, r.ptr, x, args...);
+assert(r2.ptr == r.ptr);

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked 3 inline comments as done.
lichray added inline comments.



Comment at: include/charconv:89
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+enum class _LIBCPP_ENUM_VIS chars_format

mclow.lists wrote:
> Quuxplusone wrote:
> > lichray wrote:
> > > mclow.lists wrote:
> > > > lichray wrote:
> > > > > EricWF wrote:
> > > > > > We need to hide these names when `_LIBCPP_STD_VER < 17`, since 
> > > > > > we're not allowed to introduce new names into namespace `std` in 
> > > > > > older dialects.
> > > > > But this header is backported to C++11, so I intended to not to guard 
> > > > > it.
> > > > > But this header is backported to C++11, so I intended to not to guard 
> > > > > it.
> > > > 
> > > > In general, we don't provide new features for old language versions.
> > > > 
> > > > The only time we've ever done that is for `string_view`, and I'm 
> > > > **still** not sure I did the right thing there.
> > > We need to decide on this... From my point of view this header will be 
> > > widely used by formatting and logging libraries, and it doesn't add much 
> > > to the community by enforcing C++17 here, especially when the interface 
> > > we specified are very simple and not using any features beyond C++11.
> > This question is also relevant to my interests, in re ``.
> > From my point of view this header will be widely used by formatting and 
> > logging libraries,
> 
> Non-portable formatting and logging libraries - if we provide it before C++17 
> and they use it.
> 
When they use it, what's next?

1. Someone try to use the library against libstdc++, he/she
   - file a bug report to the library, or
   - file a bug report to libstdc++
2. The library has too little users, so it's okay for it to be non-portable.

Looks good to me.



Comment at: include/charconv:151
+
+#if __has_builtin(__builtin_clzll)
+if (__tx::digits <= __diff || __tx::width(__value) <= __diff)

mclow.lists wrote:
> lichray wrote:
> > EricWF wrote:
> > > `` already has a `__clz` wrapper for `__builtin_clz` et al. We 
> > > should use that instead. That also allows us to get rid of the fallback 
> > > implementation, and it correctly uses the builtin for compilers like GCC 
> > > which don't provide `__has_builtin`.
> > I saw that, and I agree this can be improved, however `` would 
> > be too heavy to include here.  Thoughts?
> We could make this depend on `` once P0553 is adopted. (use 
> `countl_zero`)
> 
>  My intention there is to provide `__countl_zero` etc for internal use before 
> C++20, and the public names for C++20 and later.  That approach could be used 
> here as well, if we choose.
> 
OK.



Comment at: 
test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp:133
+{
+// If the pattern allows for an optional sign,
+char s[] = " - 9+12";

mclow.lists wrote:
> Rather than attempting to reuse bits of the string here, I would define a 
> struct:
> 
> struct test_data {
> const char *input;
> const char *output;
> std::errc err;
> T value;
> };
> 
> and then write a bunch of test cases and iterate over them.
No longer reusing parts from the string.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 154816.
lichray added a comment.

Less trailing return types


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  include/CMakeLists.txt
  include/charconv
  include/module.modulemap
  src/charconv.cpp
  test/libcxx/double_include.sh.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,233 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && typename std::make_unsigned::type(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= typename std::make_unsigned::type((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+assert(r.ptr == buf + len - 1);
+assert(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+assert(r.ptr == buf + len);
+assert(r.ec == std::errc{});
+assert(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+assert(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+assert(r.ptr == ep);
+assert(r.ec == std::errc::value_too_large);
+}
+
+private:
+using max_t = typename std::conditional::value, long long,
+unsigned long long>::type;
+
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+-> long long
+{
+char* last;
+auto r = strtoll(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+-> unsigned long long
+{
+char* last;
+auto r = strtoull(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10) -> max_t
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, r.ptr, x, args...);
+assert(r2.ptr == r.ptr);
+assert(x == X(v));
+}
+   

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked an inline comment as done.
lichray added inline comments.



Comment at: include/charconv:234
+to_chars(char* __first, char* __last, _Tp __value, int __base)
+-> to_chars_result
+{

mclow.lists wrote:
> lichray wrote:
> > mclow.lists wrote:
> > > Why use the trailing return type here?
> > > I don't see any advantage - it doesn't depend on the parameters (template 
> > > or runtime).
> > > 
> > > 
> > Because clang-format doesn't distinguish storage specifiers and 
> > simple-type-specifiers, and I want to format return types along with 
> > function signatures rather than letting hanging somewhere.
> That's an argument for fixing clang-format, not for writing the code this way.
> 
Yes... I did some research on ClangFormat, until... Anyway, I moved most of the 
trailing return types to the front, leaving two which are too complex in the 
header, and a few necessary ones in the tests.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 154842.
lichray added a comment.

Dropping C++11 support.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  include/CMakeLists.txt
  include/charconv
  include/module.modulemap
  src/charconv.cpp
  test/libcxx/double_include.sh.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,232 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+#if TEST_STD_VER <= 11
+#error This file requires C++14
+#endif
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && std::make_unsigned_t(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= std::make_unsigned_t((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+assert(r.ptr == buf + len - 1);
+assert(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+assert(r.ptr == buf + len);
+assert(r.ec == std::errc{});
+assert(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+assert(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+assert(r.ptr == ep);
+assert(r.ec == std::errc::value_too_large);
+}
+
+private:
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+{
+char* last;
+auto r = strtoll(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+{
+char* last;
+auto r = strtoull(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10)
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, r.ptr, x, args...);
+assert(r2.ptr == r.ptr);
+assert(x == X(v));
+}
+else
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, 

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked an inline comment as done.
lichray added inline comments.



Comment at: include/charconv:89
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+enum class _LIBCPP_ENUM_VIS chars_format

lichray wrote:
> mclow.lists wrote:
> > Quuxplusone wrote:
> > > lichray wrote:
> > > > mclow.lists wrote:
> > > > > lichray wrote:
> > > > > > EricWF wrote:
> > > > > > > We need to hide these names when `_LIBCPP_STD_VER < 17`, since 
> > > > > > > we're not allowed to introduce new names into namespace `std` in 
> > > > > > > older dialects.
> > > > > > But this header is backported to C++11, so I intended to not to 
> > > > > > guard it.
> > > > > > But this header is backported to C++11, so I intended to not to 
> > > > > > guard it.
> > > > > 
> > > > > In general, we don't provide new features for old language versions.
> > > > > 
> > > > > The only time we've ever done that is for `string_view`, and I'm 
> > > > > **still** not sure I did the right thing there.
> > > > We need to decide on this... From my point of view this header will be 
> > > > widely used by formatting and logging libraries, and it doesn't add 
> > > > much to the community by enforcing C++17 here, especially when the 
> > > > interface we specified are very simple and not using any features 
> > > > beyond C++11.
> > > This question is also relevant to my interests, in re ``.
> > > From my point of view this header will be widely used by formatting and 
> > > logging libraries,
> > 
> > Non-portable formatting and logging libraries - if we provide it before 
> > C++17 and they use it.
> > 
> When they use it, what's next?
> 
> 1. Someone try to use the library against libstdc++, he/she
>- file a bug report to the library, or
>- file a bug report to libstdc++
> 2. The library has too little users, so it's okay for it to be non-portable.
> 
> Looks good to me.
Back-ported to C++14, in-line with libstdc++.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-16 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: include/charconv:244
+static _LIBCPP_INLINE_VISIBILITY char const*
+read(char const* __p, char const* __ep, type& __a, type& __b)
+{

mclow.lists wrote:
> Same comment as above about `read` and `inner_product` - they need to be 
> "ugly names"
Unlike `traits` which is a template parameter name in the standard, `read` and 
`inner_product` are function names in the standard, which means the users 
cannot make a macro for them (and there is no guarantee about what name you 
make **not** get by including certain headers), so we don't need to use ugly 
names here, am I right?



Comment at: include/charconv:358
+
+auto __gen_digit = [](_Tp __c) {
+return "0123456789abcdefghijklmnopqrstuvwxyz"[__c];

mclow.lists wrote:
> I just want you to reassure me here - this lambda gets inlined, right?
Yes -- I read my code in assembly.



Comment at: include/charconv:359
+auto __gen_digit = [](_Tp __c) {
+return "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
+};

mclow.lists wrote:
> Thinking some more - did this used to do more? Because I don't see why having 
> a lambda here is a benefit, as compared to:
> 
> const char *__digits = "0123456789abcdefghijklmnopqrstuvwxyz";
> 
> and
> *--p = digits[__c];
> 
I use a lambda here because it may do more in the future.  If someone wants to 
let it support non-ASCII platforms, then they only need to make a patch against 
this lambda rather than changing the sites of uses.  After all, there is 
nothing wrong to abstract out anything into a function, I think...


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-16 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 155780.
lichray added a comment.

Uglify all the names


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458

Files:
  include/CMakeLists.txt
  include/charconv
  include/module.modulemap
  src/charconv.cpp
  test/libcxx/double_include.sh.cpp
  test/std/utilities/charconv/
  test/std/utilities/charconv/charconv.from.chars/
  test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
  test/std/utilities/charconv/charconv.to.chars/
  test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
  test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
  test/support/charconv_test_helpers.h

Index: test/support/charconv_test_helpers.h
===
--- /dev/null
+++ test/support/charconv_test_helpers.h
@@ -0,0 +1,232 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+
+#if TEST_STD_VER <= 11
+#error This file requires C++14
+#endif
+
+using std::false_type;
+using std::true_type;
+
+template 
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+return {};
+}
+
+template 
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+return {};
+}
+
+template 
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+return true;
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+return 0 <= v && std::make_unsigned_t(v) <= (xl::max)();
+}
+
+template >
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+return v <= std::make_unsigned_t((xl::max)());
+}
+
+template 
+constexpr bool
+fits_in(T v)
+{
+return _fits_in(v, is_non_narrowing(v), std::is_signed(),
+   std::is_signed());
+}
+
+template 
+struct to_chars_test_base
+{
+template 
+void test(T v, char const (&expect)[N], Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+constexpr size_t len = N - 1;
+static_assert(len > 0, "expected output won't be empty");
+
+if (!fits_in(v))
+return;
+
+r = to_chars(buf, buf + len - 1, X(v), args...);
+assert(r.ptr == buf + len - 1);
+assert(r.ec == std::errc::value_too_large);
+
+r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+assert(r.ptr == buf + len);
+assert(r.ec == std::errc{});
+assert(memcmp(buf, expect, len) == 0);
+}
+
+template 
+void test_value(X v, Ts... args)
+{
+using std::to_chars;
+std::to_chars_result r;
+
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+*r.ptr = '\0';
+
+auto a = fromchars(buf, r.ptr, args...);
+assert(v == a);
+
+auto ep = r.ptr - 1;
+r = to_chars(buf, ep, v, args...);
+assert(r.ptr == ep);
+assert(r.ec == std::errc::value_too_large);
+}
+
+private:
+static auto fromchars(char const* p, char const* ep, int base, true_type)
+{
+char* last;
+auto r = strtoll(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base, false_type)
+{
+char* last;
+auto r = strtoull(p, &last, base);
+assert(last == ep);
+
+return r;
+}
+
+static auto fromchars(char const* p, char const* ep, int base = 10)
+{
+return fromchars(p, ep, base, std::is_signed());
+}
+
+char buf[100];
+};
+
+template 
+struct roundtrip_test_base
+{
+template 
+void test(T v, Ts... args)
+{
+using std::from_chars;
+using std::to_chars;
+std::from_chars_result r2;
+std::to_chars_result r;
+X x = 0xc;
+
+if (fits_in(v))
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, r.ptr, x, args...);
+assert(r2.ptr == r.ptr);
+assert(x == X(v));
+}
+else
+{
+r = to_chars(buf, buf + sizeof(buf), v, args...);
+assert(r.ec == std::errc{});
+
+r2 = from_chars(buf, r.p

[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-07-16 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked 2 inline comments as done.
lichray added inline comments.



Comment at: include/charconv:244
+static _LIBCPP_INLINE_VISIBILITY char const*
+read(char const* __p, char const* __ep, type& __a, type& __b)
+{

Quuxplusone wrote:
> mclow.lists wrote:
> > lichray wrote:
> > > mclow.lists wrote:
> > > > Same comment as above about `read` and `inner_product` - they need to 
> > > > be "ugly names"
> > > Unlike `traits` which is a template parameter name in the standard, 
> > > `read` and `inner_product` are function names in the standard, which 
> > > means the users cannot make a macro for them (and there is no guarantee 
> > > about what name you make **not** get by including certain headers), so we 
> > > don't need to use ugly names here, am I right?
> > I understand your reasoning, but I don't agree. 
> > 
> > Just last month, I had to rename a function in `vector` from `allocate` to 
> > `__vallocate` because it confused our "is this an allocator" detection. The 
> > function in question was private, so it shouldn't have mattered, but GCC 
> > has a bug where sometimes it partially ignores access restrictions in 
> > non-deduced contexts, and then throws a hard error when it comes back to a 
> > different context. The easiest workaround was to rename the function in 
> > `vector`.
> > 
> > Since then, I've been leery of public names that match others. This is 
> > pretty obscure, since it's in a private namespace, but I'd feel better if 
> > they were `__read` and `__inner_product`.
> > 
> FWIW, +1 to ugly names. Even if the un-ugly code is "technically not broken 
> yet", and besides the technical reason Marshall gives,
> (1) it's nice that libc++ has style rules and sticks to them, precisely to 
> *avoid* bikeshedding the name of every private member in the world;
> (2) just because users can't `#define read write` doesn't mean they *won't* 
> do it. I would actually be extremely surprised if `read` were *not* defined 
> as a macro somewhere inside ``. :)
> 
> See also: "should this function call be `_VSTD::`-qualified?" Sometimes the 
> answer is technically "no", but stylistically "yes", precisely to indicate 
> that we *don't* intend for it to be an ADL customization point. Consistent 
> style leads to maintainability.
`read` is a function decl in ``, not redefined in other forms in 
``.



Comment at: test/support/charconv_test_helpers.h:40
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{

mclow.lists wrote:
> We don't need to use ugly names here in the test suite.
> 
Err, it's not?  Just an impl version of `fits_in` (without the _ prefix).


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39284: Allow conditions to be decomposed with structured bindings

2017-12-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 125288.
lichray marked 3 inline comments as done.
lichray added a comment.

Rephrase warning message.


Repository:
  rC Clang

https://reviews.llvm.org/D39284

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/DeclSpec.h
  lib/Parse/ParseExprCXX.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/Misc/warning-flags.c
  test/Parser/cxx1z-decomposition.cpp
  test/Parser/decomposed-condition.cpp
  test/SemaCXX/decomposed-condition.cpp

Index: test/SemaCXX/decomposed-condition.cpp
===
--- /dev/null
+++ test/SemaCXX/decomposed-condition.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -std=c++1z -w -verify %s
+
+struct X {
+  bool flag;
+  int data;
+  constexpr explicit operator bool() const {
+return flag;
+  }
+  constexpr operator int() const {
+return data;
+  }
+};
+
+namespace CondInIf {
+constexpr int f(X x) {
+  if (auto [ok, d] = x)
+return d + int(ok);
+  else
+return d * int(ok);
+  ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
+  d = {};  // expected-error {{use of undeclared identifier 'd'}}
+}
+
+static_assert(f({true, 2}) == 3);
+static_assert(f({false, 2}) == 0);
+
+constexpr char g(char const (&x)[2]) {
+  if (auto &[a, b] = x)
+return a;
+  else
+return b;
+
+  if (auto [a, b] = x) // expected-error {{an array type is not allowed here}}
+;
+}
+
+static_assert(g("x") == 'x');
+} // namespace CondInIf
+
+namespace CondInSwitch {
+constexpr int f(int n) {
+  switch (X s = {true, n}; auto [ok, d] = s) {
+s = {};
+  case 0:
+return int(ok);
+  case 1:
+return d * 10;
+  case 2:
+return d * 40;
+  default:
+return 0;
+  }
+  ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
+  d = {};  // expected-error {{use of undeclared identifier 'd'}}
+  s = {};  // expected-error {{use of undeclared identifier 's'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 10);
+static_assert(f(2) == 80);
+} // namespace CondInSwitch
+
+namespace CondInWhile {
+constexpr int f(int n) {
+  int m = 1;
+  while (auto [ok, d] = X{n > 1, n}) {
+m *= d;
+--n;
+  }
+  return m;
+  return ok; // expected-error {{use of undeclared identifier 'ok'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 1);
+static_assert(f(4) == 24);
+} // namespace CondInWhile
+
+namespace CondInFor {
+constexpr int f(int n) {
+  int a = 1, b = 1;
+  for (X x = {true, n}; auto &[ok, d] = x; --d) {
+if (d < 2)
+  ok = false;
+else {
+  int x = b;
+  b += a;
+  a = x;
+}
+  }
+  return b;
+  return d; // expected-error {{use of undeclared identifier 'd'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 1);
+static_assert(f(2) == 2);
+static_assert(f(5) == 8);
+} // namespace CondInFor
Index: test/Parser/decomposed-condition.cpp
===
--- /dev/null
+++ test/Parser/decomposed-condition.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify
+
+struct Na {
+  bool flag;
+  float data;
+};
+
+struct Rst {
+  bool flag;
+  float data;
+  explicit operator bool() const {
+return flag;
+  }
+};
+
+Rst f();
+Na g();
+
+namespace CondInIf {
+void h() {
+  if (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  if (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInIf
+
+namespace CondInWhile {
+void h() {
+  while (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  while (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInWhile
+
+namespace CondInFor {
+void h() {
+  for (; auto [ok, d] = f();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  for (; auto [ok, d] = g();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInFor
+
+struct IntegerLike {
+  bool flag;
+  float data;
+  operator int() const {
+return int(data);
+  }
+};
+
+namespace CondInSwitch {
+void h(IntegerLike x) {
+  switch (auto [ok, d] = x) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  switch (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('Na' invalid)}}
+;
+}
+} // namespace CondI

[PATCH] D39284: Allow conditions to be decomposed with structured bindings

2017-12-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: lib/Sema/SemaDeclCXX.cpp:712-720
+  Diag(Decomp.getLSquareLoc(), [&] {
+if (getLangOpts().CPlusPlus1z) {
+  if (D.getContext() == Declarator::ConditionContext)
+return diag::ext_decomp_decl_cond;
+  else
+return diag::warn_cxx14_compat_decomp_decl;
+} else

rsmith wrote:
> Using a lambda here seems like unwarranted complexity. A three-way ternary of 
> the form
> 
> ```
> !getLangOpts().CPlusPlus1z ? diag::ext_decomp_decl :
> D.getContext() == Declarator::ConditionContext ? diag::ext_decomp_decl_cond :
> diag::warn_cxx14_compat_decomp_decl
> ```
> 
> would be fine. Feel free to ignore clang-format if it wants to format it 
> stupidly.
The clang-formatted code actually looks good.



Comment at: test/Misc/warning-flags.c:19
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 

rsmith wrote:
> Please read and respect this rule :)
Do you know of some categories which can cover this kind of extensions?


Repository:
  rC Clang

https://reviews.llvm.org/D39284



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39284: Allow conditions to be decomposed with structured bindings

2017-12-05 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 125581.
lichray added a comment.

Rebased.


Repository:
  rC Clang

https://reviews.llvm.org/D39284

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/DeclSpec.h
  lib/Parse/ParseExprCXX.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/Misc/warning-flags.c
  test/Parser/cxx1z-decomposition.cpp
  test/Parser/decomposed-condition.cpp
  test/SemaCXX/decomposed-condition.cpp

Index: test/SemaCXX/decomposed-condition.cpp
===
--- /dev/null
+++ test/SemaCXX/decomposed-condition.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -std=c++1z -w -verify %s
+
+struct X {
+  bool flag;
+  int data;
+  constexpr explicit operator bool() const {
+return flag;
+  }
+  constexpr operator int() const {
+return data;
+  }
+};
+
+namespace CondInIf {
+constexpr int f(X x) {
+  if (auto [ok, d] = x)
+return d + int(ok);
+  else
+return d * int(ok);
+  ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
+  d = {};  // expected-error {{use of undeclared identifier 'd'}}
+}
+
+static_assert(f({true, 2}) == 3);
+static_assert(f({false, 2}) == 0);
+
+constexpr char g(char const (&x)[2]) {
+  if (auto &[a, b] = x)
+return a;
+  else
+return b;
+
+  if (auto [a, b] = x) // expected-error {{an array type is not allowed here}}
+;
+}
+
+static_assert(g("x") == 'x');
+} // namespace CondInIf
+
+namespace CondInSwitch {
+constexpr int f(int n) {
+  switch (X s = {true, n}; auto [ok, d] = s) {
+s = {};
+  case 0:
+return int(ok);
+  case 1:
+return d * 10;
+  case 2:
+return d * 40;
+  default:
+return 0;
+  }
+  ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
+  d = {};  // expected-error {{use of undeclared identifier 'd'}}
+  s = {};  // expected-error {{use of undeclared identifier 's'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 10);
+static_assert(f(2) == 80);
+} // namespace CondInSwitch
+
+namespace CondInWhile {
+constexpr int f(int n) {
+  int m = 1;
+  while (auto [ok, d] = X{n > 1, n}) {
+m *= d;
+--n;
+  }
+  return m;
+  return ok; // expected-error {{use of undeclared identifier 'ok'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 1);
+static_assert(f(4) == 24);
+} // namespace CondInWhile
+
+namespace CondInFor {
+constexpr int f(int n) {
+  int a = 1, b = 1;
+  for (X x = {true, n}; auto &[ok, d] = x; --d) {
+if (d < 2)
+  ok = false;
+else {
+  int x = b;
+  b += a;
+  a = x;
+}
+  }
+  return b;
+  return d; // expected-error {{use of undeclared identifier 'd'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 1);
+static_assert(f(2) == 2);
+static_assert(f(5) == 8);
+} // namespace CondInFor
Index: test/Parser/decomposed-condition.cpp
===
--- /dev/null
+++ test/Parser/decomposed-condition.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify
+
+struct Na {
+  bool flag;
+  float data;
+};
+
+struct Rst {
+  bool flag;
+  float data;
+  explicit operator bool() const {
+return flag;
+  }
+};
+
+Rst f();
+Na g();
+
+namespace CondInIf {
+void h() {
+  if (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  if (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInIf
+
+namespace CondInWhile {
+void h() {
+  while (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  while (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInWhile
+
+namespace CondInFor {
+void h() {
+  for (; auto [ok, d] = f();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  for (; auto [ok, d] = g();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInFor
+
+struct IntegerLike {
+  bool flag;
+  float data;
+  operator int() const {
+return int(data);
+  }
+};
+
+namespace CondInSwitch {
+void h(IntegerLike x) {
+  switch (auto [ok, d] = x) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  switch (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('Na' invalid)}}
+;
+}
+} // namespace CondInSwitch
Index: test/Parser/cxx1z-decomposition.cpp

[PATCH] D39284: Allow conditions to be decomposed with structured bindings

2017-12-05 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked an inline comment as done.
lichray added inline comments.



Comment at: test/Misc/warning-flags.c:19
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 

rsmith wrote:
> lichray wrote:
> > rsmith wrote:
> > > Please read and respect this rule :)
> > Do you know of some categories which can cover this kind of extensions?
> Add a new warning flag for it. Maybe `-Wbinding-in-condition`?
I wish it's still alive after Clang 6.0 released :)


Repository:
  rC Clang

https://reviews.llvm.org/D39284



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39284: Allow conditions to be decomposed with structured bindings

2017-12-05 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 125665.
lichray marked an inline comment as done.
lichray added a comment.

Added -Wbinding-in-condition.


Repository:
  rC Clang

https://reviews.llvm.org/D39284

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/DeclSpec.h
  lib/Parse/ParseExprCXX.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/Parser/cxx1z-decomposition.cpp
  test/Parser/decomposed-condition.cpp
  test/SemaCXX/decomposed-condition.cpp

Index: test/SemaCXX/decomposed-condition.cpp
===
--- /dev/null
+++ test/SemaCXX/decomposed-condition.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -std=c++1z -Wno-binding-in-condition -verify %s
+
+struct X {
+  bool flag;
+  int data;
+  constexpr explicit operator bool() const {
+return flag;
+  }
+  constexpr operator int() const {
+return data;
+  }
+};
+
+namespace CondInIf {
+constexpr int f(X x) {
+  if (auto [ok, d] = x)
+return d + int(ok);
+  else
+return d * int(ok);
+  ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
+  d = {};  // expected-error {{use of undeclared identifier 'd'}}
+}
+
+static_assert(f({true, 2}) == 3);
+static_assert(f({false, 2}) == 0);
+
+constexpr char g(char const (&x)[2]) {
+  if (auto &[a, b] = x)
+return a;
+  else
+return b;
+
+  if (auto [a, b] = x) // expected-error {{an array type is not allowed here}}
+;
+}
+
+static_assert(g("x") == 'x');
+} // namespace CondInIf
+
+namespace CondInSwitch {
+constexpr int f(int n) {
+  switch (X s = {true, n}; auto [ok, d] = s) {
+s = {};
+  case 0:
+return int(ok);
+  case 1:
+return d * 10;
+  case 2:
+return d * 40;
+  default:
+return 0;
+  }
+  ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
+  d = {};  // expected-error {{use of undeclared identifier 'd'}}
+  s = {};  // expected-error {{use of undeclared identifier 's'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 10);
+static_assert(f(2) == 80);
+} // namespace CondInSwitch
+
+namespace CondInWhile {
+constexpr int f(int n) {
+  int m = 1;
+  while (auto [ok, d] = X{n > 1, n}) {
+m *= d;
+--n;
+  }
+  return m;
+  return ok; // expected-error {{use of undeclared identifier 'ok'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 1);
+static_assert(f(4) == 24);
+} // namespace CondInWhile
+
+namespace CondInFor {
+constexpr int f(int n) {
+  int a = 1, b = 1;
+  for (X x = {true, n}; auto &[ok, d] = x; --d) {
+if (d < 2)
+  ok = false;
+else {
+  int x = b;
+  b += a;
+  a = x;
+}
+  }
+  return b;
+  return d; // expected-error {{use of undeclared identifier 'd'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 1);
+static_assert(f(2) == 2);
+static_assert(f(5) == 8);
+} // namespace CondInFor
Index: test/Parser/decomposed-condition.cpp
===
--- /dev/null
+++ test/Parser/decomposed-condition.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify
+
+struct Na {
+  bool flag;
+  float data;
+};
+
+struct Rst {
+  bool flag;
+  float data;
+  explicit operator bool() const {
+return flag;
+  }
+};
+
+Rst f();
+Na g();
+
+namespace CondInIf {
+void h() {
+  if (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  if (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInIf
+
+namespace CondInWhile {
+void h() {
+  while (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  while (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInWhile
+
+namespace CondInFor {
+void h() {
+  for (; auto [ok, d] = f();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  for (; auto [ok, d] = g();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInFor
+
+struct IntegerLike {
+  bool flag;
+  float data;
+  operator int() const {
+return int(data);
+  }
+};
+
+namespace CondInSwitch {
+void h(IntegerLike x) {
+  switch (auto [ok, d] = x) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  switch (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('Na' invalid)}}
+;
+}
+} // namespace CondIn

[PATCH] D39412: [Driver] Give LIBRARY_PATH precedence over native toolchains

2017-12-05 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 125668.
lichray added a comment.

Rebased.


Repository:
  rC Clang

https://reviews.llvm.org/D39412

Files:
  lib/Driver/ToolChains/AMDGPU.cpp
  lib/Driver/ToolChains/AVR.cpp
  lib/Driver/ToolChains/Ananas.cpp
  lib/Driver/ToolChains/BareMetal.cpp
  lib/Driver/ToolChains/CloudABI.cpp
  lib/Driver/ToolChains/CommonArgs.cpp
  lib/Driver/ToolChains/CommonArgs.h
  lib/Driver/ToolChains/CrossWindows.cpp
  lib/Driver/ToolChains/Darwin.cpp
  lib/Driver/ToolChains/DragonFly.cpp
  lib/Driver/ToolChains/FreeBSD.cpp
  lib/Driver/ToolChains/Fuchsia.cpp
  lib/Driver/ToolChains/Gnu.cpp
  lib/Driver/ToolChains/Hexagon.cpp
  lib/Driver/ToolChains/MinGW.cpp
  lib/Driver/ToolChains/Minix.cpp
  lib/Driver/ToolChains/Myriad.cpp
  lib/Driver/ToolChains/NaCl.cpp
  lib/Driver/ToolChains/NetBSD.cpp
  lib/Driver/ToolChains/OpenBSD.cpp
  lib/Driver/ToolChains/PS4CPU.cpp
  lib/Driver/ToolChains/Solaris.cpp
  lib/Driver/ToolChains/WebAssembly.cpp
  lib/Driver/ToolChains/XCore.cpp

Index: lib/Driver/ToolChains/XCore.cpp
===
--- lib/Driver/ToolChains/XCore.cpp
+++ lib/Driver/ToolChains/XCore.cpp
@@ -79,6 +79,7 @@
 CmdArgs.push_back("-fexceptions");
 
   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+  AddLibraryPaths(getToolChain(), Args, CmdArgs);
 
   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
   C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs));
Index: lib/Driver/ToolChains/WebAssembly.cpp
===
--- lib/Driver/ToolChains/WebAssembly.cpp
+++ lib/Driver/ToolChains/WebAssembly.cpp
@@ -48,6 +48,7 @@
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   Args.AddAllArgs(CmdArgs, options::OPT_u);
+  AddLibraryPaths(ToolChain, Args, CmdArgs);
   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
Index: lib/Driver/ToolChains/Solaris.cpp
===
--- lib/Driver/ToolChains/Solaris.cpp
+++ lib/Driver/ToolChains/Solaris.cpp
@@ -92,6 +92,7 @@
 Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
   }
 
+  AddLibraryPaths(getToolChain(), Args, CmdArgs);
   getToolChain().AddFilePathLibArgs(Args, CmdArgs);
 
   Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
Index: lib/Driver/ToolChains/PS4CPU.cpp
===
--- lib/Driver/ToolChains/PS4CPU.cpp
+++ lib/Driver/ToolChains/PS4CPU.cpp
@@ -25,6 +25,7 @@
 using namespace llvm::opt;
 
 using clang::driver::tools::AddLinkerInputs;
+using clang::driver::tools::AddLibraryPaths;
 
 void tools::PS4cpu::addProfileRTArgs(const ToolChain &TC, const ArgList &Args,
  ArgStringList &CmdArgs) {
@@ -125,6 +126,7 @@
 CmdArgs.push_back("--no-demangle");
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+  AddLibraryPaths(ToolChain, Args, CmdArgs);
 
   if (Args.hasArg(options::OPT_pthread)) {
 CmdArgs.push_back("-lpthread");
@@ -210,6 +212,7 @@
   }
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
+  AddLibraryPaths(ToolChain, Args, CmdArgs);
   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
   Args.AddAllArgs(CmdArgs, options::OPT_e);
Index: lib/Driver/ToolChains/OpenBSD.cpp
===
--- lib/Driver/ToolChains/OpenBSD.cpp
+++ lib/Driver/ToolChains/OpenBSD.cpp
@@ -165,6 +165,8 @@
 }
   }
 
+  AddLibraryPaths(getToolChain(), Args, CmdArgs);
+
   std::string Triple = getToolChain().getTripleString();
   if (Triple.substr(0, 6) == "x86_64")
 Triple.replace(0, 6, "amd64");
Index: lib/Driver/ToolChains/NetBSD.cpp
===
--- lib/Driver/ToolChains/NetBSD.cpp
+++ lib/Driver/ToolChains/NetBSD.cpp
@@ -249,6 +249,7 @@
 
   bool NeedsSanitizerDeps = addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+  AddLibraryPaths(getToolChain(), Args, CmdArgs);
 
   unsigned Major, Minor, Micro;
   getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
Index: lib/Driver/ToolChains/NaCl.cpp
===
--- lib/Driver/ToolChains/NaCl.cpp
+++ lib/Driver/ToolChains/NaCl.cpp
@@ -124,6 +124,7 @@
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   Args.AddAllArgs(CmdArgs, options::OPT_u);
 
+  AddLibraryPaths(ToolChain, Args, CmdArgs);
   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
 
   if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
Index: lib/Driver/ToolChains/Myriad.cpp
===
--- lib/Driver/ToolChains/Myriad.cpp
+++ lib/Driver/ToolChains/Myriad.cpp
@@ -165,6 +165,7 @@
 

[PATCH] D39284: Allow conditions to be decomposed with structured bindings

2017-12-06 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

Can someone commit this please?  One more patch then I'll go get a commit bit.


Repository:
  rC Clang

https://reviews.llvm.org/D39284



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39284: Allow conditions to be decomposed with structured bindings

2017-12-06 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC320011: Allow conditions to be decomposed with structured 
bindings (authored by lichray).

Changed prior to commit:
  https://reviews.llvm.org/D39284?vs=125665&id=125892#toc

Repository:
  rC Clang

https://reviews.llvm.org/D39284

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/DeclSpec.h
  lib/Parse/ParseExprCXX.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/Parser/cxx1z-decomposition.cpp
  test/Parser/decomposed-condition.cpp
  test/SemaCXX/decomposed-condition.cpp

Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -414,6 +414,9 @@
   "C++ standards before C++17">, DefaultIgnore, InGroup;
 def ext_decomp_decl : ExtWarn<
   "decomposition declarations are a C++17 extension">, InGroup;
+def ext_decomp_decl_cond : ExtWarn<
+  "ISO C++17 does not permit structured binding declaration in a condition">,
+  InGroup>;
 def err_decomp_decl_spec : Error<
   "decomposition declaration cannot be declared "
   "%plural{1:'%1'|:with '%1' specifiers}0">;
Index: include/clang/Sema/DeclSpec.h
===
--- include/clang/Sema/DeclSpec.h
+++ include/clang/Sema/DeclSpec.h
@@ -1995,9 +1995,9 @@
 case BlockContext:
 case ForContext:
 case InitStmtContext:
+case ConditionContext:
   return true;
 
-case ConditionContext:
 case MemberContext:
 case PrototypeContext:
 case TemplateParamContext:
Index: test/Parser/decomposed-condition.cpp
===
--- test/Parser/decomposed-condition.cpp
+++ test/Parser/decomposed-condition.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify
+
+struct Na {
+  bool flag;
+  float data;
+};
+
+struct Rst {
+  bool flag;
+  float data;
+  explicit operator bool() const {
+return flag;
+  }
+};
+
+Rst f();
+Na g();
+
+namespace CondInIf {
+void h() {
+  if (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  if (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInIf
+
+namespace CondInWhile {
+void h() {
+  while (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  while (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInWhile
+
+namespace CondInFor {
+void h() {
+  for (; auto [ok, d] = f();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  for (; auto [ok, d] = g();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+;
+}
+} // namespace CondInFor
+
+struct IntegerLike {
+  bool flag;
+  float data;
+  operator int() const {
+return int(data);
+  }
+};
+
+namespace CondInSwitch {
+void h(IntegerLike x) {
+  switch (auto [ok, d] = x) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+;
+  switch (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('Na' invalid)}}
+;
+}
+} // namespace CondInSwitch
Index: test/Parser/cxx1z-decomposition.cpp
===
--- test/Parser/cxx1z-decomposition.cpp
+++ test/Parser/cxx1z-decomposition.cpp
@@ -32,13 +32,14 @@
   void f(auto [a, b, c]); // expected-error {{'auto' not allowed in function prototype}} expected-error {{'a'}}
 
   void g() {
-// A condition is not a simple-declaration.
-for (; auto [a, b, c] = S(); ) {} // expected-error {{not permitted in this context}}
-if (auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
-if (int n; auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
-switch (auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
-switch (int n; auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
-while (auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
+// A condition is allowed as a Clang extension.
+// See commentary in test/Parser/decomposed-condition.cpp
+for (; auto [a, b, c] = S(); ) {} // expected-warning {{ISO C++17 does not

[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr

2017-12-07 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

Ping.  Just accept this as a DR, like what GCC does, I guess?


https://reviews.llvm.org/D39451



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr

2017-12-07 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 126092.
lichray added a comment.

Keep a pedantic Extension warning.


Repository:
  rC Clang

https://reviews.llvm.org/D39451

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaExprCXX.cpp
  test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
  test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
  test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
  test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp

Index: test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
===
--- test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -148,7 +148,7 @@
 }
 
 void dangle() {
-  new auto{1, 2, 3}; // expected-error {{cannot use list-initialization}}
+  new auto{1, 2, 3}; // expected-error {{new expression for type 'auto' contains multiple constructor arguments}}
   new std::initializer_list{1, 2, 3}; // expected-warning {{at the end of the full-expression}}
 }
 
Index: test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
===
--- /dev/null
+++ test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++17 -pedantic
+
+void f() {
+  new auto('a');
+  new auto {2};
+  new auto {1, 2}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+  new auto({1});
+  new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
+  new decltype(auto)({1, 2}); // expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}}
+}
Index: test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
===
--- /dev/null
+++ test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 -pedantic
+
+void f() {
+  new auto('a');
+  new auto {2}; // expected-warning {{ISO C++ standards before C++17 does not allow new expression for type 'auto' using list-initialization}}
+  new auto {1, 2}; // expected-warning {{ISO C++ standards before C++17 does not allow new expression for type 'auto' using list-initialization}} expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+  new auto({1}); // expected-warning {{ISO C++ standards before C++17 does not allow new expression for type 'auto' using list-initialization}}
+  new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
+  new decltype(auto)({1, 2}); // expected-warning {{ISO C++ standards before C++17 does not allow new expression for type 'decltype(auto)' using list-initialization}} expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}}
+}
Index: test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
===
--- test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
+++ test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
@@ -9,12 +9,14 @@
 void f() {
   only p = new const auto (0);
   only q = new (auto) (0.0);
+  only r = new auto {'a'};
 
   new auto; // expected-error{{new expression for type 'auto' requires a constructor argument}}
   new (const auto)(); // expected-error{{new expression for type 'const auto' requires a constructor argument}}
   new (auto) (1,2,3); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
-  new auto {1,2,3}; // expected-error{{new expression for type 'auto' cannot use list-initialization}}
-  new auto ({1,2,3}); // expected-error{{new expression for type 'auto' cannot use list-initialization}}
+  new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
+  new auto {1,2,3}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+  new auto ({1,2,3}); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
 }
 
 void p2example() {
Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -1748,14 +1748,21 @@
 if (AllocType.isNull())
   return ExprError();
   } else if (Deduced) {
+bool Braced = (initStyle == CXXNewExpr::ListInit);
+if (NumInits == 1) {
+  if (auto p = dyn_cast_or_null(Inits[0])) {
+Inits = p->getInits();
+NumInits = p->getNumInits();
+Braced = true;
+  }
+}
+
 if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
   return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
<< AllocType << TypeRange);
-if (initStyle == CXXNewExpr::ListInit ||
-(NumInits == 1 && isa(Inits[0])))
-  return E

[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr

2017-12-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

Ping?


Repository:
  rC Clang

https://reviews.llvm.org/D39451



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr

2017-12-11 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC320401: P0620 follow-up: deducing `auto` from 
braced-init-list in new expr (authored by lichray).

Changed prior to commit:
  https://reviews.llvm.org/D39451?vs=126092&id=126400#toc

Repository:
  rC Clang

https://reviews.llvm.org/D39451

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaExprCXX.cpp
  test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
  test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
  test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
  test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp

Index: test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
===
--- test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -148,7 +148,7 @@
 }
 
 void dangle() {
-  new auto{1, 2, 3}; // expected-error {{cannot use list-initialization}}
+  new auto{1, 2, 3}; // expected-error {{new expression for type 'auto' contains multiple constructor arguments}}
   new std::initializer_list{1, 2, 3}; // expected-warning {{at the end of the full-expression}}
 }
 
Index: test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
===
--- test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
+++ test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 -pedantic
+
+void f() {
+  new auto('a');
+  new auto {2}; // expected-warning {{ISO C++ standards before C++17 do not allow new expression for type 'auto' to use list-initialization}}
+  new auto {1, 2}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+  new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
+  new decltype(auto)({1}); // expected-warning {{ISO C++ standards before C++17 do not allow new expression for type 'decltype(auto)' to use list-initialization}}
+  new decltype(auto)({1, 2}); // expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}}
+}
Index: test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
===
--- test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
+++ test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++17 -pedantic
+
+void f() {
+  new auto('a');
+  new auto {2};
+  new auto {1, 2}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+  new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
+  new decltype(auto)({1});
+  new decltype(auto)({1, 2}); // expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}}
+}
Index: test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
===
--- test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
+++ test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
@@ -9,12 +9,14 @@
 void f() {
   only p = new const auto (0);
   only q = new (auto) (0.0);
+  only r = new auto {'a'};
 
   new auto; // expected-error{{new expression for type 'auto' requires a constructor argument}}
   new (const auto)(); // expected-error{{new expression for type 'const auto' requires a constructor argument}}
   new (auto) (1,2,3); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
-  new auto {1,2,3}; // expected-error{{new expression for type 'auto' cannot use list-initialization}}
-  new auto ({1,2,3}); // expected-error{{new expression for type 'auto' cannot use list-initialization}}
+  new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
+  new auto {1,2,3}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+  new auto ({1,2,3}); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
 }
 
 void p2example() {
Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -1748,20 +1748,27 @@
 if (AllocType.isNull())
   return ExprError();
   } else if (Deduced) {
+bool Braced = (initStyle == CXXNewExpr::ListInit);
+if (NumInits == 1) {
+  if (auto p = dyn_cast_or_null(Inits[0])) {
+Inits = p->getInits();
+NumInits = p->getNumInits();
+Braced = true;
+  }
+}
+
 if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
   return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
<< AllocType << TypeRange);
-if (initStyle == CXXNewExpr::ListInit ||
-(NumInits == 1 && isa(Inits[0])))
-  

[PATCH] D40991: [libcxx] [test] Fix line endings, avoid unnecessary non-ASCII.

2017-12-11 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

LGTM as-is with the changes to the TODO file...


https://reviews.llvm.org/D40991



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41048: [libcxx] workaround PR 28385 in __find_exactly_one_checked

2017-12-11 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray accepted this revision.
lichray added a comment.
This revision is now accepted and ready to land.

Reproduced with

  lit -sv --param=cxx_under_test="$HOME/bin/clang++" test/std/utilities/tuple/
  lit: [...] note: Using available_features: ['libc++', 'verify-support', 
'clang-6', 'modules-support', 'locale.en_US.UTF-8', 'diagnose-if-support', 
'long_tests', 'fdelayed-template-parsing', '-faligned-allocation', 
'locale.zh_CN.UTF-8', 'c++2a', 'locale.fr_CA.ISO8859-1', 'c++filesystem', 
'c++experimental', 'clang', 'locale.fr_FR.UTF-8', 'locale.ru_RU.UTF-8', 
'fsized-deallocation', 'freebsd11', 'fcoroutines-ts', 'locale.cs_CZ.ISO8859-2', 
'clang-6.0', 'thread-safety']


https://reviews.llvm.org/D41048



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33776: [libcxx] LWG2221: No formatted output operator for nullptr

2017-12-12 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: include/ostream:225
+basic_ostream& operator<<(nullptr_t)
+{ return *this << (const void*)0; }
+

Oh, common, I persuaded the committee to allow you to print a `(null)`  and you 
don't do it...


https://reviews.llvm.org/D33776



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38831: [libcxx] P0604, invoke_result and is_invocable

2017-12-12 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

  [...]test/std/utilities/meta/meta.rel/is_nothrow_invocable.pass.cpp:118:9: 
error: static_assert failed due to requirement 
'!std::is_nothrow_invocable_r_v' ""
  static_assert(!std::is_nothrow_invocable_r_v, "");
  ^ ~~~
  1 error generated.
  --

with Clang-5.0 and trunk.  Can you reproduce?


https://reviews.llvm.org/D38831



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38831: [libcxx] P0604, invoke_result and is_invocable

2017-12-12 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL320509: [libcxx] P0604, invoke_result and is_invocable 
(authored by lichray, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D38831?vs=126545&id=126580#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D38831

Files:
  libcxx/trunk/include/type_traits
  libcxx/trunk/include/variant
  libcxx/trunk/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp
  libcxx/trunk/test/std/utilities/function.objects/unord.hash/non_enum.pass.cpp
  libcxx/trunk/test/std/utilities/meta/meta.rel/is_callable.pass.cpp
  libcxx/trunk/test/std/utilities/meta/meta.rel/is_invocable.pass.cpp
  libcxx/trunk/test/std/utilities/meta/meta.rel/is_nothrow_callable.pass.cpp
  libcxx/trunk/test/std/utilities/meta/meta.rel/is_nothrow_invocable.pass.cpp
  
libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp
  
libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp

Index: libcxx/trunk/include/type_traits
===
--- libcxx/trunk/include/type_traits
+++ libcxx/trunk/include/type_traits
@@ -137,13 +137,11 @@
 template  struct is_base_of;
 template  struct is_convertible;
 
-template  struct is_callable; // not defined
-template 
-  struct is_callable;
-
-template  struct is_nothrow_callable; // not defined
-template 
-  struct is_nothrow_callable;
+template  struct is_invocable;
+template  struct is_invocable_r;
+
+template  struct is_nothrow_invocable;
+template  struct is_nothrow_invocable_r;
 
 // Alignment properties and transformations:
 template  struct alignment_of;
@@ -157,6 +155,7 @@
 template  struct underlying_type;
 template  class result_of; // undefined
 template  class result_of;
+template  struct invoke_result;  // C++17
 
 // const-volatile modifications:
 template 
@@ -215,8 +214,10 @@
   using common_type_t = typename common_type::type;  // C++14
 template 
   using underlying_type_t = typename underlying_type::type;  // C++14
-template 
-  using result_of_t   = typename result_of::type;  // C++14
+template 
+  using result_of_t   = typename result_of::type;  // C++14
+template 
+  using invoke_result_t   = typename invoke_result::type;  // C++17
 
 template 
   using void_t = void;   // C++17
@@ -370,10 +371,14 @@
 = is_base_of::value;  // C++17
   template  constexpr bool is_convertible_v
 = is_convertible::value;   // C++17
-  template  constexpr bool is_callable_v
-= is_callable::value;  // C++17
-  template  constexpr bool is_nothrow_callable_v
-= is_nothrow_callable::value;  // C++17
+  template  constexpr bool is_invocable_v
+= is_invocable::value;  // C++17
+  template  constexpr bool is_invocable_r_v
+= is_invocable_r::value; // C++17
+  template  constexpr bool is_nothrow_invocable_v
+= is_nothrow_invocable::value;  // C++17
+  template  constexpr bool is_nothrow_invocable_r_v
+= is_nothrow_invocable_r::value; // C++17
 
   // [meta.logical], logical operator traits:
   template struct conjunction;   // C++17
@@ -4402,6 +4407,13 @@
 >;
 
 template 
+using __nothrow_invokable =
+__nothrow_invokable_r_imp<
+__invokable<_Fp, _Args...>::value,
+true, void, _Fp, _Args...
+>;
+
+template 
 struct __invoke_of
 : public enable_if<
 __invokable<_Fp, _Args...>::value,
@@ -4423,30 +4435,48 @@
 
 #if _LIBCPP_STD_VER > 14
 
-// is_callable
+// invoke_result
 
-template 
-struct _LIBCPP_TEMPLATE_VIS is_callable;
+template 
+struct _LIBCPP_TEMPLATE_VIS invoke_result
+: __invoke_of<_Fn, _Args...>
+{
+};
+
+template 
+using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
+
+// is_invocable
 
-template 
-struct _LIBCPP_TEMPLATE_VIS is_callable<_Fn(_Args...), _Ret>
+template 
+struct _LIBCPP_TEMPLATE_VIS is_invocable
+: integral_constant::value> {};
+
+template 
+struct _LIBCPP_TEMPLATE_VIS is_invocable_r
 : integral_constant::value> {};
 
-template 
-constexpr bool is_callable_v = is_callable<_Fn, _Ret>::value;
+template 
+constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
+
+template 
+constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
 
 // is_nothrow_callable
 
-template 
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_callable;
+template 
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable
+: integral_constant::value> {};
+
+template 
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r
+: integral_constant::value> {};
 
-templ

[PATCH] D38831: [libcxx] P0604, invoke_result and is_invocable

2017-12-12 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

That commit message generated from `arc` wasn't all that friendly :/
Thanks for the patch, and @K-ballo you should ask Chris for a commit bit :)


Repository:
  rL LLVM

https://reviews.llvm.org/D38831



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2017-12-12 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

I beg you to resubmit this patch relative to "libcxx"; I had to `arc export` 
this patch and `patch -p1 < your.diff` manually rather than just `arc patch 
D41148`.




Comment at: libcxx/include/experimental/simd:1069
+std::is_same<_Abi, simd_abi::fixed_size>::value &&
+__is_non_narrowing_convertible<_Up, _Tp>()>::type>
+  simd(const simd<_Up, simd_abi::fixed_size>&) {}

Does it causes a problem if the logic of `is_convertible` is folded into 
`__is_non_narrowing_convertible`?



Comment at: libcxx/include/experimental/simd:1088
+  // Inserted "int = 0", otherwise it is not implementable wrt `simd(_Up&&
+  // value)`.
+  // TODO: revise P0214.

Really?  `decltype(simd(...), 0) = 0` seems passing your tests.



Comment at: libcxx/test/std/experimental/simd/simd_cast.pass.cpp:87
+
+int main() { return 0; }

No more `return 0;` in `main`; no other files do so.



Comment at: libcxx/test/std/experimental/simd/traits.pass.cpp:37
+
+static_assert(is_abi_tag >::value, "");
+static_assert(is_abi_tag >::value, "");

`> >` is not a fashion...


https://reviews.llvm.org/D41148



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40284: [Sema] Improve diagnostics for template arg deduction

2017-12-12 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

I'm not confident enough about the effects of this patch with only one test; 
the last patch also passes the test.  I hope I can understand the effects 
better.


https://reviews.llvm.org/D40284



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40707: [libcxx] Fix basic_stringbuf constructor

2017-12-13 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL320604: [libcxx] Fix basic_stringbuf constructor (authored 
by lichray, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D40707?vs=126739&id=126779#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D40707

Files:
  libcxx/trunk/include/sstream
  
libcxx/trunk/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp


Index: libcxx/trunk/include/sstream
===
--- libcxx/trunk/include/sstream
+++ libcxx/trunk/include/sstream
@@ -243,7 +243,6 @@
 : __hm_(0),
   __mode_(__wch)
 {
-str(string_type());
 }
 
 template 
Index: 
libcxx/trunk/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
===
--- 
libcxx/trunk/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
+++ 
libcxx/trunk/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
@@ -17,6 +17,21 @@
 #include 
 #include 
 
+template
+struct testbuf
+: std::basic_stringbuf
+{
+void check()
+{
+assert(this->eback() == NULL);
+assert(this->gptr() == NULL);
+assert(this->egptr() == NULL);
+assert(this->pbase() == NULL);
+assert(this->pptr() == NULL);
+assert(this->epptr() == NULL);
+}
+};
+
 int main()
 {
 {
@@ -27,4 +42,12 @@
 std::wstringbuf buf;
 assert(buf.str() == L"");
 }
+{
+testbuf buf;
+buf.check();
+}
+{
+testbuf buf;
+buf.check();
+}
 }


Index: libcxx/trunk/include/sstream
===
--- libcxx/trunk/include/sstream
+++ libcxx/trunk/include/sstream
@@ -243,7 +243,6 @@
 : __hm_(0),
   __mode_(__wch)
 {
-str(string_type());
 }
 
 template 
Index: libcxx/trunk/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
===
--- libcxx/trunk/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
+++ libcxx/trunk/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
@@ -17,6 +17,21 @@
 #include 
 #include 
 
+template
+struct testbuf
+: std::basic_stringbuf
+{
+void check()
+{
+assert(this->eback() == NULL);
+assert(this->gptr() == NULL);
+assert(this->egptr() == NULL);
+assert(this->pbase() == NULL);
+assert(this->pptr() == NULL);
+assert(this->epptr() == NULL);
+}
+};
+
 int main()
 {
 {
@@ -27,4 +42,12 @@
 std::wstringbuf buf;
 assert(buf.str() == L"");
 }
+{
+testbuf buf;
+buf.check();
+}
+{
+testbuf buf;
+buf.check();
+}
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133659: [Clang] P1169R4: static operator()

2022-09-12 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp:5
+struct Functor {
+  static int operator()(int x, int y) {
+return x + y;

I want to see some tests that diagnose `extern operator()`.



Comment at: clang/test/Parser/cxx2b-lambdas.cpp:43
+auto XL7 = []() static static {}; // expected-error {{cannot appear multiple 
times}}
+auto XL8 = []() static mutable {}; // expected-error {{cannot be both mutable 
and static}}
+

And some tests that diagnose `extern`, `mutable extern`, etc.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133659

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133659: [Clang] P1169R4: static operator()

2022-09-14 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

LGTM


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133659

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131466: [clang] add APValue type check in `TryPrintAsStringLiteral`

2022-08-09 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray accepted this revision.
lichray added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131466

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D119136: [clang] Implement Change scope of lambda trailing-return-type

2022-04-20 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

In D119136#3462660 , @aaron.ballman 
wrote:>

> Thanks for the apology, but I still think the reverts were premature, so 
> hopefully we don't do this again. The issue with reverting all of these is 
> that you put the burden back onto a relatively new contributor to try to 
> figure out how to reapply all these changes when there wasn't actually a need 
> to do so.
>
> In terms of where we go from here, there's a few options:
>
> 1. revert the reverts; this is easiest, but causes the most churn
> 2. merge all three patches into one (squashed) patch and commit that; this 
> requires a little bit more work, but causes less churn
> 3. assume that P2036R3 is not implementable until WG21 resolves CWG2569 
> because it breaks too much code
>
> I think I have a preference for #2 as that will hopefully leave us with the 
> most clear git history for when we do a blame later, but I could live with 
> #1. If we find that there is significant broken code still, but it's not in 
> system headers, then I think we should explore #3, but I don't think we have 
> evidence that we're in this situation either.

I hope we don't fix bugs in production -- WG21 bug is also a bug.

1. The decision made in the paper p2036r3 section 4.1 brings in a breaking 
change.
2. The paper is applied as a DR on all previous C++ versions that apply.
3. The paper has no Annex C entry.

These three things do not compose. The paper didn't do enough homework.

I would like to see One patch that allows other parties to try, but not 
necessarily in the trunk, since doing so couples the trial with other useful 
work in the trunk.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119136

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D113393: [c++2b] Implement P0849R8 auto(x)

2022-02-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 407425.
lichray added a comment.

  Rebased


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D113393

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.auto.deduct/p2.cpp
  clang/test/CXX/expr/expr.post/expr.type.conv/p1-2b.cpp
  clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
  clang/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
  clang/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
  clang/test/Parser/cxx2b-auto-x.cpp
  clang/test/SemaCXX/deduced-return-type-cxx14.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1388,6 +1388,11 @@
   https://wg21.link/P2360R0";>P2360R0
   Clang 14
 
+
+  auto(x): decay-copy in the language
+  https://wg21.link/P0849R8";>P0849R8
+  Clang 14
+
 
 
   Attributes on Lambda-Expressions
Index: clang/test/SemaCXX/deduced-return-type-cxx14.cpp
===
--- clang/test/SemaCXX/deduced-return-type-cxx14.cpp
+++ clang/test/SemaCXX/deduced-return-type-cxx14.cpp
@@ -442,6 +442,15 @@
   B() : decltype(auto)() {} // expected-error {{'decltype(auto)' not allowed here}}
 };
   }
+
+  namespace Cast {
+void foo() {
+  (void)decltype(auto)(0); // cxx14_20-error{{'decltype(auto)' not allowed here}} \
+  cxx2b-warning{{ISO C++23 DIS does not allow functional-style cast to 'decltype(auto)'}}
+  (void)decltype(auto){0}; // cxx14_20-error{{'decltype(auto)' not allowed here}} \
+  cxx2b-warning{{ISO C++23 DIS does not allow functional-style cast to 'decltype(auto)'}}
+}
+  }
 }
 
 namespace CurrentInstantiation {
Index: clang/test/Parser/cxx2b-auto-x.cpp
===
--- /dev/null
+++ clang/test/Parser/cxx2b-auto-x.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx2b -std=c++2b -Wpre-c++2b-compat %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx20 -std=c++20 %s
+
+void looks_like_decltype_auto() {
+  decltype(auto(42)) b = 42; // cxx20-error {{'auto' not allowed here}} \
+cxx2b-warning {{'auto' as a functional-style cast is incompatible with C++ standards before C++2b}}
+  decltype(long *) a = 42;   // expected-error {{expected '(' for function-style cast or type construction}} \
+expected-error {{expected expression}}
+  decltype(auto *) a = 42;   // expected-error {{expected '(' for function-style cast or type construction}} \
+expected-error {{expected expression}}
+  decltype(auto()) c = 42;   // cxx2b-error {{initializer for functional-style cast to 'auto' is empty}} \
+cxx20-error {{'auto' not allowed here}}
+}
+
+struct looks_like_declaration {
+  int n;
+} a;
+
+using T = looks_like_declaration *;
+void f() { T(&a)->n = 1; }
+// FIXME: They should be deemed expressions without breaking function pointer
+//parameter declarations with trailing return types.
+// void g() { auto(&a)->n = 0; }
+// void h() { auto{&a}->n = 0; }
Index: clang/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
===
--- clang/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
+++ clang/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
@@ -1,11 +1,30 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++17 -pedantic
 
+// [expr.new]p2 ... the invented declaration: T x init ;
+// C++2b [dcl.type.auto.deduct]p2.2
+// For a variable declared with a type that contains a placeholder type, T is the declared type of the variable.
 void f() {
+  // - If the initializer is a parenthesized expression-list, the expression-list shall be a single assignmentexpression and E is the assignment-expression.
   new auto('a');
-  new auto {2};
-  new auto {1, 2}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
-  new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
-  new decltype(auto)({1});
-  new decltype(auto)({1, 2}); // expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}}
+  new decltype(auto)('a');
+  // - If the initializer is a braced-init-list, it shall consist of a single brace-enclosed assignm

  1   2   3   >