Author: Matheus Izvekov
Date: 2026-05-22T13:01:04-03:00
New Revision: 78792f8576335770926f5e4b003bc5371d87c875

URL: 
https://github.com/llvm/llvm-project/commit/78792f8576335770926f5e4b003bc5371d87c875
DIFF: 
https://github.com/llvm/llvm-project/commit/78792f8576335770926f5e4b003bc5371d87c875.diff

LOG: [clang] ast-text-dump: fix printing of declref to decomposition with no 
bindings (#199215)

Clang supports empty structured binding groups as an extension, and the
text node dumper has some special handling for giving a name to
anonymous declarations, which assumed a decomposition would have at
least one binding.

Fixes #198842

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/TextNodeDumper.cpp
    clang/test/AST/ast-dump-decl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cf16e40d026c3..3d8837266739f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -676,6 +676,8 @@ Bug Fixes to AST Handling
 
 Miscellaneous Bug Fixes
 ^^^^^^^^^^^^^^^^^^^^^^^
+- Fixed a crash whith the AST text dumper, when dumping a reference to a
+  decomposition with no bindinds. (#GH198842)
 - Fixed the arguments of the format attribute on ``__builtin_os_log_format``.  
Previously, they were off by 1.
 
 Miscellaneous Clang Crashes Fixed

diff  --git a/clang/lib/AST/TextNodeDumper.cpp 
b/clang/lib/AST/TextNodeDumper.cpp
index e474517f56e6d..2b1c0cac25b6d 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -966,11 +966,13 @@ void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
       OS << " '" << Name << '\'';
     else
       switch (ND->getKind()) {
-      case Decl::Decomposition: {
-        auto *DD = cast<DecompositionDecl>(ND);
-        OS << " first_binding '" << DD->bindings()[0]->getDeclName() << '\'';
+      case Decl::Decomposition:
+        if (auto Bindings = cast<DecompositionDecl>(ND)->bindings();
+            !Bindings.empty())
+          OS << " first_binding '" << Bindings[0]->getDeclName() << '\'';
+        else
+          OS << " no_bindings";
         break;
-      }
       case Decl::Field: {
         auto *FD = cast<FieldDecl>(ND);
         OS << " field_index " << FD->getFieldIndex();

diff  --git a/clang/test/AST/ast-dump-decl.cpp 
b/clang/test/AST/ast-dump-decl.cpp
index a750375f5e62b..9b745642aedd0 100644
--- a/clang/test/AST/ast-dump-decl.cpp
+++ b/clang/test/AST/ast-dump-decl.cpp
@@ -1005,3 +1005,11 @@ namespace TestGH155936 {
   // CHECK: CXXRecordDecl 0x{{.+}} <line:[[@LINE-8]]:7, col:19> col:14 struct 
Foo definition
   // CHECH: CXXRecordDecl 0x{{.+}} <col:9, col:16> col:16 implicit struct Foo
 } // namspace GH155936
+
+namespace TestGH198842 {
+  struct X {};
+  auto && [] = X{};
+  // CHECK-LABEL: Dumping TestGH198842:
+  // CHECK: DecompositionDecl 0x{{.+}} <line:{{.+}}:3, col:18> col:11 'X &&' 
cinit external-linkage
+  // CHECK: MaterializeTemporaryExpr 0x{{.+}} <col:16, col:18> 'X' xvalue 
extended by Decomposition 0x{{.+}} no_bindings 'X &&'
+} // namespace TestGH198842


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

Reply via email to