diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-12-15 18:44:22 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-12-15 18:44:22 +0000 |
commit | 0827408865e32789e0ec4b8113a302ccdc531423 (patch) | |
tree | d8c9122a107aab93c08b01adb6df4f9c954c3705 /lib/Sema | |
parent | c46333550f5787b6d48ca3043e14ba9594cb632d (diff) |
Fix diagnostic pragmas.
Diagnostic pragmas are broken because we don't keep track of the diagnostic state changes and we only check the current/latest state.
Problems manifest if a diagnostic is emitted for a source line that has different diagnostic state than the current state; this can affect
a lot of places, like C++ inline methods, template instantiations, the lexer, etc.
Fix the issue by having the Diagnostic object keep track of the source location of the pragmas so that it is able to know what is the diagnostic state at any given source location.
Fixes rdar://8365684.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121873 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 25 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 22 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 9 |
6 files changed, 50 insertions, 37 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index a9001c6e76..f4fde40bfb 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -216,9 +216,11 @@ struct CheckFallThroughDiagnostics { unsigned diag_AlwaysFallThrough_ReturnsNonVoid; unsigned diag_NeverFallThroughOrReturn; bool funMode; + SourceLocation FuncLoc; static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { CheckFallThroughDiagnostics D; + D.FuncLoc = Func->getLocation(); D.diag_MaybeFallThrough_HasNoReturn = diag::warn_falloff_noreturn_function; D.diag_MaybeFallThrough_ReturnsNonVoid = @@ -263,18 +265,22 @@ struct CheckFallThroughDiagnostics { bool checkDiagnostics(Diagnostic &D, bool ReturnsVoid, bool HasNoReturn) const { if (funMode) { - return (D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function) - == Diagnostic::Ignored || ReturnsVoid) - && (D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr) - == Diagnostic::Ignored || !HasNoReturn) - && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block) - == Diagnostic::Ignored || !ReturnsVoid); + return (ReturnsVoid || + D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function, + FuncLoc) == Diagnostic::Ignored) + && (!HasNoReturn || + D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr, + FuncLoc) == Diagnostic::Ignored) + && (!ReturnsVoid || + D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) + == Diagnostic::Ignored); } // For blocks. return ReturnsVoid && !HasNoReturn - && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block) - == Diagnostic::Ignored || !ReturnsVoid); + && (!ReturnsVoid || + D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) + == Diagnostic::Ignored); } }; @@ -363,7 +369,8 @@ clang::sema::AnalysisBasedWarnings::Policy::Policy() { clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s) { Diagnostic &D = S.getDiagnostics(); DefaultPolicy.enableCheckUnreachable = (unsigned) - (D.getDiagnosticLevel(diag::warn_unreachable) != Diagnostic::Ignored); + (D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) != + Diagnostic::Ignored); } void clang::sema:: diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index b699f5a318..c75b27c3ec 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -2863,11 +2863,12 @@ void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T) { if (!Suspicious) return; // ...but it's currently ignored... - if (S.Diags.getDiagnosticLevel(diag::warn_impcast_integer_sign_conditional)) + if (S.Diags.getDiagnosticLevel(diag::warn_impcast_integer_sign_conditional, + CC)) return; // ...and -Wsign-compare isn't... - if (!S.Diags.getDiagnosticLevel(diag::warn_mixed_sign_conditional)) + if (!S.Diags.getDiagnosticLevel(diag::warn_mixed_sign_conditional, CC)) return; // ...then check whether it would have warned about either of the @@ -3028,7 +3029,8 @@ bool Sema::CheckParmsForFunctionDef(ParmVarDecl **P, ParmVarDecl **PEnd, void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) { // This is actually a lot of work to potentially be doing on every // cast; don't do it if we're ignoring -Wcast_align (as is the default). - if (getDiagnostics().getDiagnosticLevel(diag::warn_cast_align) + if (getDiagnostics().getDiagnosticLevel(diag::warn_cast_align, + TRange.getBegin()) == Diagnostic::Ignored) return; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 17a1a1badb..6182e8663b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -809,7 +809,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, << Context.BuiltinInfo.GetName(BID) << R; if (Context.BuiltinInfo.getHeaderName(BID) && - Diags.getDiagnosticLevel(diag::ext_implicit_lib_function_decl) + Diags.getDiagnosticLevel(diag::ext_implicit_lib_function_decl, Loc) != Diagnostic::Ignored) Diag(Loc, diag::note_please_include_header) << Context.BuiltinInfo.getHeaderName(BID) @@ -3081,7 +3081,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, /// void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) { // Return if warning is ignored. - if (Diags.getDiagnosticLevel(diag::warn_decl_shadow) == Diagnostic::Ignored) + if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, R.getNameLoc()) == + Diagnostic::Ignored) return; // Don't diagnose declarations at file scope. The scope might not @@ -3135,6 +3136,10 @@ void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) { /// \brief Check -Wshadow without the advantage of a previous lookup. void Sema::CheckShadow(Scope *S, VarDecl *D) { + if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, D->getLocation()) == + Diagnostic::Ignored) + return; + LookupResult R(*this, D->getDeclName(), D->getLocation(), Sema::LookupOrdinaryName, Sema::ForRedeclaration); LookupName(R, S); @@ -5014,10 +5019,6 @@ ParmVarDecl *Sema::BuildParmVarDeclForTypedef(DeclContext *DC, void Sema::DiagnoseUnusedParameters(ParmVarDecl * const *Param, ParmVarDecl * const *ParamEnd) { - if (Diags.getDiagnosticLevel(diag::warn_unused_parameter) == - Diagnostic::Ignored) - return; - // Don't diagnose unused-parameter errors in template instantiations; we // will already have done so in the template itself. if (!ActiveTemplateInstantiations.empty()) @@ -5048,9 +5049,6 @@ void Sema::DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Param, << D->getDeclName() << Size; } - if (Diags.getDiagnosticLevel(diag::warn_parameter_size)==Diagnostic::Ignored) - return; - // Warn if any parameter is pass-by-value and larger than the specified // threshold. for (; Param != ParamEnd; ++Param) { @@ -5255,9 +5253,6 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { CheckParmsForFunctionDef(FD->param_begin(), FD->param_end(), /*CheckParameterNames=*/true); - bool ShouldCheckShadow = - Diags.getDiagnosticLevel(diag::warn_decl_shadow) != Diagnostic::Ignored; - // Introduce our parameters into the function scope for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) { ParmVarDecl *Param = FD->getParamDecl(p); @@ -5265,8 +5260,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // If this has an identifier, add it to the scope stack. if (Param->getIdentifier() && FnBodyScope) { - if (ShouldCheckShadow) - CheckShadow(FnBodyScope, Param); + CheckShadow(FnBodyScope, Param); PushOnScopeChains(Param, FnBodyScope); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index eec80f0d5a..d538715917 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1991,8 +1991,19 @@ DiagnoseBaseOrMemInitializerOrder(Sema &SemaRef, if (Constructor->getDeclContext()->isDependentContext()) return; - if (SemaRef.Diags.getDiagnosticLevel(diag::warn_initializer_out_of_order) - == Diagnostic::Ignored) + // Don't check initializers order unless the warning is enabled at the + // location of at least one initializer. + bool ShouldCheckOrder = false; + for (unsigned InitIndex = 0; InitIndex != NumInits; ++InitIndex) { + CXXBaseOrMemberInitializer *Init = Inits[InitIndex]; + if (SemaRef.Diags.getDiagnosticLevel(diag::warn_initializer_out_of_order, + Init->getSourceLocation()) + != Diagnostic::Ignored) { + ShouldCheckOrder = true; + break; + } + } + if (!ShouldCheckOrder) return; // Build the list of bases and members in the order that they'll diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index f29a01eb45..38e91465d2 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -969,7 +969,8 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, IDecl->lookupInstanceMethod(method->getSelector()); if (!MethodInClass || !MethodInClass->isSynthesized()) { unsigned DIAG = diag::warn_unimplemented_protocol_method; - if (Diags.getDiagnosticLevel(DIAG) != Diagnostic::Ignored) { + if (Diags.getDiagnosticLevel(DIAG, ImpLoc) + != Diagnostic::Ignored) { WarnUndefinedMethod(ImpLoc, method, IncompleteImpl, DIAG); Diag(method->getLocation(), diag::note_method_declared_at); Diag(CDecl->getLocation(), diag::note_required_for_protocol_at) @@ -987,7 +988,7 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, !ClsMap.count(method->getSelector()) && (!Super || !Super->lookupClassMethod(method->getSelector()))) { unsigned DIAG = diag::warn_unimplemented_protocol_method; - if (Diags.getDiagnosticLevel(DIAG) != Diagnostic::Ignored) { + if (Diags.getDiagnosticLevel(DIAG, ImpLoc) != Diagnostic::Ignored) { WarnUndefinedMethod(ImpLoc, method, IncompleteImpl, DIAG); Diag(method->getLocation(), diag::note_method_declared_at); Diag(IDecl->getLocation(), diag::note_required_for_protocol_at) << @@ -1325,7 +1326,8 @@ ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R, ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second; bool strictSelectorMatch = receiverIdOrClass && warn && - (Diags.getDiagnosticLevel(diag::warn_strict_multiple_method_decl) != + (Diags.getDiagnosticLevel(diag::warn_strict_multiple_method_decl, + R.getBegin()) != Diagnostic::Ignored); if (warn && MethList.Method && MethList.Next) { bool issueWarning = false; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 0d4eb77698..dff9b458ba 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -8336,17 +8336,13 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { if (Params.empty()) return; - bool ShouldCheckShadow = - Diags.getDiagnosticLevel(diag::warn_decl_shadow) != Diagnostic::Ignored; - for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(), E = CurBlock->TheDecl->param_end(); AI != E; ++AI) { (*AI)->setOwningFunction(CurBlock->TheDecl); // If this has an identifier, add it to the scope stack. if ((*AI)->getIdentifier()) { - if (ShouldCheckShadow) - CheckShadow(CurBlock->TheScope, *AI); + CheckShadow(CurBlock->TheScope, *AI); PushOnScopeChains(*AI, CurBlock->TheScope); } @@ -8670,7 +8666,8 @@ bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result){ E->getSourceRange(); if (EvalResult.Diag && - Diags.getDiagnosticLevel(diag::ext_expr_not_ice) != Diagnostic::Ignored) + Diags.getDiagnosticLevel(diag::ext_expr_not_ice, EvalResult.DiagLoc) + != Diagnostic::Ignored) Diag(EvalResult.DiagLoc, EvalResult.Diag); if (Result) |