Skip to content

Commit 3fa9d9a

Browse files
author
Jenkins
committed
merge main into amd-staging
Change-Id: I093b48120154cc4a706cb2ce7575ea40a41a7b02
2 parents 7e58c24 + 0223230 commit 3fa9d9a

File tree

244 files changed

+3399
-954
lines changed

Some content is hidden

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

244 files changed

+3399
-954
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ C++2c Feature Support
234234

235235
Resolutions to C++ Defect Reports
236236
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
237+
- Implemented `CWG2137 <https://wg21.link/CWG2137>`_ which allows
238+
list-initialization from objects of the same type.
239+
- Implemented `CWG2311 <https://wg21.link/CWG2311>`_: given a prvalue ``e`` of object type
240+
``T``, ``T{e}`` will try to resolve an initializer list constructor and will use it if successful (CWG2137).
241+
Otherwise, if there is no initializer list constructor, the copy will be elided as if it was ``T(e)``.
237242

238243
- Implemented `CWG2598 <https://wg21.link/CWG2598>`_ and `CWG2096 <https://wg21.link/CWG2096>`_,
239244
making unions (that have either no members or at least one literal member) literal types.

clang/include/clang/AST/Expr.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1136,7 +1136,6 @@ class ConstantExpr final
11361136
return ConstantExprBits.APValueKind != APValue::None;
11371137
}
11381138
APValue getAPValueResult() const;
1139-
APValue &getResultAsAPValue() const { return APValueResult(); }
11401139
llvm::APSInt getResultAsAPSInt() const;
11411140
// Iterators
11421141
child_range children() { return child_range(&SubExpr, &SubExpr+1); }

clang/include/clang/Basic/LangOptions.def

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -367,16 +367,16 @@ BENIGN_ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
367367
"default visibility for types [-ftype-visibility]")
368368
LANGOPT(SetVisibilityForExternDecls, 1, 0,
369369
"apply global symbol visibility to external declarations without an explicit visibility")
370-
LANGOPT(VisibilityFromDLLStorageClass, 1, 0,
371-
"set the visiblity of globals from their DLL storage class [-fvisibility-from-dllstorageclass]")
372-
ENUM_LANGOPT(DLLExportVisibility, Visibility, 3, DefaultVisibility,
373-
"visibility for functions and variables with dllexport annotations [-fvisibility-from-dllstorageclass]")
374-
ENUM_LANGOPT(NoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility,
375-
"visibility for functions and variables without an explicit DLL storage class [-fvisibility-from-dllstorageclass]")
376-
ENUM_LANGOPT(ExternDeclDLLImportVisibility, Visibility, 3, DefaultVisibility,
377-
"visibility for external declarations with dllimport annotations [-fvisibility-from-dllstorageclass]")
378-
ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility,
379-
"visibility for external declarations without an explicit DLL storage class [-fvisibility-from-dllstorageclass]")
370+
BENIGN_LANGOPT(VisibilityFromDLLStorageClass, 1, 0,
371+
"override the visibility of globals based on their final DLL storage class [-fvisibility-from-dllstorageclass]")
372+
BENIGN_ENUM_LANGOPT(DLLExportVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Default,
373+
"how to adjust the visibility for functions and variables with dllexport annotations [-fvisibility-dllexport]")
374+
BENIGN_ENUM_LANGOPT(NoDLLStorageClassVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Hidden,
375+
"how to adjust the visibility for functions and variables without an explicit DLL storage class [-fvisibility-nodllstorageclass]")
376+
BENIGN_ENUM_LANGOPT(ExternDeclDLLImportVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Default,
377+
"how to adjust the visibility for external declarations with dllimport annotations [-fvisibility-externs-dllimport]")
378+
BENIGN_ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Hidden,
379+
"how to adjust the visibility for external declarations without an explicit DLL storage class [-fvisibility-externs-nodllstorageclass]")
380380
BENIGN_LANGOPT(SemanticInterposition , 1, 0, "semantic interposition")
381381
BENIGN_LANGOPT(HalfNoSemanticInterposition, 1, 0,
382382
"Like -fno-semantic-interposition but don't use local aliases")

clang/include/clang/Basic/LangOptions.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,17 @@ class LangOptions : public LangOptionsBase {
381381
All,
382382
};
383383

