diff --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp index d5d9687cc90f..3b1fbda414c1 100644 --- a/clang/test/SemaTemplate/default-arguments.cpp +++ b/clang/test/SemaTemplate/default-arguments.cpp @@ -229,3 +229,55 @@ namespace unevaluated { template int f(int = a); // expected-warning 0-1{{extension}} int k = sizeof(f()); } + +#if __cplusplus >= 201103L +namespace GH68490 { + +template struct S { + template + constexpr int SizeOfU(int param = sizeof(U)) const; + + template + constexpr int SizeOfT(int param = sizeof(T)) const; +}; + +template struct S { + template + constexpr int SizeOfU(int param = sizeof(U)) const; + + template + constexpr int SizeOfT(int param = sizeof(T *)) const; +}; + +template +template +constexpr int S::SizeOfU(int param) const { + return param; +} + +template +template +constexpr int S::SizeOfT(int param) const { + return param; +} + +template <> +template +constexpr int S::SizeOfU(int param) const { + return param; +} + +template <> +template +constexpr int S::SizeOfT(int param) const { + return param; +} + +static_assert(S().SizeOfU() == sizeof(char), ""); +static_assert(S().SizeOfT() == sizeof(int), ""); +static_assert(S().SizeOfU() == sizeof(char), ""); +static_assert(S().SizeOfT() == sizeof(short *), ""); + +} // namespace GH68490 + +#endif diff --git a/clang/test/SemaTemplate/default-parm-init.cpp b/clang/test/SemaTemplate/default-parm-init.cpp deleted file mode 100644 index 73ba8998df6a..000000000000 --- a/clang/test/SemaTemplate/default-parm-init.cpp +++ /dev/null @@ -1,190 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s -// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s -// expected-no-diagnostics - -namespace std { - -template class function; - -template class invoker_base { -public: - virtual ~invoker_base() { } - virtual R invoke(Args...) = 0; - virtual invoker_base* clone() = 0; -}; - -template -class functor_invoker : public invoker_base { -public: - explicit functor_invoker(const F& f) : f(f) { } - R invoke(Args... args) { return f(args...); } - functor_invoker* clone() { return new functor_invoker(f); } - -private: - F f; -}; - -template -class function { -public: - typedef R result_type; - function() : invoker (0) { } - function(const function& other) : invoker(0) { - if (other.invoker) - invoker = other.invoker->clone(); - } - - template function(const F& f) : invoker(0) { - invoker = new functor_invoker(f); - } - - ~function() { - if (invoker) - delete invoker; - } - - function& operator=(const function& other) { - function(other).swap(*this); - return *this; - } - - template - function& operator=(const F& f) { - function(f).swap(*this); - return *this; - } - - void swap(function& other) { - invoker_base* tmp = invoker; - invoker = other.invoker; - other.invoker = tmp; - } - - result_type operator()(Args... args) const { - return invoker->invoke(args...); - } - -private: - invoker_base* invoker; -}; - -} - -template -struct Problem { - template - constexpr int FuncAlign(int param = alignof(FunctionTemplateParam)); - - template - constexpr int FuncSizeof(int param = sizeof(FunctionTemplateParam)); - - template - constexpr int FuncAlign2(int param = alignof(TemplateParam)); - - template - constexpr int FuncSizeof2(int param = sizeof(TemplateParam)); -}; - -template -struct Problem { - template - constexpr int FuncAlign(int param = alignof(FunctionTemplateParam)); - - template - constexpr int FuncSizeof(int param = sizeof(FunctionTemplateParam)); - - template - constexpr int FuncAlign2(int param = alignof(TemplateParam)); - - template - constexpr int FuncSizeof2(int param = sizeof(TemplateParam)); -}; - -template -template -constexpr int Problem::FuncAlign(int param) { - return 2U*param; -} - -template -template -constexpr int Problem::FuncSizeof(int param) { - return 2U*param; -} - -template -template -constexpr int Problem::FuncAlign2(int param) { - return 2U*param; -} - -template -template -constexpr int Problem::FuncSizeof2(int param) { - return 2U*param; -} - -template <> -template -constexpr int Problem::FuncAlign(int param) { - return param; -} - -template <> -template -constexpr int Problem::FuncSizeof(int param) { - return param; -} - -template <> -template -constexpr int Problem::FuncAlign2(int param) { - return param; -} - -template <> -template -constexpr int Problem::FuncSizeof2(int param) { - return param; -} - -void foo() { - Problem p = {}; - static_assert(p.FuncAlign() == alignof(char)); - static_assert(p.FuncSizeof() == sizeof(char)); - static_assert(p.FuncAlign2() == alignof(int)); - static_assert(p.FuncSizeof2() == sizeof(int)); - Problem q = {}; - static_assert(q.FuncAlign() == 2U * alignof(char)); - static_assert(q.FuncSizeof() == 2U * sizeof(char)); - static_assert(q.FuncAlign2() == 2U *alignof(short)); - static_assert(q.FuncSizeof2() == 2U * sizeof(short)); -} - -template -class A { - public: - void run( - std::function f1 = [](auto&&) {}, - std::function f2 = [](auto&&) {}); - private: - class Helper { - public: - explicit Helper(std::function f2) : f2_(f2) {} - std::function f2_; - }; -}; - -template -void A::run(std::function f1, - std::function f2) { - Helper h(f2); -} - -struct B {}; - -int main() { - A a; - a.run([&](auto& l) {}); - return 0; -}