[clang] fba1a4b - [clang] Prevent nested RecoveryExpr in BuildConvertedConstantExpression (#207072)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 14 06:10:59 PDT 2026
Author: Hrólf Kraki
Date: 2026-07-14T06:10:54-07:00
New Revision: fba1a4b1292af3e7d08e9678e967ce12795d67d4
URL: https://github.com/llvm/llvm-project/commit/fba1a4b1292af3e7d08e9678e967ce12795d67d4
DIFF: https://github.com/llvm/llvm-project/commit/fba1a4b1292af3e7d08e9678e967ce12795d67d4.diff
LOG: [clang] Prevent nested RecoveryExpr in BuildConvertedConstantExpression (#207072)
when BuildConvertedConstantExpression receives an expression that is
already a RecoveryExpr, return it directly instead of wrapping it in
another RecoveryExpr
Fixes #186656
Fixes #202117
Added:
Modified:
clang/lib/Sema/SemaOverload.cpp
clang/test/SemaCXX/recovery-expr-type.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index c8b05a9f94bd0..eafda32198f11 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -6499,6 +6499,9 @@ static ExprResult BuildConvertedConstantExpression(Sema &S, Expr *From,
return ExprError();
if (From->containsErrors()) {
+ if (S.Context.hasSameType(From->getType(), T))
+ return From;
+
// The expression already has errors, so the correct cast kind can't be
// determined. Use RecoveryExpr to keep the expected type T and mark the
// result as invalid, preventing further cascading errors.
diff --git a/clang/test/SemaCXX/recovery-expr-type.cpp b/clang/test/SemaCXX/recovery-expr-type.cpp
index 5a42a11b82da5..bdab2940d6597 100644
--- a/clang/test/SemaCXX/recovery-expr-type.cpp
+++ b/clang/test/SemaCXX/recovery-expr-type.cpp
@@ -185,3 +185,17 @@ A<int, int> foo() { // expected-error {{implicit instantiation of undefined temp
return A<int, int>(1); // expected-error 2{{implicit instantiation of undefined template}}
}
}
+
+namespace GH186656 {
+template <template <int> typename> struct S;
+template <int, int = (foo<void, void>())> struct T; // expected-error {{use of undeclared identifier 'foo'}}
+template <typename...> struct U;
+using V = U<S<T>>;
+} // namespace GH186656
+
+namespace GH202117 {
+template<template<decltype(foo())> typename T> struct S {}; // expected-error {{use of undeclared identifier 'foo'}}
+template<int*> struct P;
+S<P> s;
+} // namespace GH202117
+
More information about the cfe-commits
mailing list