diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1921,8 +1921,10 @@ } void Sema::DiagnoseUnusedButSetDecl(const VarDecl *VD) { - // If it's not referenced, it can't be set. - if (!VD->isReferenced() || !VD->getDeclName() || VD->hasAttr()) + // If it's not referenced, it can't be set. If it has the Cleanup attribute, + // it's not really unused. + if (!VD->isReferenced() || !VD->getDeclName() || VD->hasAttr() || + VD->hasAttr()) return; const auto *Ty = VD->getType().getTypePtr()->getBaseElementTypeUnsafe(); diff --git a/clang/test/Sema/warn-unused-but-set-variables.c b/clang/test/Sema/warn-unused-but-set-variables.c --- a/clang/test/Sema/warn-unused-but-set-variables.c +++ b/clang/test/Sema/warn-unused-but-set-variables.c @@ -49,3 +49,13 @@ x = 0; (void) sizeof(x); } + +void for_cleanup(int *x) { + *x = 0; +} + +void f3(void) { + // Don't warn if the __cleanup__ attribute is used. + __attribute__((__cleanup__(for_cleanup))) int x; + x = 5; +}