Files
clang-p2996/clang/test/Modules/pr62943.cppm
Chuanqi Xu 72ac907158 [C++20] [Modules] Use the canonical decl when getting associated constraints
Close https://github.com/llvm/llvm-project/issues/62943.

The root cause for the issue is that we think the associated constraints
from the 'same' declaration in different module units are different
incorrectly. Since the constraints doesn't know anything about decls and
modules, we should fix the problem by getting the associated constraints
from the exactly the same declarations from different modules.
2023-06-21 17:00:56 +08:00

100 lines
2.2 KiB
C++

// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm
// RUN: %clang_cc1 -std=c++20 %t/b.cppm -emit-module-interface -o %t/b.pcm
// RUN: %clang_cc1 -std=c++20 %t/c.cppm -emit-module-interface \
// RUN: -fprebuilt-module-path=%t -o %t/c.pcm
// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fprebuilt-module-path=%t \
// RUN: -fsyntax-only -verify
//--- foo.h
#ifndef FOO_H
#define FOO_H
template<class _Tp>
concept __has_member_value_type = requires { typename _Tp::value_type; };
template<class _Tp>
concept __has_member_element_type = requires { typename _Tp::element_type; };
template <class _Tp>
inline constexpr bool is_object_v = __is_object(_Tp);
template<class> struct __cond_value_type {};
template<class _Tp>
requires is_object_v<_Tp>
struct __cond_value_type<_Tp> { using value_type = bool; };
template<class> struct indirectly_readable_traits {
static constexpr int value = false;
};
#endif
//--- foo.member_value_type.h
#include "foo.h"
template<__has_member_value_type _Tp>
struct indirectly_readable_traits<_Tp> : __cond_value_type<typename _Tp::value_type> {
static constexpr int value = false;
};
//--- foo.memeber_element_type.h
#include "foo.h"
template<__has_member_element_type _Tp>
struct indirectly_readable_traits<_Tp> : __cond_value_type<typename _Tp::element_type> {
static constexpr int value = false;
};
template<__has_member_value_type _Tp>
requires __has_member_element_type<_Tp>
struct indirectly_readable_traits<_Tp> {
static constexpr int value = true;
};
//--- foo.a.h
#include "foo.h"
#include "foo.member_value_type.h"
#include "foo.memeber_element_type.h"
template <typename T>
using AType = indirectly_readable_traits<T>;
//--- a.cppm
module;
#include "foo.a.h"
export module a;
export using ::AType;
//--- b.cppm
module;
#include "foo.h"
#include "foo.memeber_element_type.h"
export module b;
//--- c.cppm
export module c;
export import a;
export import b;
//--- use.cpp
// expected-no-diagnostics
import c;
template <typename T>
class U {
public:
using value_type = T;
using element_type = T;
};
template <typename T>
class V {
public:
};
static_assert(!AType<V<int*>>::value);
static_assert(AType<U<int**>>::value);