Skip to content

Commit fb694a8

Browse files
committed
Merge branch 'main' into merge-functions
2 parents 07aa7c1 + 854d730 commit fb694a8

File tree

277 files changed

+5958
-1247
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

277 files changed

+5958
-1247
lines changed

clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@ using namespace clang::ast_matchers;
2020
namespace clang::tidy::modernize {
2121

2222
static bool isNegativeComparison(const Expr *ComparisonExpr) {
23-
if (const auto *BO = llvm::dyn_cast<BinaryOperator>(ComparisonExpr))
24-
return BO->getOpcode() == BO_NE;
23+
if (const auto *Op = llvm::dyn_cast<BinaryOperator>(ComparisonExpr))
24+
return Op->getOpcode() == BO_NE;
2525

2626
if (const auto *Op = llvm::dyn_cast<CXXOperatorCallExpr>(ComparisonExpr))
2727
return Op->getOperator() == OO_ExclaimEqual;
2828

29+
if (const auto *Op =
30+
llvm::dyn_cast<CXXRewrittenBinaryOperator>(ComparisonExpr))
31+
return Op->getOperator() == BO_NE;
32+
2933
return false;
3034
}
3135

@@ -185,7 +189,7 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder *Finder) {
185189

186190
// Case 6: X.substr(0, LEN(Y)) [!=]= Y -> starts_with.
187191
Finder->addMatcher(
188-
cxxOperatorCallExpr(
192+
binaryOperation(
189193
hasAnyOperatorName("==", "!="),
190194
hasOperands(
191195
expr().bind("needle"),

clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,6 @@ bool operator==(const std::string&, const std::string&);
136136
bool operator==(const std::string&, const char*);
137137
bool operator==(const char*, const std::string&);
138138

139-
bool operator!=(const std::string&, const std::string&);
140-
bool operator!=(const std::string&, const char*);
141-
bool operator!=(const char*, const std::string&);
142-
143139
bool operator==(const std::wstring&, const std::wstring&);
144140
bool operator==(const std::wstring&, const wchar_t*);
145141
bool operator==(const wchar_t*, const std::wstring&);
@@ -148,9 +144,15 @@ bool operator==(const std::string_view&, const std::string_view&);
148144
bool operator==(const std::string_view&, const char*);
149145
bool operator==(const char*, const std::string_view&);
150146

147+
#if __cplusplus < 202002L
148+
bool operator!=(const std::string&, const std::string&);
149+
bool operator!=(const std::string&, const char*);
150+
bool operator!=(const char*, const std::string&);
151+
151152
bool operator!=(const std::string_view&, const std::string_view&);
152153
bool operator!=(const std::string_view&, const char*);
153154
bool operator!=(const char*, const std::string_view&);
155+
#endif
154156

155157
size_t strlen(const char* str);
156158
}

clang-tools-extra/test/clang-tidy/checkers/modernize/use-starts-ends-with.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,3 +320,13 @@ void test_substr() {
320320

321321
str.substr(0, strlen("hello123")) == "hello";
322322
}
323+
324+
void test_operator_rewriting(std::string str, std::string prefix) {
325+
str.substr(0, prefix.size()) == prefix;
326+
// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr
327+
// CHECK-FIXES: str.starts_with(prefix);
328+
329+
str.substr(0, prefix.size()) != prefix;
330+
// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr
331+
// CHECK-FIXES: !str.starts_with(prefix);
332+
}

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,7 @@ Bug Fixes to C++ Support
725725
- Clang now uses valid deduced type locations when diagnosing functions with trailing return type
726726
missing placeholder return type. (#GH78694)
727727
- Fixed a bug where bounds of partially expanded pack indexing expressions were checked too early. (#GH116105)
728+
- Fixed an assertion failure caused by using ``consteval`` in condition in consumed analyses. (#GH117385)
728729

729730
Bug Fixes to AST Handling
730731
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6270,7 +6270,7 @@ def err_typecheck_invalid_restrict_invalid_pointee : Error<
62706270
def ext_typecheck_zero_array_size : Extension<
62716271
"zero size arrays are an extension">, InGroup<ZeroLengthArray>;
62726272
def err_typecheck_zero_array_size : Error<
6273-
"zero-length arrays are not permitted in %select{C++|SYCL device code}0">;
6273+
"zero-length arrays are not permitted in %select{C++|SYCL device code|HIP device code}0">;
62746274
def err_array_size_non_int : Error<"size of array has non-integer type %0">;
62756275
def err_init_element_not_constant : Error<
62766276
"initializer element is not a compile-time constant">;
@@ -6670,14 +6670,15 @@ def warn_counted_by_attr_elt_type_unknown_size :
66706670
// __builtin_counted_by_ref diagnostics:
66716671
def err_builtin_counted_by_ref_must_be_flex_array_member : Error<
66726672
"'__builtin_counted_by_ref' argument must reference a flexible array member">;
6673+
def err_builtin_counted_by_ref_has_side_effects : Error<
6674+
"'__builtin_counted_by_ref' argument cannot have side-effects">;
6675+
66736676
def err_builtin_counted_by_ref_cannot_leak_reference : Error<
6674-
"value returned by '__builtin_counted_by_ref' cannot be assigned to a "
6675-
"variable, have its address taken, or passed into or returned from a function">;
6676-
def err_builtin_counted_by_ref_invalid_lhs_use : Error<
6677+
"value returned by '__builtin_counted_by_ref' cannot be %select{assigned to a "
6678+
"variable|passed into a function|returned from a function}0">;
6679+
def err_builtin_counted_by_ref_invalid_use : Error<
66776680
"value returned by '__builtin_counted_by_ref' cannot be used in "
66786681
"%select{an array subscript|a binary}0 expression">;
6679-
def err_builtin_counted_by_ref_has_side_effects : Error<
6680-
"'__builtin_counted_by_ref' argument cannot have side-effects">;
66816682

66826683
let CategoryName = "ARC Semantic Issue" in {
66836684

clang/include/clang/Sema/Sema.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2524,6 +2524,17 @@ class Sema final : public SemaBase {
25242524

25252525
bool BuiltinNonDeterministicValue(CallExpr *TheCall);
25262526

2527+
enum BuiltinCountedByRefKind {
2528+
AssignmentKind,
2529+
InitializerKind,
2530+
FunctionArgKind,
2531+
ReturnArgKind,
2532+
ArraySubscriptKind,
2533+
BinaryExprKind,
2534+
};
2535+
2536+
bool CheckInvalidBuiltinCountedByRef(const Expr *E,
2537+
BuiltinCountedByRefKind K);
25272538
bool BuiltinCountedByRef(CallExpr *TheCall);
25282539

25292540
// Matrix builtin handling.

clang/lib/Analysis/Consumed.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,6 +1229,9 @@ bool ConsumedAnalyzer::splitState(const CFGBlock *CurrBlock,
12291229

12301230
if (const auto *IfNode =
12311231
dyn_cast_or_null<IfStmt>(CurrBlock->getTerminator().getStmt())) {
1232+
if (IfNode->isConsteval())
1233+
return false;
1234+
12321235
const Expr *Cond = IfNode->getCond();
12331236

12341237
PInfo = Visitor.getInfo(Cond);

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 82 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,12 @@ class MatchDescendantVisitor : public DynamicRecursiveASTVisitor {
172172
return DynamicRecursiveASTVisitor::TraverseCXXTypeidExpr(Node);
173173
}
174174

175+
bool TraverseCXXDefaultInitExpr(CXXDefaultInitExpr *Node) override {
176+
if (!TraverseStmt(Node->getExpr()))
177+
return false;
178+
return DynamicRecursiveASTVisitor::TraverseCXXDefaultInitExpr(Node);
179+
}
180+
175181
bool TraverseStmt(Stmt *Node) override {
176182
if (!Node)
177183
return true;
@@ -1987,14 +1993,18 @@ class DerefSimplePtrArithFixableGadget : public FixableGadget {
19871993
};
19881994

19891995
/// Scan the function and return a list of gadgets found with provided kits.
1990-
static std::tuple<FixableGadgetList, WarningGadgetList, DeclUseTracker>
1991-
findGadgets(const Decl *D, const UnsafeBufferUsageHandler &Handler,
1992-
bool EmitSuggestions) {
1996+
static void findGadgets(const Stmt *S, ASTContext &Ctx,
1997+
const UnsafeBufferUsageHandler &Handler,
1998+
bool EmitSuggestions, FixableGadgetList &FixableGadgets,
1999+
WarningGadgetList &WarningGadgets,
2000+
DeclUseTracker &Tracker) {
19932001

19942002
struct GadgetFinderCallback : MatchFinder::MatchCallback {
1995-
FixableGadgetList FixableGadgets;
1996-
WarningGadgetList WarningGadgets;
1997-
DeclUseTracker Tracker;
2003+
GadgetFinderCallback(FixableGadgetList &FixableGadgets,
2004+
WarningGadgetList &WarningGadgets,
2005+
DeclUseTracker &Tracker)
2006+
: FixableGadgets(FixableGadgets), WarningGadgets(WarningGadgets),
2007+
Tracker(Tracker) {}
19982008

19992009
void run(const MatchFinder::MatchResult &Result) override {
20002010
// In debug mode, assert that we've found exactly one gadget.
@@ -2035,10 +2045,14 @@ findGadgets(const Decl *D, const UnsafeBufferUsageHandler &Handler,
20352045
assert(numFound >= 1 && "Gadgets not found in match result!");
20362046
assert(numFound <= 1 && "Conflicting bind tags in gadgets!");
20372047
}
2048+
2049+
FixableGadgetList &FixableGadgets;
2050+
WarningGadgetList &WarningGadgets;
2051+
DeclUseTracker &Tracker;
20382052
};
20392053

20402054
MatchFinder M;
2041-
GadgetFinderCallback CB;
2055+
GadgetFinderCallback CB{FixableGadgets, WarningGadgets, Tracker};
20422056

20432057
// clang-format off
20442058
M.addMatcher(
@@ -2083,9 +2097,7 @@ findGadgets(const Decl *D, const UnsafeBufferUsageHandler &Handler,
20832097
// clang-format on
20842098
}
20852099

2086-
M.match(*D->getBody(), D->getASTContext());
2087-
return {std::move(CB.FixableGadgets), std::move(CB.WarningGadgets),
2088-
std::move(CB.Tracker)};
2100+
M.match(*S, Ctx);
20892101
}
20902102

20912103
// Compares AST nodes by source locations.
@@ -3630,39 +3642,9 @@ class VariableGroupsManagerImpl : public VariableGroupsManager {
36303642
}
36313643
};
36323644

3633-
void clang::checkUnsafeBufferUsage(const Decl *D,
3634-
UnsafeBufferUsageHandler &Handler,
3635-
bool EmitSuggestions) {
3636-
#ifndef NDEBUG
3637-
Handler.clearDebugNotes();
3638-
#endif
3639-
3640-
assert(D && D->getBody());
3641-
// We do not want to visit a Lambda expression defined inside a method
3642-
// independently. Instead, it should be visited along with the outer method.
3643-
// FIXME: do we want to do the same thing for `BlockDecl`s?
3644-
if (const auto *fd = dyn_cast<CXXMethodDecl>(D)) {
3645-
if (fd->getParent()->isLambda() && fd->getParent()->isLocalClass())
3646-
return;
3647-
}
3648-
3649-
// Do not emit fixit suggestions for functions declared in an
3650-
// extern "C" block.
3651-
if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3652-
for (FunctionDecl *FReDecl : FD->redecls()) {
3653-
if (FReDecl->isExternC()) {
3654-
EmitSuggestions = false;
3655-
break;
3656-
}
3657-
}
3658-
}
3659-
3660-
WarningGadgetSets UnsafeOps;
3661-
FixableGadgetSets FixablesForAllVars;
3662-
3663-
auto [FixableGadgets, WarningGadgets, Tracker] =
3664-
findGadgets(D, Handler, EmitSuggestions);
3665-
3645+
void applyGadgets(const Decl *D, FixableGadgetList FixableGadgets,
3646+
WarningGadgetList WarningGadgets, DeclUseTracker Tracker,
3647+
UnsafeBufferUsageHandler &Handler, bool EmitSuggestions) {
36663648
if (!EmitSuggestions) {
36673649
// Our job is very easy without suggestions. Just warn about
36683650
// every problematic operation and consider it done. No need to deal
@@ -3706,8 +3688,10 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
37063688
if (WarningGadgets.empty())
37073689
return;
37083690

3709-
UnsafeOps = groupWarningGadgetsByVar(std::move(WarningGadgets));
3710-
FixablesForAllVars = groupFixablesByVar(std::move(FixableGadgets));
3691+
WarningGadgetSets UnsafeOps =
3692+
groupWarningGadgetsByVar(std::move(WarningGadgets));
3693+
FixableGadgetSets FixablesForAllVars =
3694+
groupFixablesByVar(std::move(FixableGadgets));
37113695

37123696
std::map<const VarDecl *, FixItList> FixItsForVariableGroup;
37133697

@@ -3928,3 +3912,56 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
39283912
}
39293913
}
39303914
}
3915+
3916+
void clang::checkUnsafeBufferUsage(const Decl *D,
3917+
UnsafeBufferUsageHandler &Handler,
3918+
bool EmitSuggestions) {
3919+
#ifndef NDEBUG
3920+
Handler.clearDebugNotes();
3921+
#endif
3922+
3923+
assert(D);
3924+
3925+
SmallVector<Stmt *> Stmts;
3926+
3927+
if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3928+
// We do not want to visit a Lambda expression defined inside a method
3929+
// independently. Instead, it should be visited along with the outer method.
3930+
// FIXME: do we want to do the same thing for `BlockDecl`s?
3931+
if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
3932+
if (MD->getParent()->isLambda() && MD->getParent()->isLocalClass())
3933+
return;
3934+
}
3935+
3936+
for (FunctionDecl *FReDecl : FD->redecls()) {
3937+
if (FReDecl->isExternC()) {
3938+
// Do not emit fixit suggestions for functions declared in an
3939+
// extern "C" block.
3940+
EmitSuggestions = false;
3941+
break;
3942+
}
3943+
}
3944+
3945+
Stmts.push_back(FD->getBody());
3946+
3947+
if (const auto *ID = dyn_cast<CXXConstructorDecl>(D)) {
3948+
for (const CXXCtorInitializer *CI : ID->inits()) {
3949+
Stmts.push_back(CI->getInit());
3950+
}
3951+
}
3952+
} else if (isa<BlockDecl>(D) || isa<ObjCMethodDecl>(D)) {
3953+
Stmts.push_back(D->getBody());
3954+
}
3955+
3956+
assert(!Stmts.empty());
3957+
3958+
FixableGadgetList FixableGadgets;
3959+
WarningGadgetList WarningGadgets;
3960+
DeclUseTracker Tracker;
3961+
for (Stmt *S : Stmts) {
3962+
findGadgets(S, D->getASTContext(), Handler, EmitSuggestions, FixableGadgets,
3963+
WarningGadgets, Tracker);
3964+
}
3965+
applyGadgets(D, std::move(FixableGadgets), std::move(WarningGadgets),
3966+
std::move(Tracker), Handler, EmitSuggestions);
3967+
}

clang/lib/Sema/SemaAPINotes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ static void ProcessAPINotes(Sema &S, FunctionOrMethod AnyFunc,
482482
Decl *D = FD;
483483
ObjCMethodDecl *MD = nullptr;
484484
if (!D) {
485-
MD = AnyFunc.get<ObjCMethodDecl *>();
485+
MD = cast<ObjCMethodDecl *>(AnyFunc);
486486
D = MD;
487487
}
488488

clang/lib/Sema/SemaChecking.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5664,6 +5664,45 @@ bool Sema::BuiltinCountedByRef(CallExpr *TheCall) {
56645664
return false;
56655665
}
56665666

5667+
/// The result of __builtin_counted_by_ref cannot be assigned to a variable.
5668+
/// It allows leaking and modification of bounds safety information.
5669+
bool Sema::CheckInvalidBuiltinCountedByRef(const Expr *E,
5670+
BuiltinCountedByRefKind K) {
5671+
const CallExpr *CE =
5672+
E ? dyn_cast<CallExpr>(E->IgnoreParenImpCasts()) : nullptr;
5673+
if (!CE || CE->getBuiltinCallee() != Builtin::BI__builtin_counted_by_ref)
5674+
return false;
5675+
5676+
switch (K) {
5677+
case AssignmentKind:
5678+
case InitializerKind:
5679+
Diag(E->getExprLoc(),
5680+
diag::err_builtin_counted_by_ref_cannot_leak_reference)
5681+
<< 0 << E->getSourceRange();
5682+
break;
5683+
case FunctionArgKind:
5684+
Diag(E->getExprLoc(),
5685+
diag::err_builtin_counted_by_ref_cannot_leak_reference)
5686+
<< 1 << E->getSourceRange();
5687+
break;
5688+
case ReturnArgKind:
5689+
Diag(E->getExprLoc(),
5690+
diag::err_builtin_counted_by_ref_cannot_leak_reference)
5691+
<< 2 << E->getSourceRange();
5692+
break;
5693+
case ArraySubscriptKind:
5694+
Diag(E->getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
5695+
<< 0 << E->getSourceRange();
5696+
break;
5697+
case BinaryExprKind:
5698+
Diag(E->getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
5699+
<< 1 << E->getSourceRange();
5700+
break;
5701+
}
5702+
5703+
return true;
5704+
}
5705+
56675706
namespace {
56685707

56695708
class UncoveredArgHandler {

0 commit comments

Comments
 (0)