Skip to content

Commit cbbce01

Browse files
authored
Merge branch 'main' into llvm-static-unittest
2 parents 7977613 + 0c33799 commit cbbce01

File tree

123 files changed

+3043
-582
lines changed

Some content is hidden

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

123 files changed

+3043
-582
lines changed

bolt/unittests/Profile/PerfSpeEvents.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct PerfSpeEventsTestHelper : public testing::Test {
6565
BC = cantFail(BinaryContext::createBinaryContext(
6666
ObjFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(),
6767
ObjFile->getFileName(), nullptr, /*IsPIC*/ false,
68-
DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()}));
68+
DWARFContext::create(*ObjFile), {llvm::outs(), llvm::errs()}));
6969
ASSERT_FALSE(!BC);
7070
}
7171

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ using namespace clang::ast_matchers;
1818

1919
namespace clang::tidy::cppcoreguidelines {
2020

21+
namespace {
22+
AST_MATCHER(CXXRecordDecl, isInMacro) {
23+
return Node.getBeginLoc().isMacroID() && Node.getEndLoc().isMacroID();
24+
}
25+
} // namespace
26+
2127
SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck(
2228
StringRef Name, ClangTidyContext *Context)
2329
: ClangTidyCheck(Name, Context), AllowMissingMoveFunctions(Options.get(
@@ -26,7 +32,8 @@ SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck(
2632
AllowMissingMoveFunctionsWhenCopyIsDeleted(
2733
Options.get("AllowMissingMoveFunctionsWhenCopyIsDeleted", false)),
2834
AllowImplicitlyDeletedCopyOrMove(
29-
Options.get("AllowImplicitlyDeletedCopyOrMove", false)) {}
35+
Options.get("AllowImplicitlyDeletedCopyOrMove", false)),
36+
IgnoreMacros(Options.get("IgnoreMacros", true)) {}
3037

3138
void SpecialMemberFunctionsCheck::storeOptions(
3239
ClangTidyOptions::OptionMap &Opts) {
@@ -36,6 +43,7 @@ void SpecialMemberFunctionsCheck::storeOptions(
3643
AllowMissingMoveFunctionsWhenCopyIsDeleted);
3744
Options.store(Opts, "AllowImplicitlyDeletedCopyOrMove",
3845
AllowImplicitlyDeletedCopyOrMove);
46+
Options.store(Opts, "IgnoreMacros", IgnoreMacros);
3947
}
4048

4149
std::optional<TraversalKind>
@@ -45,11 +53,12 @@ SpecialMemberFunctionsCheck::getCheckTraversalKind() const {
4553
}
4654

4755
void SpecialMemberFunctionsCheck::registerMatchers(MatchFinder *Finder) {
48-
auto IsNotImplicitOrDeleted = anyOf(unless(isImplicit()), isDeleted());
56+
const auto IsNotImplicitOrDeleted = anyOf(unless(isImplicit()), isDeleted());
57+
const ast_matchers::internal::Matcher<CXXRecordDecl> Anything = anything();
4958

5059
Finder->addMatcher(
5160
cxxRecordDecl(
52-
unless(isImplicit()),
61+
unless(isImplicit()), IgnoreMacros ? unless(isInMacro()) : Anything,
5362
eachOf(has(cxxDestructorDecl(unless(isImplicit())).bind("dtor")),
5463
has(cxxConstructorDecl(isCopyConstructor(),
5564
IsNotImplicitOrDeleted)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class SpecialMemberFunctionsCheck : public ClangTidyCheck {
6969
const bool AllowMissingMoveFunctionsWhenCopyIsDeleted;
7070
const bool AllowImplicitlyDeletedCopyOrMove;
7171
ClassDefiningSpecialMembersMap ClassWithSpecialMembers;
72+
const bool IgnoreMacros;
7273
};
7374

7475
} // namespace clang::tidy::cppcoreguidelines

clang-tools-extra/docs/ReleaseNotes.rst

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

204+
- Improved :doc:`cppcoreguidelines-special-member-functions
205+
<clang-tidy/checks/cppcoreguidelines/special-member-functions>` check by
206+
adding the option `IgnoreMacros` to ignore classes defined in macros.
207+
204208
- Improved :doc:`google-readability-namespace-comments
205209
<clang-tidy/checks/google/readability-namespace-comments>` check by adding
206210
the option `AllowOmittingNamespaceComments` to accept if a namespace comment
@@ -210,6 +214,10 @@ Changes in existing checks
210214
<clang-tidy/checks/hicpp/avoid-goto>` check by adding the option
211215
`IgnoreMacros` to ignore ``goto`` labels defined in macros.
212216

217+
- Improved :doc:`hicpp-special-member-functions
218+
<clang-tidy/checks/hicpp/special-member-functions>` check by adding the
219+
option `IgnoreMacros` to ignore classes defined in macros.
220+
213221
- Improved :doc:`llvm-namespace-comment
214222
<clang-tidy/checks/llvm/namespace-comment>` check by adding the option
215223
`AllowOmittingNamespaceComments` to accept if a namespace comment is omitted

clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/special-member-functions.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,8 @@ Options
8585
struct A : boost::noncopyable {
8686
~A() { std::cout << "dtor\n"; }
8787
};
88+
89+
.. option:: IgnoreMacros
90+
91+
If set to `true`, the check will not give warnings for classes defined
92+
inside macros. Default is `true`.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t -- -config="{CheckOptions: {cppcoreguidelines-special-member-functions.IgnoreMacros: false}}" --
2+
3+
class DefinesDestructor {
4+
~DefinesDestructor();
5+
};
6+
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
7+
8+
class DefinesDefaultedDestructor {
9+
~DefinesDefaultedDestructor() = default;
10+
};
11+
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDefaultedDestructor' defines a default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
12+
13+
class DefinesCopyConstructor {
14+
DefinesCopyConstructor(const DefinesCopyConstructor &);
15+
};
16+
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
17+
18+
class DefinesNothing {
19+
};
20+
21+
class DefinesEverything {
22+
DefinesEverything(const DefinesEverything &);
23+
DefinesEverything &operator=(const DefinesEverything &);
24+
DefinesEverything(DefinesEverything &&);
25+
DefinesEverything &operator=(DefinesEverything &&);
26+
~DefinesEverything();
27+
};
28+
29+
#define DEFINE_DESTRUCTOR_ONLY(ClassName) \
30+
class ClassName { \
31+
~ClassName(); \
32+
};
33+
34+
#define DEFINE_COPY_CTOR_ONLY(ClassName) \
35+
class ClassName { \
36+
ClassName(const ClassName &); \
37+
};
38+
39+
#define DEFINE_CLASS_WITH_DTOR(ClassName) \
40+
class ClassName { \
41+
~ClassName(); \
42+
};
43+
44+
DEFINE_DESTRUCTOR_ONLY(MacroDefinedClass1)
45+
// CHECK-MESSAGES: [[@LINE-1]]:24: warning: class 'MacroDefinedClass1' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
46+
DEFINE_COPY_CTOR_ONLY(MacroDefinedClass2)
47+
// CHECK-MESSAGES: [[@LINE-1]]:23: warning: class 'MacroDefinedClass2' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator
48+
DEFINE_CLASS_WITH_DTOR(MacroDefinedClass3)
49+
// CHECK-MESSAGES: [[@LINE-1]]:24: warning: class 'MacroDefinedClass3' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
50+
51+
// Test partial macro expansion
52+
#define CLASS_NAME MacroNamedClass
53+
class CLASS_NAME {
54+
~MacroNamedClass();
55+
};
56+
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'MacroNamedClass' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
57+

clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,29 @@ struct TemplateClass {
7070
// This should not cause problems.
7171
TemplateClass<int> InstantiationWithInt;
7272
TemplateClass<double> InstantiationWithDouble;
73+
74+
#define DEFINE_DESTRUCTOR_ONLY(ClassName) \
75+
class ClassName { \
76+
~ClassName(); \
77+
};
78+
79+
#define DEFINE_COPY_CTOR_ONLY(ClassName) \
80+
class ClassName { \
81+
ClassName(const ClassName &); \
82+
};
83+
84+
#define DEFINE_CLASS_WITH_DTOR(ClassName) \
85+
class ClassName { \
86+
~ClassName(); \
87+
};
88+
89+
DEFINE_DESTRUCTOR_ONLY(MacroDefinedClass1)
90+
DEFINE_COPY_CTOR_ONLY(MacroDefinedClass2)
91+
DEFINE_CLASS_WITH_DTOR(MacroDefinedClass3)
92+
93+
// Test partial macro expansion
94+
#define CLASS_NAME MacroNamedClass
95+
class CLASS_NAME {
96+
~MacroNamedClass();
97+
};
98+
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'MacroNamedClass' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ C23 Feature Support
295295
type. Fixes #GH140887
296296
- Documented `WG14 N3006 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm>`_
297297
which clarified how Clang is handling underspecified object declarations.
298+
- Clang now accepts single variadic parameter in type-name. It's a part of
299+
`WG14 N2975 <https://open-std.org/JTC1/SC22/WG14/www/docs/n2975.pdf>`_
298300

299301
C11 Feature Support
300302
^^^^^^^^^^^^^^^^^^^

clang/include/clang/AST/Decl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,11 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
13521352
return const_cast<VarDecl *>(this)->getInitializingDeclaration();
13531353
}
13541354

1355+
/// Checks whether this declaration has an initializer with side effects,
1356+
/// without triggering deserialization if the initializer is not yet
1357+
/// deserialized.
1358+
bool hasInitWithSideEffects() const;
1359+
13551360
/// Determine whether this variable's value might be usable in a
13561361
/// constant expression, according to the relevant language standard.
13571362
/// This only checks properties of the declaration, and does not check

clang/include/clang/AST/ExternalASTSource.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class RecordDecl;
5151
class Selector;
5252
class Stmt;
5353
class TagDecl;
54+
class VarDecl;
5455

5556
/// Abstract interface for external sources of AST nodes.
5657
///
@@ -195,6 +196,10 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
195196
/// module.
196197
virtual bool wasThisDeclarationADefinition(const FunctionDecl *FD);
197198

199+
virtual bool hasInitializerWithSideEffects(const VarDecl *VD) const {
200+
return false;
201+
}
202+
198203
/// Finds all declarations lexically contained within the given
199204
/// DeclContext, after applying an optional filter predicate.
200205
///
@@ -429,6 +434,17 @@ struct LazyOffsetPtr {
429434
return GetPtr();
430435
}
431436

437+
/// Retrieve the pointer to the AST node that this lazy pointer points to,
438+
/// if it can be done without triggering deserialization.
439+
///
440+
/// \returns a pointer to the AST node, or null if not yet deserialized.
441+
T *getWithoutDeserializing() const {
442+
if (isOffset()) {
443+
return nullptr;
444+
}
445+
return GetPtr();
446+
}
447+
432448
/// Retrieve the address of the AST node pointer. Deserializes the pointee if
433449
/// necessary.
434450
T **getAddressOfPointer(ExternalASTSource *Source) const {

clang/include/clang/Sema/MultiplexExternalSemaSource.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {
9494

9595
bool wasThisDeclarationADefinition(const FunctionDecl *FD) override;
9696

97+
bool hasInitializerWithSideEffects(const VarDecl *VD) const override;
98+
9799
/// Find all declarations with the given name in the
98100
/// given context.
99101
bool FindExternalVisibleDeclsByName(const DeclContext *DC,

clang/include/clang/Serialization/ASTReader.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,6 +1455,12 @@ class ASTReader
14551455
const StringRef &operator*() && = delete;
14561456
};
14571457

1458+
/// VarDecls with initializers containing side effects must be emitted,
1459+
/// but DeclMustBeEmitted is not allowed to deserialize the intializer.
1460+
/// FIXME: Lower memory usage by removing VarDecls once the initializer
1461+
/// is deserialized.
1462+
llvm::SmallPtrSet<Decl *, 16> InitSideEffectVars;
1463+
14581464
public:
14591465
/// Get the buffer for resolving paths.
14601466
SmallString<0> &getPathBuf() { return PathBuf; }
@@ -2406,6 +2412,8 @@ class ASTReader
24062412

24072413
bool wasThisDeclarationADefinition(const FunctionDecl *FD) override;
24082414

2415+
bool hasInitializerWithSideEffects(const VarDecl *VD) const override;
2416+
24092417
/// Retrieve a selector from the given module with its local ID
24102418
/// number.
24112419
Selector getLocalSelector(ModuleFile &M, unsigned LocalID);

clang/lib/AST/ASTContext.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13110,9 +13110,7 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
1311013110
return true;
1311113111

1311213112
// Variables that have initialization with side-effects are required.
13113-
if (VD->getInit() && VD->getInit()->HasSideEffects(*this) &&
13114-
// We can get a value-dependent initializer during error recovery.
13115-
(VD->getInit()->isValueDependent() || !VD->evaluateValue()))
13113+
if (VD->hasInitWithSideEffects())
1311613114
return true;
1311713115

1311813116
// Likewise, variables with tuple-like bindings are required if their

clang/lib/AST/Decl.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2441,6 +2441,30 @@ VarDecl *VarDecl::getInitializingDeclaration() {
24412441
return Def;
24422442
}
24432443

2444+
bool VarDecl::hasInitWithSideEffects() const {
2445+
if (!hasInit())
2446+
return false;
2447+
2448+
// Check if we can get the initializer without deserializing
2449+
const Expr *E = nullptr;
2450+
if (auto *S = dyn_cast<Stmt *>(Init)) {
2451+
E = cast<Expr>(S);
2452+
} else {
2453+
E = cast_or_null<Expr>(getEvaluatedStmt()->Value.getWithoutDeserializing());
2454+
}
2455+
2456+
if (E)
2457+
return E->HasSideEffects(getASTContext()) &&
2458+
// We can get a value-dependent initializer during error recovery.
2459+
(E->isValueDependent() || !evaluateValue());
2460+
2461+
assert(getEvaluatedStmt()->Value.isOffset());
2462+
// ASTReader tracks this without having to deserialize the initializer
2463+
if (auto Source = getASTContext().getExternalSource())
2464+
return Source->hasInitializerWithSideEffects(this);
2465+
return false;
2466+
}
2467+
24442468
bool VarDecl::isOutOfLine() const {
24452469
if (Decl::isOutOfLine())
24462470
return true;

clang/lib/AST/ExprConstant.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16719,6 +16719,12 @@ static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This,
1671916719
const Expr *E, bool AllowNonLiteralTypes) {
1672016720
assert(!E->isValueDependent());
1672116721

16722+
// Normally expressions passed to EvaluateInPlace have a type, but not when
16723+
// a VarDecl initializer is evaluated before the untyped ParenListExpr is
16724+
// replaced with a CXXConstructExpr. This can happen in LLDB.
16725+
if (E->getType().isNull())
16726+
return false;
16727+
1672216728
if (!AllowNonLiteralTypes && !CheckLiteralType(Info, E, &This))
1672316729
return false;
1672416730

clang/lib/ExtractAPI/DeclarationFragments.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,9 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXMethod(
883883
if (Method->isVolatile())
884884
Fragments.append("volatile", DeclarationFragments::FragmentKind::Keyword)
885885
.appendSpace();
886+
if (Method->isVirtual())
887+
Fragments.append("virtual", DeclarationFragments::FragmentKind::Keyword)
888+
.appendSpace();
886889

887890
// Build return type
888891
DeclarationFragments After;

clang/lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7048,7 +7048,8 @@ void Parser::ParseParenDeclarator(Declarator &D) {
70487048
// paren, because we haven't seen the identifier yet.
70497049
isGrouping = true;
70507050
} else if (Tok.is(tok::r_paren) || // 'int()' is a function.
7051-
(getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
7051+
((getLangOpts().CPlusPlus || getLangOpts().C23) &&
7052+
Tok.is(tok::ellipsis) &&
70527053
NextToken().is(tok::r_paren)) || // C++ int(...)
70537054
isDeclarationSpecifier(
70547055
ImplicitTypenameContext::No) || // 'int(int)' is a function.

clang/lib/Sema/MultiplexExternalSemaSource.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ bool MultiplexExternalSemaSource::wasThisDeclarationADefinition(
115115
return false;
116116
}
117117

118+
bool MultiplexExternalSemaSource::hasInitializerWithSideEffects(
119+
const VarDecl *VD) const {
120+
for (const auto &S : Sources)
121+
if (S->hasInitializerWithSideEffects(VD))
122+
return true;
123+
return false;
124+
}
125+
118126
bool MultiplexExternalSemaSource::FindExternalVisibleDeclsByName(
119127
const DeclContext *DC, DeclarationName Name,
120128
const DeclContext *OriginalDC) {

clang/lib/Serialization/ASTReader.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9722,6 +9722,10 @@ bool ASTReader::wasThisDeclarationADefinition(const FunctionDecl *FD) {
97229722
return ThisDeclarationWasADefinitionSet.contains(FD);
97239723
}
97249724

9725+
bool ASTReader::hasInitializerWithSideEffects(const VarDecl *VD) const {
9726+
return InitSideEffectVars.count(VD);
9727+
}
9728+
97259729
Selector ASTReader::getLocalSelector(ModuleFile &M, unsigned LocalID) {
97269730
return DecodeSelector(getGlobalSelectorID(M, LocalID));
97279731
}

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,6 +1628,9 @@ RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
16281628
VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope =
16291629
VarDeclBits.getNextBit();
16301630

1631+
if (VarDeclBits.getNextBit())
1632+
Reader.InitSideEffectVars.insert(VD);
1633+
16311634
VD->NonParmVarDeclBits.EscapingByref = VarDeclBits.getNextBit();
16321635
HasDeducedType = VarDeclBits.getNextBit();
16331636
VD->NonParmVarDeclBits.ImplicitParamKind =

0 commit comments

Comments
 (0)