384+
enum class VisibilityFromDLLStorageClassKinds {
385+
/// Keep the IR-gen assigned visibility.
386+
Keep,
387+
/// Override the IR-gen assigned visibility with default visibility.
388+
Default,
389+
/// Override the IR-gen assigned visibility with hidden visibility.
390+
Hidden,
391+
/// Override the IR-gen assigned visibility with protected visibility.
392+
Protected,
393+
};
394+
384395
enum class StrictFlexArraysLevelKind {
385396
/// Any trailing array member is a FAM.
386397
Default = 0,

clang/include/clang/Driver/Options.td

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3932,27 +3932,32 @@ def dA : Flag<["-"], "dA">, Alias<fverbose_asm>;
39323932
defm visibility_from_dllstorageclass : BoolFOption<"visibility-from-dllstorageclass",
39333933
LangOpts<"VisibilityFromDLLStorageClass">, DefaultFalse,
39343934
PosFlag<SetTrue, [], [ClangOption, CC1Option],
3935-
"Set the visibility of symbols in the generated code from their DLL storage class">,
3935+
"Override the visibility of globals based on their final DLL storage class.">,
39363936
NegFlag<SetFalse>>;
3937+
class MarshallingInfoVisibilityFromDLLStorage<KeyPathAndMacro kpm, code default>
3938+
: MarshallingInfoEnum<kpm, default>,
3939+
Values<"keep,hidden,protected,default">,
3940+
NormalizedValuesScope<"LangOptions::VisibilityFromDLLStorageClassKinds">,
3941+
NormalizedValues<["Keep", "Hidden", "Protected", "Default"]> {}
39373942
def fvisibility_dllexport_EQ : Joined<["-"], "fvisibility-dllexport=">, Group<f_Group>,
39383943
Visibility<[ClangOption, CC1Option]>,
3939-
HelpText<"The visibility for dllexport definitions [-fvisibility-from-dllstorageclass]">,
3940-
MarshallingInfoVisibility<LangOpts<"DLLExportVisibility">, "DefaultVisibility">,
3944+
HelpText<"The visibility for dllexport definitions. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
3945+
MarshallingInfoVisibilityFromDLLStorage<LangOpts<"DLLExportVisibility">, "Default">,
39413946
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
39423947
def fvisibility_nodllstorageclass_EQ : Joined<["-"], "fvisibility-nodllstorageclass=">, Group<f_Group>,
39433948
Visibility<[ClangOption, CC1Option]>,
3944-
HelpText<"The visibility for definitions without an explicit DLL export class [-fvisibility-from-dllstorageclass]">,
3945-
MarshallingInfoVisibility<LangOpts<"NoDLLStorageClassVisibility">, "HiddenVisibility">,
3949+
HelpText<"The visibility for definitions without an explicit DLL storage class. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
3950+
MarshallingInfoVisibilityFromDLLStorage<LangOpts<"NoDLLStorageClassVisibility">, "Hidden">,
39463951
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
39473952
def fvisibility_externs_dllimport_EQ : Joined<["-"], "fvisibility-externs-dllimport=">, Group<f_Group>,
39483953
Visibility<[ClangOption, CC1Option]>,
3949-
HelpText<"The visibility for dllimport external declarations [-fvisibility-from-dllstorageclass]">,
3950-
MarshallingInfoVisibility<LangOpts<"ExternDeclDLLImportVisibility">, "DefaultVisibility">,
3954+
HelpText<"The visibility for dllimport external declarations. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
3955+
MarshallingInfoVisibilityFromDLLStorage<LangOpts<"ExternDeclDLLImportVisibility">, "Default">,
39513956
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
39523957
def fvisibility_externs_nodllstorageclass_EQ : Joined<["-"], "fvisibility-externs-nodllstorageclass=">, Group<f_Group>,
39533958
Visibility<[ClangOption, CC1Option]>,
3954-
HelpText<"The visibility for external declarations without an explicit DLL dllstorageclass [-fvisibility-from-dllstorageclass]">,
3955-
MarshallingInfoVisibility<LangOpts<"ExternDeclNoDLLStorageClassVisibility">, "HiddenVisibility">,
3959+
HelpText<"The visibility for external declarations without an explicit DLL storage class. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
3960+
MarshallingInfoVisibilityFromDLLStorage<LangOpts<"ExternDeclNoDLLStorageClassVisibility">, "Hidden">,
39563961
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
39573962
def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>,
39583963
Visibility<[ClangOption, CC1Option]>,

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -726,43 +726,70 @@ void InstrProfStats::reportDiagnostics(DiagnosticsEngine &Diags,
726726
}
727727
}
728728

