Skip to content

Commit

Permalink
merge main into amd-staging
Browse files Browse the repository at this point in the history
Reverts: more Sema changes
9e1f1cf [Clang][Sema] Handle class member access expressions with valid nested-name-specifiers that become invalid after lookup (llvm#98167)

Change-Id: I80aa10cf856f4854120e2eb7446335403b163b77
  • Loading branch information
ronlieb committed Jul 10, 2024
2 parents 97572c0 + 015526b commit 99e48c6
Show file tree
Hide file tree
Showing 174 changed files with 4,885 additions and 1,228 deletions.
4 changes: 0 additions & 4 deletions bolt/include/bolt/Core/DebugData.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,6 @@ class DebugRangesSectionWriter {

std::mutex WriterMutex;

/// Current offset in the section (updated as new entries are written).
/// Starts with 16 since the first 16 bytes are reserved for an empty range.
uint32_t SectionOffset{0};

/// Offset of an empty address ranges list.
static constexpr uint64_t EmptyRangesOffset{0};

Expand Down
11 changes: 4 additions & 7 deletions bolt/lib/Core/DebugData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ DebugRangesSectionWriter::DebugRangesSectionWriter() {
RangesStream = std::make_unique<raw_svector_ostream>(*RangesBuffer);

// Add an empty range as the first entry;
SectionOffset +=
writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{});
writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{});
Kind = RangesWriterKind::DebugRangesWriter;
}

Expand All @@ -166,21 +165,20 @@ uint64_t DebugRangesSectionWriter::addRanges(DebugAddressRangesVector &Ranges) {
// Reading the SectionOffset and updating it should be atomic to guarantee
// unique and correct offsets in patches.
std::lock_guard<std::mutex> Lock(WriterMutex);
const uint32_t EntryOffset = SectionOffset;
SectionOffset += writeAddressRanges(*RangesStream.get(), Ranges);
const uint32_t EntryOffset = RangesBuffer->size();
writeAddressRanges(*RangesStream.get(), Ranges);

return EntryOffset;
}

uint64_t DebugRangesSectionWriter::getSectionOffset() {
std::lock_guard<std::mutex> Lock(WriterMutex);
return SectionOffset;
return RangesBuffer->size();
}

void DebugRangesSectionWriter::appendToRangeBuffer(
const DebugBufferVector &CUBuffer) {
*RangesStream << CUBuffer;
SectionOffset = RangesBuffer->size();
}

DebugAddrWriter *DebugRangeListsSectionWriter::AddrWriter = nullptr;
Expand Down Expand Up @@ -327,7 +325,6 @@ void DebugRangeListsSectionWriter::finalizeSection() {
*RangesStream << *Header;
*RangesStream << *CUArrayBuffer;
*RangesStream << *CUBodyBuffer;
SectionOffset = RangesBuffer->size();
}

void DebugRangeListsSectionWriter::initSection(DWARFUnit &Unit) {
Expand Down
14 changes: 5 additions & 9 deletions bolt/lib/Rewrite/DWARFRewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1342,10 +1342,7 @@ void DWARFRewriter::updateDWARFObjectAddressRanges(
assert(RangesWriterIterator != LegacyRangesWritersByCU.end() &&
"RangesWriter does not exist for DWOId");
RangesWriterIterator->second->setDie(&Die);
} else if (Unit.getVersion() == 5) {
DIEBldr.addValue(&Die, dwarf::DW_AT_rnglists_base,
dwarf::DW_FORM_sec_offset, DIEInteger(*RangesBase));
} else {
} else if (Unit.getVersion() >= 5) {
DIEBldr.addValue(&Die, dwarf::DW_AT_rnglists_base,
dwarf::DW_FORM_sec_offset, DIEInteger(*RangesBase));
}
Expand Down Expand Up @@ -1638,14 +1635,13 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
"RangesWriter does not exist for DWOId");
std::unique_ptr<DebugRangesSectionWriter> &LegacyRangesWriter =
RangesWriterIterator->second;
std::optional<DIE *> Die = LegacyRangesWriter->getDie();
if (!Die || !Die.value())
DIE *Die = LegacyRangesWriter->getDie();
if (!Die)
continue;
DIEValue DvalGNUBase =
Die.value()->findAttribute(dwarf::DW_AT_GNU_ranges_base);
DIEValue DvalGNUBase = Die->findAttribute(dwarf::DW_AT_GNU_ranges_base);
assert(DvalGNUBase && "GNU_ranges_base attribute does not exist for DWOId");
DIEBlder.replaceValue(
Die.value(), dwarf::DW_AT_GNU_ranges_base, DvalGNUBase.getForm(),
Die, dwarf::DW_AT_GNU_ranges_base, DvalGNUBase.getForm(),
DIEInteger(LegacyRangesSectionWriter->getSectionOffset()));
std::unique_ptr<DebugBufferVector> RangesWritersContents =
LegacyRangesWriter->releaseBuffer();
Expand Down
2 changes: 1 addition & 1 deletion bolt/test/X86/infer_no_exits.test
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@

