[llvm-branch-commits] [clang] release/20.x: [clang] StmtPrinter: Handle DeclRefExpr to a Decomposition (#125001) (PR #126659)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Feb 10 19:15:40 PST 2025
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/126659
Backport 00c096e604ad3a5244af06602556f8de867e36c4
Requested by: @wjristow
>From 8a9b9cf2cd9def798f4fa95c0b01370b5350af14 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Wed, 29 Jan 2025 21:58:55 -0300
Subject: [PATCH] [clang] StmtPrinter: Handle DeclRefExpr to a Decomposition
(#125001)
A DeclRefExpr could never refer to a Decomposition in valid C++ code,
but somehow the Analyzer creates these entities and then it tries to
print them.
There is no sensible answer here, so we print 'decomposition' followed
by the names of all of its bindings, separated by dashes.
(cherry picked from commit 00c096e604ad3a5244af06602556f8de867e36c4)
---
clang/lib/AST/StmtPrinter.cpp | 8 +-
clang/test/Analysis/anonymous-decls.cpp | 89 +++++++++++++++++++++
clang/test/Analysis/anonymous-parameter.cpp | 30 -------
3 files changed, 96 insertions(+), 31 deletions(-)
create mode 100644 clang/test/Analysis/anonymous-decls.cpp
delete mode 100644 clang/test/Analysis/anonymous-parameter.cpp
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 9efc88436f928d0..9299d4cb4aba845 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1291,8 +1291,14 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
<< PD->getFunctionScopeIndex();
break;
}
+ case Decl::Decomposition:
+ OS << "decomposition";
+ for (const auto &I : cast<DecompositionDecl>(VD)->bindings())
+ OS << '-' << I->getName();
+ break;
default:
- llvm_unreachable("Unhandled anonymous declaration kind");
+ OS << "unhandled-anonymous-" << VD->getDeclKindName();
+ break;
}
}
if (Node->hasExplicitTemplateArgs()) {
diff --git a/clang/test/Analysis/anonymous-decls.cpp b/clang/test/Analysis/anonymous-decls.cpp
new file mode 100644
index 000000000000000..211184523aa51c0
--- /dev/null
+++ b/clang/test/Analysis/anonymous-decls.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++20 %s 2>&1 | FileCheck %s
+
+struct A {
+ static A a;
+ char b;
+ friend bool operator==(A, A) = default;
+};
+bool _ = A() == A::a;
+
+// FIXME: steps 1 and 5 show anonymous function parameters are
+// not handled correctly.
+
+// CHECK-LABEL: bool operator==(A, A) noexcept = default
+// CHECK-NEXT: [B2 (ENTRY)]
+// CHECK-NEXT: Succs (1): B1
+// CHECK: [B1]
+// CHECK-NEXT: 1: function-parameter-0-0
+// CHECK-NEXT: 2: [B1.1].b
+// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, LValueToRValue, char)
+// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, IntegralCast, int)
+// CHECK-NEXT: 5: function-parameter-0-1
+// CHECK-NEXT: 6: [B1.5].b
+// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, LValueToRValue, char)
+// CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, IntegralCast, int)
+// CHECK-NEXT: 9: [B1.4] == [B1.8]
+// CHECK-NEXT: 10: return [B1.9];
+// CHECK-NEXT: Preds (1): B2
+// CHECK-NEXT: Succs (1): B0
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+
+namespace std {
+template <class> struct iterator_traits;
+template <class, class> struct pair;
+template <class _Tp> struct iterator_traits<_Tp *> {
+ typedef _Tp &reference;
+};
+template <long, class> struct tuple_element;
+template <class> struct tuple_size;
+template <class _T1, class _T2> struct tuple_size<pair<_T1, _T2>> {
+ static const int value = 2;
+};
+template <class _T1, class _T2> struct tuple_element<0, pair<_T1, _T2>> {
+ using type = _T1;
+};
+template <class _T1, class _T2> struct tuple_element<1, pair<_T1, _T2>> {
+ using type = _T2;
+};
+template <long _Ip, class _T1, class _T2>
+tuple_element<_Ip, pair<_T1, _T2>>::type get(pair<_T1, _T2> &);
+struct __wrap_iter {
+ iterator_traits<pair<int, int> *>::reference operator*();
+ void operator++();
+};
+bool operator!=(__wrap_iter, __wrap_iter);
+struct vector {
+ __wrap_iter begin();
+ __wrap_iter end();
+};
+} // namespace std
+int main() {
+ std::vector v;
+ for (auto &[a, b] : v)
+ ;
+}
+
+// FIXME: On steps 8 and 14, a decomposition is referred by name, which they never have.
+
+// CHECK-LABEL: int main()
+// CHECK: [B3]
+// CHECK-NEXT: 1: operator*
+// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, FunctionToPointerDecay, iterator_traits<pair<int, int> *>::reference (*)(void))
+// CHECK-NEXT: 3: __begin1
+// CHECK-NEXT: 4: * [B3.3] (OperatorCall)
+// CHECK-NEXT: 5: auto &;
+// CHECK-NEXT: 6: get<0UL>
+// CHECK-NEXT: 7: [B3.6] (ImplicitCastExpr, FunctionToPointerDecay, typename tuple_element<0L, pair<int, int> >::type (*)(pair<int, int> &))
+// CHECK-NEXT: 8: decomposition-a-b
+// CHECK-NEXT: 9: [B3.7]([B3.8])
+// CHECK-NEXT: 10: [B3.9]
+// CHECK-NEXT: 11: std::tuple_element<0, std::pair<int, int>>::type a = get<0UL>(decomposition-a-b);
+// CHECK-NEXT: 12: get<1UL>
+// CHECK-NEXT: 13: [B3.12] (ImplicitCastExpr, FunctionToPointerDecay, typename tuple_element<1L, pair<int, int> >::type (*)(pair<int, int> &))
+// CHECK-NEXT: 14: decomposition-a-b
+// CHECK-NEXT: 15: [B3.13]([B3.14])
+// CHECK-NEXT: 16: [B3.15]
+// CHECK-NEXT: 17: std::tuple_element<1, std::pair<int, int>>::type b = get<1UL>(decomposition-a-b);
+// CHECK-NEXT: Preds (1): B1
+// CHECK-NEXT: Succs (1): B2
diff --git a/clang/test/Analysis/anonymous-parameter.cpp b/clang/test/Analysis/anonymous-parameter.cpp
deleted file mode 100644
index ad2a00b3329cb3c..000000000000000
--- a/clang/test/Analysis/anonymous-parameter.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++20 %s 2>&1 | FileCheck %s
-
-struct A {
- static A a;
- char b;
- friend bool operator==(A, A) = default;
-};
-bool _ = A() == A::a;
-
-// FIXME: steps 1 and 5 show anonymous function parameters are
-// not handled correctly.
-
-// CHECK-LABEL: bool operator==(A, A) noexcept = default
-// CHECK-NEXT: [B2 (ENTRY)]
-// CHECK-NEXT: Succs (1): B1
-// CHECK: [B1]
-// CHECK-NEXT: 1: function-parameter-0-0
-// CHECK-NEXT: 2: [B1.1].b
-// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, LValueToRValue, char)
-// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, IntegralCast, int)
-// CHECK-NEXT: 5: function-parameter-0-1
-// CHECK-NEXT: 6: [B1.5].b
-// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, LValueToRValue, char)
-// CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, IntegralCast, int)
-// CHECK-NEXT: 9: [B1.4] == [B1.8]
-// CHECK-NEXT: 10: return [B1.9];
-// CHECK-NEXT: Preds (1): B2
-// CHECK-NEXT: Succs (1): B0
-// CHECK: [B0 (EXIT)]
-// CHECK-NEXT: Preds (1): B1
More information about the llvm-branch-commits
mailing list