Skip to content

Commit deb96ca

Browse files
authored
Merge branch 'main' into move_availability_docs
2 parents 9dd1d65 + 0a65849 commit deb96ca

File tree

149 files changed

+16080
-2627
lines changed

Some content is hidden

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

149 files changed

+16080
-2627
lines changed

clang-tools-extra/clang-tidy/tool/check_alphabetical_order.py

Lines changed: 412 additions & 0 deletions
Large diffs are not rendered by default.

clang-tools-extra/clang-tidy/tool/check_alphabetical_order_test.py

Lines changed: 394 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %python %S/../../../clang-tidy/tool/check_alphabetical_order.py -o %t.clang-tidy-checks-list.rst
2+
// RUN: diff --strip-trailing-cr %t.clang-tidy-checks-list.rst %S/../../../docs/clang-tidy/checks/list.rst
3+
4+
// RUN: %python %S/../../../clang-tidy/tool/check_alphabetical_order.py -o %t.ReleaseNotes.rst
5+
// RUN: diff --strip-trailing-cr %t.ReleaseNotes.rst %S/../../../docs/ReleaseNotes.rst

clang-tools-extra/test/lit.cfg.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
if config.clang_tidy_custom_check:
5858
config.available_features.add("custom-check")
5959
python_exec = shlex.quote(config.python_executable)
60+
config.substitutions.append(("%python", python_exec))
6061
check_clang_tidy = os.path.join(
6162
config.test_source_root, "clang-tidy", "check_clang_tidy.py"
6263
)

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,10 @@ Improvements to Clang's diagnostics
460460
- A new warning ``-Wshadow-header`` has been added to detect when a header file
461461
is found in multiple search directories (excluding system paths).
462462

