[Sema] Warn about unused variables if we can constant evaluate the initializer.

If the variable construction can be constant evaluated it doesn't have
side effects, so removing it is always safe. We only try to evaluate
variables that are unused, there should be no impact on compile time.

Differential Revision: https://reviews.llvm.org/D38678

llvm-svn: 315787
This commit is contained in:
Benjamin Kramer 2017-10-14 01:30:49 +00:00
parent aa4ea5fb45
commit 819ec01ce3
2 changed files with 35 additions and 1 deletions

View File

@ -1723,7 +1723,8 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
dyn_cast<CXXConstructExpr>(Init);
if (Construct && !Construct->isElidable()) {
CXXConstructorDecl *CD = Construct->getConstructor();
if (!CD->isTrivial() && !RD->hasAttr<WarnUnusedAttr>())
if (!CD->isTrivial() && !RD->hasAttr<WarnUnusedAttr>() &&
!VD->evaluateValue())
return false;
}
}

View File

@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify %s
// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify -std=c++11 %s
template<typename T> void f() {
T t;
t = 17;
@ -194,3 +195,35 @@ void test() {
}
}
#if __cplusplus >= 201103L
namespace with_constexpr {
template <typename T>
struct Literal {
T i;
Literal() = default;
constexpr Literal(T i) : i(i) {}
};
struct NoLiteral {
int i;
NoLiteral() = default;
constexpr NoLiteral(int i) : i(i) {}
~NoLiteral() {}
};
static Literal<int> gl1; // expected-warning {{unused variable 'gl1'}}
static Literal<int> gl2(1); // expected-warning {{unused variable 'gl2'}}
static const Literal<int> gl3(0); // expected-warning {{unused variable 'gl3'}}
template <typename T>
void test(int i) {
Literal<int> l1; // expected-warning {{unused variable 'l1'}}
Literal<int> l2(42); // expected-warning {{unused variable 'l2'}}
Literal<int> l3(i); // no-warning
Literal<T> l4(0); // no-warning
NoLiteral nl1; // no-warning
NoLiteral nl2(42); // no-warning
}
}
#endif