r337728 - Separate out the initialization kind for a statement expression result
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 23 12:19:08 PDT 2018
Author: rsmith
Date: Mon Jul 23 12:19:08 2018
New Revision: 337728
URL: http://llvm.org/viewvc/llvm-project?rev=337728&view=rev
Log:
Separate out the initialization kind for a statement expression result
from that for a return value.
No functionality change intended: I don't believe any of the diagnostics
affected by this patch are reachable when initializing the result of
statement expression.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Initialization.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=337728&r1=337727&r2=337728&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jul 23 12:19:08 2018
@@ -1804,7 +1804,8 @@ def err_destructor_template : Error<
// C++ initialization
def err_init_conversion_failed : Error<
- "cannot initialize %select{a variable|a parameter|return object|an "
+ "cannot initialize %select{a variable|a parameter|return object|"
+ "statement expression result|an "
"exception object|a member subobject|an array element|a new value|a value|a "
"base class|a constructor delegation|a vector element|a block element|a "
"block element|a complex element|a lambda capture|a compound literal "
@@ -1939,34 +1940,29 @@ def warn_unsequenced_mod_mod : Warning<
def warn_unsequenced_mod_use : Warning<
"unsequenced modification and access to %0">, InGroup<Unsequenced>;
+def select_initialized_entity_kind : TextSubstitution<
+ "%select{copying variable|copying parameter|"
+ "returning object|initializing statement expression result|"
+ "throwing object|copying member subobject|copying array element|"
+ "allocating object|copying temporary|initializing base subobject|"
+ "initializing vector element|capturing value}0">;
+
def err_temp_copy_no_viable : Error<
- "no viable constructor %select{copying variable|copying parameter|"
- "returning object|throwing object|copying member subobject|copying array "
- "element|allocating object|copying temporary|initializing base subobject|"
- "initializing vector element|capturing value}0 of type %1">;
+ "no viable constructor %sub{select_initialized_entity_kind}0 of type %1">;
def ext_rvalue_to_reference_temp_copy_no_viable : Extension<
- "no viable constructor %select{copying variable|copying parameter|"
- "returning object|throwing object|copying member subobject|copying array "
- "element|allocating object|copying temporary|initializing base subobject|"
- "initializing vector element|capturing value}0 of type %1; C++98 requires a copy "
- "constructor when binding a reference to a temporary">,
+ "no viable constructor %sub{select_initialized_entity_kind}0 of type %1; "
+ "C++98 requires a copy constructor when binding a reference to a temporary">,
InGroup<BindToTemporaryCopy>;
def err_temp_copy_ambiguous : Error<
- "ambiguous constructor call when %select{copying variable|copying "
- "parameter|returning object|throwing object|copying member subobject|copying "
- "array element|allocating object|copying temporary|initializing base subobject|"
- "initializing vector element|capturing value}0 of type %1">;
+ "ambiguous constructor call when %sub{select_initialized_entity_kind}0 "
+ "of type %1">;
def err_temp_copy_deleted : Error<
- "%select{copying variable|copying parameter|returning object|throwing "
- "object|copying member subobject|copying array element|allocating object|"
- "copying temporary|initializing base subobject|initializing vector element|"
- "capturing value}0 of type %1 invokes deleted constructor">;
+ "%sub{select_initialized_entity_kind}0 of type %1 "
+ "invokes deleted constructor">;
def err_temp_copy_incomplete : Error<
"copying a temporary object of incomplete type %0">;
def warn_cxx98_compat_temp_copy : Warning<
- "%select{copying variable|copying parameter|returning object|throwing "
- "object|copying member subobject|copying array element|allocating object|"
- "copying temporary|initializing base subobject|initializing vector element}1 "
+ "%sub{select_initialized_entity_kind}1 "
"of type %2 when binding a reference to a temporary would %select{invoke "
"an inaccessible constructor|find no viable constructor|find ambiguous "
"constructors|invoke a deleted constructor}0 in C++98">,
Modified: cfe/trunk/include/clang/Sema/Initialization.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=337728&r1=337727&r2=337728&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Initialization.h (original)
+++ cfe/trunk/include/clang/Sema/Initialization.h Mon Jul 23 12:19:08 2018
@@ -59,6 +59,9 @@ public:
/// The entity being initialized is the result of a function call.
EK_Result,
+ /// The entity being initialized is the result of a statement expression.
+ EK_StmtExprResult,
+
/// The entity being initialized is an exception object that
/// is being thrown.
EK_Exception,
@@ -285,6 +288,11 @@ public:
return InitializedEntity(EK_Result, ReturnLoc, Type, NRVO);
}
+ static InitializedEntity InitializeStmtExprResult(SourceLocation ReturnLoc,
+ QualType Type) {
+ return InitializedEntity(EK_StmtExprResult, ReturnLoc, Type);
+ }
+
static InitializedEntity InitializeBlock(SourceLocation BlockVarLoc,
QualType Type, bool NRVO) {
return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO);
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=337728&r1=337727&r2=337728&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jul 23 12:19:08 2018
@@ -12992,11 +12992,8 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc
LastExpr = rebuiltLastStmt;
} else {
LastExpr = PerformCopyInitialization(
- InitializedEntity::InitializeResult(LPLoc,
- Ty,
- false),
- SourceLocation(),
- LastExpr);
+ InitializedEntity::InitializeStmtExprResult(LPLoc, Ty),
+ SourceLocation(), LastExpr);
}
if (LastExpr.isInvalid())
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=337728&r1=337727&r2=337728&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Jul 23 12:19:08 2018
@@ -1020,6 +1020,7 @@ static void warnBracedScalarInit(Sema &S
case InitializedEntity::EK_BlockElement:
case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
case InitializedEntity::EK_Binding:
+ case InitializedEntity::EK_StmtExprResult:
llvm_unreachable("unexpected braced scalar init");
}
@@ -3000,6 +3001,7 @@ DeclarationName InitializedEntity::getNa
return DeclarationName(Capture.VarID);
case EK_Result:
+ case EK_StmtExprResult:
case EK_Exception:
case EK_New:
case EK_Temporary:
@@ -3030,6 +3032,7 @@ ValueDecl *InitializedEntity::getDecl()
return reinterpret_cast<ParmVarDecl*>(Parameter & ~0x1);
case EK_Result:
+ case EK_StmtExprResult:
case EK_Exception:
case EK_New:
case EK_Temporary:
@@ -3055,6 +3058,7 @@ bool InitializedEntity::allowsNRVO() con
case EK_Exception:
return LocAndNRVO.NRVO;
+ case EK_StmtExprResult:
case EK_Variable:
case EK_Parameter:
case EK_Parameter_CF_Audited:
@@ -3090,6 +3094,7 @@ unsigned InitializedEntity::dumpImpl(raw
case EK_Parameter_CF_Audited: OS << "CF audited function Parameter";
break;
case EK_Result: OS << "Result"; break;
+ case EK_StmtExprResult: OS << "StmtExprResult"; break;
case EK_Exception: OS << "Exception"; break;
case EK_Member: OS << "Member"; break;
case EK_Binding: OS << "Binding"; break;
@@ -3534,7 +3539,8 @@ static void MaybeProduceObjCObject(Sema
/// retainable type, then returns need to immediately retain the
/// object. If an autorelease is required, it will be done at the
/// last instant.
- } else if (Entity.getKind() == InitializedEntity::EK_Result) {
+ } else if (Entity.getKind() == InitializedEntity::EK_Result ||
+ Entity.getKind() == InitializedEntity::EK_StmtExprResult) {
if (!Entity.getType()->isObjCRetainableType())
return;
@@ -5632,6 +5638,7 @@ getAssignmentAction(const InitializedEnt
return !Diagnose ? Sema::AA_Passing : Sema::AA_Passing_CFAudited;
case InitializedEntity::EK_Result:
+ case InitializedEntity::EK_StmtExprResult: // FIXME: Not quite right.
return Sema::AA_Returning;
case InitializedEntity::EK_Temporary:
@@ -5661,6 +5668,7 @@ static bool shouldBindAsTemporary(const
case InitializedEntity::EK_ArrayElement:
case InitializedEntity::EK_Member:
case InitializedEntity::EK_Result:
+ case InitializedEntity::EK_StmtExprResult:
case InitializedEntity::EK_New:
case InitializedEntity::EK_Variable:
case InitializedEntity::EK_Base:
@@ -5690,6 +5698,7 @@ static bool shouldBindAsTemporary(const
static bool shouldDestroyEntity(const InitializedEntity &Entity) {
switch (Entity.getKind()) {
case InitializedEntity::EK_Result:
+ case InitializedEntity::EK_StmtExprResult:
case InitializedEntity::EK_New:
case InitializedEntity::EK_Base:
case InitializedEntity::EK_Delegating:
@@ -5721,6 +5730,7 @@ static SourceLocation getInitializationL
Expr *Initializer) {
switch (Entity.getKind()) {
case InitializedEntity::EK_Result:
+ case InitializedEntity::EK_StmtExprResult:
return Entity.getReturnLoc();
case InitializedEntity::EK_Exception:
@@ -6168,6 +6178,7 @@ InitializedEntityOutlivesFullExpression(
switch (Top->getKind()) {
case InitializedEntity::EK_Variable:
case InitializedEntity::EK_Result:
+ case InitializedEntity::EK_StmtExprResult:
case InitializedEntity::EK_Exception:
case InitializedEntity::EK_Member:
case InitializedEntity::EK_Binding:
@@ -6216,6 +6227,10 @@ enum LifetimeKind {
/// the entity is a return object.
LK_Return,
+ /// The lifetime of a temporary bound to this entity ends too soon, because
+ /// the entity is the result of a statement expression.
+ LK_StmtExprResult,
+
/// This is a mem-initializer: if it would extend a temporary (other than via
/// a default member initializer), the program is ill-formed.
LK_MemInitializer,
@@ -6274,6 +6289,11 @@ static LifetimeResult getEntityLifetime(
// destroyed at the end of the full-expression in the return statement.
return {nullptr, LK_Return};
+ case InitializedEntity::EK_StmtExprResult:
+ // FIXME: Should we lifetime-extend through the result of a statement
+ // expression?
+ return {nullptr, LK_StmtExprResult};
+
case InitializedEntity::EK_New:
// -- A temporary bound to a reference in a new-initializer persists
// until the completion of the full-expression containing the
@@ -6582,6 +6602,7 @@ void Sema::checkInitializerLifetime(cons
break;
case LK_Return:
+ case LK_StmtExprResult:
// FIXME: Move -Wreturn-stack-address checks here.
return false;
}
@@ -6660,6 +6681,7 @@ void Sema::checkInitializerLifetime(cons
break;
case LK_Return:
+ case LK_StmtExprResult:
// FIXME: Move -Wreturn-stack-address checks here.
return false;
}
More information about the cfe-commits
mailing list