diff options
author | Jan Korous <jkorous@apple.com> | 2023-01-09 17:36:48 -0800 |
---|---|---|
committer | Jan Korous <jkorous@apple.com> | 2023-01-18 14:18:54 -0800 |
commit | 39a63fc7fe9824313764a9da8565a705d3024b1a (patch) | |
tree | 581676edf453709e2a97774958af8644e513457f /clang/lib/Sema/AnalysisBasedWarnings.cpp | |
parent | 304d7307aee15b6eb88d198ae94b595f4e09f485 (diff) | |
download | llvm-39a63fc7fe9824313764a9da8565a705d3024b1a.zip llvm-39a63fc7fe9824313764a9da8565a705d3024b1a.tar.gz llvm-39a63fc7fe9824313764a9da8565a705d3024b1a.tar.bz2 |
[-Wunsafe-buffer-usage] Use relevant source locations for warnings
This way we highlight a particular unsafe subexpression by providing more accurate
source location than begin of an entire statement.
Differential Revision: https://reviews.llvm.org/D141340
Diffstat (limited to 'clang/lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 3a0f566..08cf45e 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -16,8 +16,10 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/EvaluatedExprVisitor.h" +#include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/OperationKinds.h" #include "clang/AST/ParentMap.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/StmtCXX.h" @@ -2152,8 +2154,35 @@ public: UnsafeBufferUsageReporter(Sema &S) : S(S) {} void handleUnsafeOperation(const Stmt *Operation) override { - S.Diag(Operation->getBeginLoc(), diag::warn_unsafe_buffer_expression) - << Operation->getSourceRange(); + SourceLocation Loc; + SourceRange Range; + if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Operation)) { + Loc = ASE->getBase()->getExprLoc(); + Range = ASE->getBase()->getSourceRange(); + } else if (const auto *BO = dyn_cast<BinaryOperator>(Operation)) { + BinaryOperator::Opcode Op = BO->getOpcode(); + if (Op == BO_Add || Op == BO_AddAssign || Op == BO_Sub || + Op == BO_SubAssign) { + if (BO->getRHS()->getType()->isIntegerType()) { + Loc = BO->getLHS()->getExprLoc(); + Range = BO->getLHS()->getSourceRange(); + } else { + Loc = BO->getRHS()->getExprLoc(); + Range = BO->getRHS()->getSourceRange(); + } + } + } else if (const auto *UO = dyn_cast<UnaryOperator>(Operation)) { + UnaryOperator::Opcode Op = UO->getOpcode(); + if (Op == UO_PreInc || Op == UO_PreDec || Op == UO_PostInc || + Op == UO_PostDec) { + Loc = UO->getSubExpr()->getExprLoc(); + Range = UO->getSubExpr()->getSourceRange(); + } + } else { + Loc = Operation->getBeginLoc(); + Range = Operation->getSourceRange(); + } + S.Diag(Loc, diag::warn_unsafe_buffer_expression) << Range; } void handleFixableVariable(const VarDecl *Variable, |