Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion clang/cmake/caches/release_cpack_pre_build_strip_lto.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
file(GLOB files ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/lib/*.a)

if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(strip_command
${CPACK_TEMPORARY_INSTALL_DIRECTORY}/bin/llvm-bitcode-strip)
set(strip_args -r)
else()
set(strip_command ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/bin/llvm-strip)
set(strip_args --no-strip-all -R .llvm.lto)
endif()

foreach(file ${files})
execute_process(COMMAND ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/bin/llvm-strip --no-strip-all -R .llvm.lto ${file})
execute_process(COMMAND ${strip_command} ${strip_args} ${file} -o ${file})
endforeach()
14 changes: 14 additions & 0 deletions clang/lib/Sema/SemaConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,10 @@ class HashParameterMapping : public RecursiveASTVisitor<HashParameterMapping> {
return true;
}

bool TraverseCXXThisExpr(CXXThisExpr *E) {
return inherited::TraverseType(E->getType());
}

bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true) {
// We don't care about TypeLocs. So traverse Types instead.
return TraverseType(TL.getType().getCanonicalType(), TraverseQualifier);
Expand All @@ -394,6 +398,16 @@ class HashParameterMapping : public RecursiveASTVisitor<HashParameterMapping> {
return true;
}

bool TraverseUnresolvedUsingType(UnresolvedUsingType *T,
bool TraverseQualifier) {
// Sometimes the written type doesn't contain a qualifier which contains
// necessary template arguments, whereas the declaration does.
if (NestedNameSpecifier NNS = T->getDecl()->getQualifier();
TraverseQualifier && NNS)
return inherited::TraverseNestedNameSpecifier(NNS);
return inherited::TraverseUnresolvedUsingType(T, TraverseQualifier);
}

bool TraverseInjectedClassNameType(InjectedClassNameType *T,
bool TraverseQualifier) {
return TraverseTemplateArguments(T->getTemplateArgs(SemaRef.Context));
Expand Down
98 changes: 98 additions & 0 deletions clang/test/SemaTemplate/concepts-using-decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,101 @@ struct child : base<int> {
};

}

namespace GH198663 {

template <class T>
concept HasIsTransparent = requires { typename T::is_transparent; };

template <class K, class V, class Compare>
struct FlatMapBase {
using key_compare = Compare;
};

template <class K, class V, class Compare>
struct FlatMap : FlatMapBase<K, V, Compare> {
using Base = FlatMapBase<K, V, Compare>;

using typename Base::key_compare;

void at(const K&) {}
void at(const K&) const {}
template <class Other>
void at(const Other&)
requires HasIsTransparent<key_compare>
{}
template <class Other>
void at(const Other&) const
requires HasIsTransparent<key_compare>
{}
};

template <class T>
struct Transparent {
T t;
};

struct TransparentComparator {
using is_transparent = void;

template <class T>
bool operator()(const T&, const Transparent<T>&) const;

template <class T>
bool operator()(const Transparent<T>&, const T& t) const;

template <class T>
bool operator()(const T&, const T&) const;
};

struct NonTransparentComparator {
template <class T>
bool operator()(const T&, const Transparent<T>&) const;

template <class T>
bool operator()(const Transparent<T>&, const T&) const;

template <class T>
bool operator()(const T&, const T&) const;
};

template <class M>
concept CanAt = requires(M m, Transparent<int> k) { m.at(k); };

using TransparentMap = FlatMap<int, double, TransparentComparator>;
using NonTransparentMap = FlatMap<int, double, NonTransparentComparator>;

static_assert(CanAt<TransparentMap>);

static_assert(!CanAt<NonTransparentMap>);

}

namespace GH198663_2 {

template<typename T>
auto mv(T& t) -> T&&;

template<typename S, typename T>
concept does_foo = requires(S s) {
s.template foo<T>();
};

template<typename S>
struct type {
S member;
template<typename T>
auto foo() -> T requires does_foo<decltype(mv(member)), T>;
};

struct returns_int {
template<typename T>
auto foo() -> T;
};

struct nothing {};

static_assert(does_foo<type<returns_int>&, int>);
static_assert(not does_foo<type<nothing>&, int>);

}
2 changes: 1 addition & 1 deletion cmake/Modules/LLVMVersion.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ if(NOT DEFINED LLVM_VERSION_MINOR)
set(LLVM_VERSION_MINOR 1)
endif()
if(NOT DEFINED LLVM_VERSION_PATCH)
set(LLVM_VERSION_PATCH 7)
set(LLVM_VERSION_PATCH 8)
endif()
if(NOT DEFINED LLVM_VERSION_SUFFIX)
set(LLVM_VERSION_SUFFIX)
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is
// defined to XXYYZZ.
# define _LIBCPP_VERSION 220107
# define _LIBCPP_VERSION 220108

# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
Expand Down
26 changes: 15 additions & 11 deletions libcxx/include/optional
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,10 @@ private:
template <class _Up>
constexpr static bool __libcpp_opt_ref_ctor_deleted =
is_lvalue_reference_v<_Tp> && reference_constructs_from_temporary_v<_Tp, _Up>;

template <class _Up>
constexpr static bool __ref_ctor_enabled =
is_lvalue_reference_v<_Tp> && !reference_constructs_from_temporary_v<_Tp, _Up>;
# endif

// LWG2756: conditionally explicit conversion from _Up
Expand Down Expand Up @@ -935,15 +939,15 @@ public:
template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v)
# if _LIBCPP_STD_VER >= 26
noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up&>)
noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, const _Up&>)
# endif
{
this->__construct_from(__v);
}
template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v)
# if _LIBCPP_STD_VER >= 26
noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up&>)
noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, const _Up&>)
# endif
{
this->__construct_from(__v);
Expand Down Expand Up @@ -981,25 +985,25 @@ public:

// optional(optional<U>& rhs)
template <class _Up>
requires(!__libcpp_opt_ref_ctor_deleted<_Up>) && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
(!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up&>
requires __ref_ctor_enabled<_Up&> && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) && (!is_same_v<_Tp&, _Up>) &&
is_constructible_v<_Tp&, _Up&>
_LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up&, _Tp&>)
optional(optional<_Up>& __rhs) noexcept(is_nothrow_constructible_v<_Tp&, _Up&>) {
this->__construct_from(__rhs);
}

template <class _Up>
requires __libcpp_opt_ref_ctor_deleted<_Up> && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
requires __libcpp_opt_ref_ctor_deleted<_Up&> && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
(!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up&>
constexpr explicit optional(optional<_Up>& __rhs) noexcept = delete;

// optional(const optional<U>&)
template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0>
requires __libcpp_opt_ref_ctor_deleted<_Up>
requires __libcpp_opt_ref_ctor_deleted<const _Up&>
optional(const optional<_Up>&) = delete;

template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0>
requires __libcpp_opt_ref_ctor_deleted<_Up>
requires __libcpp_opt_ref_ctor_deleted<const _Up&>
explicit optional(const optional<_Up>&) = delete;

// optional(optional<U>&&)
Expand All @@ -1013,16 +1017,16 @@ public:

// optional(const optional<U>&&)
template <class _Up>
requires(!__libcpp_opt_ref_ctor_deleted<_Up>) && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
(!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up>
requires __ref_ctor_enabled<const _Up> && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
(!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, const _Up>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(!is_convertible_v<const _Up, _Tp&>)
optional(const optional<_Up>&& __v) noexcept(is_nothrow_constructible_v<_Tp&, const _Up>) {
this->__construct_from(std::move(__v));
}

template <class _Up>
requires __libcpp_opt_ref_ctor_deleted<_Up> && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
(!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up>
requires __libcpp_opt_ref_ctor_deleted<const _Up> && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
(!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, const _Up>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>&& __v) noexcept = delete;
# endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,37 @@ constexpr bool test_ref() {
assert(*o2 == 1);
}

{
const std::optional<int> o1{2};
std::optional<const int&> o2(o1);
assert(*o2 == 2);
assert(&(*o2) == &(*o1));
}

{
const std::optional<ReferenceConversion<int>> o1({1, 2});
std::optional<const int&> o2(o1);
assert(o2.has_value());
assert(&(*o2) == &o1->lvalue);
assert(*o2 == 1);
}

{
const std::optional<ReferenceConversion<int>> o1({1, 2});
std::optional<const int&> o2(std::move(o1));
assert(o2.has_value());
assert(&(*o2) == &o1->rvalue);
assert(*o2 == 2);
}

{
const std::optional<ReferenceConversionThrows<int>> o1({1, 2});
ASSERT_NOT_NOEXCEPT(std::optional<const int&>(o1));
ASSERT_NOT_NOEXCEPT(std::optional<const int&>(std::move(o1)));
}

static_assert(!std::is_constructible_v<std::optional<int>, const std::optional<ConstRValueOnly<int>>&&>);

return true;
}
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,36 @@ constexpr bool test_ref() {
assert(*o2 == 1);
}

{
std::optional<int> o1(1);
std::optional<const int&> o2(o1);
assert(o2.has_value());
assert(*o2 == 1);
assert(&(*o2) == &(*o1));
}

{
std::optional<ReferenceConversion<int>> o1({1, 2});
std::optional<const int&> o2(o1);
assert(o2.has_value());
assert(*o2 == 1);
assert(&(*o2) == &o1->lvalue);
}

{
std::optional<ReferenceConversion<int>> o1({1, 2});
std::optional<const int&> o2(std::move(o1));
assert(o2.has_value());
assert(*o2 == 2);
assert(&(*o2) == &o1->rvalue);
}

{
std::optional<ReferenceConversionThrows<int>> o1({1, 2});
ASSERT_NOT_NOEXCEPT(std::optional<const int&>(o1));
ASSERT_NOT_NOEXCEPT(std::optional<const int&>(std::move(o1)));
}

return true;
}
#endif
Expand All @@ -164,6 +194,11 @@ int main(int, char**) {
test<Z>(std::move(rhs), true);
}

#if TEST_STD_VER >= 26
// GH: #194415
static_assert(!std::is_constructible_v<std::optional<int>, std::optional<LValueOnly<int>>&>);
#endif

static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), "");

#if TEST_STD_VER >= 26
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,10 @@ void test() {
const std::optional<int> co(1);
std::optional<int> o0(1);

// expected-error-re@*:* 10 {{call to deleted constructor of 'std::optional<{{.*}}>'}}
// expected-error-re@*:* 8 {{call to deleted constructor of 'std::optional<{{.*}}>'}}
std::optional<const int&> o1{1}; // optional(U&&)
std::optional<const int&> o2{o0}; // optional(optional<U>&)
std::optional<const int&> o3{co}; // optional(const optional<U>&)
std::optional<const int&> o4{std::move(o0)}; // optional(optional<U>&&&)
std::optional<const int&> o5{std::move(co)}; // optional(optional<U>&&&)
std::optional<const int&> o4{std::move(o0)}; // optional(optional<U>&&)
std::optional<const int&> o5{std::move(co)}; // optional(optional<U>&&)

std::optional<const X&> o6{1}; // optional(U&&)
std::optional<const X&> o7{o0}; // optional(optional<U>&)
Expand Down
Loading
Loading