# PREAGG: B X:0 #main# 1 0

# CHECK: BOLT-INFO: inferred profile for 1 (100.00% of profiled, 100.00% of stale) functions responsible for -nan% samples (0 out of 0)
# CHECK: BOLT-INFO: inferred profile for 1 (100.00% of profiled, 100.00% of stale) functions
4 changes: 2 additions & 2 deletions bolt/test/X86/jt-symbol-disambiguation-4.s
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
# REQUIRES: system-linux

# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
# RUN: %clang -no-pie %t.o -o %t.exe -Wl,-q
# RUN: %clang %cflags -no-pie %t.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --funcs=main,foo/1 %t.exe -o %t.exe.bolt --print-normalized \
# RUN: 2>&1 | FileCheck %s

.text
.globl main
.type main,@function
main:
# CHECK: Binary Function "main"
# CHECK: Binary Function "main
pushq %rbp
movq %rsp, %rbp
movq $-16, %rax
Expand Down
13 changes: 13 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,15 @@ Attribute Changes in Clang
size_t count;
};
- The attributes ``sized_by``, ``counted_by_or_null`` and ``sized_by_or_null```
have been added as variants on ``counted_by``, each with slightly different semantics.
``sized_by`` takes a byte size parameter instead of an element count, allowing pointees
with unknown size. The ``counted_by_or_null`` and ``sized_by_or_null`` variants are equivalent
to their base variants, except the pointer can be null regardless of count/size value.
If the pointer is null the size is effectively 0. ``sized_by_or_null`` is needed to properly
annotate allocator functions like ``malloc`` that return a buffer of a given byte size, but can
also return null.

- The ``guarded_by``, ``pt_guarded_by``, ``acquired_after``, ``acquired_before``
attributes now support referencing struct members in C. The arguments are also
now late parsed when ``-fexperimental-late-parse-attributes`` is passed like
Expand Down Expand Up @@ -679,6 +688,9 @@ Improvements to Clang's diagnostics

- Clang now shows implicit deduction guides when diagnosing overload resolution failure. #GH92393.

- Clang no longer emits a "no previous prototype" warning for Win32 entry points under ``-Wmissing-prototypes``.
Fixes #GH94366.

Improvements to Clang's time-trace
----------------------------------

Expand Down Expand Up @@ -994,6 +1006,7 @@ Bug Fixes to C++ Support
evaluated to an integer. (#GH96670).
- Fixed a bug where references to lambda capture inside a ``noexcept`` specifier were not correctly
instantiated. (#GH95735).
- Fixed a CTAD substitution bug involving type aliases that reference outer template parameters. (#GH94614).

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
68 changes: 68 additions & 0 deletions clang/docs/StandardCPlusPlusModules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,74 @@ A high-level overview of support for standards features, including modules, can
be found on the `C++ Feature Status <https://clang.llvm.org/cxx_status.html>`_
page.

Missing VTables for classes attached to modules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Now the compiler may miss emitting the definition of vtables
for classes attached to modules, if the definition of the class
doesn't contain any key function in that module units
(The key function is the first non-pure virtual function that is
not inline at the point of class definition.)

(Note: technically, the key function is not a thing for modules.
We use the concept here for convinient.)

For example,

.. code-block:: c++

// layer1.cppm
export module foo:layer1;
struct Fruit {
virtual ~Fruit() = default;
virtual void eval() = 0;
};
struct Banana : public Fruit {
Banana() {}
void eval() override;
};

// layer2.cppm
export module foo:layer2;
import :layer1;
export void layer2_fun() {
Banana *b = new Banana();
b->eval();
}
void Banana::eval() {
}
For the above example, we can't find the definition for the vtable of
class ``Banana`` in any object files.

The expected behavior is, for dynamic classes attached to named modules,
the vtable should always be emitted to the module units the class attaches
to.

To workaround the problem, users can add the key function manually in the
corresponding module units. e.g.,

.. code-block:: c++

// layer1.cppm
export module foo:layer1;
struct Fruit {
virtual ~Fruit() = default;
virtual void eval() = 0;
};
struct Banana : public Fruit {
// Hack a key function to hint the compiler to emit the virtual table.
virtual void anchor();

Banana() {}
void eval() override;
};

void Banana::anchor() {}

This is tracked by
`#70585 <https://github.com/llvm/llvm-project/issues/70585>`_.

Including headers after import is not well-supported
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
10 changes: 0 additions & 10 deletions clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -670,16 +670,6 @@ class alignas(8) Decl {
/// Whether this declaration comes from another module unit.
bool isInAnotherModuleUnit() const;

/// Whether this declaration comes from the same module unit being compiled.
bool isInCurrentModuleUnit() const;

/// Whether the definition of the declaration should be emitted in external
/// sources.
bool shouldEmitInExternalSource() const;

/// Whether this declaration comes from a named module;
bool isInNamedModule() const;

/// Whether this declaration comes from explicit global module.
bool isFromExplicitGlobalModule() const;

Expand Down
30 changes: 30 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -2292,6 +2292,36 @@ def CountedBy : DeclOrTypeAttr {
let LangOpts = [COnly];
}

def CountedByOrNull : DeclOrTypeAttr {
let Spellings = [Clang<"counted_by_or_null">];
let Subjects = SubjectList<[Field], ErrorDiag>;
let Args = [ExprArgument<"Count">, IntArgument<"NestedLevel", 1>];
let LateParsed = LateAttrParseExperimentalExt;
let ParseArgumentsAsUnevaluated = 1;
let Documentation = [CountedByDocs];
let LangOpts = [COnly];
}

def SizedBy : DeclOrTypeAttr {
let Spellings = [Clang<"sized_by">];
let Subjects = SubjectList<[Field], ErrorDiag>;
let Args = [ExprArgument<"Size">, IntArgument<"NestedLevel", 1>];
let LateParsed = LateAttrParseExperimentalExt;
let ParseArgumentsAsUnevaluated = 1;
let Documentation = [CountedByDocs];
let LangOpts = [COnly];
}

def SizedByOrNull : DeclOrTypeAttr {
let Spellings = [Clang<"sized_by_or_null">];
let Subjects = SubjectList<[Field], ErrorDiag>;
let Args = [ExprArgument<"Size">, IntArgument<"NestedLevel", 1>];
let LateParsed = LateAttrParseExperimentalExt;
let ParseArgumentsAsUnevaluated = 1;
let Documentation = [CountedByDocs];
let LangOpts = [COnly];
}

// This is a marker used to indicate that an __unsafe_unretained qualifier was
// ignored because ARC is not enabled. The usual representation for this
// qualifier is as an ObjCOwnership attribute with Kind == "none".
Expand Down
30 changes: 15 additions & 15 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -6570,28 +6570,28 @@ def warn_superclass_variable_sized_type_not_at_end : Warning<
"field %0 can overwrite instance variable %1 with variable sized type %2"
" in superclass %3">, InGroup<ObjCFlexibleArray>;

def err_flexible_array_count_not_in_same_struct : Error<
"'counted_by' field %0 isn't within the same struct as the flexible array">;
def err_counted_by_attr_not_on_ptr_or_flexible_array_member : Error<
"'counted_by' only applies to pointers or C99 flexible array members">;
def err_count_attr_param_not_in_same_struct : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}1' field %0 isn't within the same struct as the annotated %select{pointer|flexible array}2">;
def err_count_attr_not_on_ptr_or_flexible_array_member : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}0' only applies to pointers%select{ or C99 flexible array members|||}0%select{|; did you mean to use 'counted_by'?}1">;
def err_counted_by_attr_on_array_not_flexible_array_member : Error<
"'counted_by' on arrays only applies to C99 flexible array members">;
def err_counted_by_attr_refer_to_itself : Error<
"'counted_by' cannot refer to the flexible array member %0">;
def err_counted_by_must_be_in_structure : Error<
"field %0 in 'counted_by' not inside structure">;
def err_counted_by_attr_argument_not_integer : Error<
"'counted_by' requires a non-boolean integer type argument">;
def err_counted_by_attr_only_support_simple_decl_reference : Error<
"'counted_by' argument must be a simple declaration reference">;
def err_counted_by_attr_in_union : Error<
"'counted_by' cannot be applied to a union member">;
def err_counted_by_attr_refer_to_union : Error<
"'counted_by' argument cannot refer to a union member">;
def err_count_attr_must_be_in_structure : Error<
"field %0 in '%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}1' not inside structure">;
def err_count_attr_argument_not_integer : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}0' requires a non-boolean integer type argument">;
def err_count_attr_only_support_simple_decl_reference : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}0' argument must be a simple declaration reference">;
def err_count_attr_in_union : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}0' cannot be applied to a union member">;
def err_count_attr_refer_to_union : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}0' argument cannot refer to a union member">;
def note_flexible_array_counted_by_attr_field : Note<
"field %0 declared here">;
def err_counted_by_attr_pointee_unknown_size : Error<
"'counted_by' %select{cannot|should not}3 be applied to %select{"
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}4' %select{cannot|should not}3 be applied to %select{"
"a pointer with pointee|" // pointer
"an array with element}0" // array
" of unknown size because %1 is %select{"
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -14608,7 +14608,9 @@ class Sema final : public SemaBase {
SourceLocation AttrLoc);

QualType BuildCountAttributedArrayOrPointerType(QualType WrappedTy,
Expr *CountExpr);
Expr *CountExpr,
bool CountInBytes,
bool OrNull);

/// BuildAddressSpaceAttr - Builds a DependentAddressSpaceType if an
/// expression is uninstantiated. If instantiated it will apply the
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Sema/Template.h
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,7 @@ enum class TemplateSubstitutionKind : char {
VarTemplateSpecializationDecl *PrevDecl = nullptr);

Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
Decl *InstantiateTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
ClassTemplatePartialSpecializationDecl *
InstantiateClassTemplatePartialSpecialization(
ClassTemplateDecl *ClassTemplate,
Expand Down
3 changes: 0 additions & 3 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -721,9 +721,6 @@ enum ASTRecordTypes {

/// Record code for \#pragma clang unsafe_buffer_usage begin/end
PP_UNSAFE_BUFFER_USAGE = 69,

/// Record code for vtables to emit.
VTABLES_TO_EMIT = 70,
};

/// Record types used within a source manager block.
Expand Down
6 changes: 0 additions & 6 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -790,11 +790,6 @@ class ASTReader
/// the consumer eagerly.
SmallVector<GlobalDeclID, 16> EagerlyDeserializedDecls;

/// The IDs of all vtables to emit. The referenced declarations are passed
/// to the consumers's HandleVTable eagerly after passing
/// EagerlyDeserializedDecls.
SmallVector<GlobalDeclID, 16> VTablesToEmit;

/// The IDs of all tentative definitions stored in the chain.
///
/// Sema keeps track of all tentative definitions in a TU because it has to
Expand Down Expand Up @@ -1505,7 +1500,6 @@ class ASTReader
bool isConsumerInterestedIn(Decl *D);
void PassInterestingDeclsToConsumer();
void PassInterestingDeclToConsumer(Decl *D);
void PassVTableToConsumer(CXXRecordDecl *RD);

void finishPendingActions();
void diagnoseOdrViolations();
Expand Down
7 changes: 0 additions & 7 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,10 +500,6 @@ class ASTWriter : public ASTDeserializationListener,
std::vector<SourceRange> NonAffectingRanges;
std::vector<SourceLocation::UIntTy> NonAffectingOffsetAdjustments;

/// A list of classes which need to emit the VTable in the corresponding
/// object file.
llvm::SmallVector<CXXRecordDecl *> PendingEmittingVTables;

/// Computes input files that didn't affect compilation of the current module,
/// and initializes data structures necessary for leaving those files out
/// during \c SourceManager serialization.
Expand Down Expand Up @@ -861,8 +857,6 @@ class ASTWriter : public ASTDeserializationListener,
return PredefinedDecls.count(D);
}

void handleVTable(CXXRecordDecl *RD);

private:
// ASTDeserializationListener implementation
void ReaderInitialized(ASTReader *Reader) override;
Expand Down Expand Up @@ -957,7 +951,6 @@ class PCHGenerator : public SemaConsumer {

void InitializeSema(Sema &S) override { SemaPtr = &S; }
void HandleTranslationUnit(ASTContext &Ctx) override;
void HandleVTable(CXXRecordDecl *RD) override { Writer.handleVTable(RD); }
ASTMutationListener *GetASTMutationListener() override;
ASTDeserializationListener *GetASTDeserializationListener() override;
bool hasEmittedPCH() const { return Buffer->IsComplete; }
Expand Down
Loading

0 comments on commit 99e48c6

Please sign in to comment.