[clang] [clang][Sema] fix crash on invalid expression with trailing return type and template keyword (PR #191972)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 19 19:47:19 PDT 2026
https://github.com/firstmoonlight updated https://github.com/llvm/llvm-project/pull/191972
>From cfd43c4cc781cec16c7b25a1e67665959302a331 Mon Sep 17 00:00:00 2001
From: victorl <liuvicsen at gmail.com>
Date: Tue, 14 Apr 2026 14:31:01 +0800
Subject: [PATCH 1/3] [clang][Sema] fix crash on invalid expression with
trailing return type and template keyword
---
clang/lib/Sema/SemaExprCXX.cpp | 3 ++-
clang/test/Modules/cxx20-10-2-ex5.cpp | 3 +--
clang/test/SemaCXX/recovery-expr-type.cpp | 17 ++++++++++++-----
3 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index f7e005a40363c..8de0d6c026ef4 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1514,7 +1514,8 @@ Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep,
RParenOrBraceLoc, ListInitialization);
if (Result.isInvalid())
Result = CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(),
- RParenOrBraceLoc, exprs, Ty);
+ RParenOrBraceLoc, exprs, Ty->isIncompleteType() ? QualType() : Ty);
+
return Result;
}
diff --git a/clang/test/Modules/cxx20-10-2-ex5.cpp b/clang/test/Modules/cxx20-10-2-ex5.cpp
index f222568072393..b14234d44e3be 100644
--- a/clang/test/Modules/cxx20-10-2-ex5.cpp
+++ b/clang/test/Modules/cxx20-10-2-ex5.cpp
@@ -61,6 +61,5 @@ int main() {
auto f = rootFinder(2); // OK
// error: A is incomplete
return A{45}.value; // expected-error {{invalid use of incomplete type 'A'}}
- // expected-error at -1 {{member access into incomplete type 'A'}}
- // expected-note at std-10-2-ex5-tu1.cpp:12 2{{forward declaration of 'A'}}
+ // expected-note at std-10-2-ex5-tu1.cpp:12 {{forward declaration of 'A'}}
}
diff --git a/clang/test/SemaCXX/recovery-expr-type.cpp b/clang/test/SemaCXX/recovery-expr-type.cpp
index 5a42a11b82da5..fd38f453afc27 100644
--- a/clang/test/SemaCXX/recovery-expr-type.cpp
+++ b/clang/test/SemaCXX/recovery-expr-type.cpp
@@ -104,8 +104,7 @@ void test() {
// verify the secondary diagnostic "cannot initialize" is emitted.
namespace test8 {
typedef int arr[];
-int v = arr(); // expected-error {{array types cannot be value-initialized}} \
- expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'arr'}}
+int v = arr(); // expected-error {{array types cannot be value-initialized}}
}
namespace test9 {
@@ -178,10 +177,18 @@ void f() {
namespace test16 {
// verify we do not crash on incomplete class type.
-template<typename T, typename U> struct A; // expected-note 5{{template is declared here}}
+template<typename T, typename U> struct A; // expected-note 3{{template is declared here}}
A<int, int> foo() { // expected-error {{implicit instantiation of undefined template}}
if (1 == 1)
- return A<int, int>{1}; // expected-error 2{{implicit instantiation of undefined template}}
- return A<int, int>(1); // expected-error 2{{implicit instantiation of undefined template}}
+ return A<int, int>{1}; // expected-error {{implicit instantiation of undefined template}}
+ return A<int, int>(1); // expected-error {{implicit instantiation of undefined template}}
}
}
+
+namespace test17 {
+// Verify we do not crash on trailing expression with template keyword.
+int a((enum b )b { } // expected-error {{ISO C++ forbids forward references to 'enum' types}} \
+ // expected-error {{invalid use of incomplete type}} \
+ // expected-note {{forward declaration of}}
+ -> template c); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
+}
>From 2020a1f40f6da33329e4052f9596289ff69b1a2b Mon Sep 17 00:00:00 2001
From: victorl <liuvicsen at gmail.com>
Date: Mon, 20 Apr 2026 10:01:55 +0800
Subject: [PATCH 2/3] Revert "[clang][Sema] fix crash on invalid expression
with trailing return type and template keyword"
This reverts commit cfd43c4cc781cec16c7b25a1e67665959302a331.
---
clang/lib/Sema/SemaExprCXX.cpp | 3 +--
clang/test/Modules/cxx20-10-2-ex5.cpp | 3 ++-
clang/test/SemaCXX/recovery-expr-type.cpp | 17 +++++------------
3 files changed, 8 insertions(+), 15 deletions(-)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 8de0d6c026ef4..f7e005a40363c 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1514,8 +1514,7 @@ Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep,
RParenOrBraceLoc, ListInitialization);
if (Result.isInvalid())
Result = CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(),
- RParenOrBraceLoc, exprs, Ty->isIncompleteType() ? QualType() : Ty);
-
+ RParenOrBraceLoc, exprs, Ty);
return Result;
}
diff --git a/clang/test/Modules/cxx20-10-2-ex5.cpp b/clang/test/Modules/cxx20-10-2-ex5.cpp
index b14234d44e3be..f222568072393 100644
--- a/clang/test/Modules/cxx20-10-2-ex5.cpp
+++ b/clang/test/Modules/cxx20-10-2-ex5.cpp
@@ -61,5 +61,6 @@ int main() {
auto f = rootFinder(2); // OK
// error: A is incomplete
return A{45}.value; // expected-error {{invalid use of incomplete type 'A'}}
- // expected-note at std-10-2-ex5-tu1.cpp:12 {{forward declaration of 'A'}}
+ // expected-error at -1 {{member access into incomplete type 'A'}}
+ // expected-note at std-10-2-ex5-tu1.cpp:12 2{{forward declaration of 'A'}}
}
diff --git a/clang/test/SemaCXX/recovery-expr-type.cpp b/clang/test/SemaCXX/recovery-expr-type.cpp
index fd38f453afc27..5a42a11b82da5 100644
--- a/clang/test/SemaCXX/recovery-expr-type.cpp
+++ b/clang/test/SemaCXX/recovery-expr-type.cpp
@@ -104,7 +104,8 @@ void test() {
// verify the secondary diagnostic "cannot initialize" is emitted.
namespace test8 {
typedef int arr[];
-int v = arr(); // expected-error {{array types cannot be value-initialized}}
+int v = arr(); // expected-error {{array types cannot be value-initialized}} \
+ expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'arr'}}
}
namespace test9 {
@@ -177,18 +178,10 @@ void f() {
namespace test16 {
// verify we do not crash on incomplete class type.
-template<typename T, typename U> struct A; // expected-note 3{{template is declared here}}
+template<typename T, typename U> struct A; // expected-note 5{{template is declared here}}
A<int, int> foo() { // expected-error {{implicit instantiation of undefined template}}
if (1 == 1)
- return A<int, int>{1}; // expected-error {{implicit instantiation of undefined template}}
- return A<int, int>(1); // expected-error {{implicit instantiation of undefined template}}
+ return A<int, int>{1}; // expected-error 2{{implicit instantiation of undefined template}}
+ return A<int, int>(1); // expected-error 2{{implicit instantiation of undefined template}}
}
}
-
-namespace test17 {
-// Verify we do not crash on trailing expression with template keyword.
-int a((enum b )b { } // expected-error {{ISO C++ forbids forward references to 'enum' types}} \
- // expected-error {{invalid use of incomplete type}} \
- // expected-note {{forward declaration of}}
- -> template c); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
-}
>From 3fb7d74cc09505c202b8abb64da4d1f97082a909 Mon Sep 17 00:00:00 2001
From: victorl <liuvicsen at gmail.com>
Date: Mon, 20 Apr 2026 10:44:23 +0800
Subject: [PATCH 3/3] [clang][Sema] fix crash on invalid expression with
trailing return type and template keyword
---
clang/lib/Sema/SemaExprCXX.cpp | 2 ++
clang/test/SemaCXX/recovery-expr-type.cpp | 8 ++++++++
2 files changed, 10 insertions(+)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index f7e005a40363c..4343f6da406b0 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7047,6 +7047,8 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
// call. We'll do more incomplete-type checks later in the lookup process,
// so just skip this check for ObjC types.
if (!BaseType->isRecordType()) {
+ if (Base->containsErrors() && BaseType->isIncompleteType())
+ return ExprError();
ObjectType = ParsedType::make(BaseType);
MayBePseudoDestructor = true;
return Base;
diff --git a/clang/test/SemaCXX/recovery-expr-type.cpp b/clang/test/SemaCXX/recovery-expr-type.cpp
index 5a42a11b82da5..b93dd6b2fbe79 100644
--- a/clang/test/SemaCXX/recovery-expr-type.cpp
+++ b/clang/test/SemaCXX/recovery-expr-type.cpp
@@ -185,3 +185,11 @@ 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 test17 {
+// Verify we do not crash on trailing expression with template keyword.
+int a((enum b )b { } // expected-error {{ISO C++ forbids forward references to 'enum' types}} \
+ // expected-error {{invalid use of incomplete type}} \
+ // expected-note {{forward declaration of}}
+ -> template c);
+}
More information about the cfe-commits
mailing list