[clang] 700baeb - [-Wunsafe-buffer-usage] Use `Strategy` to determine whether to fix a parameter
Ziqing Luo via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 21 15:07:54 PDT 2023
Author: Ziqing Luo
Date: 2023-09-21T15:06:22-07:00
New Revision: 700baeb765cfe8628eb68bc24319b3db0209dd84
URL: https://github.com/llvm/llvm-project/commit/700baeb765cfe8628eb68bc24319b3db0209dd84
DIFF: https://github.com/llvm/llvm-project/commit/700baeb765cfe8628eb68bc24319b3db0209dd84.diff
LOG: [-Wunsafe-buffer-usage] Use `Strategy` to determine whether to fix a parameter
- Use Strategy to determine whether to fix a parameter
- Fix the `Strategy` construction so that only variables on the graph
are assigned the `std::span` strategy
Reviewed by: t-rasmud (Rashmi Mudduluru), NoQ (Artem Dergachev)
Differential revision: https://reviews.llvm.org/D157441
Added:
Modified:
clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
clang/lib/Analysis/UnsafeBufferUsage.cpp
clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-multi-parm-span.cpp
clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-fixits-test.cpp
clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-ptr-init-fixits.cpp
clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-ptr-init.cpp
clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-uuc-fixits.cpp
clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-uuc.cpp
clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-warnings.cpp
clang/test/SemaCXX/warn-unsafe-buffer-usage-pragma-fixit.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
index e8a93164302a47d..8a2d56668e32f92 100644
--- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
+++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
@@ -35,6 +35,10 @@ class VariableGroupsManager {
/// variables, where `Var` is in, contains parameters.
virtual VarGrpRef getGroupOfVar(const VarDecl *Var,
bool *HasParm = nullptr) const =0;
+
+ /// Returns the non-empty group of variables that include parameters of the
+ /// analyzing function, if such a group exists. An empty group, otherwise.
+ virtual VarGrpRef getGroupOfParms() const =0;
};
/// The interface that lets the caller handle unsafe buffer usage analysis
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 348585ef16e967b..a4a200469f70be3 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -1634,12 +1634,10 @@ PointerDereferenceGadget::getFixits(const Strategy &S) const {
CharSourceRange derefRange = clang::CharSourceRange::getCharRange(
Op->getBeginLoc(), Op->getBeginLoc().getLocWithOffset(1));
// Inserts the [0]
- std::optional<SourceLocation> EndOfOperand =
- getEndCharLoc(BaseDeclRefExpr, SM, Ctx.getLangOpts());
- if (EndOfOperand) {
+ if (auto LocPastOperand =
+ getPastLoc(BaseDeclRefExpr, SM, Ctx.getLangOpts())) {
return FixItList{{FixItHint::CreateRemoval(derefRange),
- FixItHint::CreateInsertion(
- (*EndOfOperand).getLocWithOffset(1), "[0]")}};
+ FixItHint::CreateInsertion(*LocPastOperand, "[0]")}};
}
break;
}
@@ -1978,18 +1976,9 @@ static bool hasConflictingOverload(const FunctionDecl *FD) {
// return f(std::span(p, <# size #>));
// }
//
-// The actual fix-its may contain more details, e.g., the attribute may be guard
-// by a macro
-// #if __has_cpp_attribute(clang::unsafe_buffer_usage)
-// [[clang::unsafe_buffer_usage]]
-// #endif
-//
-// `ParmsMask` is an array of size of `FD->getNumParams()` such
-// that `ParmsMask[i]` is true iff the `i`-th parameter will be fixed with some
-// strategy.
static std::optional<FixItList>
-createOverloadsForFixedParams(const std::vector<bool> &ParmsMask, const Strategy &S,
- const FunctionDecl *FD, const ASTContext &Ctx,
+createOverloadsForFixedParams(const Strategy &S, const FunctionDecl *FD,
+ const ASTContext &Ctx,
UnsafeBufferUsageHandler &Handler) {
// FIXME: need to make this conflict checking better:
if (hasConflictingOverload(FD))
@@ -1999,21 +1988,33 @@ createOverloadsForFixedParams(const std::vector<bool> &ParmsMask, const Strategy
const LangOptions &LangOpts = Ctx.getLangOpts();
const unsigned NumParms = FD->getNumParams();
std::vector<std::string> NewTysTexts(NumParms);
+ std::vector<bool> ParmsMask(NumParms, false);
+ bool AtLeastOneParmToFix = false;
for (unsigned i = 0; i < NumParms; i++) {
- if (!ParmsMask[i])
+ const ParmVarDecl *PVD = FD->getParamDecl(i);
+
+ if (S.lookup(PVD) == Strategy::Kind::Wontfix)
continue;
+ if (S.lookup(PVD) != Strategy::Kind::Span)
+ // Not supported, not suppose to happen:
+ return std::nullopt;
std::optional<Qualifiers> PteTyQuals = std::nullopt;
std::optional<std::string> PteTyText =
- getPointeeTypeText(FD->getParamDecl(i), SM, LangOpts, &PteTyQuals);
+ getPointeeTypeText(PVD, SM, LangOpts, &PteTyQuals);
if (!PteTyText)
// something wrong in obtaining the text of the pointee type, give up
return std::nullopt;
// FIXME: whether we should create std::span type depends on the Strategy.
NewTysTexts[i] = getSpanTypeText(*PteTyText, PteTyQuals);
+ ParmsMask[i] = true;
+ AtLeastOneParmToFix = true;
}
+ if (!AtLeastOneParmToFix)
+ // No need to create function overloads:
+ return {};
// FIXME Respect indentation of the original code.
// A lambda that creates the text representation of a function declaration
@@ -2322,28 +2323,18 @@ static FixItList createFunctionOverloadsForParms(
const VariableGroupsManager &VarGrpMgr, const FunctionDecl *FD,
const Strategy &S, ASTContext &Ctx, UnsafeBufferUsageHandler &Handler) {
FixItList FixItsSharedByParms{};
- std::vector<bool> ParmsNeedFixMask(FD->getNumParams(), false);
- const VarDecl *FirstParmNeedsFix = nullptr;
- for (unsigned i = 0; i < FD->getNumParams(); i++)
- if (FixItsForVariable.count(FD->getParamDecl(i))) {
- ParmsNeedFixMask[i] = true;
- FirstParmNeedsFix = FD->getParamDecl(i);
- }
- if (FirstParmNeedsFix) {
- // In case at least one parameter needs to be fixed:
- std::optional<FixItList> OverloadFixes =
- createOverloadsForFixedParams(ParmsNeedFixMask, S, FD, Ctx, Handler);
+ std::optional<FixItList> OverloadFixes =
+ createOverloadsForFixedParams(S, FD, Ctx, Handler);
- if (OverloadFixes) {
- FixItsSharedByParms.append(*OverloadFixes);
- } else {
- // Something wrong in generating `OverloadFixes`, need to remove the
- // whole group, where parameters are in, from `FixItsForVariable` (Note
- // that all parameters should be in the same group):
- for (auto *Member : VarGrpMgr.getGroupOfVar(FirstParmNeedsFix))
- FixItsForVariable.erase(Member);
- }
+ if (OverloadFixes) {
+ FixItsSharedByParms.append(*OverloadFixes);
+ } else {
+ // Something wrong in generating `OverloadFixes`, need to remove the
+ // whole group, where parameters are in, from `FixItsForVariable` (Note
+ // that all parameters should be in the same group):
+ for (auto *Member : VarGrpMgr.getGroupOfParms())
+ FixItsForVariable.erase(Member);
}
return FixItsSharedByParms;
}
@@ -2448,8 +2439,9 @@ getFixIts(FixableGadgetSets &FixablesForAllVars, const Strategy &S,
return FinalFixItsForVariable;
}
+template <typename VarDeclIterTy>
static Strategy
-getNaiveStrategy(const llvm::SmallVectorImpl<const VarDecl *> &UnsafeVars) {
+getNaiveStrategy(llvm::iterator_range<VarDeclIterTy> UnsafeVars) {
Strategy S;
for (const VarDecl *VD : UnsafeVars) {
S.set(VD, Strategy::Kind::Span);
@@ -2486,6 +2478,10 @@ class VariableGroupsManagerImpl : public VariableGroupsManager {
return std::nullopt;
return Groups[It->second];
}
+
+ VarGrpRef getGroupOfParms() const override {
+ return GrpsUnionForParms.getArrayRef();
+ }
};
void clang::checkUnsafeBufferUsage(const Decl *D,
@@ -2579,6 +2575,14 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
it->first, it->first->getBeginLoc(),
("failed to produce fixit for '" + it->first->getNameAsString() +
"' : neither local nor a parameter"));
+#endif
+ it = FixablesForAllVars.byVar.erase(it);
+ } else if (it->first->getType().getCanonicalType()->isReferenceType()) {
+#ifndef NDEBUG
+ Handler.addDebugNoteForVar(it->first, it->first->getBeginLoc(),
+ ("failed to produce fixit for '" +
+ it->first->getNameAsString() +
+ "' : has a reference type"));
#endif
it = FixablesForAllVars.byVar.erase(it);
} else if (Tracker.hasUnclaimedUses(it->first)) {
@@ -2605,10 +2609,6 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
}
}
- llvm::SmallVector<const VarDecl *, 16> UnsafeVars;
- for (const auto &[VD, ignore] : FixablesForAllVars.byVar)
- UnsafeVars.push_back(VD);
-
// Fixpoint iteration for pointer assignments
using DepMapTy = DenseMap<const VarDecl *, llvm::SetVector<const VarDecl *>>;
DepMapTy DependenciesMap{};
@@ -2737,7 +2737,13 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
++I;
}
- Strategy NaiveStrategy = getNaiveStrategy(UnsafeVars);
+ // We assign strategies to variables that are 1) in the graph and 2) can be
+ // fixed. Other variables have the default "Won't fix" strategy.
+ Strategy NaiveStrategy = getNaiveStrategy(llvm::make_filter_range(
+ VisitedVars, [&FixablesForAllVars](const VarDecl *V) {
+ // If a warned variable has no "Fixable", it is considered unfixable:
+ return FixablesForAllVars.byVar.count(V);
+ }));
VariableGroupsManagerImpl VarGrpMgr(Groups, VarGrpMap, GrpsUnionForParms);
if (isa<NamedDecl>(D))
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-multi-parm-span.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-multi-parm-span.cpp
index b3210e93c98fa5d..887909e048f8fc2 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-multi-parm-span.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-multi-parm-span.cpp
@@ -68,18 +68,15 @@ void * multiParmAllFix(int *p, int **q, int a[], int * r);
// Fixing local variables implicates fixing parameters
void multiParmLocalAllFix(int *p, int * r) {
- // CHECK: fix-it:{{.*}}:{[[@LINE-1]]:28-[[@LINE-1]]:34}:"std::span<int> p"
- // CHECK: fix-it:{{.*}}:{[[@LINE-2]]:36-[[@LINE-2]]:43}:"std::span<int> r"
- // CHECK: fix-it:{{.*}}:{[[@LINE+1]]:3-[[@LINE+1]]:10}:"std::span<int> x"
- int * x; // expected-warning{{'x' is an unsafe pointer used for buffer access}} \
- expected-note{{change type of 'x' to 'std::span' to preserve bounds information, and change 'p', 'z', and 'r' to safe types to make function 'multiParmLocalAllFix' bounds-safe}}
- // CHECK: fix-it:{{.*}}:{[[@LINE+1]]:3-[[@LINE+1]]:10}:"std::span<int> z"
- int * z; // expected-warning{{'z' is an unsafe pointer used for buffer access}} \
- expected-note{{change type of 'z' to 'std::span' to preserve bounds information, and change 'x', 'p', and 'r' to safe types to make function 'multiParmLocalAllFix' bounds-safe}}
+ // CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]:
+ // CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]:
+ int * x; // expected-warning{{'x' is an unsafe pointer used for buffer access}}
+ // CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]:
+ int * z; // expected-warning{{'z' is an unsafe pointer used for buffer access}}
int * y;
x = p;
- y = x;
+ y = x; // FIXME: we do not fix `y = x` here as the `.data()` fix-it is not generally correct
// `x` needs to be fixed so does the pointer assigned to `x`, i.e.,`p`
x[5] = 5; // expected-note{{used in buffer access here}}
z = r;
@@ -89,33 +86,26 @@ void multiParmLocalAllFix(int *p, int * r) {
// fixing `x` involves fixing all `p`, `r` and `z`. Similar for
// fixing `z`.
}
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:2-[[@LINE-1]]:2}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void multiParmLocalAllFix(int *p, int * r) {return multiParmLocalAllFix(std::span<int>(p, <# size #>), std::span<int>(r, <# size #>));}\n"
+// CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]:
// Fixing parameters implicates fixing local variables
-// CHECK: fix-it:{{.*}}:{[[@LINE+2]]:29-[[@LINE+2]]:35}:"std::span<int> p"
-// CHECK: fix-it:{{.*}}:{[[@LINE+1]]:37-[[@LINE+1]]:44}:"std::span<int> r"
+// CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]:
void multiParmLocalAllFix2(int *p, int * r) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} \
- expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'x', 'r', and 'z' to safe types to make function 'multiParmLocalAllFix2' bounds-safe}} \
- expected-warning{{'r' is an unsafe pointer used for buffer access}} \
- expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'p', 'x', and 'z' to safe types to make function 'multiParmLocalAllFix2' bounds-safe}}
+ expected-warning{{'r' is an unsafe pointer used for buffer access}}
int * x = new int[10];
- // CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:12}:"std::span<int> x"
- // CHECK: fix-it:{{.*}}:{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"
- // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"
+ // CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]:
int * z = new int[10];
- // CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:12}:"std::span<int> z"
- // CHECK: fix-it:{{.*}}:{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"
- // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"
+ // CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]:
int * y;
p = x;
- y = x;
+ y = x; // FIXME: we do not fix `y = x` here as the `.data()` fix-it is not generally correct
p[5] = 5; // expected-note{{used in buffer access here}}
r = z;
r[5] = 5; // expected-note{{used in buffer access here}}
}
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:2-[[@LINE-1]]:2}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void multiParmLocalAllFix2(int *p, int * r) {return multiParmLocalAllFix2(std::span<int>(p, <# size #>), std::span<int>(r, <# size #>));}\n"
+// CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]:
// No fix emitted for any of the parameter since parameter `r` cannot be fixed
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-fixits-test.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-fixits-test.cpp
index 2ab311295d343a1..0d7d117bca5c415 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-fixits-test.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-fixits-test.cpp
@@ -2,18 +2,14 @@
void foo1a() {
int *r = new int[7];
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> r"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:22-[[@LINE-3]]:22}:", 7}"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
int *p = new int[4];
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> p"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:22-[[@LINE-3]]:22}:", 4}"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
p = r;
int tmp = p[9];
int *q;
- // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> q"
- q = r;
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
+ q = r; // FIXME: we do not fix `q = r` here as the `.data()` fix-it is not generally correct
}
void foo1b() {
@@ -37,15 +33,13 @@ void foo1b() {
void foo1c() {
int *r = new int[7];
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> r"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:22-[[@LINE-3]]:22}:", 7}"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
int *p = new int[4];
- // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> p"
- p = r;
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
+ p = r; // FIXME: we do not fix `p = r` here as the `.data()` fix-it is not generally correct
int tmp = r[9];
int *q;
- // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> q"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
q = r;
tmp = q[9];
}
@@ -70,18 +64,12 @@ void foo2a() {
void foo2b() {
int *r = new int[7];
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> r"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:22-[[@LINE-3]]:22}:", 7}"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
int *p = new int[5];
- // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> p"
- // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
- // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-3]]:22-[[@LINE-3]]:22}:", 5}"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
int *q = new int[4];
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> q"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:22-[[@LINE-3]]:22}:", 4}"
- p = q;
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
+ p = q; // FIXME: we do not fix `p = q` here as the `.data()` fix-it is not generally correct
int tmp = q[8];
q = r;
}
@@ -107,14 +95,12 @@ void foo2c() {
void foo3a() {
int *r = new int[7];
- // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> r"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
int *p = new int[5];
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> p"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:22-[[@LINE-3]]:22}:", 5}"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
int *q = new int[4];
- // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> q"
- q = p;
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
+ q = p; // FIXME: we do not fix `q = p` here as the `.data()` fix-it is not generally correct
int tmp = p[8];
q = r;
}
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-ptr-init-fixits.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-ptr-init-fixits.cpp
index 4a40d3159627c3e..8ad6e11df301a47 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-ptr-init-fixits.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-ptr-init-fixits.cpp
@@ -62,13 +62,11 @@ void test_grouping() {
int *z = new int[8];
int tmp;
int *y = new int[10];
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> y"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
tmp = y[5];
int *x = new int[10];
- x = y;
+ x = y; // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct
int *w = z;
}
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-ptr-init.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-ptr-init.cpp
index 10ef66edce2be74..45d2bff77696355 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-ptr-init.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-ptr-init.cpp
@@ -27,17 +27,17 @@ void rhs_span3() {
int *q = new int[6];
int *p = q; // expected-warning{{'p' is an unsafe pointer used for buffer access}}
p[5] = 10; // expected-note{{used in buffer access here}}
- int *r = q;
+ int *r = q; // FIXME: we do not fix `int *r = q` here as the `.data()` fix-it is not generally correct
}
void test_grouping() {
int *z = new int[8];
int tmp;
- int *y = new int[10]; // expected-warning{{'y' is an unsafe pointer used for buffer access}} expected-note{{change type of 'y' to 'std::span' to preserve bounds information}}
+ int *y = new int[10]; // expected-warning{{'y' is an unsafe pointer used for buffer access}}
tmp = y[5]; // expected-note{{used in buffer access here}}
int *x = new int[10];
- x = y;
+ x = y; // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct
int *w = z;
}
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-uuc-fixits.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-uuc-fixits.cpp
index fab8d659ba65ce9..409a03fc0aad9b7 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-uuc-fixits.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-uuc-fixits.cpp
@@ -6,17 +6,13 @@ void bar(int * param) {}
void foo1a() {
int *r = new int[7];
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> r"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:22-[[@LINE-3]]:22}:", 7}"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
int *p = new int[4];
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> p"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:22-[[@LINE-3]]:22}:", 4}"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
p = r;
int tmp = p[9];
int *q;
- q = r;
+ q = r; // FIXME: we do not fix `q = r` here as the `.data()` fix-it is not generally correct
}
void uuc_if_body() {
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-uuc.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-uuc.cpp
index 9f6deac6683ba97..73fe20552d41017 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-uuc.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-uuc.cpp
@@ -3,11 +3,11 @@ void bar(int * param) {}
void foo1a() {
int *r = new int[7];
- int *p = new int[4]; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'r' to 'std::span' to propagate bounds information between them}}
+ int *p = new int[4]; // expected-warning{{'p' is an unsafe pointer used for buffer access}}
p = r;
int tmp = p[9]; // expected-note{{used in buffer access here}}
int *q;
- q = r;
+ q = r; // FIXME: we do not fix `q = r` here as the `.data()` fix-it is not generally correct
}
void uuc_if_body() {
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-warnings.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-warnings.cpp
index 0f2491888d297a6..917aa9520347d34 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-warnings.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-multi-decl-warnings.cpp
@@ -18,9 +18,9 @@ void local_assign_both_span() {
void local_assign_rhs_span() {
int tmp;
int* p = new int[10];
- int* q = new int[10]; // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information}}
+ int* q = new int[10]; // expected-warning{{'q' is an unsafe pointer used for buffer access}}
tmp = q[4]; // expected-note{{used in buffer access here}}
- p = q;
+ p = q; // FIXME: we do not fix `p = q` here as the `.data()` fix-it is not generally correct
}
void local_assign_no_span() {
@@ -49,10 +49,10 @@ void lhs_span_multi_assign() {
void rhs_span() {
int *x = new int[3];
- int *y; // expected-warning{{'y' is an unsafe pointer used for buffer access}} expected-note{{change type of 'y' to 'std::span' to preserve bounds information}}
+ int *y; // expected-warning{{'y' is an unsafe pointer used for buffer access}}
y[5] = 10; // expected-note{{used in buffer access here}}
- x = y;
+ x = y; // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct
}
void rhs_span1() {
@@ -65,43 +65,43 @@ void rhs_span1() {
void rhs_span2() {
int *q = new int[6];
- int *p = q; // expected-warning{{'p' is an unsafe pointer used for buffer access}}
+ int *p = q; // expected-warning{{'p' is an unsafe pointer used for buffer access}}
p[5] = 10; // expected-note{{used in buffer access here}}
- int *r = q;
+ int *r = q; // FIXME: we do not fix `int *r = q` here as the `.data()` fix-it is not generally correct
}
void test_grouping() {
int *z = new int[8];
int tmp;
- int *y = new int[10]; // expected-warning{{'y' is an unsafe pointer used for buffer access}} expected-note{{change type of 'y' to 'std::span' to preserve bounds information}}
+ int *y = new int[10]; // expected-warning{{'y' is an unsafe pointer used for buffer access}}
tmp = y[5]; // expected-note{{used in buffer access here}}
int *x = new int[10];
- x = y;
+ x = y; // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct
int *w = z;
}
void test_grouping1() {
int tmp;
- int *y = new int[10]; // expected-warning{{'y' is an unsafe pointer used for buffer access}} expected-note{{change type of 'y' to 'std::span' to preserve bounds information}}
+ int *y = new int[10]; // expected-warning{{'y' is an unsafe pointer used for buffer access}}
tmp = y[5]; // expected-note{{used in buffer access here}}
int *x = new int[10];
- x = y;
+ x = y; // FIXME: we do not fix `x = y` here as the `.data()` fix-it is not generally correct
- int *w = new int[10]; // expected-warning{{'w' is an unsafe pointer used for buffer access}} expected-note{{change type of 'w' to 'std::span' to preserve bounds information}}
+ int *w = new int[10]; // expected-warning{{'w' is an unsafe pointer used for buffer access}}
tmp = w[5]; // expected-note{{used in buffer access here}}
int *z = new int[10];
- z = w;
+ z = w; // FIXME: we do not fix `z = w` here as the `.data()` fix-it is not generally correct
}
void foo1a() {
int *r = new int[7];
- int *p = new int[4]; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'r' to 'std::span' to propagate bounds information between them}}
+ int *p = new int[4]; // expected-warning{{'p' is an unsafe pointer used for buffer access}}
p = r;
int tmp = p[9]; // expected-note{{used in buffer access here}}
int *q;
- q = r;
+ q = r; // FIXME: we do not fix `q = r` here as the `.data()` fix-it is not generally correct
}
void foo1b() {
@@ -115,12 +115,12 @@ void foo1b() {
}
void foo1c() {
- int *r = new int[7]; // expected-warning{{'r' is an unsafe pointer used for buffer access}} expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'q' to 'std::span' to propagate bounds information between them}}
+ int *r = new int[7]; // expected-warning{{'r' is an unsafe pointer used for buffer access}}
int *p = new int[4];
- p = r;
+ p = r; // FIXME: we do not fix `p = r` here as the `.data()` fix-it is not generally correct
int tmp = r[9]; // expected-note{{used in buffer access here}}
- int *q; // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'r' to 'std::span' to propagate bounds information between them}}
- q = r;
+ int *q; // expected-warning{{'q' is an unsafe pointer used for buffer access}}
+ q = r; // FIXME: we do not fix `q = r` here as the `.data()` fix-it is not generally correct
tmp = q[9]; // expected-note{{used in buffer access here}}
}
@@ -136,8 +136,8 @@ void foo2a() {
void foo2b() {
int *r = new int[7];
int *p = new int[5];
- int *q = new int[4]; // expected-warning{{'q' is an unsafe pointer used for buffer access}} expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'r' to 'std::span' to propagate bounds information between them}}
- p = q;
+ int *q = new int[4]; // expected-warning{{'q' is an unsafe pointer used for buffer access}}
+ p = q; // FIXME: we do not fix `p = q` here as the `.data()` fix-it is not generally correct
int tmp = q[8]; // expected-note{{used in buffer access here}}
q = r;
}
@@ -154,9 +154,9 @@ void foo2c() {
void foo3a() {
int *r = new int[7];
- int *p = new int[5]; // expected-warning{{'p' is an unsafe pointer used for buffer access}} expected-note{{change type of 'p' to 'std::span' to preserve bounds information}}
+ int *p = new int[5]; // expected-warning{{'p' is an unsafe pointer used for buffer access}}
int *q = new int[4];
- q = p;
+ q = p; // FIXME: we do not fix `q = p` here as the `.data()` fix-it is not generally correct
int tmp = p[8]; // expected-note{{used in buffer access here}}
q = r;
}
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-pragma-fixit.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-pragma-fixit.cpp
index 6bd1065e1e2be2a..74ec70b630486f9 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-pragma-fixit.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-pragma-fixit.cpp
@@ -174,7 +174,7 @@ void suppressedVarInGroup3() {
int * b;
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
int * c;
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"std::span<int> c"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
c[5] = 5;
#pragma clang unsafe_buffer_usage begin
@@ -182,6 +182,7 @@ void suppressedVarInGroup3() {
#pragma clang unsafe_buffer_usage end
a = b;
b = c;
+// FIXME: we do not fix `a = b` and `b = c` because the `.data()` fix-it is not generally correct.
}
// The implication edges are: `a` -> `b` -> `c` -> `a`.
More information about the cfe-commits
mailing list