[clang] [Clang] Don't diagnose missing members when looking at the instantiating class template (PR #180725)

via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 10 03:37:56 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)

<details>
<summary>Changes</summary>

The perfect matching patch revealed another bug where recursive instantiations could lead to the escape of SFINAE errors, as shown in the issue.

I intend to backport this to Clang 22, so I will include a release note during the backporting process.

Fixes https://github.com/llvm/llvm-project/issues/179118


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


2 Files Affected:

- (modified) clang/lib/Sema/SemaExpr.cpp (+1-1) 
- (modified) clang/test/SemaCXX/overload-resolution-deferred-templates.cpp (+81) 


``````````diff
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5795a71b5cae8..f27de8de04f7a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2938,7 +2938,7 @@ ExprResult Sema::BuildQualifiedDeclarationNameExpr(
     // members were likely supposed to be inherited.
     DeclContext *DC = computeDeclContext(SS);
     if (const auto *CD = dyn_cast<CXXRecordDecl>(DC))
-      if (CD->isInvalidDecl())
+      if (CD->isInvalidDecl() || CD->isBeingDefined())
         return ExprError();
     Diag(NameInfo.getLoc(), diag::err_no_member)
       << NameInfo.getName() << DC << SS.getRange();
diff --git a/clang/test/SemaCXX/overload-resolution-deferred-templates.cpp b/clang/test/SemaCXX/overload-resolution-deferred-templates.cpp
index c3bda3988484d..acd38b37c3b5c 100644
--- a/clang/test/SemaCXX/overload-resolution-deferred-templates.cpp
+++ b/clang/test/SemaCXX/overload-resolution-deferred-templates.cpp
@@ -310,3 +310,84 @@ void test() {
 }
 
 }
+
+namespace GH179118 {
+
+namespace std {
+
+template <bool __v> struct integral_constant {
+  static constexpr bool value = __v;
+};
+
+template <typename _Tp, typename... _Args>
+using __is_constructible_impl =
+    integral_constant<__is_constructible(_Tp, _Args...)>;
+
+template <typename _Tp, typename... _Args>
+struct is_constructible : public std::__is_constructible_impl<_Tp, _Args...> {};
+
+template <bool> struct _cond {
+  template <typename Then, typename> using invoke = Then;
+};
+template <> struct _cond<false> {
+  template <typename, typename Else> using invoke = Else;
+};
+
+template <bool If, typename Then, typename Else>
+using conditional_t = typename _cond<If>::template invoke<Then, Else>;
+
+template <bool, class _Tp = void> struct enable_if;
+template <class _Tp> struct enable_if<true, _Tp> {
+  typedef _Tp type;
+};
+template <bool _Bp, class _Tp = void>
+using enable_if_t = typename enable_if<_Bp, _Tp>::type;
+
+} // namespace std
+
+namespace base {
+
+template <typename...> struct disjunction {};
+template <typename B1, typename... Bn>
+struct disjunction<B1, Bn...>
+    : std::conditional_t<B1::value, B1, disjunction<>> {};
+template <typename> class Optional;
+
+namespace internal {
+template <typename T, typename U>
+using IsConvertibleFromOptional =
+    disjunction<std::is_constructible<T, Optional<U> &>>;
+template <typename T, typename U>
+using IsAssignableFromOptional = IsConvertibleFromOptional<T, U>;
+} // namespace internal
+
+template <typename T> class Optional {
+public:
+  Optional(Optional &&);
+
+  template <typename U,
+            std::enable_if_t<internal::IsConvertibleFromOptional<T, U>::value> =
+                false>
+  Optional(Optional<U>);
+
+  Optional(const Optional &);
+  void operator=(Optional &&);
+
+  template <typename U>
+  std::enable_if_t<std::is_constructible<T, U>::value> operator=(U &&);
+
+  template <typename U>
+  std::enable_if_t<internal::IsAssignableFromOptional<T, U>::Optional>
+  operator=(Optional<U>);
+};
+
+} // namespace base
+
+struct LayoutUnit {
+  template <typename IntegerType> LayoutUnit(IntegerType);
+};
+
+static_assert(
+    std::is_constructible<LayoutUnit, base::Optional<LayoutUnit> &>::value, "");
+
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/180725


More information about the cfe-commits mailing list