Skip to content

Commit a8cb431

Browse files
authored
Merge branch 'llvm:main' into gh-101657
2 parents 7edd558 + 180f803 commit a8cb431

File tree

141 files changed

+4327
-1279
lines changed

Some content is hidden

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

141 files changed

+4327
-1279
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ Bug Fixes in This Version
248248

249249
- Clang now outputs correct values when #embed data contains bytes with negative
250250
signed char values (#GH102798).
251+
- Fixed a crash when merging named enumerations in modules (#GH114240).
251252
- Fixed rejects-valid problem when #embed appears in std::initializer_list or
252253
when it can affect template argument deduction (#GH122306).
253254
- Fix crash on code completion of function calls involving partial order of function templates
@@ -299,6 +300,7 @@ Improvements to C++ diagnostics
299300
Bug Fixes to AST Handling
300301
^^^^^^^^^^^^^^^^^^^^^^^^^
301302
- Fixed type checking when a statement expression ends in an l-value of atomic type. (#GH106576)
303+
- Fixed uninitialized use check in a lambda within CXXOperatorCallExpr. (#GH129198)
302304

303305
Miscellaneous Bug Fixes
304306
^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ def err_decomp_decl_constraint : Error<
551551
def err_decomp_decl_parens : Error<
552552
"decomposition declaration cannot be declared with parentheses">;
553553
def err_decomp_decl_template : Error<
554-
"decomposition declaration template not supported">;
554+
"decomposition declaration cannot be a template">;
555555
def err_decomp_decl_not_alone : Error<
556556
"decomposition declaration must be the only declaration in its group">;
557557
def err_decomp_decl_requires_init : Error<

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4008,7 +4008,7 @@ class Sema final : public SemaBase {
40084008
/// Perform ODR-like check for C/ObjC when merging tag types from modules.
40094009
/// Differently from C++, actually parse the body and reject / error out
40104010
/// in case of a structural mismatch.
4011-
bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
4011+
bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody);
40124012

40134013
typedef void *SkippedDefinitionContext;
40144014

@@ -4132,6 +4132,12 @@ class Sema final : public SemaBase {
41324132
void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
41334133
LookupResult &OldDecls);
41344134

4135+
/// CleanupMergedEnum - We have just merged the decl 'New' by making another
4136+
/// definition visible.
4137+
/// This method performs any necessary cleanup on the parser state to discard
4138+
/// child nodes from newly parsed decl we are retiring.
4139+
void CleanupMergedEnum(Scope *S, Decl *New);
4140+
41354141
/// MergeFunctionDecl - We just parsed a function 'New' from
41364142
/// declarator D which has the same name and scope as a previous
41374143
/// declaration 'Old'. Figure out how to resolve this situation,

clang/lib/Format/UnwrappedLineFormatter.cpp

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -116,36 +116,18 @@ class LevelIndentTracker {
116116
Style.isCSharp()) {
117117
return 0;
118118
}
119-
120-
auto IsAccessModifier = [&](const FormatToken &RootToken) {
121-
if (Line.Type == LT_AccessModifier || RootToken.isObjCAccessSpecifier())
122-
return true;
123-
124-
const auto *Next = RootToken.Next;
125-
126-
// Handle Qt signals.
127-
if (RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
128-
Next && Next->is(tok::colon)) {
129-
return true;
130-
}
131-
132-
if (Next && Next->isOneOf(Keywords.kw_slots, Keywords.kw_qslots) &&
133-
Next->Next && Next->Next->is(tok::colon)) {
134-
return true;
135-
}
136-
137-
// Handle malformed access specifier e.g. 'private' without trailing ':'.
138-
return !Next && RootToken.isAccessSpecifier(false);
139-
};
140-
141-
if (IsAccessModifier(*Line.First)) {
119+
const auto &RootToken = *Line.First;
120+
if (Line.Type == LT_AccessModifier ||
121+
RootToken.isAccessSpecifier(/*ColonRequired=*/false) ||
122+
RootToken.isObjCAccessSpecifier() ||
123+
(RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
124+
RootToken.Next && RootToken.Next->is(tok::colon))) {
142125
// The AccessModifierOffset may be overridden by IndentAccessModifiers,
143126
// in which case we take a negative value of the IndentWidth to simulate
144127
// the upper indent level.
145128
return Style.IndentAccessModifiers ? -Style.IndentWidth
146129
: Style.AccessModifierOffset;
147130
}
148-
149131
return 0;
150132
}
151133

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 2 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -3386,75 +3386,15 @@ void UnwrappedLineParser::parseSwitch(bool IsExpr) {
33863386
NestedTooDeep.pop_back();
33873387
}
33883388

3389-
// Operators that can follow a C variable.
3390-
static bool isCOperatorFollowingVar(tok::TokenKind Kind) {
3391-
switch (Kind) {
3392-
case tok::ampamp:
3393-
case tok::ampequal:
3394-
case tok::arrow:
3395-
case tok::caret:
3396-
case tok::caretequal:
3397-
case tok::comma:
3398-
case tok::ellipsis:
3399-
case tok::equal:
3400-
case tok::equalequal:
3401-
case tok::exclaim:
3402-
case tok::exclaimequal:
3403-
case tok::greater:
3404-
case tok::greaterequal:
3405-
case tok::greatergreater:
3406-
case tok::greatergreaterequal:
3407-
case tok::l_paren:
3408-
case tok::l_square:
3409-
case tok::less:
3410-
case tok::lessequal:
3411-
case tok::lessless:
3412-
case tok::lesslessequal:
3413-
case tok::minus:
3414-
case tok::minusequal:
3415-
case tok::minusminus:
3416-
case tok::percent:
3417-
case tok::percentequal:
3418-
case tok::period:
3419-
case tok::pipe:
3420-
case tok::pipeequal:
3421-
case tok::pipepipe:
3422-
case tok::plus:
3423-
case tok::plusequal:
3424-
case tok::plusplus:
3425-
case tok::question:
3426-
case tok::r_brace:
3427-
case tok::r_paren:
3428-
case tok::r_square:
3429-
case tok::semi:
3430-
case tok::slash:
3431-
case tok::slashequal:
3432-
case tok::star:
3433-
case tok::starequal:
3434-
return true;
3435-
default:
3436-
return false;
3437-
}
3438-
}
3439-
34403389
void UnwrappedLineParser::parseAccessSpecifier() {
3441-
FormatToken *AccessSpecifierCandidate = FormatTok;
34423390
nextToken();
34433391
// Understand Qt's slots.
34443392
if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))
34453393
nextToken();
34463394
// Otherwise, we don't know what it is, and we'd better keep the next token.
3447-
if (FormatTok->is(tok::colon)) {
3395+
if (FormatTok->is(tok::colon))
34483396
nextToken();
3449-
addUnwrappedLine();
3450-
} else if (FormatTok->isNot(tok::coloncolon) &&
3451-
!isCOperatorFollowingVar(FormatTok->Tok.getKind())) {
3452-
// Not a variable name nor namespace name.
3453-
addUnwrappedLine();
3454-
} else if (AccessSpecifierCandidate) {
3455-
// Consider the access specifier to be a C identifier.
3456-
AccessSpecifierCandidate->Tok.setKind(tok::identifier);
3457-
}
3397+
addUnwrappedLine();
34583398
}
34593399

34603400
/// \brief Parses a requires, decides if it is a clause or an expression.

clang/lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5652,7 +5652,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
56525652
Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
56535653
ParseEnumBody(StartLoc, D);
56545654
if (SkipBody.CheckSameAsPrevious &&
5655-
!Actions.ActOnDuplicateDefinition(TagDecl, SkipBody)) {
5655+
!Actions.ActOnDuplicateDefinition(getCurScope(), TagDecl, SkipBody)) {
56565656
DS.SetTypeSpecError();
56575657
return;
56585658
}

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2350,7 +2350,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
23502350
// Parse the definition body.
23512351
ParseStructUnionBody(StartLoc, TagType, cast<RecordDecl>(D));
23522352
if (SkipBody.CheckSameAsPrevious &&
2353-
!Actions.ActOnDuplicateDefinition(TagOrTempResult.get(), SkipBody)) {
2353+
!Actions.ActOnDuplicateDefinition(getCurScope(),
2354+
TagOrTempResult.get(), SkipBody)) {
23542355
DS.SetTypeSpecError();
23552356
return;
23562357
}

clang/lib/Sema/SemaDecl.cpp

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include "llvm/ADT/STLForwardCompat.h"
6262
#include "llvm/ADT/SmallString.h"
6363
#include "llvm/ADT/StringExtras.h"
64+
#include "llvm/Support/SaveAndRestore.h"
6465
#include "llvm/TargetParser/Triple.h"
6566
#include <algorithm>
6667
#include <cstring>
@@ -2563,18 +2564,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
25632564
// Make the old tag definition visible.
25642565
makeMergedDefinitionVisible(Hidden);
25652566

2566-
// If this was an unscoped enumeration, yank all of its enumerators
2567-
// out of the scope.
2568-
if (isa<EnumDecl>(NewTag)) {
2569-
Scope *EnumScope = getNonFieldDeclScope(S);
2570-
for (auto *D : NewTag->decls()) {
2571-
auto *ED = cast<EnumConstantDecl>(D);
2572-
assert(EnumScope->isDeclScope(ED));
2573-
EnumScope->RemoveDecl(ED);
2574-
IdResolver.RemoveDecl(ED);
2575-
ED->getLexicalDeclContext()->removeDecl(ED);
2576-
}
2577-
}
2567+
CleanupMergedEnum(S, NewTag);
25782568
}
25792569
}
25802570

@@ -2651,6 +2641,19 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
26512641
notePreviousDefinition(Old, New->getLocation());
26522642
}
26532643