463+
- Clang now detects potential missing format and format_matches attributes on function,
464+
Objective-C method and block declarations when calling format functions. It is part
465+
of the format-nonliteral diagnostic (#GH60718)
466+
463467
Improvements to Clang's time-trace
464468
----------------------------------
465469

clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class FactsGenerator : public ConstStmtVisitor<FactsGenerator> {
9191

9292
void markUseAsWrite(const DeclRefExpr *DRE);
9393

94+
llvm::SmallVector<Fact *> issuePlaceholderLoans();
9495
FactManager &FactMgr;
9596
AnalysisDeclContext &AC;
9697
llvm::SmallVector<Fact *> CurrentBlockFacts;

clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ class LifetimeSafetyReporter {
4747
const Expr *EscapeExpr,
4848
SourceLocation ExpiryLoc,
4949
Confidence Confidence) {}
50+
51+
// Suggests lifetime bound annotations for function paramters
52+
virtual void suggestAnnotation(const ParmVarDecl *PVD,
53+
const Expr *EscapeExpr) {}
5054
};
5155

5256
/// The main entry point for the analysis.

clang/include/clang/Analysis/Analyses/LifetimeSafety/Loans.h

Lines changed: 82 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,46 +34,115 @@ struct AccessPath {
3434
AccessPath(const clang::ValueDecl *D) : D(D) {}
3535
};
3636

37-
/// Information about a single borrow, or "Loan". A loan is created when a
38-
/// reference or pointer is created.
39-
struct Loan {
37+
/// An abstract base class for a single "Loan" which represents lending a
38+
/// storage in memory.
39+
class Loan {
4040
/// TODO: Represent opaque loans.
4141
/// TODO: Represent nullptr: loans to no path. Accessing it UB! Currently it
4242
/// is represented as empty LoanSet
43-
LoanID ID;
43+
public:
44+
enum class Kind : uint8_t {
45+
/// A loan with an access path to a storage location.
46+
Path,
47+
/// A non-expiring placeholder loan for a parameter, representing a borrow
48+
/// from the function's caller.
49+
Placeholder
50+
};
51+
52+
Loan(Kind K, LoanID ID) : K(K), ID(ID) {}
53+
virtual ~Loan() = default;
54+
55+
Kind getKind() const { return K; }
56+
LoanID getID() const { return ID; }
57+
58+
virtual void dump(llvm::raw_ostream &OS) const = 0;
59+
60+
private:
61+
const Kind K;
62+
const LoanID ID;
63+
};
64+
65+
/// PathLoan represents lending a storage location that is visible within the
66+
/// function's scope (e.g., a local variable on stack).
67+
class PathLoan : public Loan {
4468
AccessPath Path;
4569
/// The expression that creates the loan, e.g., &x.
4670
const Expr *IssueExpr;
4771

48-
Loan(LoanID id, AccessPath path, const Expr *IssueExpr)
49-
: ID(id), Path(path), IssueExpr(IssueExpr) {}
72+
public:
73+
PathLoan(LoanID ID, AccessPath Path, const Expr *IssueExpr)
74+
: Loan(Kind::Path, ID), Path(Path), IssueExpr(IssueExpr) {}
75+
76+
const AccessPath &getAccessPath() const { return Path; }
77+
const Expr *getIssueExpr() const { return IssueExpr; }
5078

51-
void dump(llvm::raw_ostream &OS) const;
79+
void dump(llvm::raw_ostream &OS) const override;
80+
81+
static bool classof(const Loan *L) { return L->getKind() == Kind::Path; }
82+
};
83+
84+
/// A placeholder loan held by a function parameter, representing a borrow from
85+
/// the caller's scope.
86+
///
87+
/// Created at function entry for each pointer or reference parameter with an
88+
/// origin. Unlike PathLoan, placeholder loans:
89+
/// - Have no IssueExpr (created at function entry, not at a borrow site)
90+
/// - Have no AccessPath (the borrowed object is not visible to the function)
91+
/// - Do not currently expire, but may in the future when modeling function
92+
/// invalidations (e.g., vector::push_back)
93+
///
94+
/// When a placeholder loan escapes the function (e.g., via return), it
95+
/// indicates the parameter should be marked [[clang::lifetimebound]], enabling
96+
/// lifetime annotation suggestions.
97+
class PlaceholderLoan : public Loan {
98+
/// The function parameter that holds this placeholder loan.
99+
const ParmVarDecl *PVD;
100+
101+
public:
102+
PlaceholderLoan(LoanID ID, const ParmVarDecl *PVD)
103+
: Loan(Kind::Placeholder, ID), PVD(PVD) {}
104+
105+
const ParmVarDecl *getParmVarDecl() const { return PVD; }
106+
107+
void dump(llvm::raw_ostream &OS) const override;
108+
109+
static bool classof(const Loan *L) {
110+
return L->getKind() == Kind::Placeholder;
111+
}
52112
};
53113

54114
/// Manages the creation, storage and retrieval of loans.
55115
class LoanManager {
56116
public:
57117
LoanManager() = default;
58118

59-
Loan &addLoan(AccessPath Path, const Expr *IssueExpr) {
60-
AllLoans.emplace_back(getNextLoanID(), Path, IssueExpr);
61-
return AllLoans.back();
119+
template <typename LoanType, typename... Args>
120+
LoanType *createLoan(Args &&...args) {
121+
static_assert(
122+
std::is_same_v<LoanType, PathLoan> ||
123+
std::is_same_v<LoanType, PlaceholderLoan>,
124+
"createLoan can only be used with PathLoan or PlaceholderLoan");
125+
void *Mem = LoanAllocator.Allocate<LoanType>();
126+
auto *NewLoan =
127+
new (Mem) LoanType(getNextLoanID(), std::forward<Args>(args)...);
128+
AllLoans.push_back(NewLoan);
129+
return NewLoan;
62130
}
63131

64-
const Loan &getLoan(LoanID ID) const {
132+
const Loan *getLoan(LoanID ID) const {
65133
assert(ID.Value < AllLoans.size());
66134
return AllLoans[ID.Value];
67135
}
68-
llvm::ArrayRef<Loan> getLoans() const { return AllLoans; }
136+
llvm::ArrayRef<const Loan *> getLoans() const { return AllLoans; }
69137

70138
private:
71139
LoanID getNextLoanID() { return NextLoanID++; }
72140

73141
LoanID NextLoanID{0};
74142
/// TODO(opt): Profile and evaluate the usefullness of small buffer
75143
/// optimisation.
76-
llvm::SmallVector<Loan> AllLoans;
144+
llvm::SmallVector<const Loan *> AllLoans;
145+
llvm::BumpPtrAllocator LoanAllocator;
77146
};
78147
} // namespace clang::lifetimes::internal
79148

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,8 @@ def LifetimeSafety : DiagGroup<"experimental-lifetime-safety",
541541
Experimental warnings to detect use-after-free and related temporal safety bugs based on lifetime safety analysis.
542542
}];
543543
}
544+
def LifetimeSafetySuggestions
545+
: DiagGroup<"experimental-lifetime-safety-suggestions">;
544546

