ayzhao updated this revision to Diff 506755.
ayzhao added a comment.
remove extra semicolon
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D146465/new/
https://reviews.llvm.org/D146465
Files:
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaInit.cpp
clang/test/CodeGen/paren-list-agg-init.cpp
Index: clang/test/CodeGen/paren-list-agg-init.cpp
===================================================================
--- clang/test/CodeGen/paren-list-agg-init.cpp
+++ clang/test/CodeGen/paren-list-agg-init.cpp
@@ -69,6 +69,21 @@
char b;
};
+
+namespace gh61145 {
+ // CHECK-DAG: [[STRUCT_VEC:%.*]] = type { i8 }
+ struct Vec {
+ Vec();
+ Vec(Vec&&);
+ ~Vec();
+ };
+
+ // CHECK-DAG: [[STRUCT_S:%.*]] = type { [[STRUCT_VEC]] }
+ struct S {
+ Vec v;
+ };
+}
+
// CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.000000e+00 }, align 8
constexpr A a1(3.1, 2.0);
// CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.000000e+00 }, align 8
@@ -349,3 +364,30 @@
void foo19() {
G g(2);
}
+
+namespace gh61145 {
+ // a.k.a. void make<1>()
+ // CHECK: define {{.*}} void @_ZN7gh611454makeILi0EEEvv
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: [[V:%.*v.*]] = alloca [[STRUCT_VEC]], align 1
+ // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S]], align 1
+ // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
+ // a.k.a. Vec::Vec()
+ // CHECK-NEXT: [[V1:%.*v1.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+ // a.k.a. Vec::Vec(Vec&&)
+ // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[V1]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])
+ // a.k.a. S::~S()
+ // CHECK-NEXT: call void @_ZN7gh611451SD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]
+ // a.k.a.Vec::~Vec()
+ // CHECK-NEXT: call void @_ZN7gh611453VecD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
+ // CHECK-NEXT: ret void
+ template <int I>
+ void make() {
+ Vec v;
+ S((Vec&&) v);
+ }
+
+ void foo() {
+ make<0>();
+ }
+}
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -9180,6 +9180,8 @@
/*VerifyOnly=*/false, &CurInit);
if (CurInit.get() && ResultType)
*ResultType = CurInit.get()->getType();
+ if (shouldBindAsTemporary(Entity))
+ CurInit = S.MaybeBindToTemporary(CurInit.get());
break;
}
}
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -1548,7 +1548,7 @@
// conversion expression is equivalent (in definedness, and if defined in
// meaning) to the corresponding cast expression.
if (Exprs.size() == 1 && !ListInitialization &&
- !isa<InitListExpr>(Exprs[0])) {
+ !isa<InitListExpr>(Exprs[0]) && !isa<CXXParenListInitExpr>(Exprs[0])) {
Expr *Arg = Exprs[0];
return BuildCXXFunctionalCastExpr(TInfo, Ty, LParenOrBraceLoc, Arg,
RParenOrBraceLoc);
@@ -1579,10 +1579,28 @@
diag::err_invalid_incomplete_type_use, FullRange))
return ExprError();
- // Otherwise, the expression is a prvalue of the specified type whose
- // result object is direct-initialized (11.6) with the initializer.
- InitializationSequence InitSeq(*this, Entity, Kind, Exprs);
- ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Exprs);
+ MultiExprArg ExprsToPass;
+ if (Exprs.size() == 1 && isa<CXXParenListInitExpr>(Exprs[0])) {
+ // C++20 [expr.static.cast]p4:
+ // An expression E can be explicitly converted to a type T...if T is an
+ // aggregate type ([dcl.init.aggr]) having a first element x and there is
+ // an implicit conversion sequence from E to the type of x
+ //
+ // Unlike for InitListExprs, InitializationSequence(..) doesn't take the
+ // overall CXXParenListInitExpr as the first element, so we instead pass
+ // it the elements of the CXXParenListInitExpr and have it deduce the
+ // initialization type and generate a new CXXParenListInitExpr.
+ auto *CPLIE = cast<CXXParenListInitExpr>(Exprs[0]);
+ ExprsToPass =
+ MultiExprArg(const_cast<Expr **>(CPLIE->getInitExprs().begin()),
+ CPLIE->getInitExprs().size());
+ } else {
+ // Otherwise, the expression is a prvalue of the specified type whose
+ // result object is direct-initialized (11.6) with the initializer.
+ ExprsToPass = Exprs;
+ }
+ InitializationSequence InitSeq(*this, Entity, Kind, ExprsToPass);
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind, ExprsToPass);
if (Result.isInvalid())
return Result;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits