Skip to content

Commit 4ed8042

Browse files
Merge branch 'main' into cppcoreguidelines-rvalue-reference-param-not-moved
2 parents 33aeee4 + 6a57af8 commit 4ed8042

File tree

204 files changed

+1474
-785
lines changed

Some content is hidden

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

204 files changed

+1474
-785
lines changed

clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ void MissingStdForwardCheck::registerMatchers(MatchFinder *Finder) {
120120
equalsBoundNode("param"), equalsBoundNode("var")))))),
121121
CapturedInLambda)),
122122
callee(unresolvedLookupExpr(hasAnyDeclaration(
123-
namedDecl(hasUnderlyingDecl(hasName("::std::forward")))))),
123+
namedDecl(hasUnderlyingDecl(hasName(ForwardFunction)))))),
124124

125125
unless(anyOf(hasAncestor(typeLoc()),
126126
hasAncestor(expr(hasUnevaluatedContext())))));
@@ -149,4 +149,13 @@ void MissingStdForwardCheck::check(const MatchFinder::MatchResult &Result) {
149149
<< Param;
150150
}
151151

152+
MissingStdForwardCheck::MissingStdForwardCheck(StringRef Name,
153+
ClangTidyContext *Context)
154+
: ClangTidyCheck(Name, Context),
155+
ForwardFunction(Options.get("ForwardFunction", "::std::forward")) {}
156+
157+
void MissingStdForwardCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
158+
Options.store(Opts, "ForwardFunction", ForwardFunction);
159+
}
160+
152161
} // namespace clang::tidy::cppcoreguidelines

clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ namespace clang::tidy::cppcoreguidelines {
2121
/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/missing-std-forward.html
2222
class MissingStdForwardCheck : public ClangTidyCheck {
2323
public:
24-
MissingStdForwardCheck(StringRef Name, ClangTidyContext *Context)
25-
: ClangTidyCheck(Name, Context) {}
24+
MissingStdForwardCheck(StringRef Name, ClangTidyContext *Context);
2625
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
2726
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
2827
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
@@ -31,6 +30,10 @@ class MissingStdForwardCheck : public ClangTidyCheck {
3130
std::optional<TraversalKind> getCheckTraversalKind() const override {
3231
return TK_IgnoreUnlessSpelledInSource;
3332
}
33+
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
34+
35+
private:
36+
const StringRef ForwardFunction;
3437
};
3538

3639
} // namespace clang::tidy::cppcoreguidelines

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ Changes in existing checks
212212
<clang-tidy/checks/cppcoreguidelines/avoid-goto>` check by adding the option
213213
`IgnoreMacros` to ignore ``goto`` labels defined in macros.
214214

215+
- Improved :doc:`cppcoreguidelines-missing-std-forward
216+
<clang-tidy/checks/cppcoreguidelines/missing-std-forward>` check by adding a
217+
flag to specify the function used for forwarding instead of ``std::forward``.
218+
215219
- Improved :doc:`cppcoreguidelines-rvalue-reference-param-not-moved
216220
<clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved>` check
217221
by adding a flag to specify the function used for moving instead of

clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/missing-std-forward.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ Example:
3535
f(1, 2); // Incorrect - may not invoke the desired qualified function operator
3636
}
3737

38+
Options
39+
-------
40+
41+
.. option:: ForwardFunction
42+
43+
Specify the function used for forwarding. Default is `::std::forward`.
44+
3845
This check implements `F.19
3946
<http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-forward>`_
4047
from the C++ Core Guidelines.

clang-tools-extra/test/clang-doc/json/class.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ struct MyClass {
2323
typedef int MyTypedef;
2424

2525
class NestedClass;
26+
27+
friend struct Foo;
28+
template<typename T> friend void friendFunction(int);
2629
protected:
2730
int protectedMethod();
2831

@@ -86,6 +89,44 @@ struct MyClass {
8689
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
8790
// CHECK-NEXT: }
8891
// CHECK-NEXT: ],
92+
// CHECK-NOT: "Friends": [
93+
// CHECK-NOT: {
94+
// CHECK-NOT: "IsClass": false,
95+
// CHECK-NOT: "Params": [
96+
// CHECK-NOT: {
97+
// CHECK-NOT: "Name": "",
98+
// CHECK-NOT: "Type": "int"
99+
// CHECK-NOT: }
100+
// CHECK-NOT: ],
101+
// CHECK-NOT: "Reference": {
102+
// CHECK-NOT: "Name": "friendFunction",
103+
// CHECK-NOT: "Path": "",
104+
// CHECK-NOT: "QualName": "friendFunction",
105+
// CHECK-NOT: "USR": "{{[0-9A-F]*}}"
106+
// CHECK-NOT: },
107+
// CHECK-NOT: "ReturnType": {
108+
// CHECK-NOT: "IsBuiltIn": true,
109+
// CHECK-NOT: "IsTemplate": false,
110+
// CHECK-NOT: "Name": "void",
111+
// CHECK-NOT: "QualName": "void",
112+
// CHECK-NOT: "USR": "0000000000000000000000000000000000000000"
113+
// CHECK-NOT: },
114+
// CHECK-NOT: "Template": {
115+
// CHECK-NOT: "Parameters": [
116+
// CHECK-NOT: "typename T"
117+
// CHECK-NOT: ]
118+
// CHECK-NOT: }
119+
// CHECK-NOT: },
120+
// CHECK-NOT: {
121+
// CHECK-NOT: "IsClass": true,
122+
// CHECK-NOT: "Reference": {
123+
// CHECK-NOT: "Name": "Foo",
124+
// CHECK-NOT: "Path": "GlobalNamespace",
125+
// CHECK-NOT: "QualName": "Foo",
126+
// CHECK-NOT: "USR": "{{[0-9A-F]*}}"
127+
// CHECK-NOT: },
128+
// CHECK-NOT: },
129+
// CHECK-NOT: ],
89130
// COM: FIXME: FullName is not emitted correctly.
90131
// CHECK-NEXT: "FullName": "",
91132
// CHECK-NEXT: "IsTypedef": false,
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %check_clang_tidy -std=c++14 %s cppcoreguidelines-missing-std-forward %t -- \
2+
// RUN: -config="{CheckOptions: {cppcoreguidelines-missing-std-forward.ForwardFunction: custom_forward}}" -- -fno-delayed-template-parsing
3+
4+
// NOLINTBEGIN
5+
namespace std {
6+
7+
template <typename T> struct remove_reference { using type = T; };
8+
template <typename T> struct remove_reference<T&> { using type = T; };
9+
template <typename T> struct remove_reference<T&&> { using type = T; };
10+
11+
template <typename T> using remove_reference_t = typename remove_reference<T>::type;
12+
13+
template <typename T> constexpr T &&forward(remove_reference_t<T> &t) noexcept;
14+
template <typename T> constexpr T &&forward(remove_reference_t<T> &&t) noexcept;
15+
template <typename T> constexpr remove_reference_t<T> &&move(T &&x);
16+
17+
} // namespace std
18+
// NOLINTEND
19+
20+
template<class T>
21+
constexpr decltype(auto) custom_forward(std::remove_reference_t<T>& tmp) noexcept
22+
{
23+
return static_cast<T&&>(tmp);
24+
}
25+
26+
template<class T>
27+
constexpr decltype(auto) custom_forward(std::remove_reference_t<T>&& tmp) noexcept
28+
{
29+
return static_cast<T&&>(tmp);
30+
}
31+
32+
template<class T>
33+
void forward_with_std(T&& t) {
34+
// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]
35+
36+
T other{std::forward<T>(t)};
37+
}
38+
39+
template<class T>
40+
void move_with_custom(T&& t) {
41+
T other{custom_forward<T>(t)};
42+
}

clang/include/clang/Basic/TargetInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1851,7 +1851,7 @@ class TargetInfo : public TransferrableTargetInfo,
18511851

18521852
/// Returns the version of the darwin target variant SDK which was used during
18531853
/// the compilation if one was specified, or an empty version otherwise.
1854-
const std::optional<VersionTuple> getDarwinTargetVariantSDKVersion() const {
1854+
std::optional<VersionTuple> getDarwinTargetVariantSDKVersion() const {
18551855
return !getTargetOpts().DarwinTargetVariantSDKVersion.empty()
18561856
? getTargetOpts().DarwinTargetVariantSDKVersion
18571857
: std::optional<VersionTuple>();

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4574,22 +4574,23 @@ VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD,
45744574
template <class Emitter>
45754575
bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
45764576
bool ConstantContext) {
4577-
std::optional<PrimType> VarT = classify(VD->getType());
45784577

45794578
// We only create variables if we're evaluating in a constant context.
45804579
// Otherwise, just evaluate the initializer and return it.
45814580
if (!ConstantContext) {
45824581
DeclScope<Emitter> LS(this, VD);
4583-
if (!this->visit(VD->getAnyInitializer()))
4582+
const Expr *Init = VD->getInit();
4583+
if (!this->visit(Init))
45844584
return false;
4585-
return this->emitRet(VarT.value_or(PT_Ptr), VD) && LS.destroyLocals() &&
4586-
this->emitCheckAllocations(VD);
4585+
return this->emitRet(classify(Init).value_or(PT_Ptr), VD) &&
4586+
LS.destroyLocals() && this->emitCheckAllocations(VD);
45874587
}
45884588

45894589
LocalScope<Emitter> VDScope(this, VD);
45904590
if (!this->visitVarDecl(VD, /*Toplevel=*/true))
45914591
return false;
45924592

4593+
std::optional<PrimType> VarT = classify(VD->getType());
45934594
if (Context::shouldBeGloballyIndexed(VD)) {
45944595
auto GlobalIndex = P.getGlobal(VD);
45954596
assert(GlobalIndex); // visitVarDecl() didn't return false.

clang/lib/AST/Type.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4870,15 +4870,6 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
48704870
->getCanonicalTypeInternal());
48714871
case Type::HLSLInlineSpirv:
48724872
return LinkageInfo::external();
4873-
{
4874-
const auto *ST = cast<HLSLInlineSpirvType>(T);
4875-
LinkageInfo LV = LinkageInfo::external();
4876-
for (auto &Operand : ST->getOperands()) {
4877-
if (Operand.isConstant() || Operand.isType())
4878-
LV.merge(computeTypeLinkageInfo(Operand.getResultType()));
4879-
}
4880-
return LV;
4881-
}
48824873
}
48834874

48844875
llvm_unreachable("unhandled type class");

clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,12 +613,39 @@ class OpenACCClauseCIREmitter final
613613
} else {
614614
llvm_unreachable("var-list version of self shouldn't get here");
615615
}
616+
} else if constexpr (isOneOfTypes<OpTy, mlir::acc::UpdateOp>) {
617+
assert(!clause.isEmptySelfClause() && !clause.isConditionExprClause() &&
618+
"var-list version of self required for update");
619+
for (const Expr *var : clause.getVarList())
620+
addDataOperand<mlir::acc::GetDevicePtrOp, mlir::acc::UpdateHostOp>(
621+
var, mlir::acc::DataClause::acc_update_self, {},
622+
/*structured=*/false, /*implicit=*/false);
616623
} else if constexpr (isCombinedType<OpTy>) {
617624
applyToComputeOp(clause);
618625
} else {
619-
// TODO: When we've implemented this for everything, switch this to an
620-
// unreachable. update construct remains.
621-
return clauseNotImplemented(clause);
626+
llvm_unreachable("Unknown construct kind in VisitSelfClause");
627+
}
628+
}
629+
630+
void VisitHostClause(const OpenACCHostClause &clause) {
631+
if constexpr (isOneOfTypes<OpTy, mlir::acc::UpdateOp>) {
632+
for (const Expr *var : clause.getVarList())
633+
addDataOperand<mlir::acc::GetDevicePtrOp, mlir::acc::UpdateHostOp>(
634+
var, mlir::acc::DataClause::acc_update_host, {},
635+
/*structured=*/false, /*implicit=*/false);
636+
} else {
637+
llvm_unreachable("Unknown construct kind in VisitHostClause");
638+
}
639+
}
640+
641+
void VisitDeviceClause(const OpenACCDeviceClause &clause) {
642+
if constexpr (isOneOfTypes<OpTy, mlir::acc::UpdateOp>) {
643+
for (const Expr *var : clause.getVarList())
644+
addDataOperand<mlir::acc::UpdateDeviceOp>(
645+
var, mlir::acc::DataClause::acc_update_device, {},
646+
/*structured=*/false, /*implicit=*/false);
647+
} else {
648+
llvm_unreachable("Unknown construct kind in VisitDeviceClause");
622649
}
623650
}
624651

@@ -1095,6 +1122,7 @@ EXPL_SPEC(mlir::acc::WaitOp)
10951122
EXPL_SPEC(mlir::acc::HostDataOp)
10961123
EXPL_SPEC(mlir::acc::EnterDataOp)
10971124
EXPL_SPEC(mlir::acc::ExitDataOp)
1125+
EXPL_SPEC(mlir::acc::UpdateOp)
10981126
#undef EXPL_SPEC
10991127

11001128
template <typename ComputeOp, typename LoopOp>

0 commit comments

Comments
 (0)