Skip to content

Commit 67bfd48

Browse files
authored
Merge branch 'main' into fix/116485
2 parents 8c3117a + 8a6a76b commit 67bfd48

Some content is hidden

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

50 files changed

+1087
-779
lines changed

clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace {
2020

2121
AST_MATCHER_P(FunctionDecl, isEnabled, llvm::StringSet<>,
2222
FunctionsThatShouldNotThrow) {
23-
return FunctionsThatShouldNotThrow.count(Node.getNameAsString()) > 0;
23+
return FunctionsThatShouldNotThrow.contains(Node.getNameAsString());
2424
}
2525

2626
AST_MATCHER(FunctionDecl, isExplicitThrow) {

clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ ExceptionAnalyzer::ExceptionInfo::filterIgnoredExceptions(
418418
if (TD->getDeclName().isIdentifier()) {
419419
if ((IgnoreBadAlloc &&
420420
(TD->getName() == "bad_alloc" && TD->isInStdNamespace())) ||
421-
(IgnoredTypes.count(TD->getName()) > 0))
421+
(IgnoredTypes.contains(TD->getName())))
422422
TypesToDelete.push_back(T);
423423
}
424424
}
@@ -449,7 +449,8 @@ void ExceptionAnalyzer::ExceptionInfo::reevaluateBehaviour() {
449449
ExceptionAnalyzer::ExceptionInfo ExceptionAnalyzer::throwsException(
450450
const FunctionDecl *Func, const ExceptionInfo::Throwables &Caught,
451451
llvm::SmallSet<const FunctionDecl *, 32> &CallStack) {
452-
if (!Func || CallStack.count(Func) || (!CallStack.empty() && !canThrow(Func)))
452+
if (!Func || CallStack.contains(Func) ||
453+
(!CallStack.empty() && !canThrow(Func)))
453454
return ExceptionInfo::createNonThrowing();
454455

455456
if (const Stmt *Body = Func->getBody()) {
@@ -507,7 +508,7 @@ ExceptionAnalyzer::ExceptionInfo ExceptionAnalyzer::throwsException(
507508
for (unsigned I = 0; I < Try->getNumHandlers(); ++I) {
508509
const CXXCatchStmt *Catch = Try->getHandler(I);
509510

510-
// Everything is catched through 'catch(...)'.
511+
// Everything is caught through 'catch(...)'.
511512
if (!Catch->getExceptionDecl()) {
512513
ExceptionInfo Rethrown = throwsException(
513514
Catch->getHandlerBlock(), Uncaught.getExceptionTypes(), CallStack);

clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ class ExceptionAnalyzer {
101101
/// Recalculate the 'Behaviour' for example after filtering.
102102
void reevaluateBehaviour();
103103

104-
/// Keep track if the entity related to this 'ExceptionInfo' can in princple
105-
/// throw, if it's unknown or if it won't throw.
104+
/// Keep track if the entity related to this 'ExceptionInfo' can in
105+
/// principle throw, if it's unknown or if it won't throw.
106106
State Behaviour;
107107

108108
/// Keep track if the entity contains any unknown elements to keep track

clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,13 @@ findContextForNS(llvm::StringRef TargetNS, const DeclContext *CurContext) {
109109
// afterwards it can be shared with define-inline code action.
110110
llvm::Expected<std::string>
111111
getFunctionSourceAfterReplacements(const FunctionDecl *FD,
112-
const tooling::Replacements &Replacements) {
112+
const tooling::Replacements &Replacements,
113+
bool TargetFileIsHeader) {
113114
const auto &SM = FD->getASTContext().getSourceManager();
114115
auto OrigFuncRange = toHalfOpenFileRange(
115116
SM, FD->getASTContext().getLangOpts(), FD->getSourceRange());
116117
if (!OrigFuncRange)
117118
return error("Couldn't get range for function.");
118-
assert(!FD->getDescribedFunctionTemplate() &&
119-
"Define out-of-line doesn't apply to function templates.");
120119

121120
// Get new begin and end positions for the qualified function definition.
122121
unsigned FuncBegin = SM.getFileOffset(OrigFuncRange->getBegin());
@@ -129,24 +128,38 @@ getFunctionSourceAfterReplacements(const FunctionDecl *FD,
129128
if (!QualifiedFunc)
130129
return QualifiedFunc.takeError();
131130

131+
auto Source = QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
132132
std::string TemplatePrefix;
133+
auto AddToTemplatePrefixIfApplicable = [&](const Decl *D) {
134+
const TemplateParameterList *Params = D->getDescribedTemplateParams();
135+
if (!Params)
136+
return;
137+
for (Decl *P : *Params) {
138+
if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(P))
139+
TTP->removeDefaultArgument();
140+
else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
141+
NTTP->removeDefaultArgument();
142+
else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(P))
143+
TTPD->removeDefaultArgument();
144+
}
145+
std::string S;
146+
llvm::raw_string_ostream Stream(S);
147+
Params->print(Stream, FD->getASTContext());
148+
if (!S.empty())
149+
*S.rbegin() = '\n'; // Replace space with newline
150+
TemplatePrefix.insert(0, S);
151+
};
152+
AddToTemplatePrefixIfApplicable(FD);
133153
if (auto *MD = llvm::dyn_cast<CXXMethodDecl>(FD)) {
134154
for (const CXXRecordDecl *Parent = MD->getParent(); Parent;
135155
Parent =
136156
llvm::dyn_cast_or_null<const CXXRecordDecl>(Parent->getParent())) {
137-
if (const TemplateParameterList *Params =
138-
Parent->getDescribedTemplateParams()) {
139-
std::string S;
140-
llvm::raw_string_ostream Stream(S);
141-
Params->print(Stream, FD->getASTContext());
142-
if (!S.empty())
143-
*S.rbegin() = '\n'; // Replace space with newline
144-
TemplatePrefix.insert(0, S);
145-
}
157+
AddToTemplatePrefixIfApplicable(Parent);
146158
}
147159
}
148160

149-
auto Source = QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
161+
if (TargetFileIsHeader)
162+
Source.insert(0, "inline ");
150163
if (!TemplatePrefix.empty())
151164
Source.insert(0, TemplatePrefix);
152165
return Source;
@@ -202,7 +215,8 @@ deleteTokensWithKind(const syntax::TokenBuffer &TokBuf, tok::TokenKind Kind,
202215
llvm::Expected<std::string>
203216
getFunctionSourceCode(const FunctionDecl *FD, const DeclContext *TargetContext,
204217
const syntax::TokenBuffer &TokBuf,
205-
const HeuristicResolver *Resolver) {
218+
const HeuristicResolver *Resolver,
219+
bool TargetFileIsHeader) {
206220
auto &AST = FD->getASTContext();
207221
auto &SM = AST.getSourceManager();
208222

@@ -337,7 +351,8 @@ getFunctionSourceCode(const FunctionDecl *FD, const DeclContext *TargetContext,
337351

338352
if (Errors)
339353
return std::move(Errors);
340-
return getFunctionSourceAfterReplacements(FD, DeclarationCleanups);
354+
return getFunctionSourceAfterReplacements(FD, DeclarationCleanups,
355+
TargetFileIsHeader);
341356
}
342357

343358
struct InsertionPoint {
@@ -419,15 +434,15 @@ class DefineOutline : public Tweak {
419434
Source->isOutOfLine())
420435
return false;
421436

422-
// Bail out if this is a function template or specialization, as their
437+
// Bail out if this is a function template specialization, as their
423438
// definitions need to be visible in all including translation units.
424-
if (Source->getDescribedFunctionTemplate())
425-
return false;
426439
if (Source->getTemplateSpecializationInfo())
427440
return false;
428441

429442
auto *MD = llvm::dyn_cast<CXXMethodDecl>(Source);
430443
if (!MD) {
444+
if (Source->getDescribedFunctionTemplate())
445+
return false;
431446
// Can't outline free-standing functions in the same file.
432447
return !SameFile;
433448
}
@@ -450,6 +465,19 @@ class DefineOutline : public Tweak {
450465
}
451466
}
452467

468+
// For function templates, the same limitations as for class templates
469+
// apply.
470+
if (const TemplateParameterList *Params =
471+
MD->getDescribedTemplateParams()) {
472+
// FIXME: Is this really needed? It inhibits application on
473+
// e.g. std::enable_if.
474+
for (NamedDecl *P : *Params) {
475+
if (!P->getIdentifier())
476+
return false;
477+
}
478+
SameFile = true;
479+
}
480+
453481
// The refactoring is meaningless for unnamed classes and namespaces,
454482
// unless we're outlining in the same file
455483
for (const DeclContext *DC = MD->getParent(); DC; DC = DC->getParent()) {
@@ -485,7 +513,8 @@ class DefineOutline : public Tweak {
485513

486514
auto FuncDef = getFunctionSourceCode(
487515
Source, InsertionPoint->EnclosingNamespace, Sel.AST->getTokens(),
488-
Sel.AST->getHeuristicResolver());
516+
Sel.AST->getHeuristicResolver(),
517+
SameFile && isHeaderFile(Sel.AST->tuPath(), Sel.AST->getLangOpts()));
489518
if (!FuncDef)
490519
return FuncDef.takeError();
491520

clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,17 @@ TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
111111
template <typename> struct Foo { void fo^o(){} };
112112
)cpp");
113113

114-
// Not available on function templates and specializations, as definition must
115-
// be visible to all translation units.
114+
// Not available on function template specializations and free function
115+
// templates.
116116
EXPECT_UNAVAILABLE(R"cpp(
117-
template <typename> void fo^o() {};
118-
template <> void fo^o<int>() {};
117+
template <typename T> void fo^o() {}
118+
template <> void fo^o<int>() {}
119+
)cpp");
120+
121+
// Not available on member function templates with unnamed template
122+
// parameters.
123+
EXPECT_UNAVAILABLE(R"cpp(
124+
struct Foo { template <typename> void ba^r() {} };
119125
)cpp");
120126

121127
// Not available on methods of unnamed classes.
@@ -237,7 +243,7 @@ TEST_F(DefineOutlineTest, ApplyTest) {
237243
Foo(T z) __attribute__((weak)) ;
238244
int bar;
239245
};template <typename T>
240-
Foo<T>::Foo(T z) __attribute__((weak)) : bar(2){}
246+
inline Foo<T>::Foo(T z) __attribute__((weak)) : bar(2){}
241247
)cpp",
242248
""},
243249
// Virt specifiers.
@@ -390,7 +396,7 @@ Foo<T>::Foo(T z) __attribute__((weak)) : bar(2){}
390396
};
391397
};template <typename T, typename ...U>
392398
template <class V, int A>
393-
typename O1<T, U...>::template O2<V, A>::E O1<T, U...>::template O2<V, A>::I::foo(T, U..., V, E) { return E1; }
399+
inline typename O1<T, U...>::template O2<V, A>::E O1<T, U...>::template O2<V, A>::I::foo(T, U..., V, E) { return E1; }
394400
)cpp",
395401
""},
396402
// Destructors
@@ -399,6 +405,37 @@ typename O1<T, U...>::template O2<V, A>::E O1<T, U...>::template O2<V, A>::I::fo
399405
"class A { ~A(); };",
400406
"A::~A(){} ",
401407
},
408+
409+
// Member template
410+
{
411+
R"cpp(
412+
struct Foo {
413+
template <typename T, bool B = true>
414+
void ^bar() {}
415+
};)cpp",
416+
R"cpp(
417+
struct Foo {
418+
template <typename T, bool B = true>
419+
void bar() ;
420+
};template <typename T, bool B>
421+
inline void Foo::bar() {}
422+
)cpp",
423+
""},
424+
425+
// Class template with member template
426+
{
427+
R"cpp(
428+
template <typename T> struct Foo {
429+
template <typename U> void ^bar(const T& t, const U& u) {}
430+
};)cpp",
431+
R"cpp(
432+
template <typename T> struct Foo {
433+
template <typename U> void bar(const T& t, const U& u) ;
434+
};template <typename T>
435+
template <typename U>
436+
inline void Foo<T>::bar(const T& t, const U& u) {}
437+
)cpp",
438+
""},
402439
};
403440
for (const auto &Case : Cases) {
404441
SCOPED_TRACE(Case.Test);

clang/docs/ReleaseNotes.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,22 @@ Improvements to Clang's diagnostics
539539

540540
- Clang now omits shadow warnings for enum constants in separate class scopes (#GH62588).
541541

542+
- When diagnosing an unused return value of a type declared ``[[nodiscard]]``, the type
543+
itself is now included in the diagnostic.
544+
545+
- Clang will now prefer the ``[[nodiscard]]`` declaration on function declarations over ``[[nodiscard]]``
546+
declaration on the return type of a function. Previously, when both have a ``[[nodiscard]]`` declaration attached,
547+
the one on the return type would be preferred. This may affect the generated warning message:
548+
549+
.. code-block:: c++
550+
551+
struct [[nodiscard("Reason 1")]] S {};
552+
[[nodiscard("Reason 2")]] S getS();
553+
void use()
554+
{
555+
getS(); // Now diagnoses "Reason 2", previously diagnoses "Reason 1"
556+
}
557+
542558
- Clang now diagnoses missing return value in functions containing ``if consteval`` (#GH116485).
543559

544560
Improvements to Clang's time-trace

clang/include/clang/AST/Expr.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3181,12 +3181,14 @@ class CallExpr : public Expr {
31813181
QualType getCallReturnType(const ASTContext &Ctx) const;
31823182

31833183
/// Returns the WarnUnusedResultAttr that is either declared on the called
3184-
/// function, or its return type declaration.
3185-
const Attr *getUnusedResultAttr(const ASTContext &Ctx) const;
3184+
/// function, or its return type declaration, together with a NamedDecl that
3185+
/// refers to the declaration the attribute is attached onto.
3186+
std::pair<const NamedDecl *, const Attr *>
3187+
getUnusedResultAttr(const ASTContext &Ctx) const;
31863188

31873189
/// Returns true if this call expression should warn on unused results.
31883190
bool hasUnusedResultAttr(const ASTContext &Ctx) const {
3189-
return getUnusedResultAttr(Ctx) != nullptr;
3191+
return getUnusedResultAttr(Ctx).second != nullptr;
31903192
}
31913193

31923194
SourceLocation getRParenLoc() const { return RParenLoc; }

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9300,11 +9300,11 @@ def warn_unused_container_subscript_expr : Warning<
93009300
def warn_unused_call : Warning<
93019301
"ignoring return value of function declared with %0 attribute">,
93029302
InGroup<UnusedValue>;
9303-
def warn_unused_constructor : Warning<
9304-
"ignoring temporary created by a constructor declared with %0 attribute">,
9303+
def warn_unused_return_type : Warning<
9304+
"ignoring %select{return value|temporary}0 of type %2 declared with %1 attribute%select{|: %4}3">,
93059305
InGroup<UnusedValue>;
9306-
def warn_unused_constructor_msg : Warning<
9307-
"ignoring temporary created by a constructor declared with %0 attribute: %1">,
9306+
def warn_unused_constructor : Warning<
9307+
"ignoring temporary created by a constructor declared with %0 attribute%select{|: %2}1">,
93089308
InGroup<UnusedValue>;
93099309
def warn_side_effects_unevaluated_context : Warning<
93109310
"expression with side effects has no effect in an unevaluated context">,
@@ -9313,10 +9313,7 @@ def warn_side_effects_typeid : Warning<
93139313
"expression with side effects will be evaluated despite being used as an "
93149314
"operand to 'typeid'">, InGroup<PotentiallyEvaluatedExpression>;
93159315
def warn_unused_result : Warning<
9316-
"ignoring return value of function declared with %0 attribute">,
9317-
InGroup<UnusedResult>;
9318-
def warn_unused_result_msg : Warning<
9319-
"ignoring return value of function declared with %0 attribute: %1">,
9316+
"ignoring return value of function declared with %0 attribute%select{|: %2}1">,
93209317
InGroup<UnusedResult>;
93219318
def warn_unused_result_typedef_unsupported_spelling : Warning<
93229319
"'[[%select{nodiscard|gnu::warn_unused_result}0]]' attribute ignored when "

clang/include/clang/Basic/arm_mve.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -753,8 +753,8 @@ let params = T.Float in {
753753
defm: compare<"ne", fcmp_ne>;
754754
defm: compare<"gt", fcmp_gt>;
755755
defm: compare<"ge", fcmp_ge>;
756-
defm: compare<"lt", fcmp_lt>;
757-
defm: compare<"le", fcmp_le>;
756+
defm: compare<"lt", fcmp_ult>;
757+
defm: compare<"le", fcmp_ule>;
758758
}
759759

760760
let params = T.Signed in {

clang/include/clang/Basic/arm_mve_defs.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ def fcmp_eq: IRBuilder<"CreateFCmpOEQ">;
116116
def fcmp_ne: IRBuilder<"CreateFCmpUNE">; // not O: it must return true on NaNs
117117
def fcmp_gt: IRBuilder<"CreateFCmpOGT">;
118118
def fcmp_ge: IRBuilder<"CreateFCmpOGE">;
119-
def fcmp_lt: IRBuilder<"CreateFCmpOLT">;
120-
def fcmp_le: IRBuilder<"CreateFCmpOLE">;
119+
def fcmp_ult: IRBuilder<"CreateFCmpULT">;
120+
def fcmp_ule: IRBuilder<"CreateFCmpULE">;
121121
def splat: CGHelperFn<"ARMMVEVectorSplat">;
122122
def select: IRBuilder<"CreateSelect">;
123123
def fneg: IRBuilder<"CreateFNeg">;

0 commit comments

Comments
 (0)