Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Clang][NFC] Consolidate tests for default argument substitution #105617

Merged
merged 2 commits into from
Aug 30, 2024

Conversation

zyn0217
Copy link
Contributor

@zyn0217 zyn0217 commented Aug 22, 2024

Follow-up on 8ac140f.

The test SemaTemplate/default-parm-init.cpp was introduced since the fix #80288 and mainly did the following things:

  • Ensure the default arguments are properly substituted inside either the primary template & their explicit / out-of-line specializations.
  • Ensure the strategy doesn't mess up the substitution of a lambda expression as a default argument.

The 1st is for the bug of #68490, yet it does some redundant work: each of the member functions is duplicated twice for the sizeof and alignof operators, respectively, and the principle under the hood are essentially the same. So this patch removes the duplication and reduces the 8 functions to 4 functions that reveal the same thing.

The 2nd is presumably testing that the fix in #80288 doesn't impact a complicated substitution. However, that seems unnecessary & unrelated to the original issue. And more importantly, we don't have any problems with that ever. Hence, I'll remove that test from this patch.

The test for default arguments is merged into SemaTemplate/default-arguments.cpp with a new namespace, and hopefully this could reduce the entropy of our testing cases.

@zyn0217 zyn0217 added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Aug 22, 2024
@zyn0217 zyn0217 requested a review from cor3ntin August 22, 2024 05:32
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Aug 22, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Aug 22, 2024

@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)

Changes

Follow-up on 8ac140f.

The test SemaTemplate/default-parm-init.cpp was introduced since the fix for #80288 and mainly did the following things:

  • Ensure the default arguments are properly substituted inside either the primary template & their explicit / out-of-line specializations.
  • Ensure the strategy doesn't mess up the substitution of a lambda expression as a default argument.

The 1st is for the bug of #68490, yet it does some redundant work: each of the member functions is duplicated twice for the sizeof and alignof operators, respectively, and the principal under the hood are essentially the same. So this patch removes the duplication and reduces the 8 functions to 4 functions that reveal the same thing.

The 2nd is presumably testing that the fix in #80288 doesn't impact a complicated substitution. However, that seems unnecessary & unrelated to the original issue. And more importantly, we don't have any problems with that ever. Hence, I'll remove that test from this patch.

The test for default arguments is merged into SemaTemplate/default-arguments.cpp with a new namespace, and hopefully this could reduce the entropy of our testing cases.


Full diff: https://github.com/llvm/llvm-project/pull/105617.diff

2 Files Affected:

  • (modified) clang/test/SemaTemplate/default-arguments.cpp (+52)
  • (removed) clang/test/SemaTemplate/default-parm-init.cpp (-190)
diff --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp
index d5d9687cc90f49..3b1fbda414c12b 100644
--- a/clang/test/SemaTemplate/default-arguments.cpp
+++ b/clang/test/SemaTemplate/default-arguments.cpp
@@ -229,3 +229,55 @@ namespace unevaluated {
   template<int = 0> int f(int = a); // expected-warning 0-1{{extension}}
   int k = sizeof(f());
 }
+
+#if __cplusplus >= 201103L
+namespace GH68490 {
+
+template <typename T> struct S {
+  template <typename U>
+  constexpr int SizeOfU(int param = sizeof(U)) const;
+
+  template <typename U>
+  constexpr int SizeOfT(int param = sizeof(T)) const;
+};
+
+template <typename T> struct S<T *> {
+  template <typename U>
+  constexpr int SizeOfU(int param = sizeof(U)) const;
+
+  template <typename U>
+  constexpr int SizeOfT(int param = sizeof(T *)) const;
+};
+
+template <typename T>
+template <typename U>
+constexpr int S<T *>::SizeOfU(int param) const {
+  return param;
+}
+
+template <typename T>
+template <typename U>
+constexpr int S<T *>::SizeOfT(int param) const {
+  return param;
+}
+
+template <>
+template <typename T>
+constexpr int S<int>::SizeOfU(int param) const {
+  return param;
+}
+
+template <>
+template <typename T>
+constexpr int S<int>::SizeOfT(int param) const {
+  return param;
+}
+
+static_assert(S<int>().SizeOfU<char>() == sizeof(char), "");
+static_assert(S<int>().SizeOfT<char>() == sizeof(int), "");
+static_assert(S<short *>().SizeOfU<char>() == sizeof(char), "");
+static_assert(S<short *>().SizeOfT<char>() == 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 73ba8998df6a98..00000000000000
--- 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<typename Signature> class function;
-
-template<typename R, typename... Args> class invoker_base {
-public: 
-  virtual ~invoker_base() { } 
-  virtual R invoke(Args...) = 0; 
-  virtual invoker_base* clone() = 0;
-};
-
-template<typename F, typename R, typename... Args> 
-class functor_invoker : public invoker_base<R, Args...> {
-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<typename R, typename... Args>
-class function<R (Args...)> {
-public: 
-  typedef R result_type;
-  function() : invoker (0) { }
-  function(const function& other) : invoker(0) { 
-    if (other.invoker)
-      invoker = other.invoker->clone();
-  }
-
-  template<typename F> function(const F& f) : invoker(0) {
-    invoker = new functor_invoker<F, R, Args...>(f);
-  }
-
-  ~function() { 
-    if (invoker)
-      delete invoker;
-  }
-
-  function& operator=(const function& other) { 
-    function(other).swap(*this); 
-    return *this;
-  }
-
-  template<typename F> 
-  function& operator=(const F& f) {
-    function(f).swap(*this); 
-    return *this;
-  }
-
-  void swap(function& other) { 
-    invoker_base<R, Args...>* tmp = invoker; 
-    invoker = other.invoker; 
-    other.invoker = tmp;
-  }
-
-  result_type operator()(Args... args) const { 
-    return invoker->invoke(args...);
-  }
-
-private: 
-  invoker_base<R, Args...>* invoker;
-};
-
-}
-
-template<typename TemplateParam>
-struct Problem {
-  template<typename FunctionTemplateParam>
-  constexpr int FuncAlign(int param = alignof(FunctionTemplateParam));
-
-  template<typename FunctionTemplateParam>
-  constexpr int FuncSizeof(int param = sizeof(FunctionTemplateParam));
-
-  template<typename FunctionTemplateParam>
-  constexpr int FuncAlign2(int param = alignof(TemplateParam));
-
-  template<typename FunctionTemplateParam>
-  constexpr int FuncSizeof2(int param = sizeof(TemplateParam));
-};
-
-template<typename TemplateParam>
-struct Problem<TemplateParam*> {
-  template<typename FunctionTemplateParam>
-  constexpr int FuncAlign(int param = alignof(FunctionTemplateParam));
-
-  template<typename FunctionTemplateParam>
-  constexpr int FuncSizeof(int param = sizeof(FunctionTemplateParam));
-
-  template<typename FunctionTemplateParam>
-  constexpr int FuncAlign2(int param = alignof(TemplateParam));
-
-  template<typename FunctionTemplateParam>
-  constexpr int FuncSizeof2(int param = sizeof(TemplateParam));
-};
-
-template<typename TemplateParam>
-template<typename FunctionTemplateParam>
-constexpr int Problem<TemplateParam*>::FuncAlign(int param) {
-	return 2U*param;
-}
-
-template<typename TemplateParam>
-template<typename FunctionTemplateParam>
-constexpr int Problem<TemplateParam*>::FuncSizeof(int param) {
-    return 2U*param;
-}
-
-template<typename TemplateParam>
-template<typename FunctionTemplateParam>
-constexpr int Problem<TemplateParam*>::FuncAlign2(int param) {
-	return 2U*param;
-}
-
-template<typename TemplateParam>
-template<typename FunctionTemplateParam>
-constexpr int Problem<TemplateParam*>::FuncSizeof2(int param) {
-	return 2U*param;
-}
-
-template <>
-template<typename FunctionTemplateParam>
-constexpr int Problem<int>::FuncAlign(int param) {
-	return param;
-}
-
-template <>
-template<typename FunctionTemplateParam>
-constexpr int Problem<int>::FuncSizeof(int param) {
-	return param;
-}
-
-template <>
-template<typename FunctionTemplateParam>
-constexpr int Problem<int>::FuncAlign2(int param) {
-	return param;
-}
-
-template <>
-template<typename FunctionTemplateParam>
-constexpr int Problem<int>::FuncSizeof2(int param) {
-	return param;
-}
-
-void foo() {
-    Problem<int> p = {};
-    static_assert(p.FuncAlign<char>() == alignof(char));
-    static_assert(p.FuncSizeof<char>() == sizeof(char));
-    static_assert(p.FuncAlign2<char>() == alignof(int));
-    static_assert(p.FuncSizeof2<char>() == sizeof(int));
-    Problem<short*> q = {};
-    static_assert(q.FuncAlign<char>() == 2U * alignof(char));
-    static_assert(q.FuncSizeof<char>() == 2U * sizeof(char));
-    static_assert(q.FuncAlign2<char>() == 2U *alignof(short));
-    static_assert(q.FuncSizeof2<char>() == 2U * sizeof(short));
-}
-
-template <typename T>
-class A {
- public:
-  void run(
-    std::function<void(T&)> f1 = [](auto&&) {},
-    std::function<void(T&)> f2 = [](auto&&) {});
- private:
-  class Helper {
-   public:
-    explicit Helper(std::function<void(T&)> f2) : f2_(f2) {}
-    std::function<void(T&)> f2_;
-  };
-};
-
-template <typename T>
-void A<T>::run(std::function<void(T&)> f1,
-               std::function<void(T&)> f2) {
-  Helper h(f2);
-}
-
-struct B {};
-
-int main() {
-    A<B> a;
-    a.run([&](auto& l) {});
-    return 0;
-}

@zyn0217
Copy link
Contributor Author

zyn0217 commented Aug 22, 2024

libcxx failures are unrelated.

Copy link
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@zyn0217 zyn0217 merged commit 0722b8a into llvm:main Aug 30, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants