Skip to content

Commit 57c0f5e

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:df575be9d864886684e536cd76c5a96bb0d443a6 into amd-gfx:bd7b8d70663d
Local branch amd-gfx bd7b8d7 Merged main:16bb7e89a995dfe8b14a8ddbce3da79c217e884a into amd-gfx:10687805b78f Remote branch main df575be [clang][NFC] Add `const` qualifier in `Sema::isIncompatibleTypedef`
2 parents bd7b8d7 + df575be commit 57c0f5e

Some content is hidden

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

43 files changed

+1243
-237
lines changed

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,8 @@ class MCPlusBuilder {
438438
return false;
439439
}
440440

441-
/// Check whether we support inverting this branch
442-
virtual bool isUnsupportedBranch(const MCInst &Inst) const { return false; }
441+
/// Check whether this conditional branch can be reversed
442+
virtual bool isReversibleBranch(const MCInst &Inst) const { return true; }
443443

444444
/// Return true of the instruction is of pseudo kind.
445445
virtual bool isPseudo(const MCInst &Inst) const {

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,7 @@ Error BinaryFunction::disassemble() {
12841284
const bool IsCondBranch = MIB->isConditionalBranch(Instruction);
12851285
MCSymbol *TargetSymbol = nullptr;
12861286

1287-
if (BC.MIB->isUnsupportedBranch(Instruction)) {
1287+
if (!BC.MIB->isReversibleBranch(Instruction)) {
12881288
setIgnored();
12891289
if (BinaryFunction *TargetFunc =
12901290
BC.getBinaryFunctionContainingAddress(TargetAddress))
@@ -3381,7 +3381,7 @@ void BinaryFunction::fixBranches() {
33813381

33823382
// Reverse branch condition and swap successors.
33833383
auto swapSuccessors = [&]() {
3384-
if (MIB->isUnsupportedBranch(*CondBranch)) {
3384+
if (!MIB->isReversibleBranch(*CondBranch)) {
33853385
if (opts::Verbosity) {
33863386
BC.outs() << "BOLT-INFO: unable to swap successors in " << *this
33873387
<< '\n';

bolt/lib/Passes/Instrumentation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ void Instrumentation::instrumentFunction(BinaryFunction &Function,
480480
else if (BC.MIB->isUnconditionalBranch(Inst))
481481
HasUnconditionalBranch = true;
482482
else if ((!BC.MIB->isCall(Inst) && !BC.MIB->isConditionalBranch(Inst)) ||
483-
BC.MIB->isUnsupportedBranch(Inst))
483+
!BC.MIB->isReversibleBranch(Inst))
484484
continue;
485485

486486
const uint32_t FromOffset = *BC.MIB->getOffset(Inst);

bolt/lib/Target/X86/X86MCPlusBuilder.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -328,19 +328,19 @@ class X86MCPlusBuilder : public MCPlusBuilder {
328328
return false;
329329
}
330330

331-
bool isUnsupportedBranch(const MCInst &Inst) const override {
331+
bool isReversibleBranch(const MCInst &Inst) const override {
332332
if (isDynamicBranch(Inst))
333-
return true;
333+
return false;
334334

335335
switch (Inst.getOpcode()) {
336336
default:
337-
return false;
337+
return true;
338338
case X86::LOOP:
339339
case X86::LOOPE:
340340
case X86::LOOPNE:
341341
case X86::JECXZ:
342342
case X86::JRCXZ:
343-
return true;
343+
return false;
344344
}
345345
}
346346

@@ -1874,7 +1874,7 @@ class X86MCPlusBuilder : public MCPlusBuilder {
18741874
}
18751875

18761876
// Handle conditional branches and ignore indirect branches
1877-
if (!isUnsupportedBranch(*I) && getCondCode(*I) == X86::COND_INVALID) {
1877+
if (isReversibleBranch(*I) && getCondCode(*I) == X86::COND_INVALID) {
18781878
// Indirect branch
18791879
return false;
18801880
}

clang/docs/ReleaseNotes.rst

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,8 @@ New Compiler Flags
317317

318318
- ``-fexperimental-late-parse-attributes`` enables an experimental feature to
319319
allow late parsing certain attributes in specific contexts where they would
320-
not normally be late parsed.
320+
not normally be late parsed. Currently this allows late parsing the
321+
`counted_by` attribute in C. See `Attribute Changes in Clang`_.
321322

322323
- ``-fseparate-named-sections`` uses separate unique sections for global
323324
symbols in named special sections (i.e. symbols annotated with
@@ -406,6 +407,24 @@ Attribute Changes in Clang
406407
- The ``clspv_libclc_builtin`` attribute has been added to allow clspv
407408
(`OpenCL-C to Vulkan SPIR-V compiler <https://github.com/google/clspv>`_) to identify functions coming from libclc
408409
(`OpenCL-C builtin library <https://libclc.llvm.org>`_).
410+
- The ``counted_by`` attribute is now allowed on pointers that are members of a
411+
struct in C.
412+
413+
- The ``counted_by`` attribute can now be late parsed in C when
414+
``-fexperimental-late-parse-attributes`` is passed but only when attribute is
415+
used in the declaration attribute position. This allows using the
416+
attribute on existing code where it previously impossible to do so without
417+
re-ordering struct field declarations would break ABI as shown below.
418+
419+
.. code-block:: c
420+
421+
struct BufferTy {
422+
/* Refering to `count` requires late parsing */
423+
char* buffer __counted_by(count);
424+
/* Swapping `buffer` and `count` to avoid late parsing would break ABI */
425+
size_t count;
426+
};
427+
409428
410429
Improvements to Clang's diagnostics
411430
-----------------------------------

clang/include/clang/AST/Type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2515,6 +2515,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
25152515
bool isRecordType() const;
25162516
bool isClassType() const;
25172517
bool isStructureType() const;
2518+
bool isStructureTypeWithFlexibleArrayMember() const;
25182519
bool isObjCBoxableRecordType() const;
25192520
bool isInterfaceType() const;
25202521
bool isStructureOrClassType() const;

clang/include/clang/Basic/Attr.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2229,7 +2229,8 @@ def TypeNullUnspecified : TypeAttr {
22292229
def CountedBy : DeclOrTypeAttr {
22302230
let Spellings = [Clang<"counted_by">];
22312231
let Subjects = SubjectList<[Field], ErrorDiag>;
2232-
let Args = [ExprArgument<"Count">, IntArgument<"NestedLevel">];
2232+
let Args = [ExprArgument<"Count">, IntArgument<"NestedLevel", 1>];
2233+
let LateParsed = LateAttrParseExperimentalExt;
22332234
let ParseArgumentsAsUnevaluated = 1;
22342235
let Documentation = [CountedByDocs];
22352236
let LangOpts = [COnly];

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6533,8 +6533,10 @@ def warn_superclass_variable_sized_type_not_at_end : Warning<
65336533

65346534
def err_flexible_array_count_not_in_same_struct : Error<
65356535
"'counted_by' field %0 isn't within the same struct as the flexible array">;
6536-
def err_counted_by_attr_not_on_flexible_array_member : Error<
6537-
"'counted_by' only applies to C99 flexible array members">;
6536+
def err_counted_by_attr_not_on_ptr_or_flexible_array_member : Error<
6537+
"'counted_by' only applies to pointers or C99 flexible array members">;
6538+
def err_counted_by_attr_on_array_not_flexible_array_member : Error<
6539+
"'counted_by' on arrays only applies to C99 flexible array members">;
65386540
def err_counted_by_attr_refer_to_itself : Error<
65396541
"'counted_by' cannot refer to the flexible array member %0">;
65406542
def err_counted_by_must_be_in_structure : Error<
@@ -6549,6 +6551,17 @@ def err_counted_by_attr_refer_to_union : Error<
65496551
"'counted_by' argument cannot refer to a union member">;
65506552
def note_flexible_array_counted_by_attr_field : Note<
65516553
"field %0 declared here">;
6554+
def err_counted_by_attr_pointee_unknown_size : Error<
6555+
"'counted_by' cannot be applied to %select{"
6556+
"a pointer with pointee|" // pointer
6557+
"an array with element}0" // array
6558+
" of unknown size because %1 is %select{"
6559+
"an incomplete type|" // CountedByInvalidPointeeTypeKind::INCOMPLETE
6560+
"a sizeless type|" // CountedByInvalidPointeeTypeKind::SIZELESS
6561+
"a function type|" // CountedByInvalidPointeeTypeKind::FUNCTION
6562+
// CountedByInvalidPointeeTypeKind::FLEXIBLE_ARRAY_MEMBER
6563+
"a struct type with a flexible array member"
6564+
"}2">;
65526565

65536566
let CategoryName = "ARC Semantic Issue" in {
65546567

clang/include/clang/Parse/Parser.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1645,6 +1645,8 @@ class Parser : public CodeCompletionHandler {
16451645
bool EnterScope, bool OnDefinition);
16461646
void ParseLexedAttribute(LateParsedAttribute &LA,
16471647
bool EnterScope, bool OnDefinition);
1648+
void ParseLexedCAttribute(LateParsedAttribute &LA,
1649+
ParsedAttributes *OutAttrs = nullptr);
16481650
void ParseLexedMethodDeclarations(ParsingClass &Class);
16491651
void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM);
16501652
void ParseLexedMethodDefs(ParsingClass &Class);
@@ -2531,7 +2533,8 @@ class Parser : public CodeCompletionHandler {
25312533

25322534
void ParseStructDeclaration(
25332535
ParsingDeclSpec &DS,
2534-
llvm::function_ref<void(ParsingFieldDeclarator &)> FieldsCallback);
2536+
llvm::function_ref<Decl *(ParsingFieldDeclarator &)> FieldsCallback,
2537+
LateParsedAttrList *LateFieldAttrs = nullptr);
25352538

25362539
DeclGroupPtrTy ParseTopLevelStmtDecl();
25372540

@@ -3109,6 +3112,8 @@ class Parser : public CodeCompletionHandler {
31093112
SourceLocation ScopeLoc,
31103113
ParsedAttr::Form Form);
31113114

3115+
void DistributeCLateParsedAttrs(Decl *Dcl, LateParsedAttrList *LateAttrs);
3116+
31123117
void ParseBoundsAttribute(IdentifierInfo &AttrName,
31133118
SourceLocation AttrNameLoc, ParsedAttributes &Attrs,
31143119
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,

clang/include/clang/Sema/Sema.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3309,7 +3309,7 @@ class Sema final : public SemaBase {
33093309
/// Subroutines of ActOnDeclarator().
33103310
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
33113311
TypeSourceInfo *TInfo);
3312-
bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New);
3312+
bool isIncompatibleTypedef(const TypeDecl *Old, TypedefNameDecl *New);
33133313

33143314
/// Describes the kind of merge to perform for availability
33153315
/// attributes (including "deprecated", "unavailable", and "availability").
@@ -11396,7 +11396,8 @@ class Sema final : public SemaBase {
1139611396
QualType BuildMatrixType(QualType T, Expr *NumRows, Expr *NumColumns,
1139711397
SourceLocation AttrLoc);
1139811398

11399-
QualType BuildCountAttributedArrayType(QualType WrappedTy, Expr *CountExpr);
11399+
QualType BuildCountAttributedArrayOrPointerType(QualType WrappedTy,
11400+
Expr *CountExpr);
1140011401

1140111402
QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace,
1140211403
SourceLocation AttrLoc);

clang/lib/AST/Type.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,16 @@ bool Type::isStructureType() const {
632632
return false;
633633
}
634634

635+
bool Type::isStructureTypeWithFlexibleArrayMember() const {
636+
const auto *RT = getAs<RecordType>();
637+
if (!RT)
638+
return false;
639+
const auto *Decl = RT->getDecl();
640+
if (!Decl->isStruct())
641+
return false;
642+
return Decl->hasFlexibleArrayMember();
643+
}
644+
635645
bool Type::isObjCBoxableRecordType() const {
636646
if (const auto *RT = getAs<RecordType>())
637647
return RT->getDecl()->hasAttr<ObjCBoxableAttr>();

clang/lib/Parse/ParseDecl.cpp

Lines changed: 97 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3288,6 +3288,19 @@ void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
32883288
}
32893289
}
32903290

3291+
void Parser::DistributeCLateParsedAttrs(Decl *Dcl,
3292+
LateParsedAttrList *LateAttrs) {
3293+
assert(Dcl && "Dcl cannot be null");
3294+
3295+
if (!LateAttrs)
3296+
return;
3297+
3298+
for (auto *LateAttr : *LateAttrs) {
3299+
if (LateAttr->Decls.empty())
3300+
LateAttr->addDecl(Dcl);
3301+
}
3302+
}
3303+
32913304
/// Bounds attributes (e.g., counted_by):
32923305
/// AttrName '(' expression ')'
32933306
void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName,
@@ -4825,13 +4838,14 @@ static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS,
48254838
///
48264839
void Parser::ParseStructDeclaration(
48274840
ParsingDeclSpec &DS,
4828-
llvm::function_ref<void(ParsingFieldDeclarator &)> FieldsCallback) {
4841+
llvm::function_ref<Decl *(ParsingFieldDeclarator &)> FieldsCallback,
4842+
LateParsedAttrList *LateFieldAttrs) {
48294843

48304844
if (Tok.is(tok::kw___extension__)) {
48314845
// __extension__ silences extension warnings in the subexpression.
48324846
ExtensionRAIIObject O(Diags); // Use RAII to do this.
48334847
ConsumeToken();
4834-
return ParseStructDeclaration(DS, FieldsCallback);
4848+
return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
48354849
}
48364850

48374851
// Parse leading attributes.
@@ -4896,10 +4910,12 @@ void Parser::ParseStructDeclaration(
48964910
}
48974911

48984912
// If attributes exist after the declarator, parse them.
4899-
MaybeParseGNUAttributes(DeclaratorInfo.D);
4913+
MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
49004914

49014915
// We're done with this declarator; invoke the callback.
4902-
FieldsCallback(DeclaratorInfo);
4916+
Decl *Field = FieldsCallback(DeclaratorInfo);
4917+
if (Field)
4918+
DistributeCLateParsedAttrs(Field, LateFieldAttrs);
49034919

49044920
// If we don't have a comma, it is either the end of the list (a ';')
49054921
// or an error, bail out.
@@ -4910,6 +4926,69 @@ void Parser::ParseStructDeclaration(
49104926
}
49114927
}
49124928

4929+
/// Finish parsing an attribute for which parsing was delayed.
4930+
/// This will be called at the end of parsing a class declaration
4931+
/// for each LateParsedAttribute. We consume the saved tokens and
4932+
/// create an attribute with the arguments filled in. We add this
4933+
/// to the Attribute list for the decl.
4934+
void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
4935+
ParsedAttributes *OutAttrs) {
4936+
// Create a fake EOF so that attribute parsing won't go off the end of the
4937+
// attribute.
4938+
Token AttrEnd;
4939+
AttrEnd.startToken();
4940+
AttrEnd.setKind(tok::eof);
4941+
AttrEnd.setLocation(Tok.getLocation());
4942+
AttrEnd.setEofData(LA.Toks.data());
4943+
LA.Toks.push_back(AttrEnd);
4944+
4945+
// Append the current token at the end of the new token stream so that it
4946+
// doesn't get lost.
4947+
LA.Toks.push_back(Tok);
4948+
PP.EnterTokenStream(LA.Toks, /*DisableMacroExpansion=*/true,
4949+
/*IsReinject=*/true);
4950+
// Drop the current token and bring the first cached one. It's the same token
4951+
// as when we entered this function.
4952+
ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
4953+
4954+
ParsedAttributes Attrs(AttrFactory);
4955+
4956+
assert(LA.Decls.size() <= 1 &&
4957+
"late field attribute expects to have at most one declaration.");
4958+
4959+
// Dispatch based on the attribute and parse it
4960+
const AttributeCommonInfo::Form ParsedForm = ParsedAttr::Form::GNU();
4961+
IdentifierInfo *ScopeName = nullptr;
4962+
const ParsedAttr::Kind AttrKind =
4963+
ParsedAttr::getParsedKind(&LA.AttrName, /*ScopeName=*/ScopeName,
4964+
/*SyntaxUsed=*/ParsedForm.getSyntax());
4965+
switch (AttrKind) {
4966+
case ParsedAttr::Kind::AT_CountedBy:
4967+
ParseBoundsAttribute(LA.AttrName, LA.AttrNameLoc, Attrs,
4968+
/*ScopeName=*/ScopeName, SourceLocation(),
4969+
/*Form=*/ParsedForm);
4970+
break;
4971+
default:
4972+
llvm_unreachable("Unhandled late parsed attribute");
4973+
}
4974+
4975+
for (auto *D : LA.Decls)
4976+
Actions.ActOnFinishDelayedAttribute(getCurScope(), D, Attrs);
4977+
4978+
// Due to a parsing error, we either went over the cached tokens or
4979+
// there are still cached tokens left, so we skip the leftover tokens.
4980+
while (Tok.isNot(tok::eof))
4981+
ConsumeAnyToken();
4982+
4983+
// Consume the fake EOF token if it's there
4984+
if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4985+
ConsumeAnyToken();
4986+
4987+
if (OutAttrs) {
4988+
OutAttrs->takeAllFrom(Attrs);
4989+
}
4990+
}
4991+
49134992
/// ParseStructUnionBody
49144993
/// struct-contents:
49154994
/// struct-declaration-list
@@ -4933,6 +5012,11 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
49335012
ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
49345013
Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
49355014

5015+
// `LateAttrParseExperimentalExtOnly=true` requests that only attributes
5016+
// marked with `LateAttrParseExperimentalExt` are late parsed.
5017+
LateParsedAttrList LateFieldAttrs(/*PSoon=*/false,
5018+
/*LateAttrParseExperimentalExtOnly=*/true);
5019+
49365020
// While we still have something to read, read the declarations in the struct.
49375021
while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
49385022
Tok.isNot(tok::eof)) {
@@ -4983,18 +5067,19 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
49835067
}
49845068

49855069
if (!Tok.is(tok::at)) {
4986-
auto CFieldCallback = [&](ParsingFieldDeclarator &FD) {
5070+
auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
49875071
// Install the declarator into the current TagDecl.
49885072
Decl *Field =
49895073
Actions.ActOnField(getCurScope(), TagDecl,
49905074
FD.D.getDeclSpec().getSourceRange().getBegin(),
49915075
FD.D, FD.BitfieldSize);
49925076
FD.complete(Field);
5077+
return Field;
49935078
};
49945079

49955080
// Parse all the comma separated declarators.
49965081
ParsingDeclSpec DS(*this);
4997-
ParseStructDeclaration(DS, CFieldCallback);
5082+
ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
49985083
} else { // Handle @defs
49995084
ConsumeToken();
50005085
if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
@@ -5035,7 +5120,12 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
50355120

50365121
ParsedAttributes attrs(AttrFactory);
50375122
// If attributes exist after struct contents, parse them.
5038-
MaybeParseGNUAttributes(attrs);
5123+
MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
5124+
5125+
// Late parse field attributes if necessary.
5126+
assert(!getLangOpts().CPlusPlus);
5127+
for (auto *LateAttr : LateFieldAttrs)
5128+
ParseLexedCAttribute(*LateAttr);
50395129

50405130
SmallVector<Decl *, 32> FieldDecls(TagDecl->fields());
50415131

0 commit comments

Comments
 (0)