Skip to content

Commit 9fc5dfc

Browse files
committed
Merging r314733:
------------------------------------------------------------------------ r314733 | rsmith | 2017-10-02 15:43:36 -0700 (Mon, 02 Oct 2017) | 5 lines PR33839: Fix -Wunused handling for structured binding declarations. We warn about a structured binding declaration being unused only if none of its bindings are used. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_50@319847 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent bfac2c5 commit 9fc5dfc

File tree

4 files changed

+72
-10
lines changed

4 files changed

+72
-10
lines changed

lib/Sema/SemaDecl.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,7 +1603,24 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
16031603
if (D->isInvalidDecl())
16041604
return false;
16051605

1606-
if (D->isReferenced() || D->isUsed() || D->hasAttr<UnusedAttr>() ||
1606+
bool Referenced = false;
1607+
if (auto *DD = dyn_cast<DecompositionDecl>(D)) {
1608+
// For a decomposition declaration, warn if none of the bindings are
1609+
// referenced, instead of if the variable itself is referenced (which
1610+
// it is, by the bindings' expressions).
1611+
for (auto *BD : DD->bindings()) {
1612+
if (BD->isReferenced()) {
1613+
Referenced = true;
1614+
break;
1615+
}
1616+
}
1617+
} else if (!D->getDeclName()) {
1618+
return false;
1619+
} else if (D->isReferenced() || D->isUsed()) {
1620+
Referenced = true;
1621+
}
1622+
1623+
if (Referenced || D->hasAttr<UnusedAttr>() ||
16071624
D->hasAttr<ObjCPreciseLifetimeAttr>())
16081625
return false;
16091626

@@ -1726,7 +1743,7 @@ void Sema::DiagnoseUnusedDecl(const NamedDecl *D) {
17261743
else
17271744
DiagID = diag::warn_unused_variable;
17281745

1729-
Diag(D->getLocation(), DiagID) << D->getDeclName() << Hint;
1746+
Diag(D->getLocation(), DiagID) << D << Hint;
17301747
}
17311748

17321749
static void CheckPoppedLabel(LabelDecl *L, Sema &S) {
@@ -1756,15 +1773,15 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
17561773
assert(isa<NamedDecl>(TmpD) && "Decl isn't NamedDecl?");
17571774
NamedDecl *D = cast<NamedDecl>(TmpD);
17581775

1759-
if (!D->getDeclName()) continue;
1760-
17611776
// Diagnose unused variables in this scope.
17621777
if (!S->hasUnrecoverableErrorOccurred()) {
17631778
DiagnoseUnusedDecl(D);
17641779
if (const auto *RD = dyn_cast<RecordDecl>(D))
17651780
DiagnoseUnusedNestedTypedefs(RD);
17661781
}
17671782

1783+
if (!D->getDeclName()) continue;
1784+
17681785
// If this was a forward reference to a label, verify it was defined.
17691786
if (LabelDecl *LD = dyn_cast<LabelDecl>(D))
17701787
CheckPoppedLabel(LD, *this);
@@ -6155,7 +6172,6 @@ NamedDecl *Sema::ActOnVariableDeclarator(
61556172
IdentifierInfo *II = Name.getAsIdentifierInfo();
61566173

61576174
if (D.isDecompositionDeclarator()) {
6158-
AddToScope = false;
61596175
// Take the name of the first declarator as our name for diagnostic
61606176
// purposes.
61616177
auto &Decomp = D.getDecompositionDeclarator();

lib/Sema/SemaDeclCXX.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,10 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
826826
NamedDecl *New =
827827
ActOnVariableDeclarator(S, D, DC, TInfo, Previous,
828828
MultiTemplateParamsArg(), AddToScope, Bindings);
829-
CurContext->addHiddenDecl(New);
829+
if (AddToScope) {
830+
S->AddDecl(New);
831+
CurContext->addHiddenDecl(New);
832+
}
830833

831834
if (isInOpenMPDeclareTargetContext())
832835
checkDeclIsAllowedInOpenMPTarget(nullptr, New);

lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
677677
Decl *TemplateDeclInstantiator::VisitBindingDecl(BindingDecl *D) {
678678
auto *NewBD = BindingDecl::Create(SemaRef.Context, Owner, D->getLocation(),
679679
D->getIdentifier());
680+
NewBD->setReferenced(D->isReferenced());
680681
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewBD);
681682
return NewBD;
682683
}

test/SemaCXX/unused.cpp

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify %s
2-
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
3-
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
1+
// RUN: %clang_cc1 -fsyntax-only -verify -Wunused %s
2+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -Wunused %s
3+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wunused %s
4+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wunused %s
45

56
// PR4103 : Make sure we don't get a bogus unused expression warning
67
namespace PR4103 {
78
class APInt {
89
char foo;
910
};
1011
class APSInt : public APInt {
11-
char bar;
12+
char bar; // expected-warning {{private field 'bar' is not used}}
1213
public:
1314
APSInt &operator=(const APSInt &RHS);
1415
};
@@ -69,3 +70,44 @@ namespace UnresolvedLookup {
6970
}
7071
};
7172
}
73+
74+
#if __cplusplus >= 201703L
75+
namespace PR33839 {
76+
void a() {
77+
struct X { int a, b; } x;
78+
auto [a, b] = x; // expected-warning {{unused variable '[a, b]'}}
79+
auto [c, d] = x;
80+
(void)d;
81+
}
82+
83+
template<typename T> void f() {
84+
struct A { int n; } a[1];
85+
for (auto [x] : a) {
86+
(void)x;
87+
}
88+
auto [y] = a[0]; // expected-warning {{unused}}
89+
}
90+
template<bool b> void g() {
91+
struct A { int n; } a[1];
92+
for (auto [x] : a) {
93+
if constexpr (b)
94+
(void)x;
95+
}
96+
97+
auto [y] = a[0];
98+
if constexpr (b)
99+
(void)y; // ok, even when b == false
100+
}
101+
template<typename T> void h() {
102+
struct A { int n; } a[1];
103+
for (auto [x] : a) { // expected-warning {{unused variable '[x]'}}
104+
}
105+
}
106+
void use() {
107+
f<int>(); // expected-note {{instantiation of}}
108+
g<true>();
109+
g<false>();
110+
h<int>(); // expected-note {{instantiation of}}
111+
}
112+
}
113+
#endif

0 commit comments

Comments
 (0)