Skip to content

Commit 99eab31

Browse files
mizvekovtstellar
authored andcommitted
[clang] StmtPrinter: Handle DeclRefExpr to a Decomposition (llvm#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 00c096e)
1 parent 7643bd6 commit 99eab31

File tree

3 files changed

+96
-31
lines changed

3 files changed

+96
-31
lines changed

Diff for: clang/lib/AST/StmtPrinter.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -1291,8 +1291,14 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
12911291
<< PD->getFunctionScopeIndex();
12921292
break;
12931293
}
1294+
case Decl::Decomposition:
1295+
OS << "decomposition";
1296+
for (const auto &I : cast<DecompositionDecl>(VD)->bindings())
1297+
OS << '-' << I->getName();
1298+
break;
12941299
default:
1295-
llvm_unreachable("Unhandled anonymous declaration kind");
1300+
OS << "unhandled-anonymous-" << VD->getDeclKindName();
1301+
break;
12961302
}
12971303
}
12981304
if (Node->hasExplicitTemplateArgs()) {

Diff for: clang/test/Analysis/anonymous-decls.cpp

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++20 %s 2>&1 | FileCheck %s
2+
3+
struct A {
4+
static A a;
5+
char b;
6+
friend bool operator==(A, A) = default;
7+
};
8+
bool _ = A() == A::a;
9+
10+
// FIXME: steps 1 and 5 show anonymous function parameters are
11+
// not handled correctly.
12+
13+
// CHECK-LABEL: bool operator==(A, A) noexcept = default
14+
// CHECK-NEXT: [B2 (ENTRY)]
15+
// CHECK-NEXT: Succs (1): B1
16+
// CHECK: [B1]
17+
// CHECK-NEXT: 1: function-parameter-0-0
18+
// CHECK-NEXT: 2: [B1.1].b
19+
// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, LValueToRValue, char)
20+
// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, IntegralCast, int)
21+
// CHECK-NEXT: 5: function-parameter-0-1
22+
// CHECK-NEXT: 6: [B1.5].b
23+
// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, LValueToRValue, char)
24+
// CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, IntegralCast, int)
25+
// CHECK-NEXT: 9: [B1.4] == [B1.8]
26+
// CHECK-NEXT: 10: return [B1.9];
27+
// CHECK-NEXT: Preds (1): B2
28+
// CHECK-NEXT: Succs (1): B0
29+
// CHECK: [B0 (EXIT)]
30+
// CHECK-NEXT: Preds (1): B1
31+
32+
namespace std {
33+
template <class> struct iterator_traits;
34+
template <class, class> struct pair;
35+
template <class _Tp> struct iterator_traits<_Tp *> {
36+
typedef _Tp &reference;
37+
};
38+
template <long, class> struct tuple_element;
39+
template <class> struct tuple_size;
40+
template <class _T1, class _T2> struct tuple_size<pair<_T1, _T2>> {
41+
static const int value = 2;
42+
};
43+
template <class _T1, class _T2> struct tuple_element<0, pair<_T1, _T2>> {
44+
using type = _T1;
45+
};
46+
template <class _T1, class _T2> struct tuple_element<1, pair<_T1, _T2>> {
47+
using type = _T2;
48+
};
49+
template <long _Ip, class _T1, class _T2>
50+
tuple_element<_Ip, pair<_T1, _T2>>::type get(pair<_T1, _T2> &);
51+
struct __wrap_iter {
52+
iterator_traits<pair<int, int> *>::reference operator*();
53+
void operator++();
54+
};
55+
bool operator!=(__wrap_iter, __wrap_iter);
56+
struct vector {
57+
__wrap_iter begin();
58+
__wrap_iter end();
59+
};
60+
} // namespace std
61+
int main() {
62+
std::vector v;
63+
for (auto &[a, b] : v)
64+
;
65+
}
66+
67+
// FIXME: On steps 8 and 14, a decomposition is referred by name, which they never have.
68+
69+
// CHECK-LABEL: int main()
70+
// CHECK: [B3]
71+
// CHECK-NEXT: 1: operator*
72+
// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, FunctionToPointerDecay, iterator_traits<pair<int, int> *>::reference (*)(void))
73+
// CHECK-NEXT: 3: __begin1
74+
// CHECK-NEXT: 4: * [B3.3] (OperatorCall)
75+
// CHECK-NEXT: 5: auto &;
76+
// CHECK-NEXT: 6: get<0UL>
77+
// CHECK-NEXT: 7: [B3.6] (ImplicitCastExpr, FunctionToPointerDecay, typename tuple_element<0L, pair<int, int> >::type (*)(pair<int, int> &))
78+
// CHECK-NEXT: 8: decomposition-a-b
79+
// CHECK-NEXT: 9: [B3.7]([B3.8])
80+
// CHECK-NEXT: 10: [B3.9]
81+
// CHECK-NEXT: 11: std::tuple_element<0, std::pair<int, int>>::type a = get<0UL>(decomposition-a-b);
82+
// CHECK-NEXT: 12: get<1UL>
83+
// CHECK-NEXT: 13: [B3.12] (ImplicitCastExpr, FunctionToPointerDecay, typename tuple_element<1L, pair<int, int> >::type (*)(pair<int, int> &))
84+
// CHECK-NEXT: 14: decomposition-a-b
85+
// CHECK-NEXT: 15: [B3.13]([B3.14])
86+
// CHECK-NEXT: 16: [B3.15]
87+
// CHECK-NEXT: 17: std::tuple_element<1, std::pair<int, int>>::type b = get<1UL>(decomposition-a-b);
88+
// CHECK-NEXT: Preds (1): B1
89+
// CHECK-NEXT: Succs (1): B2

Diff for: clang/test/Analysis/anonymous-parameter.cpp

-30
This file was deleted.

0 commit comments

Comments
 (0)