729+
static std::optional<llvm::GlobalValue::VisibilityTypes>
730+
getLLVMVisibility(clang::LangOptions::VisibilityFromDLLStorageClassKinds K) {
731+
// Map to LLVM visibility.
732+
switch (K) {
733+
case clang::LangOptions::VisibilityFromDLLStorageClassKinds::Keep:
734+
return std::nullopt;
735+
case clang::LangOptions::VisibilityFromDLLStorageClassKinds::Default:
736+
return llvm::GlobalValue::DefaultVisibility;
737+
case clang::LangOptions::VisibilityFromDLLStorageClassKinds::Hidden:
738+
return llvm::GlobalValue::HiddenVisibility;
739+
case clang::LangOptions::VisibilityFromDLLStorageClassKinds::Protected:
740+
return llvm::GlobalValue::ProtectedVisibility;
741+
}
742+
llvm_unreachable("unknown option value!");
743+
}
744+
745+
void setLLVMVisibility(llvm::GlobalValue &GV,
746+
std::optional<llvm::GlobalValue::VisibilityTypes> V) {
747+
if (!V)
748+
return;
749+
750+
// Reset DSO locality before setting the visibility. This removes
751+
// any effects that visibility options and annotations may have
752+
// had on the DSO locality. Setting the visibility will implicitly set
753+
// appropriate globals to DSO Local; however, this will be pessimistic
754+
// w.r.t. to the normal compiler IRGen.
755+
GV.setDSOLocal(false);
756+
GV.setVisibility(*V);
757+
}
758+
729759
static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO,
730760
llvm::Module &M) {
731761
if (!LO.VisibilityFromDLLStorageClass)
732762
return;
733763

734-
llvm::GlobalValue::VisibilityTypes DLLExportVisibility =
735-
CodeGenModule::GetLLVMVisibility(LO.getDLLExportVisibility());
736-
llvm::GlobalValue::VisibilityTypes NoDLLStorageClassVisibility =
737-
CodeGenModule::GetLLVMVisibility(LO.getNoDLLStorageClassVisibility());
738-
llvm::GlobalValue::VisibilityTypes ExternDeclDLLImportVisibility =
739-
CodeGenModule::GetLLVMVisibility(LO.getExternDeclDLLImportVisibility());
740-
llvm::GlobalValue::VisibilityTypes ExternDeclNoDLLStorageClassVisibility =
741-
CodeGenModule::GetLLVMVisibility(
742-
LO.getExternDeclNoDLLStorageClassVisibility());
764+
std::optional<llvm::GlobalValue::VisibilityTypes> DLLExportVisibility =
765+
getLLVMVisibility(LO.getDLLExportVisibility());
766+
767+
std::optional<llvm::GlobalValue::VisibilityTypes>
768+
NoDLLStorageClassVisibility =
769+
getLLVMVisibility(LO.getNoDLLStorageClassVisibility());
770+
771+
std::optional<llvm::GlobalValue::VisibilityTypes>
772+
ExternDeclDLLImportVisibility =
773+
getLLVMVisibility(LO.getExternDeclDLLImportVisibility());
774+
775+
std::optional<llvm::GlobalValue::VisibilityTypes>
776+
ExternDeclNoDLLStorageClassVisibility =
777+
getLLVMVisibility(LO.getExternDeclNoDLLStorageClassVisibility());
743778

744779
for (llvm::GlobalValue &GV : M.global_values()) {
745780
if (GV.hasAppendingLinkage() || GV.hasLocalLinkage())
746781
continue;
747782

748-
// Reset DSO locality before setting the visibility. This removes
749-
// any effects that visibility options and annotations may have
750-
// had on the DSO locality. Setting the visibility will implicitly set
751-
// appropriate globals to DSO Local; however, this will be pessimistic
752-
// w.r.t. to the normal compiler IRGen.
753-
GV.setDSOLocal(false);
754-
755-
if (GV.isDeclarationForLinker()) {
756-
GV.setVisibility(GV.getDLLStorageClass() ==
757-
llvm::GlobalValue::DLLImportStorageClass
758-
? ExternDeclDLLImportVisibility
759-
: ExternDeclNoDLLStorageClassVisibility);
760-
} else {
761-
GV.setVisibility(GV.getDLLStorageClass() ==
762-
llvm::GlobalValue::DLLExportStorageClass
763-
? DLLExportVisibility
764-
: NoDLLStorageClassVisibility);
765-
}
783+
if (GV.isDeclarationForLinker())
784+
setLLVMVisibility(GV, GV.getDLLStorageClass() ==
785+
llvm::GlobalValue::DLLImportStorageClass
786+
? ExternDeclDLLImportVisibility
787+
: ExternDeclNoDLLStorageClassVisibility);
788+
else
789+
setLLVMVisibility(GV, GV.getDLLStorageClass() ==
790+
llvm::GlobalValue::DLLExportStorageClass
791+
? DLLExportVisibility
792+
: NoDLLStorageClassVisibility);
766793

767794
GV.setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
768795
}

clang/lib/Sema/SemaInit.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4200,7 +4200,7 @@ static OverloadingResult ResolveConstructorOverload(
42004200
/// \param IsListInit Is this list-initialization?
42014201
/// \param IsInitListCopy Is this non-list-initialization resulting from a
42024202
/// list-initialization from {x} where x is the same
4203-
/// type as the entity?
4203+
/// aggregate type as the entity?
42044204
static void TryConstructorInitialization(Sema &S,
42054205
const InitializedEntity &Entity,
42064206
const InitializationKind &Kind,
@@ -4230,6 +4230,14 @@ static void TryConstructorInitialization(Sema &S,
42304230
Entity.getKind() !=
42314231
InitializedEntity::EK_LambdaToBlockConversionBlockElement);
42324232

4233+
bool CopyElisionPossible = false;
4234+
auto ElideConstructor = [&] {
4235+
// Convert qualifications if necessary.
4236+
Sequence.AddQualificationConversionStep(DestType, VK_PRValue);
4237+
if (ILE)
4238+
Sequence.RewrapReferenceInitList(DestType, ILE);
4239+
};
4240+
42334241
// C++17 [dcl.init]p17:
42344242
// - If the initializer expression is a prvalue and the cv-unqualified
42354243
// version of the source type is the same class as the class of the
@@ -4242,11 +4250,17 @@ static void TryConstructorInitialization(Sema &S,
42424250
if (S.getLangOpts().CPlusPlus17 && !RequireActualConstructor &&
42434251
UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isPRValue() &&
42444252
S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) {
4245-
// Convert qualifications if necessary.
4246-
Sequence.AddQualificationConversionStep(DestType, VK_PRValue);
4247-
if (ILE)
4248-
Sequence.RewrapReferenceInitList(DestType, ILE);
4249-
return;
4253+
if (ILE && !DestType->isAggregateType()) {
4254+
// CWG2311: T{ prvalue_of_type_T } is not eligible for copy elision
4255+
// Make this an elision if this won't call an initializer-list
4256+
// constructor. (Always on an aggregate type or check constructors first.)
4257+
assert(!IsInitListCopy &&
4258+
"IsInitListCopy only possible with aggregate types");
4259+
CopyElisionPossible = true;
4260+
} else {
4261+
ElideConstructor();
4262+
return;
4263+
}
42504264
}
42514265

42524266
const RecordType *DestRecordType = DestType->getAs<RecordType>();
@@ -4291,6 +4305,12 @@ static void TryConstructorInitialization(Sema &S,
42914305
S, Kind.getLocation(), Args, CandidateSet, DestType, Ctors, Best,
42924306
CopyInitialization, AllowExplicit,
42934307
/*OnlyListConstructors=*/true, IsListInit, RequireActualConstructor);
4308+
4309+
if (CopyElisionPossible && Result == OR_No_Viable_Function) {
4310+
// No initializer list candidate
4311+
ElideConstructor();
4312+
return;
4313+
}
42944314
}
42954315

42964316
// C++11 [over.match.list]p1:
@@ -4572,9 +4592,9 @@ static void TryListInitialization(Sema &S,
45724592
return;
45734593
}
45744594

4575-
// C++11 [dcl.init.list]p3, per DR1467:
4576-
// - If T is a class type and the initializer list has a single element of
4577-
// type cv U, where U is T or a class derived from T, the object is
4595+
// C++11 [dcl.init.list]p3, per DR1467 and DR2137:
4596+
// - If T is an aggregate class and the initializer list has a single element
4597+
// of type cv U, where U is T or a class derived from T, the object is
45784598
// initialized from that element (by copy-initialization for
45794599
// copy-list-initialization, or by direct-initialization for
45804600
// direct-list-initialization).
@@ -4585,7 +4605,7 @@ static void TryListInitialization(Sema &S,
45854605
// - Otherwise, if T is an aggregate, [...] (continue below).
45864606
if (S.getLangOpts().CPlusPlus11 && InitList->getNumInits() == 1 &&
45874607
!IsDesignatedInit) {
4588-
if (DestType->isRecordType()) {
4608+
if (DestType->isRecordType() && DestType->isAggregateType()) {
45894609
QualType InitType = InitList->getInit(0)->getType();
45904610
if (S.Context.hasSameUnqualifiedType(InitType, DestType) ||
45914611
S.IsDerivedFrom(InitList->getBeginLoc(), InitType, DestType)) {

clang/lib/Sema/SemaOverload.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,19 +1568,37 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
15681568
// called for those cases.
15691569
if (CXXConstructorDecl *Constructor
15701570
= dyn_cast<CXXConstructorDecl>(ICS.UserDefined.ConversionFunction)) {
1571-
QualType FromCanon
1572-
= S.Context.getCanonicalType(From->getType().getUnqualifiedType());
1571+
QualType FromType;
1572+
SourceLocation FromLoc;
1573+
// C++11 [over.ics.list]p6, per DR2137:
1574+
// C++17 [over.ics.list]p6:
1575+
// If C is not an initializer-list constructor and the initializer list
1576+
// has a single element of type cv U, where U is X or a class derived
1577+
// from X, the implicit conversion sequence has Exact Match rank if U is
1578+
// X, or Conversion rank if U is derived from X.
1579+
if (const auto *InitList = dyn_cast<InitListExpr>(From);
1580+
InitList && InitList->getNumInits() == 1 &&
1581+
!S.isInitListConstructor(Constructor)) {
1582+
const Expr *SingleInit = InitList->getInit(0);
1583+
FromType = SingleInit->getType();
1584+
FromLoc = SingleInit->getBeginLoc();
1585+
} else {
1586+
FromType = From->getType();
1587+
FromLoc = From->getBeginLoc();
1588+
}
1589+
QualType FromCanon =
1590+
S.Context.getCanonicalType(FromType.getUnqualifiedType());
15731591
QualType ToCanon
15741592
= S.Context.getCanonicalType(ToType).getUnqualifiedType();
15751593
if (Constructor->isCopyConstructor() &&
15761594
(FromCanon == ToCanon ||
1577-
S.IsDerivedFrom(From->getBeginLoc(), FromCanon, ToCanon))) {
1595+
S.IsDerivedFrom(FromLoc, FromCanon, ToCanon))) {
15781596
// Turn this into a "standard" conversion sequence, so that it
15791597
// gets ranked with standard conversion sequences.
15801598
DeclAccessPair Found = ICS.UserDefined.FoundConversionFunction;
15811599
ICS.setStandard();
15821600
ICS.Standard.setAsIdentityConversion();
1583-
ICS.Standard.setFromType(From->getType());
1601+
ICS.Standard.setFromType(FromType);
15841602
ICS.Standard.setAllToTypes(ToType);
15851603
ICS.Standard.CopyConstructor = Constructor;
15861604
ICS.Standard.FoundCopyConstructor = Found;
@@ -5306,18 +5324,18 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
53065324
IsDesignatedInit)
53075325
return Result;
53085326

5309-
// Per DR1467:
5310-
// If the parameter type is a class X and the initializer list has a single
5311-
// element of type cv U, where U is X or a class derived from X, the
5312-
// implicit conversion sequence is the one required to convert the element
5313-
// to the parameter type.
5327+
// Per DR1467 and DR2137:
5328+
// If the parameter type is an aggregate class X and the initializer list
5329+
// has a single element of type cv U, where U is X or a class derived from
5330+
// X, the implicit conversion sequence is the one required to convert the
5331+
// element to the parameter type.
53145332
//
53155333
// Otherwise, if the parameter type is a character array [... ]
53165334
// and the initializer list has a single element that is an
53175335
// appropriately-typed string literal (8.5.2 [dcl.init.string]), the
53185336
// implicit conversion sequence is the identity conversion.
53195337
if (From->getNumInits() == 1 && !IsDesignatedInit) {
5320-
if (ToType->isRecordType()) {
5338+
if (ToType->isRecordType() && ToType->isAggregateType()) {
53215339
QualType InitType = From->getInit(0)->getType();
53225340
if (S.Context.hasSameUnqualifiedType(InitType, ToType) ||
53235341
S.IsDerivedFrom(From->getBeginLoc(), InitType, ToType))

0 commit comments

Comments
 (0)