[clang] 924f773 - [Clang] Don't diagnose missing members when looking at the instantiating class template (#180725)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 11 04:42:16 PST 2026
Author: Younan Zhang
Date: 2026-02-11T20:42:11+08:00
New Revision: 924f773f5e261df260116ccb9849dbb58af56b69
URL: https://github.com/llvm/llvm-project/commit/924f773f5e261df260116ccb9849dbb58af56b69
DIFF: https://github.com/llvm/llvm-project/commit/924f773f5e261df260116ccb9849dbb58af56b69.diff
LOG: [Clang] Don't diagnose missing members when looking at the instantiating class template (#180725)
The perfect matching patch revealed another bug where recursive
instantiations could lead to the escape of SFINAE errors, as shown in
the issue.
Fixes https://github.com/llvm/llvm-project/issues/179118
Added:
Modified:
clang/lib/Sema/SemaExpr.cpp
clang/test/SemaCXX/overload-resolution-deferred-templates.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 60b5478371288..233f9ff297608 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, "");
+
+}
More information about the cfe-commits
mailing list