[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