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