545547
def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
546548
def DllexportExplicitInstantiationDecl : DiagGroup<"dllexport-explicit-instantiation-decl">;
@@ -607,7 +609,6 @@ def MainReturnType : DiagGroup<"main-return-type">;
607609
def MaxUnsignedZero : DiagGroup<"max-unsigned-zero">;
608610
def MissingBraces : DiagGroup<"missing-braces">;
609611
def MissingDeclarations: DiagGroup<"missing-declarations">;
610-
def : DiagGroup<"missing-format-attribute">;
611612
def MissingIncludeDirs : DiagGroup<"missing-include-dirs">;
612613
def MissingNoreturn : DiagGroup<"missing-noreturn">;
613614
def MultiChar : DiagGroup<"multichar">;
@@ -1186,6 +1187,7 @@ def FormatY2K : DiagGroup<"format-y2k">;
11861187
def FormatPedantic : DiagGroup<"format-pedantic">;
11871188
def FormatSignedness : DiagGroup<"format-signedness">;
11881189
def FormatTypeConfusion : DiagGroup<"format-type-confusion">;
1190+
def MissingFormatAttribute : DiagGroup<"missing-format-attribute">;
11891191

11901192
def FormatOverflowNonKprintf: DiagGroup<"format-overflow-non-kprintf">;
11911193
def FormatOverflow: DiagGroup<"format-overflow", [FormatOverflowNonKprintf]>;
@@ -1197,7 +1199,7 @@ def Format : DiagGroup<"format",
11971199
FormatSecurity, FormatY2K, FormatInvalidSpecifier,
11981200
FormatInsufficientArgs, FormatOverflow, FormatTruncation]>,
11991201
DiagCategory<"Format String Issue">;
1200-
def FormatNonLiteral : DiagGroup<"format-nonliteral">;
1202+
def FormatNonLiteral : DiagGroup<"format-nonliteral", [MissingFormatAttribute]>;
12011203
def Format2 : DiagGroup<"format=2",
12021204
[FormatNonLiteral, FormatSecurity, FormatY2K]>;
12031205

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3496,6 +3496,10 @@ def err_format_attribute_result_not : Error<"function does not return %0">;
34963496
def err_format_attribute_implicit_this_format_string : Error<
34973497
"format attribute cannot specify the implicit this argument as the format "
34983498
"string">;
3499+
def warn_missing_format_attribute : Warning<
3500+
"diagnostic behavior may be improved by adding the '%0' attribute to the "
3501+
"declaration of %1">,
3502+
InGroup<MissingFormatAttribute>, DefaultIgnore;
34993503
def err_callback_attribute_no_callee : Error<
35003504
"'callback' attribute specifies no callback callee">;
35013505
def err_callback_attribute_invalid_callee : Error<
@@ -8672,7 +8676,7 @@ def err_conditional_vector_has_void : Error<
86728676
def err_conditional_vector_operand_type
86738677
: Error<"enumeration type %0 is not allowed in a vector conditional">;
86748678
def err_conditional_vector_cond_result_mismatch
8675-
: Error<"cannot mix vectors and extended vectors in a vector conditional">;
8679+
: Error<"cannot mix vectors and %select{sizeless|extended}0 vectors in a vector conditional">;
86768680
def err_conditional_vector_mismatched
86778681
: Error<"vector operands to the vector conditional must be the same type "
86788682
"%diff{($ and $)|}0,1}">;
@@ -10784,6 +10788,13 @@ def note_lifetime_safety_used_here : Note<"later used here">;
1078410788
def note_lifetime_safety_destroyed_here : Note<"destroyed here">;
1078510789
def note_lifetime_safety_returned_here : Note<"returned here">;
1078610790

10791+
def warn_lifetime_safety_suggest_lifetimebound
10792+
: Warning<"param should be marked [[clang::lifetimebound]]">,
10793+
InGroup<LifetimeSafetySuggestions>,
10794+
DefaultIgnore;
10795+
10796+
def note_lifetime_safety_suggestion_returned_here : Note<"param returned here">;
10797+
1078710798
// For non-floating point, expressions of the form x == x or x != x
1078810799
// should result in a warning, since these always evaluate to a constant.
1078910800
// Array comparisons have similar warnings

0 commit comments

Comments
 (0)