mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-12 09:41:26 +00:00
Reinstate the fix for PR7556. A silly use of isTrivial() was
suppressing copies of objects with trivial copy constructors. llvm-svn: 107857
This commit is contained in:
parent
be1f7a931e
commit
747eb7840a
@ -822,12 +822,8 @@ public:
|
||||
///
|
||||
/// This expression type represents a C++ "functional" cast
|
||||
/// (C++[expr.type.conv]) with N != 1 arguments that invokes a
|
||||
/// constructor to build a temporary object. If N == 0 but no
|
||||
/// constructor will be called (because the functional cast is
|
||||
/// performing a value-initialized an object whose class type has no
|
||||
/// user-declared constructors), CXXZeroInitValueExpr will represent
|
||||
/// the functional cast. Finally, with N == 1 arguments the functional
|
||||
/// cast expression will be represented by CXXFunctionalCastExpr.
|
||||
/// constructor to build a temporary object. With N == 1 arguments the
|
||||
/// functional cast expression will be represented by CXXFunctionalCastExpr.
|
||||
/// Example:
|
||||
/// @code
|
||||
/// struct X { X(int, float); }
|
||||
@ -861,22 +857,21 @@ public:
|
||||
static bool classof(const CXXTemporaryObjectExpr *) { return true; }
|
||||
};
|
||||
|
||||
/// CXXZeroInitValueExpr - [C++ 5.2.3p2]
|
||||
/// CXXScalarValueInitExpr - [C++ 5.2.3p2]
|
||||
/// Expression "T()" which creates a value-initialized rvalue of type
|
||||
/// T, which is either a non-class type or a class type without any
|
||||
/// user-defined constructors.
|
||||
/// T, which is a non-class type.
|
||||
///
|
||||
class CXXZeroInitValueExpr : public Expr {
|
||||
class CXXScalarValueInitExpr : public Expr {
|
||||
SourceLocation TyBeginLoc;
|
||||
SourceLocation RParenLoc;
|
||||
|
||||
public:
|
||||
CXXZeroInitValueExpr(QualType ty, SourceLocation tyBeginLoc,
|
||||
CXXScalarValueInitExpr(QualType ty, SourceLocation tyBeginLoc,
|
||||
SourceLocation rParenLoc ) :
|
||||
Expr(CXXZeroInitValueExprClass, ty, false, false),
|
||||
Expr(CXXScalarValueInitExprClass, ty, false, false),
|
||||
TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
|
||||
explicit CXXZeroInitValueExpr(EmptyShell Shell)
|
||||
: Expr(CXXZeroInitValueExprClass, Shell) { }
|
||||
explicit CXXScalarValueInitExpr(EmptyShell Shell)
|
||||
: Expr(CXXScalarValueInitExprClass, Shell) { }
|
||||
|
||||
SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
|
||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
@ -895,9 +890,9 @@ public:
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXZeroInitValueExprClass;
|
||||
return T->getStmtClass() == CXXScalarValueInitExprClass;
|
||||
}
|
||||
static bool classof(const CXXZeroInitValueExpr *) { return true; }
|
||||
static bool classof(const CXXScalarValueInitExpr *) { return true; }
|
||||
|
||||
// Iterators
|
||||
virtual child_iterator child_begin();
|
||||
|
@ -1545,7 +1545,7 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DEF_TRAVERSE_STMT(CXXZeroInitValueExpr, {
|
||||
DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
|
||||
// This is called for code like 'return MyClass()' where MyClass
|
||||
// has no user-defined constructor. It's also called for 'return
|
||||
// int()'. We recurse on type MyClass/int.
|
||||
|
@ -509,6 +509,9 @@ def err_access_dtor_vbase :
|
||||
def err_access_dtor_temp :
|
||||
Error<"temporary of type %0 has %select{private|protected}1 destructor">,
|
||||
NoSFINAE;
|
||||
def err_access_dtor_exception :
|
||||
Error<"exception object of type %0 has %select{private|protected}1 "
|
||||
"destructor">, NoSFINAE;
|
||||
def err_access_dtor_field :
|
||||
Error<"field of type %1 has %select{private|protected}2 destructor">,
|
||||
NoSFINAE;
|
||||
|
@ -95,7 +95,7 @@ def CXXNullPtrLiteralExpr : DStmt<Expr>;
|
||||
def CXXThisExpr : DStmt<Expr>;
|
||||
def CXXThrowExpr : DStmt<Expr>;
|
||||
def CXXDefaultArgExpr : DStmt<Expr>;
|
||||
def CXXZeroInitValueExpr : DStmt<Expr>;
|
||||
def CXXScalarValueInitExpr : DStmt<Expr>;
|
||||
def CXXNewExpr : DStmt<Expr>;
|
||||
def CXXDeleteExpr : DStmt<Expr>;
|
||||
def CXXPseudoDestructorExpr : DStmt<Expr>;
|
||||
|
@ -778,7 +778,7 @@ namespace clang {
|
||||
EXPR_CXX_DEFAULT_ARG, // CXXDefaultArgExpr
|
||||
EXPR_CXX_BIND_TEMPORARY, // CXXBindTemporaryExpr
|
||||
//
|
||||
EXPR_CXX_ZERO_INIT_VALUE, // CXXZeroInitValueExpr
|
||||
EXPR_CXX_SCALAR_VALUE_INIT, // CXXScalarValueInitExpr
|
||||
EXPR_CXX_NEW, // CXXNewExpr
|
||||
EXPR_CXX_DELETE, // CXXDeleteExpr
|
||||
EXPR_CXX_PSEUDO_DESTRUCTOR, // CXXPseudoDestructorExpr
|
||||
|
@ -261,7 +261,7 @@ void ASTContext::PrintStats() const {
|
||||
#include "clang/AST/TypeNodes.def"
|
||||
|
||||
fprintf(stderr, "Total bytes = %d\n", int(TotalBytes));
|
||||
|
||||
|
||||
// Implicit special member functions.
|
||||
fprintf(stderr, " %u/%u implicit default constructors created\n",
|
||||
NumImplicitDefaultConstructorsDeclared,
|
||||
@ -282,6 +282,9 @@ void ASTContext::PrintStats() const {
|
||||
fprintf(stderr, "\n");
|
||||
ExternalSource->PrintStats();
|
||||
}
|
||||
|
||||
if (!FreeMemory)
|
||||
BumpAlloc.PrintStats();
|
||||
}
|
||||
|
||||
|
||||
|
@ -74,11 +74,11 @@ Stmt::child_iterator CXXDefaultArgExpr::child_end() {
|
||||
return child_iterator();
|
||||
}
|
||||
|
||||
// CXXZeroInitValueExpr
|
||||
Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
|
||||
// CXXScalarValueInitExpr
|
||||
Stmt::child_iterator CXXScalarValueInitExpr::child_begin() {
|
||||
return child_iterator();
|
||||
}
|
||||
Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
|
||||
Stmt::child_iterator CXXScalarValueInitExpr::child_end() {
|
||||
return child_iterator();
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
|
||||
// Some C++ expressions are always class temporaries.
|
||||
case Expr::CXXConstructExprClass:
|
||||
case Expr::CXXTemporaryObjectExprClass:
|
||||
case Expr::CXXZeroInitValueExprClass:
|
||||
case Expr::CXXScalarValueInitExprClass:
|
||||
return Cl::CL_ClassTemporary;
|
||||
|
||||
// Everything we haven't handled is a prvalue.
|
||||
|
@ -938,7 +938,7 @@ public:
|
||||
return Success(0, E);
|
||||
}
|
||||
|
||||
bool VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
|
||||
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
|
||||
return Success(0, E);
|
||||
}
|
||||
|
||||
@ -1756,7 +1756,7 @@ public:
|
||||
bool VisitBinaryOperator(const BinaryOperator *E);
|
||||
bool VisitFloatingLiteral(const FloatingLiteral *E);
|
||||
bool VisitCastExpr(CastExpr *E);
|
||||
bool VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
|
||||
bool VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
|
||||
bool VisitConditionalOperator(ConditionalOperator *E);
|
||||
|
||||
bool VisitChooseExpr(const ChooseExpr *E)
|
||||
@ -1952,7 +1952,7 @@ bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
|
||||
bool FloatExprEvaluator::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
||||
Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType()));
|
||||
return true;
|
||||
}
|
||||
@ -2410,7 +2410,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
|
||||
case Expr::IntegerLiteralClass:
|
||||
case Expr::CharacterLiteralClass:
|
||||
case Expr::CXXBoolLiteralExprClass:
|
||||
case Expr::CXXZeroInitValueExprClass:
|
||||
case Expr::CXXScalarValueInitExprClass:
|
||||
case Expr::TypesCompatibleExprClass:
|
||||
case Expr::UnaryTypeTraitExprClass:
|
||||
return NoDiag();
|
||||
|
@ -1086,7 +1086,7 @@ void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
|
||||
void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
|
||||
OS << Node->getType().getAsString(Policy) << "()";
|
||||
}
|
||||
|
||||
|
@ -721,7 +721,7 @@ void StmtProfiler::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *S) {
|
||||
VisitCXXConstructExpr(S);
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S) {
|
||||
void StmtProfiler::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *S) {
|
||||
VisitExpr(S);
|
||||
}
|
||||
|
||||
|
@ -655,7 +655,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
|
||||
case Stmt::CXXTryStmtClass:
|
||||
case Stmt::CXXTypeidExprClass:
|
||||
case Stmt::CXXUnresolvedConstructExprClass:
|
||||
case Stmt::CXXZeroInitValueExprClass:
|
||||
case Stmt::CXXScalarValueInitExprClass:
|
||||
case Stmt::DependentScopeDeclRefExprClass:
|
||||
case Stmt::UnaryTypeTraitExprClass:
|
||||
case Stmt::UnresolvedLookupExprClass:
|
||||
@ -962,7 +962,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
|
||||
// C++ stuff we don't support yet.
|
||||
case Stmt::CXXExprWithTemporariesClass:
|
||||
case Stmt::CXXMemberCallExprClass:
|
||||
case Stmt::CXXZeroInitValueExprClass: {
|
||||
case Stmt::CXXScalarValueInitExprClass: {
|
||||
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
|
||||
Builder->BuildSinks = true;
|
||||
MakeNode(Dst, Ex, Pred, GetState(Pred));
|
||||
|
@ -544,8 +544,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
|
||||
return EmitCXXBindTemporaryLValue(cast<CXXBindTemporaryExpr>(E));
|
||||
case Expr::CXXExprWithTemporariesClass:
|
||||
return EmitCXXExprWithTemporariesLValue(cast<CXXExprWithTemporaries>(E));
|
||||
case Expr::CXXZeroInitValueExprClass:
|
||||
return EmitNullInitializationLValue(cast<CXXZeroInitValueExpr>(E));
|
||||
case Expr::CXXScalarValueInitExprClass:
|
||||
return EmitNullInitializationLValue(cast<CXXScalarValueInitExpr>(E));
|
||||
case Expr::CXXDefaultArgExprClass:
|
||||
return EmitLValue(cast<CXXDefaultArgExpr>(E)->getExpr());
|
||||
case Expr::CXXTypeidExprClass:
|
||||
@ -1829,7 +1829,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
|
||||
}
|
||||
|
||||
LValue CodeGenFunction::EmitNullInitializationLValue(
|
||||
const CXXZeroInitValueExpr *E) {
|
||||
const CXXScalarValueInitExpr *E) {
|
||||
QualType Ty = E->getType();
|
||||
LValue LV = LValue::MakeAddr(CreateMemTemp(Ty), MakeQualifiers(Ty));
|
||||
EmitNullInitialization(LV.getAddress(), Ty);
|
||||
|
@ -127,7 +127,7 @@ public:
|
||||
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
|
||||
void VisitCXXConstructExpr(const CXXConstructExpr *E);
|
||||
void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
|
||||
void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
|
||||
void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
|
||||
void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
|
||||
|
||||
void VisitVAArgExpr(VAArgExpr *E);
|
||||
@ -557,7 +557,7 @@ void AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
|
||||
CGF.EmitCXXExprWithTemporaries(E, Val, VolatileDest, IsInitializer);
|
||||
}
|
||||
|
||||
void AggExprEmitter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
|
||||
void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
||||
llvm::Value *Val = DestPtr;
|
||||
|
||||
if (!Val) {
|
||||
|
@ -572,6 +572,14 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
|
||||
}
|
||||
|
||||
if (CXXConstructorDecl *Ctor = E->getConstructor()) {
|
||||
// Per C++ [expr.new]p15, if we have an initializer, then we're performing
|
||||
// direct initialization. C++ [dcl.init]p5 requires that we
|
||||
// zero-initialize storage if there are no user-declared constructors.
|
||||
if (E->hasInitializer() &&
|
||||
!Ctor->getParent()->hasUserDeclaredConstructor() &&
|
||||
!Ctor->getParent()->isEmpty())
|
||||
CGF.EmitNullInitialization(NewPtr, E->getAllocatedType());
|
||||
|
||||
CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false,
|
||||
NewPtr, E->constructor_arg_begin(),
|
||||
E->constructor_arg_end());
|
||||
|
@ -181,7 +181,7 @@ public:
|
||||
ComplexPairTy VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
|
||||
return CGF.EmitCXXExprWithTemporaries(E).getComplexVal();
|
||||
}
|
||||
ComplexPairTy VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
|
||||
ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
||||
assert(E->getType()->isAnyComplexType() && "Expected complex type!");
|
||||
QualType Elem = E->getType()->getAs<ComplexType>()->getElementType();
|
||||
llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
|
||||
|
@ -126,7 +126,7 @@ public:
|
||||
Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
|
||||
return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
|
||||
}
|
||||
Value *VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
|
||||
Value *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
|
||||
return EmitNullValue(E->getType());
|
||||
}
|
||||
Value *VisitGNUNullExpr(const GNUNullExpr *E) {
|
||||
|
@ -1209,7 +1209,7 @@ public:
|
||||
LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E);
|
||||
LValue EmitConditionalOperatorLValue(const ConditionalOperator *E);
|
||||
LValue EmitCastLValue(const CastExpr *E);
|
||||
LValue EmitNullInitializationLValue(const CXXZeroInitValueExpr *E);
|
||||
LValue EmitNullInitializationLValue(const CXXScalarValueInitExpr *E);
|
||||
|
||||
llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
|
||||
const ObjCIvarDecl *Ivar);
|
||||
|
@ -132,7 +132,7 @@ namespace clang {
|
||||
void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
|
||||
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
|
||||
|
||||
void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
|
||||
void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
|
||||
void VisitCXXNewExpr(CXXNewExpr *E);
|
||||
void VisitCXXDeleteExpr(CXXDeleteExpr *E);
|
||||
void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
|
||||
@ -1003,7 +1003,7 @@ void PCHStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
|
||||
E->setSubExpr(Reader.ReadSubExpr());
|
||||
}
|
||||
|
||||
void PCHStmtReader::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
|
||||
void PCHStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
||||
VisitExpr(E);
|
||||
E->setTypeBeginLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
@ -1574,8 +1574,8 @@ Stmt *PCHReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) {
|
||||
S = new (Context) CXXBindTemporaryExpr(Empty);
|
||||
break;
|
||||
|
||||
case pch::EXPR_CXX_ZERO_INIT_VALUE:
|
||||
S = new (Context) CXXZeroInitValueExpr(Empty);
|
||||
case pch::EXPR_CXX_SCALAR_VALUE_INIT:
|
||||
S = new (Context) CXXScalarValueInitExpr(Empty);
|
||||
break;
|
||||
case pch::EXPR_CXX_NEW:
|
||||
S = new (Context) CXXNewExpr(Empty);
|
||||
|
@ -132,7 +132,7 @@ namespace clang {
|
||||
void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
|
||||
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
|
||||
|
||||
void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
|
||||
void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
|
||||
void VisitCXXNewExpr(CXXNewExpr *E);
|
||||
void VisitCXXDeleteExpr(CXXDeleteExpr *E);
|
||||
void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
|
||||
@ -1007,11 +1007,11 @@ void PCHStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
|
||||
Code = pch::EXPR_CXX_BIND_TEMPORARY;
|
||||
}
|
||||
|
||||
void PCHStmtWriter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
|
||||
void PCHStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
||||
VisitExpr(E);
|
||||
Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
|
||||
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
||||
Code = pch::EXPR_CXX_ZERO_INIT_VALUE;
|
||||
Code = pch::EXPR_CXX_SCALAR_VALUE_INIT;
|
||||
}
|
||||
|
||||
void PCHStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
|
||||
|
@ -460,7 +460,7 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
|
||||
|
||||
MarkDeclarationReferenced(E->getExprLoc(), Destructor);
|
||||
CheckDestructorAccess(E->getExprLoc(), Destructor,
|
||||
PDiag(diag::err_access_dtor_temp) << Ty);
|
||||
PDiag(diag::err_access_dtor_exception) << Ty);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -546,27 +546,19 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
|
||||
RParenLoc));
|
||||
}
|
||||
|
||||
if (const RecordType *RT = Ty->getAs<RecordType>()) {
|
||||
CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
|
||||
if (Ty->isRecordType()) {
|
||||
InitializedEntity Entity = InitializedEntity::InitializeTemporary(Ty);
|
||||
InitializationKind Kind
|
||||
= NumExprs ? InitializationKind::CreateDirect(TypeRange.getBegin(),
|
||||
LParenLoc, RParenLoc)
|
||||
: InitializationKind::CreateValue(TypeRange.getBegin(),
|
||||
LParenLoc, RParenLoc);
|
||||
InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs);
|
||||
OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
|
||||
move(exprs));
|
||||
|
||||
if (NumExprs > 1 || !Record->hasTrivialConstructor() ||
|
||||
!Record->hasTrivialDestructor()) {
|
||||
InitializedEntity Entity = InitializedEntity::InitializeTemporary(Ty);
|
||||
InitializationKind Kind
|
||||
= NumExprs ? InitializationKind::CreateDirect(TypeRange.getBegin(),
|
||||
LParenLoc, RParenLoc)
|
||||
: InitializationKind::CreateValue(TypeRange.getBegin(),
|
||||
LParenLoc, RParenLoc);
|
||||
InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs);
|
||||
OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
|
||||
move(exprs));
|
||||
|
||||
// FIXME: Improve AST representation?
|
||||
return move(Result);
|
||||
}
|
||||
|
||||
// Fall through to value-initialize an object of class type that
|
||||
// doesn't have a user-declared default constructor.
|
||||
// FIXME: Improve AST representation?
|
||||
return move(Result);
|
||||
}
|
||||
|
||||
// C++ [expr.type.conv]p1:
|
||||
@ -585,7 +577,7 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
|
||||
// rvalue of the specified type, which is value-initialized.
|
||||
//
|
||||
exprs.release();
|
||||
return Owned(new (Context) CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc));
|
||||
return Owned(new (Context) CXXScalarValueInitExpr(Ty, TyBeginLoc, RParenLoc));
|
||||
}
|
||||
|
||||
|
||||
@ -1992,7 +1984,7 @@ QualType Sema::CheckPointerToMemberOperands(
|
||||
BasePath);
|
||||
}
|
||||
|
||||
if (isa<CXXZeroInitValueExpr>(rex->IgnoreParens())) {
|
||||
if (isa<CXXScalarValueInitExpr>(rex->IgnoreParens())) {
|
||||
// Diagnose use of pointer-to-member type which when used as
|
||||
// the functional cast in a pointer-to-member expression.
|
||||
Diag(Loc, diag::err_pointer_to_member_type) << isIndirect;
|
||||
|
@ -2772,8 +2772,7 @@ static void TryValueInitialization(Sema &S,
|
||||
// zero-initialized and, if T’s implicitly-declared default
|
||||
// constructor is non-trivial, that constructor is called.
|
||||
if ((ClassDecl->getTagKind() == TTK_Class ||
|
||||
ClassDecl->getTagKind() == TTK_Struct) &&
|
||||
!ClassDecl->hasTrivialConstructor()) {
|
||||
ClassDecl->getTagKind() == TTK_Struct)) {
|
||||
Sequence.AddZeroInitializationStep(Entity.getType());
|
||||
return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);
|
||||
}
|
||||
@ -3838,7 +3837,7 @@ InitializationSequence::Perform(Sema &S,
|
||||
} else if (Kind.getKind() == InitializationKind::IK_Value &&
|
||||
S.getLangOptions().CPlusPlus &&
|
||||
!Kind.isImplicitValueInit()) {
|
||||
CurInit = S.Owned(new (S.Context) CXXZeroInitValueExpr(Step->Type,
|
||||
CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr(Step->Type,
|
||||
Kind.getRange().getBegin(),
|
||||
Kind.getRange().getEnd()));
|
||||
} else {
|
||||
|
@ -92,12 +92,6 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
|
||||
|
||||
if (const CXXExprWithTemporaries *Temps = dyn_cast<CXXExprWithTemporaries>(E))
|
||||
E = Temps->getSubExpr();
|
||||
if (const CXXZeroInitValueExpr *Zero = dyn_cast<CXXZeroInitValueExpr>(E)) {
|
||||
if (const RecordType *RecordT = Zero->getType()->getAs<RecordType>())
|
||||
if (CXXRecordDecl *RecordD = dyn_cast<CXXRecordDecl>(RecordT->getDecl()))
|
||||
if (!RecordD->hasTrivialDestructor())
|
||||
return;
|
||||
}
|
||||
|
||||
if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
|
||||
if (E->getType()->isVoidType())
|
||||
|
@ -1577,7 +1577,7 @@ public:
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new expression.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
|
||||
OwningExprResult RebuildCXXScalarValueInitExpr(SourceLocation TypeStartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
QualType T,
|
||||
SourceLocation RParenLoc) {
|
||||
@ -5219,7 +5219,7 @@ TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
|
||||
|
||||
template<typename Derived>
|
||||
Sema::OwningExprResult
|
||||
TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
|
||||
TreeTransform<Derived>::TransformCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
||||
TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
|
||||
|
||||
QualType T = getDerived().TransformType(E->getType());
|
||||
@ -5230,10 +5230,10 @@ TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
|
||||
T == E->getType())
|
||||
return SemaRef.Owned(E->Retain());
|
||||
|
||||
return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
|
||||
/*FIXME:*/E->getTypeBeginLoc(),
|
||||
T,
|
||||
E->getRParenLoc());
|
||||
return getDerived().RebuildCXXScalarValueInitExpr(E->getTypeBeginLoc(),
|
||||
/*FIXME:*/E->getTypeBeginLoc(),
|
||||
T,
|
||||
E->getRParenLoc());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
|
@ -423,6 +423,7 @@ namespace test15 {
|
||||
|
||||
// PR7281
|
||||
namespace test16 {
|
||||
class A { ~A(); }; // expected-note {{declared private here}}
|
||||
void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}}
|
||||
class A { ~A(); }; // expected-note 2{{declared private here}}
|
||||
void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}} \
|
||||
// expected-error{{exception object of type 'test16::A' has private destructor}}
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ class obj{ int a; float b; double d; };
|
||||
// CHECK: define void @_Z1hv()
|
||||
void h() {
|
||||
// CHECK: call void @llvm.memset.p0i8.i64(
|
||||
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(
|
||||
obj o = obj();
|
||||
}
|
||||
|
||||
|
@ -320,3 +320,21 @@ namespace UserConvertToValue {
|
||||
f(1);
|
||||
}
|
||||
}
|
||||
|
||||
namespace PR7556 {
|
||||
struct A { ~A(); };
|
||||
struct B { int i; ~B(); };
|
||||
struct C { int C::*pm; ~C(); };
|
||||
// CHECK: define void @_ZN6PR75563fooEv()
|
||||
void foo() {
|
||||
// CHECK: call void @_ZN6PR75561AD1Ev
|
||||
A();
|
||||
// CHECK: call void @llvm.memset.p0i8.i64
|
||||
// CHECK: call void @_ZN6PR75561BD1Ev
|
||||
B();
|
||||
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
|
||||
// CHECK: call void @_ZN6PR75561CD1Ev
|
||||
C();
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace PR5531 {
|
||||
};
|
||||
|
||||
void test() {
|
||||
A(); // expected-warning{{expression result unused}}
|
||||
A();
|
||||
B(17);
|
||||
C();
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) {
|
||||
case Stmt::CXXThisExprClass:
|
||||
case Stmt::CXXThrowExprClass:
|
||||
case Stmt::CXXDefaultArgExprClass:
|
||||
case Stmt::CXXZeroInitValueExprClass:
|
||||
case Stmt::CXXScalarValueInitExprClass:
|
||||
case Stmt::CXXNewExprClass:
|
||||
case Stmt::CXXDeleteExprClass:
|
||||
case Stmt::CXXPseudoDestructorExprClass:
|
||||
|
Loading…
Reference in New Issue
Block a user