[clang] d444e3e - [Clang][Sema] Fix crash in UnresolvedMemberExpr check (#209792)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 17 03:28:26 PDT 2026
Author: Chibuoyim (Wilson) Ogbonna
Date: 2026-07-17T18:28:21+08:00
New Revision: d444e3ebb8ae69cdb628be3b3b0c632f13df9a08
URL: https://github.com/llvm/llvm-project/commit/d444e3ebb8ae69cdb628be3b3b0c632f13df9a08
DIFF: https://github.com/llvm/llvm-project/commit/d444e3ebb8ae69cdb628be3b3b0c632f13df9a08.diff
LOG: [Clang][Sema] Fix crash in UnresolvedMemberExpr check (#209792)
This closes https://github.com/llvm/llvm-project/issues/209427
The test currently crashes because while iterating over the candidate
members of an unresolved member expression, `decl` is a `UsingShadowDecl`
with underlying decl as `UnresolvedUsingValueDecl`.
The current `isa<UnresolvedUsingValueDecl>(decl)` guard only checks the
outer `UsingShadowDecl` and misses the unresolved-using decl hidden
inside it, so `getAsFunction()` returns nullptr and
`cast<CXXMethodDecl>(nullptr)` asserts.
This patch checks the `UnresolvedUsingValueDecl` inside by calling
`getUnderlyingDecl()` before the guard.
This used to happen before a2794f9f363361f87a3538b90b78ff13381d5ce1.
Added:
Modified:
clang/docs/ReleaseNotes.md
clang/lib/AST/ExprCXX.cpp
clang/test/SemaCXX/using-decl-templates.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index eb5059cb76bec..06ded79f4d995 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -320,6 +320,9 @@ features cannot lower the translation-unit ABI level;
-Fixed an issue where we tried to compare invalid NTTPs for variable declarations, which ended up in hitting an assertion with a constrained non-plain-auto NTTP, which we don't quite implement yet. (#GH208658)
+- Fixed a crash when a using-declaration naming an unresolvable member of a
+ dependent base was shadowed by an invalid using-declaration. (#GH209427)
+
#### Bug Fixes to AST Handling
- Fixed a non-deterministic ordering of unused local typedefs that made
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index a1ea91994969c..6c1cde6540d85 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1602,14 +1602,13 @@ CXXThisExpr *CXXThisExpr::CreateEmpty(const ASTContext &Ctx) {
static bool hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin,
UnresolvedSetIterator end) {
do {
- NamedDecl *decl = *begin;
+ NamedDecl *decl = (*begin)->getUnderlyingDecl();
if (isa<UnresolvedUsingValueDecl>(decl))
return false;
// Unresolved member expressions should only contain methods and
// method templates.
- if (cast<CXXMethodDecl>(decl->getUnderlyingDecl()->getAsFunction())
- ->isStatic())
+ if (cast<CXXMethodDecl>(decl->getAsFunction())->isStatic())
return false;
} while (++begin != end);
diff --git a/clang/test/SemaCXX/using-decl-templates.cpp b/clang/test/SemaCXX/using-decl-templates.cpp
index 58b30595b148c..a1a9b7ba0c31d 100644
--- a/clang/test/SemaCXX/using-decl-templates.cpp
+++ b/clang/test/SemaCXX/using-decl-templates.cpp
@@ -64,6 +64,17 @@ template <class T> struct Bar : public Foo<T>, Baz {
template int Bar<int>::foo();
}
+namespace CrashOnInvalidUsingShadow {
+template <class T> struct BaseTpl {};
+template <class T> struct Derived : public BaseTpl<T>, Derivd { // expected-error {{expected class name}} expected-note {{'Derived' declared here}}
+ using BaseTpl<T>::k;
+ using Derivd::k; // expected-error {{use of undeclared identifier 'Derivd'; did you mean 'Derived'?}}
+ int foo() {
+ return k(1.0f);
+ }
+};
+} // namespace CrashOnInvalidUsingShadow
+
// PR10883
namespace PR10883 {
template <typename T>
More information about the cfe-commits
mailing list