aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/AnalysisBasedWarnings.cpp
diff options
context:
space:
mode:
authorJan Korous <jkorous@apple.com>2023-01-09 17:36:48 -0800
committerJan Korous <jkorous@apple.com>2023-01-18 14:18:54 -0800
commit39a63fc7fe9824313764a9da8565a705d3024b1a (patch)
tree581676edf453709e2a97774958af8644e513457f /clang/lib/Sema/AnalysisBasedWarnings.cpp
parent304d7307aee15b6eb88d198ae94b595f4e09f485 (diff)
downloadllvm-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.cpp33
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,