https://github.com/patrykstefanski updated 
https://github.com/llvm/llvm-project/pull/210151

>From dd698af44e700fbd57816466d6740377130fc0de Mon Sep 17 00:00:00 2001
From: Patryk Stefanski <[email protected]>
Date: Thu, 16 Jul 2026 12:02:57 -0700
Subject: [PATCH] [clang][sema] Fix crash on decomposition decl missing
 initializer

ActOnUninitializedDecl dereferenced the std::optional<Token> from
Lexer::findNextToken() unconditionally when diagnosing a structured
binding with no initializer. Guard the optional and fall back to the
declaration's location.
---
 clang/lib/Sema/SemaDecl.cpp               | 15 +++++++++------
 clang/test/Parser/cxx1z-decomposition.cpp |  3 +++
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c5920f03ed6e1..9b2efd96cb62d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14521,12 +14521,15 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
     }
     // C++1z [dcl.dcl]p1 grammar implies that an initializer is mandatory.
     if (isa<DecompositionDecl>(RealDecl)) {
-      // Point the caret to the token immediately after the closing bracket.
-      auto NextLoc = dyn_cast<DecompositionDecl>(RealDecl)->getRSquareLoc();
-      NextLoc =
-          Lexer::findNextToken(NextLoc, PP.getSourceManager(), 
PP.getLangOpts())
-              ->getLocation();
-      Diag(NextLoc, diag::err_decomp_decl_requires_init) << Var;
+      // Point the caret to the token immediately after the closing bracket if
+      // it can be found; otherwise fall back to the declaration's location.
+      SourceLocation Loc = Var->getLocation();
+      SourceLocation RSquareLoc =
+          dyn_cast<DecompositionDecl>(RealDecl)->getRSquareLoc();
+      if (std::optional<Token> Next = Lexer::findNextToken(
+              RSquareLoc, PP.getSourceManager(), PP.getLangOpts()))
+        Loc = Next->getLocation();
+      Diag(Loc, diag::err_decomp_decl_requires_init) << Var;
       Var->setInvalidDecl();
       return;
     }
diff --git a/clang/test/Parser/cxx1z-decomposition.cpp 
b/clang/test/Parser/cxx1z-decomposition.cpp
index fb22364ddb802..607a628506e8a 100644
--- a/clang/test/Parser/cxx1z-decomposition.cpp
+++ b/clang/test/Parser/cxx1z-decomposition.cpp
@@ -152,6 +152,7 @@ namespace Template {
 }
 
 #define MYC C
+#define CLOSE_NO_INIT ] ;
 
 namespace Init {
   template<typename T> T f(T t) {
@@ -171,6 +172,8 @@ namespace Init {
     T t1 = t; // check that uninitialized structured binding declaration error 
works with templates and macros
     auto [t0, t2] MYC = {t, t1}; // expected-error{{structured binding 
declaration '[t0, t2]' requires an initializer; expected '=' or braced 
initializer list}} expected-error{{expected ';' at end of declaration}}
                                  // CHECK: :[[@LINE-1]]:19: error: structured 
binding declaration '[t0, t2]' requires an initializer; expected '=' or braced 
initializer list
+    auto [bad4 CLOSE_NO_INIT // expected-error {{structured binding 
declaration '[bad4]' requires an initializer; expected '=' or braced 
initializer list}}
+                             // CHECK: :[[@LINE-1]]:10: error: structured 
binding declaration '[bad4]' requires an initializer; expected '=' or braced 
initializer list
   }
 }
 

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

Reply via email to