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>


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to