2644+
void Sema::CleanupMergedEnum(Scope *S, Decl *New) {
2645+
// If this was an unscoped enumeration, yank all of its enumerators
2646+
// out of the scope.
2647+
if (auto *ED = dyn_cast<EnumDecl>(New); ED && !ED->isScoped()) {
2648+
Scope *EnumScope = getNonFieldDeclScope(S);
2649+
for (auto *ECD : ED->enumerators()) {
2650+
assert(EnumScope->isDeclScope(ECD));
2651+
EnumScope->RemoveDecl(ECD);
2652+
IdResolver.RemoveDecl(ECD);
2653+
}
2654+
}
2655+
}
2656+
26542657
/// DeclhasAttr - returns true if decl Declaration already has the target
26552658
/// attribute.
26562659
static bool DeclHasAttr(const Decl *D, const Attr *A) {
@@ -12611,6 +12614,7 @@ namespace {
1261112614
bool isRecordType;
1261212615
bool isPODType;
1261312616
bool isReferenceType;
12617+
bool isInCXXOperatorCall;
1261412618

1261512619
bool isInitList;
1261612620
llvm::SmallVector<unsigned, 4> InitFieldIndex;
@@ -12623,6 +12627,7 @@ namespace {
1262312627
isPODType = false;
1262412628
isRecordType = false;
1262512629
isReferenceType = false;
12630+
isInCXXOperatorCall = false;
1262612631
isInitList = false;
1262712632
if (ValueDecl *VD = dyn_cast<ValueDecl>(OrigDecl)) {
1262812633
isPODType = VD->getType().isPODType(S.Context);
@@ -12810,6 +12815,7 @@ namespace {
1281012815
}
1281112816

1281212817
void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
12818+
llvm::SaveAndRestore CxxOpCallScope(isInCXXOperatorCall, true);
1281312819
Expr *Callee = E->getCallee();
1281412820

1281512821
if (isa<UnresolvedLookupExpr>(Callee))
@@ -12820,6 +12826,19 @@ namespace {
1282012826
HandleValue(Arg->IgnoreParenImpCasts());
1282112827
}
1282212828

12829+
void VisitLambdaExpr(LambdaExpr *E) {
12830+
if (!isInCXXOperatorCall) {
12831+
Inherited::VisitLambdaExpr(E);
12832+
return;
12833+
}
12834+
12835+
for (Expr *Init : E->capture_inits())
12836+
if (DeclRefExpr *DRE = dyn_cast_if_present<DeclRefExpr>(Init))
12837+
HandleDeclRefExpr(DRE);
12838+
else if (Init)
12839+
Visit(Init);
12840+
}
12841+
1282312842
void VisitUnaryOperator(UnaryOperator *E) {
1282412843
// For POD record types, addresses of its own members are well-defined.
1282512844
if (E->getOpcode() == UO_AddrOf && isRecordType &&
@@ -18330,12 +18349,14 @@ void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) {
1833018349
AddPushedVisibilityAttribute(Tag);
1833118350
}
1833218351

18333-
bool Sema::ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody) {
18352+
bool Sema::ActOnDuplicateDefinition(Scope *S, Decl *Prev,
18353+
SkipBodyInfo &SkipBody) {
1833418354
if (!hasStructuralCompatLayout(Prev, SkipBody.New))
1833518355
return false;
1833618356

1833718357
// Make the previous decl visible.
1833818358
makeMergedDefinitionVisible(SkipBody.Previous);
18359+
CleanupMergedEnum(S, SkipBody.New);
1833918360
return true;
1834018361
}
1834118362

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -733,8 +733,11 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
733733
}
734734

735735
if (!TemplateParamLists.empty()) {
736-
// FIXME: There's no rule against this, but there are also no rules that
737-
// would actually make it usable, so we reject it for now.
736+
// C++17 [temp]/1:
737+
// A template defines a family of class, functions, or variables, or an
738+
// alias for a family of types.
739+
//
740+
// Structured bindings are not included.
738741
Diag(TemplateParamLists.front()->getTemplateLoc(),
739742
diag::err_decomp_decl_template);
740743
return nullptr;

clang/test/CXX/drs/cwg22xx.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
22
// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
33
// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
4-
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
5-
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
6-
// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
7-
// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
4+
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
5+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
6+
// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
7+
// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
88

99

1010
namespace cwg2211 { // cwg2211: 8
@@ -196,6 +196,17 @@ void g() {
196196
#endif
197197
} // namespace cwg2277
198198

199+
namespace cwg2285 { // cwg2285: 4
200+
// Note: Clang 4 implements this DR but it set a wrong value of `__cplusplus`
201+
#if __cplusplus >= 201703L
202+
void test() {
203+
using T = int[1];
204+
auto [a] = T{a};
205+
// since-cxx17-error@-1 {{binding 'a' cannot appear in the initializer of its own decomposition declaration}}
206+
}
207+
#endif
208+
} // namespace cwg2285
209+
199210
namespace cwg2292 { // cwg2292: 9
200211
#if __cplusplus >= 201103L
201212
template<typename T> using id = T;

0 commit comments

Comments
 (0)