mizvekov created this revision.
Herald added subscribers: jansvoboda11, dexonsmith, lxfind, dang.
mizvekov requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
WIP, not yet ready for review.
Small sample of things wrong with this patch:
- Have to remove some copypasta.
- Fix from D98971 <https://reviews.llvm.org/D98971> directly imported here
- Some further simplifications needed.
- Test suite not updated to test new mode.
- In fact, the test suite was not run at all...
Just some manual testing:
- return: moderate
- throw: light
- co_return: not tested yet
Signed-off-by: Matheus Izvekov <[email protected]>
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D99005
Files:
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Sema/SemaCoroutine.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaStmt.cpp
clang/lib/Sema/SemaType.cpp
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -8839,6 +8839,10 @@
if (E->isTypeDependent())
return S.Context.DependentTy;
+ Expr *IDExpr = E;
+ if (auto ImplCastExpr = dyn_cast<ImplicitCastExpr>(E)) {
+ IDExpr = ImplCastExpr->getSubExpr();
+ }
// C++11 [dcl.type.simple]p4:
// The type denoted by decltype(e) is defined as follows:
@@ -8849,7 +8853,7 @@
// Note that this does not pick up the implicit 'const' for a template
// parameter object. This rule makes no difference before C++20 so we apply
// it unconditionally.
- if (const auto *SNTTPE = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
+ if (const auto *SNTTPE = dyn_cast<SubstNonTypeTemplateParmExpr>(IDExpr))
return SNTTPE->getParameterType(S.Context);
// - if e is an unparenthesized id-expression or an unparenthesized class
@@ -8858,21 +8862,22 @@
// functions, the program is ill-formed;
//
// We apply the same rules for Objective-C ivar and property references.
- if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(IDExpr)) {
const ValueDecl *VD = DRE->getDecl();
if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD))
return TPO->getType().getUnqualifiedType();
return VD->getType();
- } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
+ } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(IDExpr)) {
if (const ValueDecl *VD = ME->getMemberDecl())
if (isa<FieldDecl>(VD) || isa<VarDecl>(VD))
return VD->getType();
- } else if (const ObjCIvarRefExpr *IR = dyn_cast<ObjCIvarRefExpr>(E)) {
+ } else if (const ObjCIvarRefExpr *IR = dyn_cast<ObjCIvarRefExpr>(IDExpr)) {
return IR->getDecl()->getType();
- } else if (const ObjCPropertyRefExpr *PR = dyn_cast<ObjCPropertyRefExpr>(E)) {
+ } else if (const ObjCPropertyRefExpr *PR =
+ dyn_cast<ObjCPropertyRefExpr>(IDExpr)) {
if (PR->isExplicitProperty())
return PR->getExplicitProperty()->getType();
- } else if (auto *PE = dyn_cast<PredefinedExpr>(E)) {
+ } else if (auto *PE = dyn_cast<PredefinedExpr>(IDExpr)) {
return PE->getType();
}
@@ -8885,8 +8890,8 @@
// entity.
using namespace sema;
if (S.getCurLambda()) {
- if (isa<ParenExpr>(E)) {
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParens())) {
+ if (isa<ParenExpr>(IDExpr)) {
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(IDExpr->IgnoreParens())) {
if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
QualType T = S.getCapturedDeclRefType(Var, DRE->getLocation());
if (!T.isNull())
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -3041,6 +3041,8 @@
/// NRVO, or NULL if there is no such candidate.
VarDecl *Sema::getCopyElisionCandidate(QualType ReturnType, Expr *E,
CopyElisionSemanticsKind CESK) {
+ if (auto ImplCastExpr = dyn_cast<ImplicitCastExpr>(E))
+ E = ImplCastExpr->getSubExpr();
// - in a return statement in a function [where] ...
// ... the expression is the name of a non-volatile automatic object ...
DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParens());
@@ -3086,15 +3088,14 @@
if (VD->hasAttr<BlocksAttr>())
return false;
- // ...non-volatile...
- if (VD->getType().isVolatileQualified())
- return false;
-
- // C++20 [class.copy.elision]p3:
- // ...rvalue reference to a non-volatile...
- if (VD->getType()->isRValueReferenceType() &&
- (!(CESK & CES_AllowRValueReferenceType) ||
- VD->getType().getNonReferenceType().isVolatileQualified()))
+ QualType VDNonRefType = VDType;
+ if (VDType->isReferenceType()) {
+ if (!(CESK & CES_AllowRValueReferenceType) ||
+ !VDType->isRValueReferenceType())
+ return false;
+ VDNonRefType = VDType.getNonReferenceType();
+ }
+ if (!VDNonRefType->isObjectType() || VDNonRefType.isVolatileQualified())
return false;
if (CESK & CES_AllowDifferentTypes)
@@ -3102,8 +3103,8 @@
// Variables with higher required alignment than their type's ABI
// alignment cannot use NRVO.
- if (!VD->getType()->isDependentType() && VD->hasAttr<AlignedAttr>() &&
- Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VD->getType()))
+ if (!VDNonRefType->isDependentType() && VD->hasAttr<AlignedAttr>() &&
+ Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VDNonRefType))
return false;
return true;
@@ -3221,15 +3222,16 @@
ExprResult Res = ExprError();
bool NeedSecondOverloadResolution = true;
- if (AllowNRVO) {
- CopyElisionSemanticsKind CESK = CES_Strict;
- if (getLangOpts().CPlusPlus20) {
- CESK = CES_ImplicitlyMovableCXX20;
- } else if (getLangOpts().CPlusPlus11) {
- CESK = CES_ImplicitlyMovableCXX11CXX14CXX17;
- }
-
+ if (!(getLangOpts().CPlusPlus2b &&
+ getLangOpts().CPlusPlusSimplerImplicitMove) &&
+ AllowNRVO) {
if (!NRVOCandidate) {
+ CopyElisionSemanticsKind CESK = CES_Strict;
+ if (getLangOpts().CPlusPlus20) {
+ CESK = CES_ImplicitlyMovableCXX20;
+ } else if (getLangOpts().CPlusPlus11) {
+ CESK = CES_ImplicitlyMovableCXX11CXX14CXX17;
+ }
NRVOCandidate = getCopyElisionCandidate(ResultType, Value, CESK);
}
@@ -3650,6 +3652,15 @@
if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))
return StmtError();
+ if (getLangOpts().CPlusPlus2b && getLangOpts().CPlusPlusSimplerImplicitMove) {
+ if (VarDecl *VD = getCopyElisionCandidate(QualType{}, RetValExp,
+ CES_ImplicitlyMovableCXX20)) {
+ RetValExp = ImplicitCastExpr::Create(
+ Context, VD->getType().getNonReferenceType(), CK_NoOp, RetValExp,
+ nullptr, VK_XValue, FPOptionsOverride());
+ }
+ }
+
if (isa<CapturingScopeInfo>(getCurFunction()))
return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp);
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -851,6 +851,16 @@
Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw";
if (Ex && !Ex->isTypeDependent()) {
+ if (getLangOpts().CPlusPlus2b &&
+ getLangOpts().CPlusPlusSimplerImplicitMove) {
+ if (VarDecl *VD = getCopyElisionCandidate(QualType{}, Ex,
+ CES_ImplicitlyMovableCXX20)) {
+ Ex = ImplicitCastExpr::Create(
+ Context, VD->getType().getNonReferenceType(), CK_NoOp, Ex, nullptr,
+ VK_XValue, FPOptionsOverride());
+ }
+ }
+
QualType ExceptionObjectTy = Context.getExceptionObjectType(Ex->getType());
if (CheckCXXThrowOperand(OpLoc, ExceptionObjectTy, Ex))
return ExprError();
Index: clang/lib/Sema/SemaCoroutine.cpp
===================================================================
--- clang/lib/Sema/SemaCoroutine.cpp
+++ clang/lib/Sema/SemaCoroutine.cpp
@@ -999,10 +999,13 @@
const VarDecl *NRVOCandidate = this->getCopyElisionCandidate(
E->getType(), E, CES_ImplicitlyMovableCXX20);
if (NRVOCandidate) {
+ QualType T = NRVOCandidate->getType();
+ E = ImplicitCastExpr::Create(Context, T.getNonReferenceType(), CK_NoOp, E,
+ nullptr, VK_XValue, FPOptionsOverride());
InitializedEntity Entity =
- InitializedEntity::InitializeResult(Loc, E->getType(), NRVOCandidate);
- ExprResult MoveResult = this->PerformMoveOrCopyInitialization(
- Entity, NRVOCandidate, E->getType(), E);
+ InitializedEntity::InitializeResult(Loc, T, NRVOCandidate);
+ ExprResult MoveResult =
+ this->PerformMoveOrCopyInitialization(Entity, NRVOCandidate, T, E);
if (MoveResult.get())
E = MoveResult.get();
}
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -5837,6 +5837,12 @@
CmdArgs.push_back("-fcoroutines-ts");
}
+ if (Args.hasFlag(options::OPT_fsimpler_implicit_move,
+ options::OPT_fno_simpler_implicit_move, false) &&
+ types::isCXX(InputType)) {
+ CmdArgs.push_back("-fsimpler-implicit-move");
+ }
+
Args.AddLastArg(CmdArgs, options::OPT_fdouble_square_bracket_attributes,
options::OPT_fno_double_square_bracket_attributes);
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1069,6 +1069,12 @@
PosFlag<SetTrue, [CC1Option], "Enable support for the C++ Coroutines TS">,
NegFlag<SetFalse>>;
+// C++2b Simpler Implicit Move
+defm simpler_implicit_move : BoolFOption<"simpler-implicit-move",
+ LangOpts<"CPlusPlusSimplerImplicitMove">, DefaultFalse,
+ PosFlag<SetTrue, [CC1Option], "Enable support for C++2b simpler implicit move (P2266)">,
+ NegFlag<SetFalse>>;
+
def fembed_bitcode_EQ : Joined<["-"], "fembed-bitcode=">,
Group<f_Group>, Flags<[NoXarchOption, CC1Option, CC1AsOption]>, MetaVarName<"<option>">,
HelpText<"Embed LLVM bitcode (option: off, all, bitcode, marker)">,
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -144,6 +144,7 @@
LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions")
LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly")
LANGOPT(Coroutines , 1, 0, "C++20 coroutines")
+LANGOPT(CPlusPlusSimplerImplicitMove, 1, 0, "C++2b simpler implicit move")
LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods")
LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments")
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits