[libcxx] r324193 - Mark LWG 3014 as complete. No code changes needed

2018-02-03 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Feb  3 23:37:09 2018
New Revision: 324193

URL: http://llvm.org/viewvc/llvm-project?rev=324193=rev
Log:
Mark LWG 3014 as complete. No code changes needed

Modified:
libcxx/trunk/www/upcoming_meeting.html

Modified: libcxx/trunk/www/upcoming_meeting.html
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/upcoming_meeting.html?rev=324193=324192=324193=diff
==
--- libcxx/trunk/www/upcoming_meeting.html (original)
+++ libcxx/trunk/www/upcoming_meeting.html Sat Feb  3 23:37:09 2018
@@ -77,7 +77,7 @@
 https://wg21.link/LWG3010;>3010[networking.ts] 
uses_executor says "if a type T::executor_type 
exists"Jacksonville
 https://wg21.link/LWG3013;>3013(recursive_)directory_iterator
 construction and traversal should not be 
noexceptJacksonvilleComplete
 https://wg21.link/LWG3014;>3014More 
noexcept issues with filesystem 
operationsJacksonvilleComplete
-https://wg21.link/LWG3015;>3015copy_options::unspecified
 underspecifiedJacksonville
+  https://wg21.link/LWG3015;>3015copy_options::unspecified
 underspecifiedJacksonvilleNothing to do
 https://wg21.link/LWG3017;>3017list 
splice functions should use 
addressofJacksonville
 https://wg21.link/LWG3020;>3020[networking.ts] 
Remove spurious nested value_type buffer sequence 
requirementJacksonville
 https://wg21.link/LWG3026;>3026filesystem::weakly_canonical
 still defined in terms of canonical(p, 
base)Jacksonville
@@ -114,7 +114,7 @@
  3010 - No networking TS implementation yet
  3013 - We already implement this
  3014 - We implement this
- 3015 - Eric? 
+ 3015 - Wording changes only
  3017 - We don't do the splicing stuff yet
  3020 - No networking TS implementation yet
  3026 - I think this is just wording cleanup - Eric?


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


[libcxx] r324192 - Implement LWG 3014 - Fix more noexcept issues in filesystem.

2018-02-03 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Feb  3 23:35:36 2018
New Revision: 324192

URL: http://llvm.org/viewvc/llvm-project?rev=324192=rev
Log:
Implement LWG 3014 - Fix more noexcept issues in filesystem.

This patch removes the noexcept declaration from filesystem
operations which require creating temporary paths or
creating a directory iterator. Either of these operations
can throw.

Modified:
libcxx/trunk/include/experimental/filesystem

libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp

libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp

libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp
libcxx/trunk/www/upcoming_meeting.html

Modified: libcxx/trunk/include/experimental/filesystem
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/filesystem?rev=324192=324191=324192=diff
==
--- libcxx/trunk/include/experimental/filesystem (original)
+++ libcxx/trunk/include/experimental/filesystem Sat Feb  3 23:35:36 2018
@@ -88,17 +88,17 @@
error_code& ec);
 
 bool copy_file(const path& from, const path& to);
-bool copy_file(const path& from, const path& to, error_code& ec) _NOEXCEPT;
+bool copy_file(const path& from, const path& to, error_code& ec);
 bool copy_file(const path& from, const path& to, copy_options option);
 bool copy_file(const path& from, const path& to, copy_options option,
-   error_code& ec) _NOEXCEPT;
+   error_code& ec);
 
 void copy_symlink(const path& existing_symlink, const path& new_symlink);
 void copy_symlink(const path& existing_symlink, const path& new_symlink,
   error_code& ec) _NOEXCEPT;
 
 bool create_directories(const path& p);
-bool create_directories(const path& p, error_code& ec) _NOEXCEPT;
+bool create_directories(const path& p, error_code& ec);
 
 bool create_directory(const path& p);
 bool create_directory(const path& p, error_code& ec) _NOEXCEPT;
@@ -188,7 +188,7 @@
 bool remove(const path& p, error_code& ec) _NOEXCEPT;
 
 uintmax_tremove_all(const path& p);
-uintmax_tremove_all(const path& p, error_code& ec) _NOEXCEPT;
+uintmax_tremove_all(const path& p, error_code& ec);
 
 void rename(const path& from, const path& to);
 void rename(const path& from, const path& to, error_code& ec) _NOEXCEPT;
@@ -1375,7 +1375,7 @@ bool copy_file(const path& __from, const
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
-bool copy_file(const path& __from, const path& __to, error_code& __ec) 
_NOEXCEPT {
+bool copy_file(const path& __from, const path& __to, error_code& __ec) {
 return __copy_file(__from, __to, copy_options::none, &__ec);
 }
 
@@ -1386,7 +1386,7 @@ bool copy_file(const path& __from, const
 
 inline _LIBCPP_INLINE_VISIBILITY
 bool copy_file(const path& __from, const path& __to,
-   copy_options __opt, error_code& __ec) _NOEXCEPT {
+   copy_options __opt, error_code& __ec){
 return __copy_file(__from, __to, __opt, &__ec);
 }
 
@@ -1406,7 +1406,7 @@ bool create_directories(const path& __p)
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
-bool create_directories(const path& __p, error_code& __ec) _NOEXCEPT {
+bool create_directories(const path& __p, error_code& __ec) {
 return __create_directories(__p, &__ec);
 }
 
@@ -1699,7 +1699,7 @@ uintmax_t remove_all(const path& __p) {
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
-uintmax_t remove_all(const path& __p, error_code& __ec) _NOEXCEPT {
+uintmax_t remove_all(const path& __p, error_code& __ec) {
 return __remove_all(__p, &__ec);
 }
 

Modified: 
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp?rev=324192=324191=324192=diff
==
--- 
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
 Sat Feb  3 23:35:36 2018
@@ -44,8 +44,8 @@ TEST_CASE(test_signatures)
 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts, ec)), bool);
 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p));
 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts));
-ASSERT_NOEXCEPT(fs::copy_file(p, p, ec));
-ASSERT_NOEXCEPT(fs::copy_file(p, p, opts, ec));
+ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, ec));
+ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts, ec));
 }
 
 TEST_CASE(test_error_reporting)

Modified: 
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp
URL: 

[libcxx] r324191 - Mark LWG 3013 as already complete. See r316941

2018-02-03 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Feb  3 23:29:53 2018
New Revision: 324191

URL: http://llvm.org/viewvc/llvm-project?rev=324191=rev
Log:
Mark LWG 3013 as already complete. See r316941

Modified:
libcxx/trunk/www/upcoming_meeting.html

Modified: libcxx/trunk/www/upcoming_meeting.html
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/upcoming_meeting.html?rev=324191=324190=324191=diff
==
--- libcxx/trunk/www/upcoming_meeting.html (original)
+++ libcxx/trunk/www/upcoming_meeting.html Sat Feb  3 23:29:53 2018
@@ -75,7 +75,7 @@
 https://wg21.link/LWG3007;>3007allocate_shared 
should rebind allocator to cv-unqualified value_type for 
constructionJacksonville
 https://wg21.link/LWG3009;>3009Including 
string_view doesn't provide 
std::size/empty/dataJacksonvilleComplete
 https://wg21.link/LWG3010;>3010[networking.ts] 
uses_executor says "if a type T::executor_type 
exists"Jacksonville
-https://wg21.link/LWG3013;>3013(recursive_)directory_iterator
 construction and traversal should not be 
noexceptJacksonville
+https://wg21.link/LWG3013;>3013(recursive_)directory_iterator
 construction and traversal should not be 
noexceptJacksonvilleComplete
 https://wg21.link/LWG3014;>3014More 
noexcept issues with filesystem 
operationsJacksonville
 https://wg21.link/LWG3015;>3015copy_options::unspecified
 underspecifiedJacksonville
 https://wg21.link/LWG3017;>3017list 
splice functions should use 
addressofJacksonville
@@ -112,7 +112,7 @@
  3007 - Looks easy
  3009 - We do this already; tests added in r323719
  3010 - No networking TS implementation yet
- 3013 - Eric? 
+ 3013 - We already implement this
  3014 - Eric? 
  3015 - Eric? 
  3017 - We don't do the splicing stuff yet


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


[libcxx] r324190 - Remove debug println from rec.dir.itr.increment test

2018-02-03 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Feb  3 19:26:55 2018
New Revision: 324190

URL: http://llvm.org/viewvc/llvm-project?rev=324190=rev
Log:
Remove debug println from rec.dir.itr.increment test

Modified:

libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp

Modified: 
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp?rev=324190=324189=324190=diff
==
--- 
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
 Sat Feb  3 19:26:55 2018
@@ -24,7 +24,6 @@
 #include "test_macros.h"
 #include "rapid-cxx-test.hpp"
 #include "filesystem_test_helper.hpp"
-#include 
 
 using namespace std::experimental::filesystem;
 
@@ -347,7 +346,6 @@ TEST_CASE(test_PR35078_with_symlink)
 Opts |= directory_options::follow_directory_symlink;
   recursive_directory_iterator it(startDir, Opts, ec);
   while (!ec && it != endIt && *it != symDir) {
-std::cout << *it << std::endl;
 if (*it == nestedFile)
   SeenFile3 = true;
 it.increment(ec);


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


[libcxx] r324189 - Implement LWG2989: path's streaming operators allow everything under the sun.

2018-02-03 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Feb  3 19:10:53 2018
New Revision: 324189

URL: http://llvm.org/viewvc/llvm-project?rev=324189=rev
Log:
Implement LWG2989: path's streaming operators allow everything under the sun.

Because path can be constructed from a ton of different types, including string
and wide strings, this caused it's streaming operators to suck up all sorts
of silly types via silly conversions. For example:

using namespace std::experimental::filesystem::v1;
std::wstring w(L"wide");
std::cout << w; // converts to path.

This patch tentatively adopts the resolution to LWG2989 and fixes the issue
by making the streaming operators friends of path.

Modified:
libcxx/trunk/include/experimental/filesystem

libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp
libcxx/trunk/www/upcoming_meeting.html

Modified: libcxx/trunk/include/experimental/filesystem
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/filesystem?rev=324189=324188=324189=diff
==
--- libcxx/trunk/include/experimental/filesystem (original)
+++ libcxx/trunk/include/experimental/filesystem Sat Feb  3 19:10:53 2018
@@ -28,12 +28,13 @@
 
 path operator/ (const path& lhs, const path& rhs);
 
+// fs.path.io operators are friends of path.
 template 
-basic_ostream&
+friend basic_ostream&
 operator<<(basic_ostream& os, const path& p);
 
 template 
-basic_istream&
+friend basic_istream&
 operator>>(basic_istream& is, path& p);
 
 template 
@@ -994,6 +995,40 @@ public:
 iterator begin() const;
 iterator end() const;
 
+
+template 
+_LIBCPP_INLINE_VISIBILITY
+friend typename enable_if::value &&
+   is_same<_Traits, char_traits>::value,
+   basic_ostream<_CharT, _Traits>&
+>::type
+operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
+__os << std::__quoted(__p.native());
+return __os;
+}
+
+template 
+_LIBCPP_INLINE_VISIBILITY
+friend typename enable_if::value ||
+   !is_same<_Traits, char_traits>::value,
+   basic_ostream<_CharT, _Traits>&
+>::type
+operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
+__os << std::__quoted(__p.string<_CharT, _Traits>());
+return __os;
+}
+
+template 
+_LIBCPP_INLINE_VISIBILITY
+friend basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
+{
+basic_string<_CharT, _Traits> __tmp;
+__is >> __quoted(__tmp);
+__p = __tmp;
+return __is;
+}
+
 private:
 inline _LIBCPP_INLINE_VISIBILITY
 path& __assign_view(__string_view const& __s) noexcept { __pn_ = 
string_type(__s); return *this; }
@@ -1037,39 +1072,6 @@ path operator/(const path& __lhs, const
 return path(__lhs) /= __rhs;
 }
 
-template 
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if::value &&
-   is_same<_Traits, char_traits>::value,
-   basic_ostream<_CharT, _Traits>&
->::type
-operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
-__os << std::__quoted(__p.native());
-return __os;
-}
-
-template 
-_LIBCPP_INLINE_VISIBILITY
-typename enable_if::value ||
-   !is_same<_Traits, char_traits>::value,
-   basic_ostream<_CharT, _Traits>&
->::type
-operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
-__os << std::__quoted(__p.string<_CharT, _Traits>());
-return __os;
-}
-
-template 
-_LIBCPP_INLINE_VISIBILITY
-basic_istream<_CharT, _Traits>&
-operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
-{
-basic_string<_CharT, _Traits> __tmp;
-__is >> __quoted(__tmp);
-__p = __tmp;
-return __is;
-}
-
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_pathable<_Source>::value, path>::type

Modified: 
libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp?rev=324189=324188=324189=diff
==
--- 
libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp
 Sat Feb  3 19:10:53 2018
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "test_macros.h"
 #include "test_iterators.h"
@@ -35,6 +36,8 @@
 MultiStringType InStr =  MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789");
 MultiStringType OutStr = 

[libcxx] r324188 - Mark issue 2851 as complete

2018-02-03 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Feb  3 18:45:33 2018
New Revision: 324188

URL: http://llvm.org/viewvc/llvm-project?rev=324188=rev
Log:
Mark issue 2851 as complete

Modified:
libcxx/trunk/www/upcoming_meeting.html

Modified: libcxx/trunk/www/upcoming_meeting.html
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/upcoming_meeting.html?rev=324188=324187=324188=diff
==
--- libcxx/trunk/www/upcoming_meeting.html (original)
+++ libcxx/trunk/www/upcoming_meeting.html Sat Feb  3 18:45:33 2018
@@ -64,7 +64,7 @@
 https://wg21.link/LWG2816;>2816resize_file has 
impossible postconditionJacksonvilleNothing to 
do
 https://wg21.link/LWG2843;>2843Unclear behavior 
of 
std::pmr::memory_resource::do_allocate()Jacksonville
 https://wg21.link/LWG2849;>2849Why does 
!is_regular_file(from) cause copy_file to report a "file 
already exists" error?JacksonvilleNothing to do
-https://wg21.link/LWG2851;>2851std::filesystem enum 
classes are now underspecifiedJacksonville
+https://wg21.link/LWG2851;>2851std::filesystem enum 
classes are now underspecifiedJacksonvilleNothing to 
do
 https://wg21.link/LWG2969;>2969polymorphic_allocator::construct()
 shouldn't pass resource()Jacksonville
 https://wg21.link/LWG2975;>2975Missing case for 
pair construction in scoped and polymorphic 
allocatorsJacksonville
 https://wg21.link/LWG2989;>2989path's 
stream insertion operator lets you insert everything under the 
sunJacksonville
@@ -101,7 +101,7 @@
  2816 - Wording changes only
  2843 - We don't have PMRs yet
  2849 - We already report different errors. 
- 2851 - Eric? 
+ 2851 - Wording changes only
  2969 - We don't have PMRs yet
  2975 - We can do the scoped_ bit, but the PMR stuff will have to 
wait.
  2989 - Eric? 


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


[libcxx] r324187 - Address LWG 2849 and fix missing failure condition in copy_file.

2018-02-03 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Feb  3 18:43:32 2018
New Revision: 324187

URL: http://llvm.org/viewvc/llvm-project?rev=324187=rev
Log:
Address LWG 2849 and fix missing failure condition in copy_file.

Previously copy_file didn't handle the case where the input and
output were the same file.

Modified:
libcxx/trunk/src/experimental/filesystem/operations.cpp

libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
libcxx/trunk/www/upcoming_meeting.html

Modified: libcxx/trunk/src/experimental/filesystem/operations.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/experimental/filesystem/operations.cpp?rev=324187=324186=324187=diff
==
--- libcxx/trunk/src/experimental/filesystem/operations.cpp (original)
+++ libcxx/trunk/src/experimental/filesystem/operations.cpp Sat Feb  3 18:43:32 
2018
@@ -263,18 +263,22 @@ void __copy(const path& from, const path
 bool __copy_file(const path& from, const path& to, copy_options options,
  std::error_code *ec)
 {
-if (ec) ec->clear();
+using StatT = struct ::stat;
+if (ec)
+  ec->clear();
 
 std::error_code m_ec;
-auto from_st = detail::posix_stat(from, _ec);
+StatT from_stat;
+auto from_st = detail::posix_stat(from, from_stat, _ec);
 if (not is_regular_file(from_st)) {
-if (not m_ec)
-m_ec = make_error_code(errc::not_supported);
-set_or_throw(m_ec, ec, "copy_file", from, to);
-return false;
+  if (not m_ec)
+m_ec = make_error_code(errc::not_supported);
+  set_or_throw(m_ec, ec, "copy_file", from, to);
+  return false;
 }
 
-auto to_st = detail::posix_stat(to, _ec);
+StatT to_stat;
+auto to_st = detail::posix_stat(to, to_stat, _ec);
 if (!status_known(to_st)) {
 set_or_throw(m_ec, ec, "copy_file", from, to);
 return false;
@@ -285,6 +289,11 @@ bool __copy_file(const path& from, const
 set_or_throw(make_error_code(errc::not_supported), ec, "copy_file", 
from, to);
 return false;
 }
+if (to_exists && detail::stat_equivalent(from_stat, to_stat)) {
+  set_or_throw(make_error_code(errc::file_exists), ec, "copy_file", from,
+   to);
+  return false;
+}
 if (to_exists && bool(copy_options::skip_existing & options)) {
 return false;
 }
@@ -302,8 +311,9 @@ bool __copy_file(const path& from, const
 return detail::copy_file_impl(from, to, from_st.permissions(), ec);
 }
 else {
-set_or_throw(make_error_code(errc::file_exists), ec, "copy", from, to);
-return false;
+  set_or_throw(make_error_code(errc::file_exists), ec, "copy_file", from,
+   to);
+  return false;
 }
 
 _LIBCPP_UNREACHABLE();
@@ -443,7 +453,7 @@ bool __equivalent(const path& p1, const
 if (!exists(s2))
   return make_unsupported_error();
 if (ec) ec->clear();
-return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
+return detail::stat_equivalent(st1, st2);
 }
 
 

Modified: 
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp?rev=324187=324186=324187=diff
==
--- 
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
 Sat Feb  3 18:43:32 2018
@@ -70,17 +70,21 @@ TEST_CASE(test_error_reporting)
 scoped_test_env env;
 const path file = env.create_file("file1", 42);
 const path file2 = env.create_file("file2", 55);
+const path non_regular_file = env.create_fifo("non_reg");
 const path dne = env.make_env_path("dne");
 { // exists(to) && equivalent(to, from)
 std::error_code ec;
-TEST_CHECK(fs::copy_file(file, file, ec) == false);
+TEST_CHECK(fs::copy_file(file, file, copy_options::overwrite_existing,
+ ec) == false);
 TEST_REQUIRE(ec);
+TEST_CHECK(ec == std::make_error_code(std::errc::file_exists));
 TEST_CHECK(checkThrow(file, file, ec));
 }
 { // exists(to) && !(skip_existing | overwrite_existing | update_existing)
 std::error_code ec;
 TEST_CHECK(fs::copy_file(file, file2, ec) == false);
 TEST_REQUIRE(ec);
+TEST_CHECK(ec == std::make_error_code(std::errc::file_exists));
 TEST_CHECK(checkThrow(file, file2, ec));
 }
 }
@@ -181,6 +185,7 @@ TEST_CASE(non_regular_file_test)
 TEST_REQUIRE(fs::copy_file(file, fifo, 
copy_options::overwrite_existing, ec) == false);
 TEST_CHECK(ec);
 TEST_CHECK(ec != GetTestEC());
+

[libcxx] r324186 - correct comment about C++03 assignment operators

2018-02-03 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Feb  3 18:22:33 2018
New Revision: 324186

URL: http://llvm.org/viewvc/llvm-project?rev=324186=rev
Log:
correct comment about C++03 assignment operators

Modified:

libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp

Modified: 
libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp?rev=324186=324185=324186=diff
==
--- 
libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp
 Sat Feb  3 18:22:33 2018
@@ -20,10 +20,10 @@
 // Disable the missing braces warning for this reason.
 #include "disable_missing_braces_warning.h"
 
-// FIXME: Clang generates copy assignment operators for types with const 
members
-// in C++03. The generated operator is ill-formed but still present.
-// I'm not sure if this is a Clang bug, but we need to work around it for now.
-#if TEST_STD_VER < 11 && defined(__clang__)
+// In C++03 the copy assignment operator is not deleted when the implicitly
+// generated operator would be ill-formed; like in the case of a struct with a
+// const member.
+#if TEST_STD_VER < 11
 #define TEST_NOT_COPY_ASSIGNABLE(T) ((void)0)
 #else
 #define TEST_NOT_COPY_ASSIGNABLE(T) 
static_assert(!std::is_copy_assignable::value, "")


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


[libcxx] r324185 - Make array non-CopyAssignable and make swap and fill ill-formed.

2018-02-03 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Feb  3 18:17:02 2018
New Revision: 324185

URL: http://llvm.org/viewvc/llvm-project?rev=324185=rev
Log:
Make array non-CopyAssignable and make swap and fill ill-formed.

The standard isn't exactly clear how std::array should handle zero-sized arrays
with const element types. In particular W.R.T. copy assignment, swap, and fill.

This patch takes the position that those operations should be ill-formed,
and makes changes to libc++ to make it so.

This follows up on commit r324182.

Added:

libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp
libcxx/trunk/test/std/containers/sequences/array/array.fill/fill.fail.cpp
libcxx/trunk/test/std/containers/sequences/array/array.swap/swap.fail.cpp
Modified:
libcxx/trunk/include/array
libcxx/trunk/test/std/containers/sequences/array/array.data/data.pass.cpp

Modified: libcxx/trunk/include/array
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/array?rev=324185=324184=324185=diff
==
--- libcxx/trunk/include/array (original)
+++ libcxx/trunk/include/array Sat Feb  3 18:17:02 2018
@@ -122,7 +122,8 @@ struct __array_traits {
   typedef _Tp _StorageT[_Size];
 
   _LIBCPP_INLINE_VISIBILITY
-  static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp* __data(_StorageT& __store) {
+  static _LIBCPP_CONSTEXPR_AFTER_CXX14 typename remove_const<_Tp>::type*
+  __data(typename remove_const<_StorageT>::type& __store) {
 return __store;
   }
 
@@ -144,12 +145,16 @@ struct __array_traits {
 
 template 
 struct __array_traits<_Tp, 0> {
-  typedef typename aligned_storage::value>::type _StorageT;
+  typedef typename aligned_storage::value>::type
+  _NonConstStorageT;
+  typedef typename conditional::value, const _NonConstStorageT,
+   _NonConstStorageT>::type _StorageT;
 
+  typedef typename remove_const<_Tp>::type _NonConstTp;
   _LIBCPP_INLINE_VISIBILITY
-  static _Tp* __data(_StorageT& __store) {
+  static _NonConstTp* __data(_NonConstStorageT& __store) {
 _StorageT *__ptr = std::addressof(__store);
-return reinterpret_cast<_Tp*>(__ptr);
+return reinterpret_cast<_NonConstTp*>(__ptr);
   }
 
   _LIBCPP_INLINE_VISIBILITY
@@ -162,8 +167,7 @@ struct __array_traits<_Tp, 0> {
   static void __swap(_StorageT&, _StorageT&) {}
 
   _LIBCPP_INLINE_VISIBILITY
-  static void __fill(_StorageT&, _Tp const&) {
-  }
+  static void __fill(_StorageT&, _Tp const&) {}
 };
 
 template 
@@ -187,12 +191,19 @@ struct _LIBCPP_TEMPLATE_VIS array
 typename _Traits::_StorageT __elems_;
 
 // No explicit construct/copy/destroy for aggregate type
-_LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u)
-{_Traits::__fill(__elems_, __u);}
+_LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) {
+  static_assert(_Size != 0 || !is_const<_Tp>::value,
+"cannot fill zero-sized array of type 'const T'");
+  _Traits::__fill(__elems_, __u);
+}
 
 _LIBCPP_INLINE_VISIBILITY
-void swap(array& __a) _NOEXCEPT_(_Size == 0 || 
__is_nothrow_swappable<_Tp>::value)
-{ _Traits::__swap(__elems_, __a.__elems_); }
+void swap(array& __a)
+_NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) {
+  static_assert(_Size != 0 || !is_const<_Tp>::value,
+"cannot swap zero-sized array of type 'const T'");
+  _Traits::__swap(__elems_, __a.__elems_);
+}
 
 // iterators:
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14

Added: 
libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp?rev=324185=auto
==
--- 
libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp
 (added)
+++ 
libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp
 Sat Feb  3 18:17:02 2018
@@ -0,0 +1,93 @@
+//===--===//
+//
+// 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.
+//
+//===--===//
+
+// 
+
+// implicitly generated array constructors / assignment operators
+
+#include 
+#include 
+#include 
+#include "test_macros.h"
+
+// std::array is explicitly allowed to be initialized with A a = { init-list 
};.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
+
+// FIXME: Clang generates copy assignment operators for types with const 
members
+// in C++03. The generated 

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

2018-02-03 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Feb  3 17:03:08 2018
New Revision: 324182

URL: http://llvm.org/viewvc/llvm-project?rev=324182=rev
Log:
[libc++] Fix PR35491 - std::array of zero-size doesn't work with non-default 
constructible types.

Summary:
This patch fixes llvm.org/PR35491 and LWG2157  
(https://cplusplus.github.io/LWG/issue2157)

The fix attempts to maintain ABI compatibility by replacing the array with a 
instance of `aligned_storage`.

Reviewers: mclow.lists, EricWF

Reviewed By: EricWF

Subscribers: lichray, cfe-commits

Differential Revision: https://reviews.llvm.org/D41223

Modified:
libcxx/trunk/include/array
libcxx/trunk/test/std/containers/sequences/array/array.cons/default.pass.cpp
libcxx/trunk/test/std/containers/sequences/array/array.data/data.pass.cpp

libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp
libcxx/trunk/test/std/containers/sequences/array/begin.pass.cpp

Modified: libcxx/trunk/include/array
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/array?rev=324182=324181=324182=diff
==
--- libcxx/trunk/include/array (original)
+++ libcxx/trunk/include/array Sat Feb  3 17:03:08 2018
@@ -118,6 +118,55 @@ template  c
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template 
+struct __array_traits {
+  typedef _Tp _StorageT[_Size];
+
+  _LIBCPP_INLINE_VISIBILITY
+  static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp* __data(_StorageT& __store) {
+return __store;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp const* __data(const _StorageT& 
__store) {
+return __store;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __swap(_StorageT& __lhs, _StorageT& __rhs) {
+std::swap_ranges(__lhs, __lhs + _Size, __rhs);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __fill(_StorageT& __arr, _Tp const& __val) {
+_VSTD::fill_n(__arr, _Size, __val);
+  }
+};
+
+template 
+struct __array_traits<_Tp, 0> {
+  typedef typename aligned_storage::value>::type _StorageT;
+
+  _LIBCPP_INLINE_VISIBILITY
+  static _Tp* __data(_StorageT& __store) {
+_StorageT *__ptr = std::addressof(__store);
+return reinterpret_cast<_Tp*>(__ptr);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static const _Tp* __data(const _StorageT& __store) {
+const _StorageT *__ptr = std::addressof(__store);
+return reinterpret_cast(__ptr);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __swap(_StorageT&, _StorageT&) {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __fill(_StorageT&, _Tp const&) {
+  }
+};
+
+template 
 struct _LIBCPP_TEMPLATE_VIS array
 {
 // types:
@@ -134,31 +183,26 @@ struct _LIBCPP_TEMPLATE_VIS array
 typedef std::reverse_iterator   reverse_iterator;
 typedef std::reverse_iterator const_reverse_iterator;
 
-value_type __elems_[_Size > 0 ? _Size : 1];
+typedef __array_traits<_Tp, _Size> _Traits;
+typename _Traits::_StorageT __elems_;
 
 // No explicit construct/copy/destroy for aggregate type
 _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u)
-{_VSTD::fill_n(__elems_, _Size, __u);}
-_LIBCPP_INLINE_VISIBILITY
-void swap(array& __a) _NOEXCEPT_(_Size == 0 || 
__is_nothrow_swappable<_Tp>::value)
-{ __swap_dispatch((std::integral_constant()), __a); }
+{_Traits::__fill(__elems_, __u);}
 
 _LIBCPP_INLINE_VISIBILITY
-void __swap_dispatch(std::true_type, array&) {}
-
-_LIBCPP_INLINE_VISIBILITY
-void __swap_dispatch(std::false_type, array& __a)
-{ _VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);}
+void swap(array& __a) _NOEXCEPT_(_Size == 0 || 
__is_nothrow_swappable<_Tp>::value)
+{ _Traits::__swap(__elems_, __a.__elems_); }
 
 // iterators:
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-iterator begin() _NOEXCEPT {return iterator(__elems_);}
+iterator begin() _NOEXCEPT {return iterator(data());}
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);}
+const_iterator begin() const _NOEXCEPT {return const_iterator(data());}
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);}
+iterator end() _NOEXCEPT {return iterator(data() + _Size);}
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + 
_Size);}
+const_iterator end() const _NOEXCEPT {return const_iterator(data() + 
_Size);}
 
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
@@ -201,9 +245,9 @@ struct _LIBCPP_TEMPLATE_VIS array
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference 
back() const  {return __elems_[_Size > 0 ? _Size-1 : 0];}
 
 

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

2018-02-03 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF updated this revision to Diff 132758.
EricWF added a comment.

- Address review comments.
- Add initialization tests.


https://reviews.llvm.org/D41223

Files:
  include/array
  test/std/containers/sequences/array/array.cons/default.pass.cpp
  test/std/containers/sequences/array/array.data/data.pass.cpp
  test/std/containers/sequences/array/array.data/data_const.pass.cpp
  test/std/containers/sequences/array/begin.pass.cpp

Index: test/std/containers/sequences/array/begin.pass.cpp
===
--- test/std/containers/sequences/array/begin.pass.cpp
+++ test/std/containers/sequences/array/begin.pass.cpp
@@ -31,4 +31,13 @@
 *i = 5.5;
 assert(c[0] == 5.5);
 }
+{
+  struct NoDefault {
+NoDefault(int) {}
+  };
+  typedef NoDefault T;
+  typedef std::array C;
+  C c = {};
+  assert(c.begin() == c.end());
+}
 }
Index: test/std/containers/sequences/array/array.data/data_const.pass.cpp
===
--- test/std/containers/sequences/array/array.data/data_const.pass.cpp
+++ test/std/containers/sequences/array/array.data/data_const.pass.cpp
@@ -38,6 +38,16 @@
 const T* p = c.data();
 (void)p; // to placate scan-build
 }
+{
+  struct NoDefault {
+NoDefault(int) {}
+  };
+  typedef NoDefault T;
+  typedef std::array C;
+  const C c = {};
+  const T* p = c.data();
+  assert(p != nullptr);
+}
 #if TEST_STD_VER > 14
 {
 typedef std::array C;
Index: test/std/containers/sequences/array/array.data/data.pass.cpp
===
--- test/std/containers/sequences/array/array.data/data.pass.cpp
+++ test/std/containers/sequences/array/array.data/data.pass.cpp
@@ -36,4 +36,14 @@
 T* p = c.data();
 (void)p; // to placate scan-build
 }
+{
+  struct NoDefault {
+NoDefault(int) {}
+  };
+  typedef NoDefault T;
+  typedef std::array C;
+  C c = {};
+  T* p = c.data();
+  assert(p != nullptr);
+}
 }
Index: test/std/containers/sequences/array/array.cons/default.pass.cpp
===
--- test/std/containers/sequences/array/array.cons/default.pass.cpp
+++ test/std/containers/sequences/array/array.cons/default.pass.cpp
@@ -14,6 +14,14 @@
 #include 
 #include 
 
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
+
+struct NoDefault {
+  NoDefault(int) {}
+};
+
 int main()
 {
 {
@@ -28,4 +36,13 @@
 C c;
 assert(c.size() == 0);
 }
+{
+  typedef std::array C;
+  C c;
+  assert(c.size() == 0);
+  C c1 = {};
+  assert(c1.size() == 0);
+  C c2 = {{}};
+  assert(c2.size() == 0);
+}
 }
Index: include/array
===
--- include/array
+++ include/array
@@ -118,6 +118,55 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template 
+struct __array_traits {
+  typedef _Tp _StorageT[_Size];
+
+  _LIBCPP_INLINE_VISIBILITY
+  static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp* __data(_StorageT& __store) {
+return __store;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp const* __data(const _StorageT& __store) {
+return __store;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __swap(_StorageT& __lhs, _StorageT& __rhs) {
+std::swap_ranges(__lhs, __lhs + _Size, __rhs);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __fill(_StorageT& __arr, _Tp const& __val) {
+_VSTD::fill_n(__arr, _Size, __val);
+  }
+};
+
+template 
+struct __array_traits<_Tp, 0> {
+  typedef typename aligned_storage::value>::type _StorageT;
+
+  _LIBCPP_INLINE_VISIBILITY
+  static _Tp* __data(_StorageT& __store) {
+_StorageT *__ptr = std::addressof(__store);
+return reinterpret_cast<_Tp*>(__ptr);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static const _Tp* __data(const _StorageT& __store) {
+const _StorageT *__ptr = std::addressof(__store);
+return reinterpret_cast(__ptr);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __swap(_StorageT&, _StorageT&) {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __fill(_StorageT&, _Tp const&) {
+  }
+};
+
+template 
 struct _LIBCPP_TEMPLATE_VIS array
 {
 // types:
@@ -134,31 +183,26 @@
 typedef std::reverse_iterator   reverse_iterator;
 typedef std::reverse_iterator const_reverse_iterator;
 
-value_type __elems_[_Size > 0 ? _Size : 1];
+typedef __array_traits<_Tp, _Size> _Traits;
+typename _Traits::_StorageT __elems_;
 
 // No explicit construct/copy/destroy for aggregate type
 _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u)
-

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

2018-02-03 Thread Eric Fiselier via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rCXX324182: [libc++] Fix PR35491 - std::array of zero-size 
doesnt work with non-default… (authored by EricWF, committed by ).

Repository:
  rCXX libc++

https://reviews.llvm.org/D41223

Files:
  include/array
  test/std/containers/sequences/array/array.cons/default.pass.cpp
  test/std/containers/sequences/array/array.data/data.pass.cpp
  test/std/containers/sequences/array/array.data/data_const.pass.cpp
  test/std/containers/sequences/array/begin.pass.cpp

Index: include/array
===
--- include/array
+++ include/array
@@ -118,6 +118,55 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template 
+struct __array_traits {
+  typedef _Tp _StorageT[_Size];
+
+  _LIBCPP_INLINE_VISIBILITY
+  static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp* __data(_StorageT& __store) {
+return __store;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp const* __data(const _StorageT& __store) {
+return __store;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __swap(_StorageT& __lhs, _StorageT& __rhs) {
+std::swap_ranges(__lhs, __lhs + _Size, __rhs);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __fill(_StorageT& __arr, _Tp const& __val) {
+_VSTD::fill_n(__arr, _Size, __val);
+  }
+};
+
+template 
+struct __array_traits<_Tp, 0> {
+  typedef typename aligned_storage::value>::type _StorageT;
+
+  _LIBCPP_INLINE_VISIBILITY
+  static _Tp* __data(_StorageT& __store) {
+_StorageT *__ptr = std::addressof(__store);
+return reinterpret_cast<_Tp*>(__ptr);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static const _Tp* __data(const _StorageT& __store) {
+const _StorageT *__ptr = std::addressof(__store);
+return reinterpret_cast(__ptr);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __swap(_StorageT&, _StorageT&) {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  static void __fill(_StorageT&, _Tp const&) {
+  }
+};
+
+template 
 struct _LIBCPP_TEMPLATE_VIS array
 {
 // types:
@@ -134,31 +183,26 @@
 typedef std::reverse_iterator   reverse_iterator;
 typedef std::reverse_iterator const_reverse_iterator;
 
-value_type __elems_[_Size > 0 ? _Size : 1];
+typedef __array_traits<_Tp, _Size> _Traits;
+typename _Traits::_StorageT __elems_;
 
 // No explicit construct/copy/destroy for aggregate type
 _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u)
-{_VSTD::fill_n(__elems_, _Size, __u);}
-_LIBCPP_INLINE_VISIBILITY
-void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value)
-{ __swap_dispatch((std::integral_constant()), __a); }
+{_Traits::__fill(__elems_, __u);}
 
 _LIBCPP_INLINE_VISIBILITY
-void __swap_dispatch(std::true_type, array&) {}
-
-_LIBCPP_INLINE_VISIBILITY
-void __swap_dispatch(std::false_type, array& __a)
-{ _VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);}
+void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value)
+{ _Traits::__swap(__elems_, __a.__elems_); }
 
 // iterators:
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-iterator begin() _NOEXCEPT {return iterator(__elems_);}
+iterator begin() _NOEXCEPT {return iterator(data());}
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);}
+const_iterator begin() const _NOEXCEPT {return const_iterator(data());}
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);}
+iterator end() _NOEXCEPT {return iterator(data() + _Size);}
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);}
+const_iterator end() const _NOEXCEPT {return const_iterator(data() + _Size);}
 
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
@@ -201,9 +245,9 @@
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const  {return __elems_[_Size > 0 ? _Size-1 : 0];}
 
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-value_type* data() _NOEXCEPT {return __elems_;}
+value_type* data() _NOEXCEPT {return _Traits::__data(__elems_);}
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
-const value_type* data() const _NOEXCEPT {return __elems_;}
+const value_type* data() const _NOEXCEPT {return _Traits::__data(__elems_);}
 };
 
 template 
Index: test/std/containers/sequences/array/begin.pass.cpp
===
--- test/std/containers/sequences/array/begin.pass.cpp
+++ test/std/containers/sequences/array/begin.pass.cpp
@@ -31,4 +31,13 @@
 *i = 

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

2018-02-03 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a comment.

In https://reviews.llvm.org/D41223#997264, @EricWF wrote:

> > and also test `{{}}` cases.
>
> I don't agree those cases are valid. That initialization syntax suggests 
> there is something in the zero-sized array which is default constructible - 
> or that users should be able to control construction of. I disagree with that.


Nevermind, I see STL is insisting that case be handled. I'll add tests and then 
complain to him later.


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.

2018-02-03 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a comment.

In https://reviews.llvm.org/D41223#957308, @mclow.lists wrote:

> I'm wondering if it's not a better idea to have an explicit specialization 
> for size == 0
>
>   template 
>   class array {
>   // and so on.
>   };


I think that's probably more work than it's worth. I think we should change the 
primary template to support the bare minimum number of operations, and then let 
the rest of the operations blow up if users attempt to use them.

In https://reviews.llvm.org/D41223#957334, @lichray wrote:

> BTW, this is https://cplusplus.github.io/LWG/issue2157 , so please update 
> `www` accordingly,


The `www` pages will get updated when the issue is actually accepted, which it 
currently isn't.
There is no place to put that information now.

> and also test `{{}}` cases.

I don't agree those cases are valid. That initialization syntax suggests there 
is something in the zero-sized array which is default constructible - or that 
users should be able to control construction of. I disagree with that.




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

lichray wrote:
> 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?
`_LIBCPP_INLINE_VISIBILITY` should force inlining. 


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] D42887: [Driver] Add option to manually control discarding value names in LLVM IR.

2018-02-03 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF marked an inline comment as done.
EricWF added inline comments.



Comment at: lib/Driver/ToolChains/Clang.cpp:3269
 
-// Disable the verification pass in -asserts builds.
+  const bool IsAssertBuild =
 #ifdef NDEBUG

lebedev.ri wrote:
> This logic seems sidewards.
> If `NDEBUG` is specified, then it is `assert()`-less build.
> If `NDEBUG` is *not* specified, then `assert()`'s are actually functional.
> 
Woops! Silly me. Thats a dumb mistake and I feel dumb having made it.


https://reviews.llvm.org/D42887



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


[PATCH] D42887: [Driver] Add option to manually control discarding value names in LLVM IR.

2018-02-03 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF updated this revision to Diff 132752.
EricWF marked an inline comment as done.
EricWF added a comment.

- Address really really really dumb mistake.


https://reviews.llvm.org/D42887

Files:
  docs/UsersManual.rst
  include/clang/Driver/Options.td
  lib/Driver/ToolChains/Clang.cpp
  test/Driver/clang_f_opts.c


Index: test/Driver/clang_f_opts.c
===
--- test/Driver/clang_f_opts.c
+++ test/Driver/clang_f_opts.c
@@ -517,3 +517,8 @@
 // RUN: %clang -### -S %s 2>&1 | FileCheck 
-check-prefix=CHECK-NO-CF-PROTECTION-BRANCH %s
 // CHECK-CF-PROTECTION-BRANCH: -fcf-protection=branch
 // CHECK-NO-CF-PROTECTION-BRANCH-NOT: -fcf-protection=branch
+
+// RUN: %clang -### -S -fdiscard-value-names %s 2>&1 | FileCheck 
-check-prefix=CHECK-DISCARD-NAMES %s
+// RUN: %clang -### -S -fno-discard-value-names %s 2>&1 | FileCheck 
-check-prefix=CHECK-NO-DISCARD-NAMES %s
+// CHECK-DISCARD-NAMES: "-discard-value-names"
+// CHECK-NO-DISCARD-NAMES-NOT: "-discard-value-names"
Index: lib/Driver/ToolChains/Clang.cpp
===
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -3266,12 +3266,23 @@
   if (!C.isForDiagnostics())
 CmdArgs.push_back("-disable-free");
 
-// Disable the verification pass in -asserts builds.
+  const bool IsAssertBuild =
 #ifdef NDEBUG
-  CmdArgs.push_back("-disable-llvm-verifier");
-  // Discard LLVM value names in -asserts builds.
-  CmdArgs.push_back("-discard-value-names");
+  false;
+#else
+  true;
 #endif
+  // Disable the verification pass in -asserts builds.
+  if (!IsAssertBuild)
+CmdArgs.push_back("disable-llvm-verifier");
+
+  // Discard value names in assert builds unless otherwise specified.
+  if (const Arg *A = Args.getLastArg(options::OPT_fdiscard_value_names,
+ options::OPT_fno_discard_value_names)) {
+if (A->getOption().matches(options::OPT_fdiscard_value_names))
+  CmdArgs.push_back("-discard-value-names");
+  } else if (!IsAssertBuild)
+CmdArgs.push_back("-discard-value-names");
 
   // Set the main file name, so that debug info works even with
   // -save-temps.
Index: include/clang/Driver/Options.td
===
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -790,6 +790,10 @@
 HelpText<"Print a template comparison tree for differing templates">;
 def fdeclspec : Flag<["-"], "fdeclspec">, Group,
   HelpText<"Allow __declspec as a keyword">, Flags<[CC1Option]>;
+def fdiscard_value_names : Flag<["-"], "fdiscard-value-names">, 
Group,
+  HelpText<"Discard value names in LLVM IR">, Flags<[DriverOption]>;
+def fno_discard_value_names : Flag<["-"], "fno-discard-value-names">, 
Group,
+  HelpText<"Do not discard value names in LLVM IR">, Flags<[DriverOption]>;
 def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, 
Group,
   HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>;
 def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, 
Group;
Index: docs/UsersManual.rst
===
--- docs/UsersManual.rst
+++ docs/UsersManual.rst
@@ -1855,6 +1855,27 @@
   must come first.)
 
 
+Controlling LLVM IR Output
+---
+
+Controlling Values Names in LLVM IR
+
+
+Emitting value names in LLVM IR increases the size and verbosity of the IR.
+By default value names are only emitted in assertion enabled builds of Clang.
+However, when reading IR it can be useful to re-enable the emission of value
+names to improve readability.
+
+.. option:: -fdiscard-value-names
+
+  Discard value names when generating LLVM IR.
+
+.. option:: -fno-discard-value-names
+
+  Do not discard value names when generating LLVM IR. This option can be used
+  to re-enable names for release builds of Clang.
+
+
 Comment Parsing Options
 ---
 


Index: test/Driver/clang_f_opts.c
===
--- test/Driver/clang_f_opts.c
+++ test/Driver/clang_f_opts.c
@@ -517,3 +517,8 @@
 // RUN: %clang -### -S %s 2>&1 | FileCheck -check-prefix=CHECK-NO-CF-PROTECTION-BRANCH %s
 // CHECK-CF-PROTECTION-BRANCH: -fcf-protection=branch
 // CHECK-NO-CF-PROTECTION-BRANCH-NOT: -fcf-protection=branch
+
+// RUN: %clang -### -S -fdiscard-value-names %s 2>&1 | FileCheck -check-prefix=CHECK-DISCARD-NAMES %s
+// RUN: %clang -### -S -fno-discard-value-names %s 2>&1 | FileCheck -check-prefix=CHECK-NO-DISCARD-NAMES %s
+// CHECK-DISCARD-NAMES: "-discard-value-names"
+// CHECK-NO-DISCARD-NAMES-NOT: "-discard-value-names"
Index: lib/Driver/ToolChains/Clang.cpp
===
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -3266,12 +3266,23 @@
   if (!C.isForDiagnostics())
 

[PATCH] D42887: [Driver] Add option to manually control discarding value names in LLVM IR.

2018-02-03 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added inline comments.



Comment at: lib/Driver/ToolChains/Clang.cpp:3269
 
-// Disable the verification pass in -asserts builds.
+  const bool IsAssertBuild =
 #ifdef NDEBUG

This logic seems sidewards.
If `NDEBUG` is specified, then it is `assert()`-less build.
If `NDEBUG` is *not* specified, then `assert()`'s are actually functional.




Comment at: lib/Driver/ToolChains/Clang.cpp:3270
-// Disable the verification pass in -asserts builds.
+  const bool IsAssertBuild =
 #ifdef NDEBUG
-  CmdArgs.push_back("-disable-llvm-verifier");

`-assert` is `assert()`-less build


https://reviews.llvm.org/D42887



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


[PATCH] D42887: [Driver] Add option to manually control discarding value names in LLVM IR.

2018-02-03 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF created this revision.
EricWF added reviewers: erichkeane, aaron.ballman, lebedev.ri.

Currently, assertion-disabled Clang builds emit value names when generating 
LLVM IR. This is controlled by the `NDEBUG` macro, and is not easily 
overridable. In order to get IR output containing names from a release build of 
Clang, the user must manually construct the CC1 invocation w/o the 
`-discard-value-names` option. This is less than ideal.

For example, Godbolt uses a release build of Clang, and so when asked to emit 
LLVM IR the result lacks names, making it harder to read. Manually invoking CC1 
on Compiler Explorer is not feasible.

This patch adds the driver options `-fdiscard-value-names` and 
`-fno-discard-value-names` which allow the user to override the default 
behavior. If neither is specified, the old behavior remains.


https://reviews.llvm.org/D42887

Files:
  docs/UsersManual.rst
  include/clang/Driver/Options.td
  lib/Driver/ToolChains/Clang.cpp
  test/Driver/clang_f_opts.c


Index: test/Driver/clang_f_opts.c
===
--- test/Driver/clang_f_opts.c
+++ test/Driver/clang_f_opts.c
@@ -517,3 +517,8 @@
 // RUN: %clang -### -S %s 2>&1 | FileCheck 
-check-prefix=CHECK-NO-CF-PROTECTION-BRANCH %s
 // CHECK-CF-PROTECTION-BRANCH: -fcf-protection=branch
 // CHECK-NO-CF-PROTECTION-BRANCH-NOT: -fcf-protection=branch
+
+// RUN: %clang -### -S -fdiscard-value-names %s 2>&1 | FileCheck 
-check-prefix=CHECK-DISCARD-NAMES %s
+// RUN: %clang -### -S -fno-discard-value-names %s 2>&1 | FileCheck 
-check-prefix=CHECK-NO-DISCARD-NAMES %s
+// CHECK-DISCARD-NAMES: "-discard-value-names"
+// CHECK-NO-DISCARD-NAMES-NOT: "-discard-value-names"
Index: lib/Driver/ToolChains/Clang.cpp
===
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -3266,12 +3266,23 @@
   if (!C.isForDiagnostics())
 CmdArgs.push_back("-disable-free");
 
-// Disable the verification pass in -asserts builds.
+  const bool IsAssertBuild =
 #ifdef NDEBUG
-  CmdArgs.push_back("-disable-llvm-verifier");
-  // Discard LLVM value names in -asserts builds.
-  CmdArgs.push_back("-discard-value-names");
+  true;
+#else
+  false;
 #endif
+  // Disable the verification pass in -asserts builds.
+  if (IsAssertBuild)
+CmdArgs.push_back("disable-llvm-verifier");
+
+  // Discard value names in assert builds unless otherwise specified.
+  if (const Arg *A = Args.getLastArg(options::OPT_fdiscard_value_names,
+ options::OPT_fno_discard_value_names)) {
+if (A->getOption().matches(options::OPT_fdiscard_value_names))
+  CmdArgs.push_back("-discard-value-names");
+  } else if (IsAssertBuild)
+CmdArgs.push_back("-discard-value-names");
 
   // Set the main file name, so that debug info works even with
   // -save-temps.
Index: include/clang/Driver/Options.td
===
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -790,6 +790,10 @@
 HelpText<"Print a template comparison tree for differing templates">;
 def fdeclspec : Flag<["-"], "fdeclspec">, Group,
   HelpText<"Allow __declspec as a keyword">, Flags<[CC1Option]>;
+def fdiscard_value_names : Flag<["-"], "fdiscard-value-names">, 
Group,
+  HelpText<"Discard value names in LLVM IR">, Flags<[DriverOption]>;
+def fno_discard_value_names : Flag<["-"], "fno-discard-value-names">, 
Group,
+  HelpText<"Do not discard value names in LLVM IR">, Flags<[DriverOption]>;
 def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, 
Group,
   HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>;
 def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, 
Group;
Index: docs/UsersManual.rst
===
--- docs/UsersManual.rst
+++ docs/UsersManual.rst
@@ -1855,6 +1855,27 @@
   must come first.)
 
 
+Controlling LLVM IR Output
+---
+
+Controlling Values Names in LLVM IR
+
+
+Emitting value names in LLVM IR increases the size and verbosity of the IR.
+By default value names are only emitted in assertion enabled builds of Clang.
+However, when reading IR it can be useful to re-enable the emission of value
+names to improve readability.
+
+.. option:: -fdiscard-value-names
+
+  Discard value names when generating LLVM IR.
+
+.. option:: -fno-discard-value-names
+
+  Do not discard value names when generating LLVM IR. This option can be used
+  to re-enable names for release builds of Clang.
+
+
 Comment Parsing Options
 ---
 


Index: test/Driver/clang_f_opts.c
===
--- test/Driver/clang_f_opts.c
+++ test/Driver/clang_f_opts.c
@@ -517,3 +517,8 @@
 // RUN: %clang -### -S %s 2>&1 | FileCheck -check-prefix=CHECK-NO-CF-PROTECTION-BRANCH %s
 // 

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-02-03 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp:12
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);

Quuxplusone wrote:
> "test/Parser/cxx-concept-declaration.cpp" has some syntax tests for 
> "value-concepts" of the form `template concept...`. Would it make 
> sense to add some semantic tests for `template concept...` in or near 
> this test file?
> (This could plausibly be "out of scope." I merely mention it.)
Good idea, I'll add some of those.



Comment at: test/Parser/cxx-concept-declaration.cpp:36
+template concept C11 = sizeof(T); // expected-error {{atomic 
constraint 'sizeof(T)' must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+template concept C13 = (bool&&)true;

Quuxplusone wrote:
> Peanut gallery says: IIUC, C12 is satisfied whenever T has a constexpr 
> constructor and a constexpr implicit conversion to `bool` that returns 
> `true`?  Or (because this is an atomic constraint and atomic constraints 
> don't do conversions, as we can see on line 31 above) is C12 *actually* 
> never satisfiable (but there's no diagnostic expected here because `T{}` is 
> dependent)?
C12 will only accept bool, and there's no diagnostic because it's dependent is 
correct.


Repository:
  rC Clang

https://reviews.llvm.org/D41217



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


[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-02-03 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone added inline comments.



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:2404
+def err_concept_non_constant_constraint_expression : Error<
+  "concept specialization '%0' resulted in a non-constant expression '%1'.">;
+def err_non_bool_atomic_constraint : Error<

Extra period `.` here



Comment at: lib/Serialization/ASTReaderStmt.cpp:4053
+case EXPR_CONCEPT_SPECIALIZATION:
+  S = new (Context) ConceptSpecializationExpr(Context);
+  break;

Peanut gallery says: All the other cases look like
S = new (Context) FooExpr(Context, Empty);
or
S = new (Context) FooExpr::CreateEmpty(Context);
not
S = new (Context) FooExpr(Context);
Is the visual difference in this case significant?



Comment at: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp:12
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);

"test/Parser/cxx-concept-declaration.cpp" has some syntax tests for 
"value-concepts" of the form `template concept...`. Would it make sense 
to add some semantic tests for `template concept...` in or near this 
test file?
(This could plausibly be "out of scope." I merely mention it.)



Comment at: test/Parser/cxx-concept-declaration.cpp:36
+template concept C11 = sizeof(T); // expected-error {{atomic 
constraint 'sizeof(T)' must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+template concept C13 = (bool&&)true;

Peanut gallery says: IIUC, C12 is satisfied whenever T has a constexpr 
constructor and a constexpr implicit conversion to `bool` that returns `true`?  
Or (because this is an atomic constraint and atomic constraints don't do 
conversions, as we can see on line 31 above) is C12 *actually* never 
satisfiable (but there's no diagnostic expected here because `T{}` is 
dependent)?


Repository:
  rC Clang

https://reviews.llvm.org/D41217



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


[PATCH] D41284: [Concepts] Associated constraints infrastructure.

2018-02-03 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 132748.
saar.raz added a comment.

Moved function into SemaConcept.cpp.


Repository:
  rC Clang

https://reviews.llvm.org/D41284

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Sema/Sema.h
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace nodiag {
+
+struct B {
+template  requires bool(T())
+static int A;
+};
+
+template  requires bool(U())
+int B::A = int(U());
+
+} // end namespace nodiag
+
+namespace diag {
+
+struct B {
+template  requires bool(T()) // expected-note{{previous template declaration is here}}
+static int A;
+};
+
+template  requires !bool(U())  // expected-error{{associated constraints differ in template redeclaration}}
+int B::A = int(U());
+
+} // end namespace diag
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
===
--- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
@@ -1,65 +1,52 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
 
 namespace nodiag {
 
 template  requires bool(T())
-struct A;
+int A();
 template  requires bool(U())
-struct A;
+int A();
 
 } // end namespace nodiag
 
 namespace diag {
 
 template  requires true // expected-note{{previous template declaration is here}}
-struct A;
-template  struct A; // expected-error{{associated constraints differ in template redeclaration}}
+int A();
+template  int A(); // expected-error{{associated constraints differ in template redeclaration}}
 
-template  struct B; // expected-note{{previous template declaration is here}}
+template  int B(); // expected-note{{previous template declaration is here}}
 template  requires true // expected-error{{associated constraints differ in template redeclaration}}
-struct B;
+int B();
 
 template  requires true // expected-note{{previous template declaration is here}}
-struct C;
+int C();
 template  requires !0 // expected-error{{associated constraints differ in template redeclaration}}
-struct C;
+int C();
 
 } // end namespace diag
 
 namespace nodiag {
 
 struct AA {
   template  requires someFunc(T())
-  struct A;
+  int A();
 };
 
 template  requires someFunc(T())
-struct AA::A { };
-
-struct AAF {
-  template  requires someFunc(T())
-  friend struct AA::A;
-};
+int AA::A() { return sizeof(T); }
 
 } // end namespace nodiag
 
 namespace diag {
 
 template 
 struct TA {
-  template  class TT> requires TT::happy // expected-note 2{{previous template declaration is here}}
-  struct A;
-
-  struct AF;
+  template  class TT> requires TT::happy // expected-note{{previous template declaration is here}}
+  int A();
 };
 
 template 
-template  class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}}
-
-template 
-struct TA::AF {
-  template  class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}}
-  friend struct TA::A;
-};
+template  class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}}
 
 } // end namespace diag
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
===
--- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
 
 namespace nodiag {
 
@@ -33,7 +33,7 @@
   struct A;
 };
 
-template  requires someFunc(T())
+template  requires someFunc(U())
 struct AA::A { };
 
 struct AAF {
@@ -47,18 +47,26 @@
 
 template 
 struct TA {
-  template  class TT> requires TT::happy // expected-note 2{{previous template declaration is here}}
+  template  class TT> requires TT::happy // expected-note 

[PATCH] D41889: [libcxxabi][demangler] Clean up and llvm-ify the type parser

2018-02-03 Thread Erik Pilkington via Phabricator via cfe-commits
erik.pilkington updated this revision to Diff 132747.
erik.pilkington added a comment.

Rebase and remove the qualifier substitution bug fix.


https://reviews.llvm.org/D41889

Files:
  src/cxa_demangle.cpp

Index: src/cxa_demangle.cpp
===
--- src/cxa_demangle.cpp
+++ src/cxa_demangle.cpp
@@ -340,20 +340,17 @@
 
 class VendorExtQualType final : public Node {
   const Node *Ty;
-  const Node *Ext;
+  StringView Ext;
 
 public:
-  VendorExtQualType(Node *Ty_, Node *Ext_)
-  : Node(KVendorExtQualType,
- std::min(Ty_->ParameterPackSize, Ext_->ParameterPackSize)),
+  VendorExtQualType(Node *Ty_, StringView Ext_)
+  : Node(KVendorExtQualType, Ty_->ParameterPackSize),
 Ty(Ty_), Ext(Ext_) {}
 
-  const Node* getQual() const { return Ext; }
-
   void printLeft(OutputStream ) const override {
 Ty->print(S);
 S += " ";
-Ext->print(S);
+S += Ext;
   }
 };
 
@@ -465,12 +462,12 @@
 
 class ObjCProtoName : public Node {
   Node *Ty;
-  Node *Protocol;
+  StringView Protocol;
 
   friend class PointerType;
 
 public:
-  ObjCProtoName(Node *Ty_, Node *Protocol_)
+  ObjCProtoName(Node *Ty_, StringView Protocol_)
   : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
 
   bool isObjCObject() const {
@@ -481,7 +478,7 @@
   void printLeft(OutputStream ) const override {
 Ty->print(S);
 S += "<";
-Protocol->print(S);
+S += Protocol;
 S += ">";
   }
 };
@@ -512,7 +509,7 @@
 } else {
   const auto *objcProto = static_cast(Pointee);
   s += "id<";
-  objcProto->Protocol->print(s);
+  s += objcProto->Protocol;
   s += ">";
 }
   }
@@ -1958,6 +1955,8 @@
 
   StringView parseNumber(bool AllowNegative = false);
   Qualifiers parseCVQualifiers();
+  bool parsePositiveInteger(size_t *Out);
+  StringView parseBareSourceName();
 
   /// Parse the  production.
   Node *parseExpr();
@@ -1970,6 +1969,15 @@
   Node *parseNewExpr();
   Node *parseConversionExpr();
 
+  /// Parse the  production.
+  Node *parseType();
+  Node *parseFunctionType();
+  Node *parseVectorType();
+  Node *parseDecltype();
+  Node *parseArrayType();
+  Node *parsePointerToMemberType();
+  Node *parseClassEnumType();
+
   // FIXME: remove this when all the parse_* functions have been rewritten.
   template 
   Node *legacyParse() {
@@ -1983,6 +1991,18 @@
 Names.pop_back();
 return R;
   }
+  template 
+  Node *legacyParse() {
+size_t BeforeType = Names.size();
+const char *OrigFirst = First;
+const char *T = parse_fn(First, Last, *this, nullptr);
+if (T == OrigFirst || BeforeType + 1 != Names.size())
+  return nullptr;
+First = T;
+Node *R = Names.back();
+Names.pop_back();
+return R;
+  }
 };
 
 const char *parse_expression(const char *first, const char *last, Db ) {
@@ -2005,6 +2025,26 @@
   return db.First;
 }
 
+const char *parse_type(const char *first, const char *last, Db ) {
+  db.First = first;
+  db.Last = last;
+  Node *R = db.parseType();
+  if (R == nullptr)
+return first;
+  db.Names.push_back(R);
+  return db.First;
+}
+
+const char *parse_decltype(const char *first, const char *last, Db ) {
+  db.First = first;
+  db.Last = last;
+  Node *R = db.parseDecltype();
+  if (R == nullptr)
+return first;
+  db.Names.push_back(R);
+  return db.First;
+}
+
 const char *parse_type(const char *first, const char *last, Db );
 const char *parse_encoding(const char *first, const char *last, Db );
 const char *parse_name(const char *first, const char *last, Db ,
@@ -2015,6 +2055,7 @@
 const char *parse_unqualified_name(const char *first, const char *last, Db );
 const char *parse_decltype(const char *first, const char *last, Db );
 const char *parse_unresolved_name(const char *, const char *, Db &);
+const char *parse_substitution(const char *, const char *, Db &);
 
 //  ::= [n] 
 StringView Db::parseNumber(bool AllowNegative) {
@@ -2028,6 +2069,541 @@
   return StringView(Tmp, First);
 }
 
+//  ::= [0-9]*
+bool Db::parsePositiveInteger(size_t *Out) {
+  *Out = 0;
+  if (look() < '0' || look() > '9')
+return true;
+  while (look() >= '0' && look() <= '9') {
+*Out *= 10;
+*Out += static_cast(consume() - '0');
+  }
+  return false;
+}
+
+StringView Db::parseBareSourceName() {
+  size_t Int = 0;
+  if (parsePositiveInteger() || numLeft() < Int)
+return StringView();
+  StringView R(First, First + Int);
+  First += Int;
+  return R;
+}
+
+//  ::= F [Y]  [] E
+//
+//   ::= R   # & ref-qualifier
+//   ::= O   # && ref-qualifier
+Node *Db::parseFunctionType() {
+  if (!consumeIf('F'))
+return nullptr;
+  consumeIf('Y'); // extern "C"
+  Node *ReturnType = parseType();
+  if (ReturnType == nullptr)
+return nullptr;
+
+  FunctionRefQual ReferenceQualifier = FrefQualNone;
+  size_t ParamsBegin = Names.size();
+  while (true) {
+if (consumeIf('E'))
+  break;
+if (consumeIf('v'))
+  continue;
+  

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-02-03 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 132743.
saar.raz added a comment.
Herald added subscribers: hintonda, mgorny.

- Moved general concepts-related function into SemaConcept.cpp


Repository:
  rC Clang

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Parse/ParseExpr.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -231,6 +231,7 @@
   case Stmt::TypeTraitExprClass:
   case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ test/Parser/cxx-concept-declaration.cpp
@@ -9,8 +9,6 @@
 
 template concept D1 = true; // expected-error {{expected template parameter}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be 'bool'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -29,3 +27,12 @@
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
+
+template concept C7 = 2; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C8 = 2 && x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C9 = x || 2 || x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C10 = 8ull && x || x; // expected-error {{atomic constraint '8ULL' must be of type 'bool' (found 'unsigned long long')}}
+template concept C11 = sizeof(T); // expected-error {{atomic constraint 'sizeof(T)' must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+template concept C13 = (bool&&)true;
+template concept C14 = (const bool&)true;
Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
===
--- test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
+++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -1,5 +1,52 @@
 // RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
-// expected-no-diagnostics
 
-template concept C = true;
-static_assert(C);
+template concept C1 = true;
+static_assert(C1);
+
+template concept C2 = sizeof(T) == 4;
+static_assert(C2);
+static_assert(!C2);
+static_assert(C2);
+static_assert(!C2);
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);
+static_assert(!C3);
+
+struct A {
+static constexpr int add(int a, int b) {
+return a + b;
+}
+};
+struct B {
+static int add(int a, int b) {
+return a + b;
+}
+};
+template
+concept C4 = U::add(1, 2) == 3;
+static_assert(C4);
+static_assert(!C4); // expected-error {{concept specialization 'C4' resulted in a non-constant expression 'B::add(1, 2) == 3'}}
+
+template
+constexpr bool is_same_v = false;
+
+template
+constexpr bool is_same_v = true;
+
+template
+concept Same = is_same_v;
+
+static_assert(Same);
+static_assert(Same);
+static_assert(!Same);
+static_assert(!Same);
+static_assert(Same);
+
+static_assert(Same);
+static_assert(Same);
+static_assert(Same)>);
+static_assert(Same);
+
+template concept C5 = T{}; // expected-error {{atomic constraint 'int{}' must be of type 'bool' (found 'int')}}
+constexpr bool x = C5; // expected-note {{in concept specialization 'C5'}}
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1018,6 +1018,7 @@
 case 

[PATCH] D40787: [clang-tidy] Replace the usage of std::uncaught_exception with std::uncaught_exceptions

2018-02-03 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

This LGTM with a few minor nits to fix.




Comment at: clang-tidy/modernize/ModernizeTidyModule.cpp:80-81
 CheckFactories.registerCheck("modernize-use-override");
+CheckFactories.registerCheck(
+"modernize-use-uncaught-exceptions");
 CheckFactories.registerCheck(

Please keep this list alphabetized.



Comment at: docs/clang-tidy/checks/modernize-use-uncaught-exceptions.rst:19
+int uncaught_exception() {
+return 0;
+}

The indentation of the code examples (here and below) is incorrect.


https://reviews.llvm.org/D40787



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


r324173 - Recommit rL323952: [DebugInfo] Enable debug information for C99 VLA types.

2018-02-03 Thread Sander de Smalen via cfe-commits
Author: s.desmalen
Date: Sat Feb  3 05:55:59 2018
New Revision: 324173

URL: http://llvm.org/viewvc/llvm-project?rev=324173=rev
Log:
Recommit rL323952: [DebugInfo] Enable debug information for C99 VLA types.

Fixed build issue when building with g++-4.8 (specialization after 
instantiation).


Modified:
cfe/trunk/lib/CodeGen/CGBlocks.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.h
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/test/CodeGen/debug-info-vla.c
cfe/trunk/test/CodeGenCXX/debug-info-vla.cpp
cfe/trunk/test/CodeGenCXX/vla-consruct.cpp
cfe/trunk/test/CodeGenObjC/arc.m
cfe/trunk/test/OpenMP/target_codegen.cpp
cfe/trunk/test/OpenMP/target_parallel_codegen.cpp
cfe/trunk/test/OpenMP/target_parallel_for_codegen.cpp
cfe/trunk/test/OpenMP/target_parallel_for_simd_codegen.cpp
cfe/trunk/test/OpenMP/target_simd_codegen.cpp
cfe/trunk/test/OpenMP/target_teams_codegen.cpp
cfe/trunk/test/OpenMP/target_teams_distribute_codegen.cpp
cfe/trunk/test/OpenMP/target_teams_distribute_simd_codegen.cpp

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=324173=324172=324173=diff
==
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Sat Feb  3 05:55:59 2018
@@ -1479,8 +1479,8 @@ CodeGenFunction::GenerateBlockFunction(G
 const CGBlockInfo::Capture  = blockInfo.getCapture(variable);
 if (capture.isConstant()) {
   auto addr = LocalDeclMap.find(variable)->second;
-  DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(),
-Builder);
+  (void)DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(),
+  Builder);
   continue;
 }
 

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=324173=324172=324173=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Sat Feb  3 05:55:59 2018
@@ -2292,12 +2292,14 @@ llvm::DIType *CGDebugInfo::CreateType(co
   llvm::DIFile *Unit) {
   llvm::DIType *ElementTy = getOrCreateType(Ty->getElementType(), Unit);
   int64_t Count = Ty->getNumElements();
-  if (Count == 0)
-// If number of elements are not known then this is an unbounded array.
-// Use Count == -1 to express such arrays.
-Count = -1;
 
-  llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(0, Count);
+  llvm::Metadata *Subscript;
+  QualType QTy(Ty, 0);
+  auto SizeExpr = SizeExprCache.find(QTy);
+  if (SizeExpr != SizeExprCache.end())
+Subscript = DBuilder.getOrCreateSubrange(0, SizeExpr->getSecond());
+  else
+Subscript = DBuilder.getOrCreateSubrange(0, Count ? Count : -1);
   llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
 
   uint64_t Size = CGM.getContext().getTypeSize(Ty);
@@ -2354,8 +2356,12 @@ llvm::DIType *CGDebugInfo::CreateType(co
   }
 }
 
-// FIXME: Verify this is right for VLAs.
-Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count));
+auto SizeNode = SizeExprCache.find(EltTy);
+if (SizeNode != SizeExprCache.end())
+  Subscripts.push_back(
+  DBuilder.getOrCreateSubrange(0, SizeNode->getSecond()));
+else
+  Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count));
 EltTy = Ty->getElementType();
   }
 
@@ -3473,13 +3479,14 @@ llvm::DIType *CGDebugInfo::EmitTypeForVa
nullptr, Elements);
 }
 
-void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage,
-  llvm::Optional ArgNo,
-  CGBuilderTy ) {
+llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
+llvm::Value *Storage,
+llvm::Optional ArgNo,
+CGBuilderTy ) {
   assert(DebugKind >= codegenoptions::LimitedDebugInfo);
   assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
   if (VD->hasAttr())
-return;
+return nullptr;
 
   bool Unwritten =
   VD->isImplicit() || (isa(VD->getDeclContext()) &&
@@ -3497,7 +3504,7 @@ void CGDebugInfo::EmitDeclare(const VarD
   // If there is no debug info for this type then do not emit debug 

[PATCH] D42745: [analyzer] Add support for __builtin_constant_p to BuiltinFunctionChecker

2018-02-03 Thread Felix Kostenzer via Phabricator via cfe-commits
sp4r74n-117 updated this revision to Diff 132738.
sp4r74n-117 added a comment.

Thanks for the feedback.
I've added two additional tests to 'test_constant_p' for the case where an 
expression evaluating to a constant 0 is passed to the builtin.
The existing tests have been refactored to check explicitly for 0 or 1 instead 
of relying on the implicit boolean conversion.


https://reviews.llvm.org/D42745

Files:
  lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
  test/Analysis/builtin-functions.cpp


Index: test/Analysis/builtin-functions.cpp
===
--- test/Analysis/builtin-functions.cpp
+++ test/Analysis/builtin-functions.cpp
@@ -64,3 +64,20 @@
 // We give up the analysis on this path.
   }
 }
+
+void test_constant_p() {
+  int i = 1;
+  const int j = 2;
+  constexpr int k = 3;
+  clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // 
expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning 
{{FALSE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning 
{{TRUE}}
+}
Index: lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -113,6 +113,24 @@
 C.addTransition(state->BindExpr(CE, LCtx, V));
 return true;
   }
+
+  case Builtin::BI__builtin_constant_p: {
+SVal V;
+SValBuilder& SVB = C.getSValBuilder();
+
+llvm::APSInt Result;
+// Model semantics as 'A return of 0 does not indicate that the value is
+// not a constant, but merely that GCC cannot prove it is a constant [...]'
+if (CE->EvaluateAsInt(Result, C.getASTContext(), Expr::SE_NoSideEffects)) {
+  SVB.getBasicValueFactory().getAPSIntType(CE->getType()).apply(Result);
+  V = SVB.makeIntVal(Result);
+}
+else
+  V = SVB.makeZeroVal(CE->getType());
+
+C.addTransition(state->BindExpr(CE, LCtx, V));
+return true;
+  }
   }
 }
 


Index: test/Analysis/builtin-functions.cpp
===
--- test/Analysis/builtin-functions.cpp
+++ test/Analysis/builtin-functions.cpp
@@ -64,3 +64,20 @@
 // We give up the analysis on this path.
   }
 }
+
+void test_constant_p() {
+  int i = 1;
+  const int j = 2;
+  constexpr int k = 3;
+  clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning {{FALSE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning {{TRUE}}
+}
Index: lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -113,6 +113,24 @@
 C.addTransition(state->BindExpr(CE, LCtx, V));
 return true;
   }
+
+  case Builtin::BI__builtin_constant_p: {
+SVal V;
+SValBuilder& SVB = C.getSValBuilder();
+
+llvm::APSInt Result;
+// Model semantics as 'A return of 0 does not indicate that the value is
+// not a constant, but merely that GCC cannot prove it is a constant [...]'
+if (CE->EvaluateAsInt(Result, C.getASTContext(), Expr::SE_NoSideEffects)) {
+  SVB.getBasicValueFactory().getAPSIntType(CE->getType()).apply(Result);
+  V = 

r324170 - [RISCV] Create a LinuxTargetInfo when targeting Linux

2018-02-03 Thread Alex Bradbury via cfe-commits
Author: asb
Date: Sat Feb  3 03:56:11 2018
New Revision: 324170

URL: http://llvm.org/viewvc/llvm-project?rev=324170=rev
Log:
[RISCV] Create a LinuxTargetInfo when targeting Linux

Previously, RISCV32TargetInfo or RISCV64TargetInfo were created 
unconditionally. Use LinuxTargetInfo to ensure that the 
proper OS-specific defines are present.

This patch only adds logic to instantiate LinuxTargetInfo and leaves a TODO, 
as I'm reluctant to add logic for other targets (e.g. FreeBSD, RTEMS) until 
I've produced and tested at least one binary for that OS+target combo.

Thanks to @mgrang to reporting the issue.

Modified:
cfe/trunk/lib/Basic/Targets.cpp
cfe/trunk/test/Preprocessor/init.c

Modified: cfe/trunk/lib/Basic/Targets.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=324170=324169=324170=diff
==
--- cfe/trunk/lib/Basic/Targets.cpp (original)
+++ cfe/trunk/lib/Basic/Targets.cpp Sat Feb  3 03:56:11 2018
@@ -372,8 +372,14 @@ TargetInfo *AllocateTarget(const llvm::T
 return new AMDGPUTargetInfo(Triple, Opts);
 
   case llvm::Triple::riscv32:
+// TODO: add cases for FreeBSD, NetBSD, RTEMS once tested.
+if (os == llvm::Triple::Linux)
+  return new LinuxTargetInfo(Triple, Opts);
 return new RISCV32TargetInfo(Triple, Opts);
   case llvm::Triple::riscv64:
+// TODO: add cases for FreeBSD, NetBSD, RTEMS once tested.
+if (os == llvm::Triple::Linux)
+  return new LinuxTargetInfo(Triple, Opts);
 return new RISCV64TargetInfo(Triple, Opts);
 
   case llvm::Triple::sparc:

Modified: cfe/trunk/test/Preprocessor/init.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/init.c?rev=324170=324169=324170=diff
==
--- cfe/trunk/test/Preprocessor/init.c (original)
+++ cfe/trunk/test/Preprocessor/init.c Sat Feb  3 03:56:11 2018
@@ -10005,6 +10005,8 @@
 
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=riscv32 < /dev/null \
 // RUN:   | FileCheck -match-full-lines -check-prefix=RISCV32 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=riscv32-unknown-linux < 
/dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefixes=RISCV32,RISCV32-LINUX 
%s
 // RISCV32: #define _ILP32 1
 // RISCV32: #define __ATOMIC_ACQUIRE 2
 // RISCV32: #define __ATOMIC_ACQ_REL 4
@@ -10196,13 +10198,22 @@
 // RISCV32: #define __WINT_TYPE__ unsigned int
 // RISCV32: #define __WINT_UNSIGNED__ 1
 // RISCV32: #define __WINT_WIDTH__ 32
+// RISCV32-LINUX: #define __gnu_linux__ 1
+// RISCV32-LINUX: #define __linux 1
+// RISCV32-LINUX: #define __linux__ 1
 // RISCV32: #define __riscv 1
 // RISCV32: #define __riscv_cmodel_medlow 1
 // RISCV32: #define __riscv_float_abi_soft 1
 // RISCV32: #define __riscv_xlen 32
+// RISCV32-LINUX: #define __unix 1
+// RISCV32-LINUX: #define __unix__ 1
+// RISCV32-LINUX: #define linux 1
+// RISCV32-LINUX: #define unix 1
 
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=riscv64 < /dev/null \
 // RUN:   | FileCheck -match-full-lines -check-prefix=RISCV64 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=riscv64-unknown-linux < 
/dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefixes=RISCV64,RISCV64-LINUX 
%s
 // RISCV64: #define _LP64 1
 // RISCV64: #define __ATOMIC_ACQUIRE 2
 // RISCV64: #define __ATOMIC_ACQ_REL 4
@@ -10394,7 +10405,14 @@
 // RISCV64: #define __WINT_TYPE__ unsigned int
 // RISCV64: #define __WINT_UNSIGNED__ 1
 // RISCV64: #define __WINT_WIDTH__ 32
+// RISCV64-LINUX: #define __gnu_linux__ 1
+// RISCV64-LINUX: #define __linux 1
+// RISCV64-LINUX: #define __linux__ 1
 // RISCV64: #define __riscv 1
 // RISCV64: #define __riscv_cmodel_medlow 1
 // RISCV64: #define __riscv_float_abi_soft 1
 // RISCV64: #define __riscv_xlen 64
+// RISCV64-LINUX: #define __unix 1
+// RISCV64-LINUX: #define __unix__ 1
+// RISCV64-LINUX: #define linux 1
+// RISCV64-LINUX: #define unix 1


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


[PATCH] D41655: [clang-tidy] New check bugprone-unused-return-value

2018-02-03 Thread Kalle Huttunen via Phabricator via cfe-commits
khuttun added a comment.

> From what I can tell of these reports, they almost all boil down to ignoring 
> the call to `release()` because the pointer is no longer owned by the 
> `unique_ptr`. This is a pretty reasonable code pattern, but it also seems 
> reasonable to expect users to cast the result to `void` to silence the 
> warning, so I think this is fine. Have you checked any other large C++ code 
> bases, like Qt or boost?

Yep, there's already code also in LLVM where the release() return value is cast 
to void, for example in lib/Bitcode/Reader/BitReader.cpp. I haven't run the 
checker on other large code bases yet, but I can test also that.




Comment at: clang-tidy/bugprone/UnusedReturnValueCheck.cpp:45-48
+"^::std::async$|"
+"^::std::launder$|"
+"^::std::remove$|"
+"^::std::remove_if$|"

alexfh wrote:
> alexfh wrote:
> > I strongly suspect that we could get away without regexs here. hasAnyName 
> > supports inline namespaces, so at least the first five entries here are 
> > covered. The main problem with std::unique_ptr<.*>::release is the need to 
> > match any template parameters. I *think*, we could adjust hasName to allow 
> > omitting template parameters (so that `std::unique_ptr::release` would 
> > match specializations of unique_ptr as well). The `empty` and `allocate` 
> > would need some research. Can we just list all specific classes where we 
> > care about `empty`? (Alternatively, can we match `empty` unqualified and 
> > check that it's somewhere inside `std`, but I don't like that much, since 
> > it would add inconsistency in how this check is configured.)
> A clarification: we could go with your current version and optimize this part 
> later. But the option may start being used by someone and then will change - 
> that would be nice to avoid.
> 
> Alternatively, we could switch to hasAnyName right away and leave only the 
> functions that can be easily supported, and then figure out what to do with 
> `release`, `allocate` and `empty`.
> 
> I'd probably prefer the latter.
If the ultimate goal would be to have this checker working without regexes, 
then I agree that we shouldn't introduce a version that uses them in the config 
string, as changing that later would break things.

About creating a version of hasName that ignores template arguments: as I 
understand it we'd need a new PrintingPolicy to suppress printing the template 
argument list in NamedDecl::printQualifiedName. Is this correct?

WG21 P0600R1 lists 8 allocate() and 24 empty() functions in std that should be 
marked with [[nodiscard]]. We could list all of them separately in the checker 
config, but the config string would get quite long. Regex matching handles 
these nicely, but if the performance is unacceptable, we have to look for other 
ways or just skip checking these.


https://reviews.llvm.org/D41655



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