diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 37 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 7 |
3 files changed, 30 insertions, 17 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 24480fe81a0..3bea485c8fb 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1761,7 +1761,8 @@ public: /// DiagnoseUnusedExprResult - If the statement passed in is an expression /// whose result is unused, warn. void DiagnoseUnusedExprResult(const Stmt *S); - + void DiagnoseUnusedDecl(const NamedDecl *ND); + ParsingDeclStackState PushParsingDeclaration(); void PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy D); void EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index bf3c1724836..40ba8ffc195 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -544,9 +544,9 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { return false; } - // If we failed to complete the type for some reason, don't - // diagnose the variable. - if (Ty->isIncompleteType()) + // If we failed to complete the type for some reason, or if the type is + // dependent, don't diagnose the variable. + if (Ty->isIncompleteType() || Ty->isDependentType()) return false; if (const TagType *TT = Ty->getAs<TagType>()) { @@ -555,9 +555,10 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { return false; if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Tag)) { - if (!RD->hasTrivialConstructor()) - return false; - if (!RD->hasTrivialDestructor()) + // FIXME: Checking for the presence of a user-declared constructor + // isn't completely accurate; we'd prefer to check that the initializer + // has no side effects. + if (RD->hasUserDeclaredConstructor() || !RD->hasTrivialDestructor()) return false; } } @@ -568,6 +569,18 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { return true; } +void Sema::DiagnoseUnusedDecl(const NamedDecl *D) { + if (!ShouldDiagnoseUnusedDecl(D)) + return; + + if (isa<VarDecl>(D) && cast<VarDecl>(D)->isExceptionVariable()) + Diag(D->getLocation(), diag::warn_unused_exception_param) + << D->getDeclName(); + else + Diag(D->getLocation(), diag::warn_unused_variable) + << D->getDeclName(); +} + void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (S->decl_empty()) return; assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) && @@ -584,15 +597,9 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (!D->getDeclName()) continue; // Diagnose unused variables in this scope. - if (ShouldDiagnoseUnusedDecl(D) && - S->getNumErrorsAtStart() == getDiagnostics().getNumErrors()) { - if (isa<VarDecl>(D) && cast<VarDecl>(D)->isExceptionVariable()) - Diag(D->getLocation(), diag::warn_unused_exception_param) - << D->getDeclName(); - else - Diag(D->getLocation(), diag::warn_unused_variable) - << D->getDeclName(); - } + if (S->getNumErrorsAtStart() == getDiagnostics().getNumErrors()) + DiagnoseUnusedDecl(D); + // Remove this name from our lexical scope. IdResolver.RemoveDecl(D); } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index a32c0e1ac32..d3d6c2209f5 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -351,7 +351,8 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { Var->setLexicalDeclContext(D->getLexicalDeclContext()); Var->setAccess(D->getAccess()); - + Var->setUsed(D->isUsed()); + // FIXME: In theory, we could have a previous declaration for variables that // are not static data members. bool Redeclaration = false; @@ -419,6 +420,10 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { } else if (!Var->isStaticDataMember() || Var->isOutOfLine()) SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false); + // Diagnose unused local variables. + if (!Var->isInvalidDecl() && Owner->isFunctionOrMethod() && !Var->isUsed()) + SemaRef.DiagnoseUnusedDecl(Var); + return Var; } |

