Skip to content

Commit 8cec474

Browse files
authored
Merge branch 'main' into hgh/libcxx/P2255R2-A_type_trait_to_detect_reference_binding_to_temporary
2 parents a8de754 + 1adb001 commit 8cec474

File tree

82 files changed

+1030
-1120
lines changed

Some content is hidden

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

82 files changed

+1030
-1120
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ Bug Fixes in This Version
225225

226226
- Clang now outputs correct values when #embed data contains bytes with negative
227227
signed char values (#GH102798).
228+
- Fixed rejects-valid problem when #embed appears in std::initializer_list or
229+
when it can affect template argument deduction (#GH122306).
228230

229231
Bug Fixes to Compiler Builtins
230232
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/AST/Expr.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5189,6 +5189,16 @@ class InitListExpr : public Expr {
51895189

51905190
unsigned getNumInits() const { return InitExprs.size(); }
51915191

5192+
/// getNumInits but if the list has an EmbedExpr inside includes full length
5193+
/// of embedded data.
5194+
unsigned getNumInitsWithEmbedExpanded() const {
5195+
unsigned Sum = InitExprs.size();
5196+
for (auto *IE : InitExprs)
5197+
if (auto *EE = dyn_cast<EmbedExpr>(IE))
5198+
Sum += EE->getDataElementCount() - 1;
5199+
return Sum;
5200+
}
5201+
51925202
/// Retrieve the set of initializers.
51935203
Expr **getInits() { return reinterpret_cast<Expr **>(InitExprs.data()); }
51945204

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3176,7 +3176,7 @@ def modules_reduced_bmi : Flag<["-"], "fmodules-reduced-bmi">,
31763176
HelpText<"Generate the reduced BMI">,
31773177
MarshallingInfoFlag<FrontendOpts<"GenReducedBMI">>;
31783178

3179-
def experimental_modules_reduced_bmi : Flag<["-"], "fexperimental-modules-reduced-bmi">,
3179+
def experimental_modules_reduced_bmi : Flag<["-"], "fexperimental-modules-reduced-bmi">,
31803180
Group<f_Group>, Visibility<[ClangOption, CC1Option]>, Alias<modules_reduced_bmi>;
31813181

31823182
def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">,
@@ -7431,7 +7431,7 @@ def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfie
74317431
def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">,
74327432
HelpText<"Turn off Type Based Alias Analysis">,
74337433
MarshallingInfoFlag<CodeGenOpts<"RelaxedAliasing">>;
7434-
defm pointer_tbaa: BoolOption<"", "pointer-tbaa", CodeGenOpts<"PointerTBAA">,
7434+
defm pointer_tbaa: BoolOption<"", "pointer-tbaa", CodeGenOpts<"PointerTBAA">,
74357435
DefaultTrue,
74367436
PosFlag<SetTrue, [], [ClangOption], "Enable">,
74377437
NegFlag<SetFalse, [], [ClangOption], "Disable">,

clang/lib/CodeGen/CGCoroutine.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,20 @@ void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) {
855855
// Create parameter copies. We do it before creating a promise, since an
856856
// evolution of coroutine TS may allow promise constructor to observe
857857
// parameter copies.
858+
for (const ParmVarDecl *Parm : FnArgs) {
859+
// If the original param is in an alloca, exclude it from the coroutine
860+
// frame. The parameter copy will be part of the frame, but the original
861+
// parameter memory should remain on the stack. This is necessary to
862+
// ensure that parameters destroyed in callees, as with `trivial_abi` or
863+
// in the MSVC C++ ABI, are appropriately destroyed after setting up the
864+
// coroutine.
865+
Address ParmAddr = GetAddrOfLocalVar(Parm);
866+
if (auto *ParmAlloca =
867+
dyn_cast<llvm::AllocaInst>(ParmAddr.getBasePointer())) {
868+
ParmAlloca->setMetadata(llvm::LLVMContext::MD_coro_outside_frame,
869+
llvm::MDNode::get(CGM.getLLVMContext(), {}));
870+
}
871+
}
858872
for (auto *PM : S.getParamMoves()) {
859873
EmitStmt(PM);
860874
ParamReplacer.addCopy(cast<DeclStmt>(PM));

clang/lib/Headers/vecintrin.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10+
#ifndef _VECINTRIN_H
11+
#define _VECINTRIN_H
12+
1013
#if defined(__s390x__) && defined(__VEC__)
1114

1215
#define __ATTRS_ai __attribute__((__always_inline__))
@@ -12861,3 +12864,5 @@ vec_search_string_until_zero_cc(__vector unsigned int __a,
1286112864
#error "Use -fzvector to enable vector extensions"
1286212865

1286312866
#endif
12867+
12868+
#endif /* _VECINTRIN_H */

clang/lib/Sema/SemaDecl.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13427,9 +13427,13 @@ bool Sema::GloballyUniqueObjectMightBeAccidentallyDuplicated(
1342713427
FunDcl->getTemplateSpecializationKind() != TSK_Undeclared;
1342813428
}
1342913429

13430-
// Non-inline functions/variables can only legally appear in one TU,
13431-
// unless they were part of a template.
13432-
if (!TargetIsInline && !TargetWasTemplated)
13430+
// Non-inline functions/variables can only legally appear in one TU
13431+
// unless they were part of a template. Unfortunately, making complex
13432+
// template instantiations visible is infeasible in practice, since
13433+
// everything the template depends on also has to be visible. To avoid
13434+
// giving impractical-to-fix warnings, don't warn if we're inside
13435+
// something that was templated, even on inline stuff.
13436+
if (!TargetIsInline || TargetWasTemplated)
1343313437
return false;
1343413438

1343513439
// If the object isn't hidden, the dynamic linker will prevent duplication.
@@ -13469,8 +13473,8 @@ void Sema::DiagnoseUniqueObjectDuplication(const VarDecl *VD) {
1346913473
// FIXME: Windows uses dllexport/dllimport instead of visibility, and we don't
1347013474
// handle that yet. Disable the warning on Windows for now.
1347113475

13472-
// Don't diagnose if we're inside a template;
13473-
// we'll diagnose during instantiation instead.
13476+
// Don't diagnose if we're inside a template, because it's not practical to
13477+
// fix the warning in most cases.
1347413478
if (!Context.getTargetInfo().shouldDLLImportComdatSymbols() &&
1347513479
!VD->isTemplated() &&
1347613480
GloballyUniqueObjectMightBeAccidentallyDuplicated(VD)) {

clang/lib/Sema/SemaInit.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4261,7 +4261,7 @@ static bool TryInitializerListConstruction(Sema &S,
42614261
QualType ArrayType = S.Context.getConstantArrayType(
42624262
E.withConst(),
42634263
llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),
4264-
List->getNumInits()),
4264+
List->getNumInitsWithEmbedExpanded()),
42654265
nullptr, clang::ArraySizeModifier::Normal, 0);
42664266
InitializedEntity HiddenArray =
42674267
InitializedEntity::InitializeTemporary(ArrayType);

clang/lib/Sema/SemaOverload.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5710,12 +5710,14 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
57105710
// - if the initializer list has one element that is not itself an
57115711
// initializer list, the implicit conversion sequence is the one
57125712
// required to convert the element to the parameter type.
5713+
// Bail out on EmbedExpr as well since we never create EmbedExpr for a
5714+
// single integer.
57135715
unsigned NumInits = From->getNumInits();
5714-
if (NumInits == 1 && !isa<InitListExpr>(From->getInit(0)))
5715-
Result = TryCopyInitialization(S, From->getInit(0), ToType,
5716-
SuppressUserConversions,
5717-
InOverloadResolution,
5718-
AllowObjCWritebackConversion);
5716+
if (NumInits == 1 && !isa<InitListExpr>(From->getInit(0)) &&
5717+
!isa<EmbedExpr>(From->getInit(0)))
5718+
Result = TryCopyInitialization(
5719+
S, From->getInit(0), ToType, SuppressUserConversions,
5720+
InOverloadResolution, AllowObjCWritebackConversion);
57195721
// - if the initializer list has no elements, the implicit conversion
57205722
// sequence is the identity conversion.
57215723
else if (NumInits == 0) {

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4506,7 +4506,8 @@ static TemplateDeductionResult DeduceFromInitializerList(
45064506
// C++ [temp.deduct.type]p13:
45074507
// The type of N in the type T[N] is std::size_t.
45084508
QualType T = S.Context.getSizeType();
4509-
llvm::APInt Size(S.Context.getIntWidth(T), ILE->getNumInits());
4509+
llvm::APInt Size(S.Context.getIntWidth(T),
4510+
ILE->getNumInitsWithEmbedExpanded());
45104511
if (auto Result = DeduceNonTypeTemplateArgument(
45114512
S, TemplateParams, NTTP, llvm::APSInt(Size), T,
45124513
/*ArrayBound=*/true, Info, /*PartialOrdering=*/false, Deduced,

clang/test/CodeGenCoroutines/coro-params.cpp

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Vefifies that parameter copies are used in the body of the coroutine
44
// Verifies that parameter copies are used to construct the promise type, if that type has a matching constructor
55
// RUN: %clang_cc1 -std=c++20 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -disable-llvm-passes -fexceptions | FileCheck %s
6+
// RUN: %clang_cc1 -std=c++20 -triple=x86_64-pc-win32 -emit-llvm -o - %s -disable-llvm-passes -fexceptions | FileCheck %s --check-prefix=MSABI
67

78
namespace std {
89
template <typename... T> struct coroutine_traits;
@@ -59,46 +60,65 @@ struct MoveAndCopy {
5960
~MoveAndCopy();
6061
};
6162

62-
void consume(int,int,int) noexcept;
63+
struct [[clang::trivial_abi]] TrivialABI {
64+
int val;
65+
TrivialABI(TrivialABI&&) noexcept;
66+
~TrivialABI();
67+
};
68+
69+
void consume(int,int,int,int) noexcept;
6370

6471
// TODO: Add support for CopyOnly params
65-
// CHECK: define{{.*}} void @_Z1fi8MoveOnly11MoveAndCopy(i32 noundef %val, ptr noundef %[[MoParam:.+]], ptr noundef %[[McParam:.+]]) #0 personality ptr @__gxx_personality_v0
66-
void f(int val, MoveOnly moParam, MoveAndCopy mcParam) {
72+
// CHECK: define{{.*}} void @_Z1fi8MoveOnly11MoveAndCopy10TrivialABI(i32 noundef %val, ptr noundef %[[MoParam:.+]], ptr noundef %[[McParam:.+]], i32 %[[TrivialParam:.+]]) #0 personality ptr @__gxx_personality_v0
73+
void f(int val, MoveOnly moParam, MoveAndCopy mcParam, TrivialABI trivialParam) {
74+
// CHECK: %[[TrivialAlloca:.+]] = alloca %struct.TrivialABI,
75+
// CHECK-SAME: !coro.outside.frame
6776
// CHECK: %[[MoCopy:.+]] = alloca %struct.MoveOnly,
6877
// CHECK: %[[McCopy:.+]] = alloca %struct.MoveAndCopy,
78+
// CHECK: %[[TrivialCopy:.+]] = alloca %struct.TrivialABI,
6979
// CHECK: store i32 %val, ptr %[[ValAddr:.+]]
7080

7181
// CHECK: call ptr @llvm.coro.begin(
7282
// CHECK: call void @_ZN8MoveOnlyC1EOS_(ptr {{[^,]*}} %[[MoCopy]], ptr noundef nonnull align 4 dereferenceable(4) %[[MoParam]])
7383
// CHECK-NEXT: call void @llvm.lifetime.start.p0(
7484
// CHECK-NEXT: call void @_ZN11MoveAndCopyC1EOS_(ptr {{[^,]*}} %[[McCopy]], ptr noundef nonnull align 4 dereferenceable(4) %[[McParam]]) #
7585
// CHECK-NEXT: call void @llvm.lifetime.start.p0(
76-
// CHECK-NEXT: invoke void @_ZNSt16coroutine_traitsIJvi8MoveOnly11MoveAndCopyEE12promise_typeC1Ev(
86+
// CHECK-NEXT: call void @_ZN10TrivialABIC1EOS_(ptr {{[^,]*}} %[[TrivialCopy]], ptr {{[^,]*}} %[[TrivialAlloca]])
87+
// CHECK-NEXT: call void @llvm.lifetime.start.p0(
88+
// CHECK-NEXT: invoke void @_ZNSt16coroutine_traitsIJvi8MoveOnly11MoveAndCopy10TrivialABIEE12promise_typeC1Ev(
7789

7890
// CHECK: call void @_ZN14suspend_always12await_resumeEv(
7991
// CHECK: %[[IntParam:.+]] = load i32, ptr %{{.*}}
8092
// CHECK: %[[MoGep:.+]] = getelementptr inbounds nuw %struct.MoveOnly, ptr %[[MoCopy]], i32 0, i32 0
8193
// CHECK: %[[MoVal:.+]] = load i32, ptr %[[MoGep]]
82-
// CHECK: %[[McGep:.+]] = getelementptr inbounds nuw %struct.MoveAndCopy, ptr %[[McCopy]], i32 0, i32 0
94+
// CHECK: %[[McGep:.+]] = getelementptr inbounds nuw %struct.MoveAndCopy, ptr %[[McCopy]], i32 0, i32 0
8395
// CHECK: %[[McVal:.+]] = load i32, ptr %[[McGep]]
84-
// CHECK: call void @_Z7consumeiii(i32 noundef %[[IntParam]], i32 noundef %[[MoVal]], i32 noundef %[[McVal]])
96+
// CHECK: %[[TrivialGep:.+]] = getelementptr inbounds nuw %struct.TrivialABI, ptr %[[TrivialCopy]], i32 0, i32 0
97+
// CHECK: %[[TrivialVal:.+]] = load i32, ptr %[[TrivialGep]]
98+
// CHECK: call void @_Z7consumeiiii(i32 noundef %[[IntParam]], i32 noundef %[[MoVal]], i32 noundef %[[McVal]], i32 noundef %[[TrivialVal]])
8599

86-
consume(val, moParam.val, mcParam.val);
100+
consume(val, moParam.val, mcParam.val, trivialParam.val);
87101
co_return;
88102

89103
// Skip to final suspend:
90-
// CHECK: call void @_ZNSt16coroutine_traitsIJvi8MoveOnly11MoveAndCopyEE12promise_type13final_suspendEv(
104+
// CHECK: call void @_ZNSt16coroutine_traitsIJvi8MoveOnly11MoveAndCopy10TrivialABIEE12promise_type13final_suspendEv(
91105
// CHECK: call void @_ZN14suspend_always12await_resumeEv(
92106

93107
// Destroy promise, then parameter copies:
94-
// CHECK: call void @_ZNSt16coroutine_traitsIJvi8MoveOnly11MoveAndCopyEE12promise_typeD1Ev(ptr {{[^,]*}} %__promise)
108+
// CHECK: call void @_ZNSt16coroutine_traitsIJvi8MoveOnly11MoveAndCopy10TrivialABIEE12promise_typeD1Ev(ptr {{[^,]*}} %__promise)
109+
// CHECK-NEXT: call void @llvm.lifetime.end.p0(
110+
// CHECK-NEXT: call void @_ZN10TrivialABID1Ev(ptr {{[^,]*}} %[[TrivialCopy]])
95111
// CHECK-NEXT: call void @llvm.lifetime.end.p0(
96112
// CHECK-NEXT: call void @_ZN11MoveAndCopyD1Ev(ptr {{[^,]*}} %[[McCopy]])
97113
// CHECK-NEXT: call void @llvm.lifetime.end.p0(
98114
// CHECK-NEXT: call void @_ZN8MoveOnlyD1Ev(ptr {{[^,]*}} %[[MoCopy]]
99115
// CHECK-NEXT: call void @llvm.lifetime.end.p0(
100116
// CHECK-NEXT: call void @llvm.lifetime.end.p0(
101117
// CHECK-NEXT: call ptr @llvm.coro.free(
118+
119+
// The original trivial_abi parameter is destroyed when returning from the ramp.
120+
// CHECK: call i1 @llvm.coro.end
121+
// CHECK: call void @_ZN10TrivialABID1Ev(ptr {{[^,]*}} %[[TrivialAlloca]])
102122
}
103123

104124
// CHECK-LABEL: void @_Z16dependent_paramsI1A1BEvT_T0_S3_(ptr noundef %x, ptr noundef %0, ptr noundef %y)
@@ -190,3 +210,38 @@ method some_class::good_coroutine_calls_custom_constructor(float) {
190210
// CHECK: invoke void @_ZNSt16coroutine_traitsIJ6methodR10some_classfEE12promise_typeC1ES2_f(ptr {{[^,]*}} %__promise, ptr noundef nonnull align 1 dereferenceable(1) %{{.+}}, float
191211
co_return;
192212
}
213+
214+
215+
struct MSParm {
216+
int val;
217+
~MSParm();
218+
};
219+
220+
void consume(int) noexcept;
221+
222+
// Similarly to the [[clang::trivial_abi]] parameters, with the MSVC ABI
223+
// parameters are also destroyed by the callee, and on x86-64 such parameters
224+
// may get passed in registers. In that case it's again important that the
225+
// parameter's local alloca does not become part of the coro frame since that
226+
// may be destroyed before the destructor call.
227+
void msabi(MSParm p) {
228+
// MSABI: define{{.*}} void @"?msabi@@YAXUMSParm@@@Z"(i32 %[[Param:.+]])
229+
230+
// The parameter's local alloca is marked not part of the frame.
231+
// MSABI: %[[ParamAlloca:.+]] = alloca %struct.MSParm
232+
// MSABI-SAME: !coro.outside.frame
233+
234+
// MSABI: %[[ParamCopy:.+]] = alloca %struct.MSParm
235+
236+
consume(p.val);
237+
// The parameter's copy is used by the coroutine.
238+
// MSABI: %[[ValPtr:.+]] = getelementptr inbounds nuw %struct.MSParm, ptr %[[ParamCopy]], i32 0, i32 0
239+
// MSABI: %[[Val:.+]] = load i32, ptr %[[ValPtr]]
240+
// MSABI: call void @"?consume@@YAXH@Z"(i32{{.*}} %[[Val]])
241+
242+
co_return;
243+
244+
// The local alloca is used for the destructor call at the end of the ramp.
245+
// MSABI: call i1 @llvm.coro.end
246+
// MSABI: call void @"??1MSParm@@QEAA@XZ"(ptr{{.*}} %[[ParamAlloca]])
247+
}

0 commit comments

Comments
 (0)