summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/AST/ExprConstant.cpp220
-rw-r--r--lib/AST/Type.cpp4
-rw-r--r--test/CXX/expr/expr.const/p2-0x.cpp4
-rw-r--r--test/CXX/special/class.ctor/p6-0x.cpp12
-rw-r--r--test/CodeGenCXX/value-init.cpp3
-rw-r--r--test/SemaCXX/constexpr-printing.cpp7
-rw-r--r--test/SemaCXX/constexpr-value-init.cpp31
-rw-r--r--test/SemaObjCXX/arc-type-traits.mm16
8 files changed, 68 insertions, 229 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 3579e75d94..ba5b1f4bb6 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -767,25 +767,9 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, const Expr *E,
return true;
}
-/// Check that this core constant expression is of literal type, and if not,
-/// produce an appropriate diagnostic.
-static bool CheckLiteralType(EvalInfo &Info, const Expr *E) {
- if (!E->isRValue() || E->getType()->isLiteralType())
- return true;
-
- // Prvalue constant expressions must be of literal types.
- if (Info.getLangOpts().CPlusPlus0x)
- Info.Diag(E->getExprLoc(), diag::note_constexpr_nonliteral)
- << E->getType();
- else
- Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
- return false;
-}
-
/// Check that this core constant expression value is a valid value for a
/// constant expression, and if it is, produce the corresponding constant value.
-/// If not, report an appropriate diagnostic. Does not check that the expression
-/// is of literal type.
+/// If not, report an appropriate diagnostic.
static bool CheckConstantExpression(EvalInfo &Info, const Expr *E,
const CCValue &CCValue, APValue &Value,
CheckConstantExpressionKind CCEK
@@ -1660,23 +1644,17 @@ static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
/// constexpr. If it is marked as constexpr, we will never implicitly define it,
/// so we need special handling.
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc,
- const CXXConstructorDecl *CD,
- bool IsValueInitialization) {
+ const CXXConstructorDecl *CD) {
if (!CD->isTrivial() || !CD->isDefaultConstructor())
return false;
if (!CD->isConstexpr()) {
if (Info.getLangOpts().CPlusPlus0x) {
- // Value-initialization does not call a trivial default constructor, so
- // such a call is a core constant expression whether or not the
- // constructor is constexpr.
- if (!IsValueInitialization) {
- // FIXME: If DiagDecl is an implicitly-declared special member function,
- // we should be much more explicit about why it's not constexpr.
- Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
- << /*IsConstexpr*/0 << /*IsConstructor*/1 << CD;
- Info.Note(CD->getLocation(), diag::note_declared_at);
- }
+ // FIXME: If DiagDecl is an implicitly-declared special member function,
+ // we should be much more explicit about why it's not constexpr.
+ Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
+ << /*IsConstexpr*/0 << /*IsConstructor*/1 << CD;
+ Info.Note(CD->getLocation(), diag::note_declared_at);
} else {
Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
}
@@ -1742,7 +1720,8 @@ static bool HandleFunctionCall(const Expr *CallExpr, const FunctionDecl *Callee,
static bool HandleConstructorCall(const Expr *CallExpr, const LValue &This,
ArrayRef<const Expr*> Args,
const CXXConstructorDecl *Definition,
- EvalInfo &Info, APValue &Result) {
+ EvalInfo &Info,
+ APValue &Result) {
if (!Info.CheckCallLimit(CallExpr->getExprLoc()))
return false;
@@ -1761,7 +1740,7 @@ static bool HandleConstructorCall(const Expr *CallExpr, const LValue &This,
// Reserve space for the struct members.
const CXXRecordDecl *RD = Definition->getParent();
- if (!RD->isUnion() && Result.isUninit())
+ if (!RD->isUnion())
Result = APValue(APValue::UninitStruct(), RD->getNumBases(),
std::distance(RD->field_begin(), RD->field_end()));
@@ -1930,8 +1909,8 @@ private:
RetTy DerivedSuccess(const CCValue &V, const Expr *E) {
return static_cast<Derived*>(this)->Success(V, E);
}
- RetTy DerivedZeroInitialization(const Expr *E) {
- return static_cast<Derived*>(this)->ZeroInitialization(E);
+ RetTy DerivedValueInitialization(const Expr *E) {
+ return static_cast<Derived*>(this)->ValueInitialization(E);
}
protected:
@@ -1953,7 +1932,7 @@ protected:
return Error(E, diag::note_invalid_subexpr_in_const_expr);
}
- RetTy ZeroInitialization(const Expr *E) { return Error(E); }
+ RetTy ValueInitialization(const Expr *E) { return Error(E); }
public:
ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
@@ -2130,20 +2109,20 @@ public:
RetTy VisitInitListExpr(const InitListExpr *E) {
if (Info.getLangOpts().CPlusPlus0x) {
if (E->getNumInits() == 0)
- return DerivedZeroInitialization(E);
+ return DerivedValueInitialization(E);
if (E->getNumInits() == 1)
return StmtVisitorTy::Visit(E->getInit(0));
}
return Error(E);
}
RetTy VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
- return DerivedZeroInitialization(E);
+ return DerivedValueInitialization(E);
}
RetTy VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
- return DerivedZeroInitialization(E);
+ return DerivedValueInitialization(E);
}
RetTy VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
- return DerivedZeroInitialization(E);
+ return DerivedValueInitialization(E);
}
/// A member expression where the object is a prvalue is itself a prvalue.
@@ -2532,7 +2511,7 @@ public:
Result.setFrom(V);
return true;
}
- bool ZeroInitialization(const Expr *E) {
+ bool ValueInitialization(const Expr *E) {
return Success((Expr*)0);
}
@@ -2652,7 +2631,7 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
return HandleBaseToDerivedCast(Info, E, Result);
case CK_NullToPointer:
- return ZeroInitialization(E);
+ return ValueInitialization(E);
case CK_IntegralToPointer: {
CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
@@ -2725,7 +2704,7 @@ public:
Result.setFrom(V);
return true;
}
- bool ZeroInitialization(const Expr *E) {
+ bool ValueInitialization(const Expr *E) {
return Success((const ValueDecl*)0);
}
@@ -2746,7 +2725,7 @@ bool MemberPointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
return ExprEvaluatorBaseTy::VisitCastExpr(E);
case CK_NullToMemberPointer:
- return ZeroInitialization(E);
+ return ValueInitialization(E);
case CK_BaseToDerivedMemberPointer: {
if (!Visit(E->getSubExpr()))
@@ -2807,7 +2786,6 @@ namespace {
bool Success(const CCValue &V, const Expr *E) {
return CheckConstantExpression(Info, E, V, Result);
}
- bool ZeroInitialization(const Expr *E);
bool VisitCastExpr(const CastExpr *E);
bool VisitInitListExpr(const InitListExpr *E);
@@ -2815,75 +2793,6 @@ namespace {
};
}
-/// Perform zero-initialization on an object of non-union class type.
-/// C++11 [dcl.init]p5:
-/// To zero-initialize an object or reference of type T means:
-/// [...]
-/// -- if T is a (possibly cv-qualified) non-union class type,
-/// each non-static data member and each base-class subobject is
-/// zero-initialized
-static bool HandleClassZeroInitialization(EvalInfo &Info, const RecordDecl *RD,
- const LValue &This, APValue &Result) {
- assert(!RD->isUnion() && "Expected non-union class type");
- const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
- Result = APValue(APValue::UninitStruct(), CD ? CD->getNumBases() : 0,
- std::distance(RD->field_begin(), RD->field_end()));
-
- const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
-
- if (CD) {
- unsigned Index = 0;
- for (CXXRecordDecl::base_class_const_iterator I = CD->bases_begin(),
- E = CD->bases_end(); I != E; ++I, ++Index) {
- const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
- LValue Subobject = This;
- HandleLValueDirectBase(Info, Subobject, CD, Base, &Layout);
- if (!HandleClassZeroInitialization(Info, Base, Subobject,
- Result.getStructBase(Index)))
- return false;
- }
- }
-
- for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
- I != E; ++I) {
- // -- if T is a reference type, no initialization is performed.
- if ((*I)->getType()->isReferenceType())
- continue;
-
- LValue Subobject = This;
- HandleLValueMember(Info, Subobject, *I, &Layout);
-
- ImplicitValueInitExpr VIE((*I)->getType());
- if (!EvaluateConstantExpression(
- Result.getStructField((*I)->getFieldIndex()), Info, Subobject, &VIE))
- return false;
- }
-
- return true;
-}
-
-bool RecordExprEvaluator::ZeroInitialization(const Expr *E) {
- const RecordDecl *RD = E->getType()->castAs<RecordType>()->getDecl();
- if (RD->isUnion()) {
- // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the
- // object's first non-static named data member is zero-initialized
- RecordDecl::field_iterator I = RD->field_begin();
- if (I == RD->field_end()) {
- Result = APValue((const FieldDecl*)0);
- return true;
- }
-
- LValue Subobject = This;
- HandleLValueMember(Info, Subobject, *I);
- Result = APValue(*I);
- ImplicitValueInitExpr VIE((*I)->getType());
- return EvaluateConstantExpression(Result.getUnionValue(), Info,
- Subobject, &VIE);
- }
-
- return HandleClassZeroInitialization(Info, RD, This, Result);
-}
-
bool RecordExprEvaluator::VisitCastExpr(const CastExpr *E) {
switch (E->getCastKind()) {
default:
@@ -2967,11 +2876,7 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
const CXXConstructorDecl *FD = E->getConstructor();
- bool ZeroInit = E->requiresZeroInitialization();
- if (CheckTrivialDefaultConstructor(Info, E->getExprLoc(), FD, ZeroInit)) {
- if (ZeroInit)
- return ZeroInitialization(E);
-
+ if (CheckTrivialDefaultConstructor(Info, E->getExprLoc(), FD)) {
const CXXRecordDecl *RD = FD->getParent();
if (RD->isUnion())
Result = APValue((FieldDecl*)0);
@@ -2988,14 +2893,11 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
return false;
// FIXME: Elide the copy/move construction wherever we can.
- if (E->isElidable() && !ZeroInit)
+ if (E->isElidable())
if (const MaterializeTemporaryExpr *ME
= dyn_cast<MaterializeTemporaryExpr>(E->getArg(0)))
return Visit(ME->GetTemporaryExpr());
- if (ZeroInit && !ZeroInitialization(E))
- return false;
-
llvm::ArrayRef<const Expr*> Args(E->getArgs(), E->getNumArgs());
return HandleConstructorCall(E, This, Args,
cast<CXXConstructorDecl>(Definition), Info,
@@ -3005,6 +2907,7 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
static bool EvaluateRecord(const Expr *E, const LValue &This,
APValue &Result, EvalInfo &Info) {
assert(E->isRValue() && E->getType()->isRecordType() &&
+ E->getType()->isLiteralType() &&
"can't evaluate expression as a record rvalue");
return RecordExprEvaluator(Info, This, Result).Visit(E);
}
@@ -3054,6 +2957,14 @@ public:
/// Evaluate an expression of record type as a temporary.
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info) {
assert(E->isRValue() && E->getType()->isRecordType());
+ if (!E->getType()->isLiteralType()) {
+ if (Info.getLangOpts().CPlusPlus0x)
+ Info.Diag(E->getExprLoc(), diag::note_constexpr_nonliteral)
+ << E->getType();
+ else
+ Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ return false;
+ }
return TemporaryExprEvaluator(Info, Result).Visit(E);
}
@@ -3081,7 +2992,7 @@ namespace {
Result = V;
return true;
}
- bool ZeroInitialization(const Expr *E);
+ bool ValueInitialization(const Expr *E);
bool VisitUnaryReal(const UnaryOperator *E)
{ return Visit(E->getSubExpr()); }
@@ -3233,7 +3144,7 @@ VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
}
bool
-VectorExprEvaluator::ZeroInitialization(const Expr *E) {
+VectorExprEvaluator::ValueInitialization(const Expr *E) {
const VectorType *VT = E->getType()->getAs<VectorType>();
QualType EltTy = VT->getElementType();
APValue ZeroElement;
@@ -3249,7 +3160,7 @@ VectorExprEvaluator::ZeroInitialization(const Expr *E) {
bool VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
VisitIgnoredValue(E->getSubExpr());
- return ZeroInitialization(E);
+ return ValueInitialization(E);
}
//===----------------------------------------------------------------------===//
@@ -3272,7 +3183,7 @@ namespace {
return true;
}
- bool ZeroInitialization(const Expr *E) {
+ bool ValueInitialization(const Expr *E) {
const ConstantArrayType *CAT =
Info.Ctx.getAsConstantArrayType(E->getType());
if (!CAT)
@@ -3282,7 +3193,7 @@ namespace {
CAT->getSize().getZExtValue());
if (!Result.hasArrayFiller()) return true;
- // Zero-initialize all elements.
+ // Value-initialize all elements.
LValue Subobject = This;
Subobject.Designator.addIndex(0);
ImplicitValueInitExpr VIE(CAT->getElementType());
@@ -3297,7 +3208,8 @@ namespace {
static bool EvaluateArray(const Expr *E, const LValue &This,
APValue &Result, EvalInfo &Info) {
- assert(E->isRValue() && E->getType()->isArrayType() && "not an array rvalue");
+ assert(E->isRValue() && E->getType()->isArrayType() &&
+ E->getType()->isLiteralType() && "not a literal array rvalue");
return ArrayExprEvaluator(Info, This, Result).Visit(E);
}
@@ -3367,16 +3279,7 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
const CXXConstructorDecl *FD = E->getConstructor();
- bool ZeroInit = E->requiresZeroInitialization();
- if (CheckTrivialDefaultConstructor(Info, E->getExprLoc(), FD, ZeroInit)) {
- if (ZeroInit) {
- LValue Subobject = This;
- Subobject.Designator.addIndex(0);
- ImplicitValueInitExpr VIE(CAT->getElementType());
- return EvaluateConstantExpression(Result.getArrayFiller(), Info,
- Subobject, &VIE);
- }
-
+ if (CheckTrivialDefaultConstructor(Info, E->getExprLoc(), FD)) {
const CXXRecordDecl *RD = FD->getParent();
if (RD->isUnion())
Result.getArrayFiller() = APValue((FieldDecl*)0);
@@ -3399,14 +3302,6 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
// S s[10];
LValue Subobject = This;
Subobject.Designator.addIndex(0);
-
- if (ZeroInit) {
- ImplicitValueInitExpr VIE(CAT->getElementType());
- if (!EvaluateConstantExpression(Result.getArrayFiller(), Info, Subobject,
- &VIE))
- return false;
- }
-
llvm::ArrayRef<const Expr*> Args(E->getArgs(), E->getNumArgs());
return HandleConstructorCall(E, Subobject, Args,
cast<CXXConstructorDecl>(Definition),
@@ -3470,7 +3365,7 @@ public:
return Success(V.getInt(), E);
}
- bool ZeroInitialization(const Expr *E) { return Success(0, E); }
+ bool ValueInitialization(const Expr *E) { return Success(0, E); }
//===--------------------------------------------------------------------===//
// Visitor Methods
@@ -3513,7 +3408,7 @@ public:
// Note, GNU defines __null as an integer, not a pointer.
bool VisitGNUNullExpr(const GNUNullExpr *E) {
- return ZeroInitialization(E);
+ return ValueInitialization(E);
}
bool VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
@@ -4516,7 +4411,7 @@ public:
return true;
}
- bool ZeroInitialization(const Expr *E) {
+ bool ValueInitialization(const Expr *E) {
Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType()));
return true;
}
@@ -4531,7 +4426,8 @@ public:
bool VisitUnaryReal(const UnaryOperator *E);
bool VisitUnaryImag(const UnaryOperator *E);
- // FIXME: Missing: array subscript of vector, member of vector
+ // FIXME: Missing: array subscript of vector, member of vector,
+ // ImplicitValueInitExpr
};
} // end anonymous namespace
@@ -5138,13 +5034,13 @@ static bool Evaluate(CCValue &Result, EvalInfo &Info, const Expr *E) {
return false;
P.moveInto(Result);
return true;
- } else if (E->getType()->isArrayType()) {
+ } else if (E->getType()->isArrayType() && E->getType()->isLiteralType()) {
LValue LV;
LV.set(E, Info.CurrentCall);
if (!EvaluateArray(E, LV, Info.CurrentCall->Temporaries[E], Info))
return false;
Result = Info.CurrentCall->Temporaries[E];
- } else if (E->getType()->isRecordType()) {
+ } else if (E->getType()->isRecordType() && E->getType()->isLiteralType()) {
LValue LV;
LV.set(E, Info.CurrentCall);
if (!EvaluateRecord(E, LV, Info.CurrentCall->Temporaries[E], Info))
@@ -5176,10 +5072,7 @@ static bool Evaluate(CCValue &Result, EvalInfo &Info, const Expr *E) {
static bool EvaluateConstantExpression(APValue &Result, EvalInfo &Info,
const LValue &This, const Expr *E,
CheckConstantExpressionKind CCEK) {
- if (!CheckLiteralType(Info, E))
- return false;
-
- if (E->isRValue()) {
+ if (E->isRValue() && E->getType()->isLiteralType()) {
// Evaluate arrays and record types in-place, so that later initializers can
// refer to earlier-initialized members of the object.
if (E->getType()->isArrayType())
@@ -5197,9 +5090,6 @@ static bool EvaluateConstantExpression(APValue &Result, EvalInfo &Info,
/// EvaluateAsRValue - Try to evaluate this expression, performing an implicit
/// lvalue-to-rvalue cast if it is an lvalue.
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) {
- if (!CheckLiteralType(Info, E))
- return false;
-
CCValue Value;
if (!::Evaluate(Value, Info, E))
return false;
@@ -5283,23 +5173,9 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
EvalInfo InitInfo(Ctx, EStatus);
InitInfo.setEvaluatingDecl(VD, Value);
- if (!CheckLiteralType(InitInfo, this))
- return false;
-
LValue LVal;
LVal.set(VD);
- // C++11 [basic.start.init]p2:
- // Variables with static storage duration or thread storage duration shall be
- // zero-initialized before any other initialization takes place.
- // This behavior is not present in C.
- if (Ctx.getLangOptions().CPlusPlus && !VD->hasLocalStorage() &&
- !VD->getType()->isReferenceType()) {
- ImplicitValueInitExpr VIE(VD->getType());
- if (!EvaluateConstantExpression(Value, InitInfo, LVal, &VIE))
- return false;
- }
-
return EvaluateConstantExpression(Value, InitInfo, LVal, this) &&
!EStatus.HasSideEffects;
}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index ddeeacd551..d375e7c59d 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1126,6 +1126,10 @@ bool Type::isLiteralType() const {
if (BaseTy->isIncompleteType())
return false;
+ // Objective-C lifetime types are not literal types.
+ if (BaseTy->isObjCRetainableType())
+ return false;
+
// C++0x [basic.types]p10:
// A type is a literal type if it is:
// -- a scalar type; or
diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp
index f0581fcc09..d95af8a95f 100644
--- a/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/test/CXX/expr/expr.const/p2-0x.cpp
@@ -33,11 +33,11 @@ struct NonConstexpr3 {
int m : NonConstexpr2().n; // expected-error {{constant expression}} expected-note {{undefined constructor 'NonConstexpr2'}}
};
struct NonConstexpr4 {
- NonConstexpr4(); // expected-note {{declared here}}
+ NonConstexpr4();
int n;
};
struct NonConstexpr5 {
- int n : NonConstexpr4().n; // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr4' cannot be used in a constant expression}}
+ int n : NonConstexpr4().n; // expected-error {{constant expression}} expected-note {{non-literal type 'NonConstexpr4' cannot be used in a constant expression}}
};
// - an invocation of an undefined constexpr function or an undefined
diff --git a/test/CXX/special/class.ctor/p6-0x.cpp b/test/CXX/special/class.ctor/p6-0x.cpp
index 71afd244bd..19e324d8df 100644
--- a/test/CXX/special/class.ctor/p6-0x.cpp
+++ b/test/CXX/special/class.ctor/p6-0x.cpp
@@ -8,16 +8,8 @@ struct NonConstexpr1 { // expected-note {{here}}
struct NonConstexpr2 { // expected-note {{here}}
NonConstexpr1 nl;
};
-struct NonConstexpr2a : NonConstexpr1 { };
-constexpr NonConstexpr1 nc1 = NonConstexpr1(); // ok, does not call constructor
-constexpr NonConstexpr2 nc2 = NonConstexpr2(); // ok, does not call constructor
-constexpr NonConstexpr2a nc2a = NonConstexpr2a(); // expected-error {{constant expression}} expected-note {{non-literal type 'const NonConstexpr2a'}}
-constexpr int nc2_a = NonConstexpr2().nl.a; // ok
-constexpr int nc2a_a = NonConstexpr2a().a; // ok
-struct Helper {
- friend constexpr NonConstexpr1::NonConstexpr1(); // expected-error {{follows non-constexpr declaration}}
- friend constexpr NonConstexpr2::NonConstexpr2(); // expected-error {{follows non-constexpr declaration}}
-};
+constexpr NonConstexpr1 nc1 = NonConstexpr1(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr1'}}
+constexpr NonConstexpr2 nc2 = NonConstexpr2(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr2'}}
struct Constexpr1 {};
constexpr Constexpr1 c1 = Constexpr1(); // ok
diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp
index 6e60f80110..fb981d1ff7 100644
--- a/test/CodeGenCXX/value-init.cpp
+++ b/test/CodeGenCXX/value-init.cpp
@@ -134,7 +134,8 @@ namespace zeroinit {
// CHECK: define i32 @_ZN8zeroinit4testEv()
int test() {
// CHECK: call void @llvm.memset.p0i8.i64
- // CHECK: ret i32 0
+ // CHECK: getelementptr
+ // CHECK: ret i32
return S().i;
}
diff --git a/test/SemaCXX/constexpr-printing.cpp b/test/SemaCXX/constexpr-printing.cpp
index cccefca9fa..e6cf209819 100644
--- a/test/SemaCXX/constexpr-printing.cpp
+++ b/test/SemaCXX/constexpr-printing.cpp
@@ -11,11 +11,8 @@ struct S {
constexpr int extract(const S &s) { return s.n; } // expected-note {{read of uninitialized object is not allowed in a constant expression}}
-constexpr S s1; // ok
-void f() {
- constexpr S s1; // expected-error {{constant expression}} expected-note {{in call to 'S()'}}
- constexpr S s2(10);
-}
+constexpr S s1; // expected-error {{constant expression}} expected-note {{in call to 'S()'}}
+constexpr S s2(10);
typedef __attribute__((vector_size(16))) int vector_int;
diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp
deleted file mode 100644
index efa9e94da1..0000000000
--- a/test/SemaCXX/constexpr-value-init.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify
-
-struct A {
- constexpr A() : a(b + 1), b(a + 1) {} // expected-note {{uninitialized}}
- int a;
- int b;
-};
-struct B {
- A a;
-};
-
-constexpr A a; // ok, zero initialization preceeds static initialization
-void f() {
- constexpr A a; // expected-error {{constant expression}} expected-note {{in call to 'A()'}}
-}
-
-constexpr B b1; // expected-error {{requires a user-provided default constructor}}
-constexpr B b2 = B(); // ok
-static_assert(b2.a.a == 1, "");
-static_assert(b2.a.b == 2, "");
-
-struct C {
- int c;
-};
-struct D : C { int d; };
-constexpr C c1; // expected-error {{requires a user-provided default constructor}}
-constexpr C c2 = C(); // ok
-constexpr D d1; // expected-error {{requires a user-provided default constructor}}
-constexpr D d2 = D(); // expected-error {{constant expression}} expected-note {{non-literal type 'const D'}}
-static_assert(D().c == 0, "");
-static_assert(D().d == 0, "");
diff --git a/test/SemaObjCXX/arc-type-traits.mm b/test/SemaObjCXX/arc-type-traits.mm
index 9877870f94..b876018e25 100644
--- a/test/SemaObjCXX/arc-type-traits.mm
+++ b/test/SemaObjCXX/arc-type-traits.mm
@@ -53,16 +53,16 @@ TRAIT_IS_TRUE(__has_trivial_destructor, __autoreleasing id);
TRAIT_IS_TRUE(__has_trivial_destructor, __unsafe_unretained id);
// __is_literal
-TRAIT_IS_TRUE(__is_literal, __strong id);
-TRAIT_IS_TRUE(__is_literal, __weak id);
-TRAIT_IS_TRUE(__is_literal, __autoreleasing id);
-TRAIT_IS_TRUE(__is_literal, __unsafe_unretained id);
+TRAIT_IS_FALSE(__is_literal, __strong id);
+TRAIT_IS_FALSE(__is_literal, __weak id);
+TRAIT_IS_FALSE(__is_literal, __autoreleasing id);
+TRAIT_IS_FALSE(__is_literal, __unsafe_unretained id);
// __is_literal_type
-TRAIT_IS_TRUE(__is_literal_type, __strong id);
-TRAIT_IS_TRUE(__is_literal_type, __weak id);
-TRAIT_IS_TRUE(__is_literal_type, __autoreleasing id);
-TRAIT_IS_TRUE(__is_literal_type, __unsafe_unretained id);
+TRAIT_IS_FALSE(__is_literal_type, __strong id);
+TRAIT_IS_FALSE(__is_literal_type, __weak id);
+TRAIT_IS_FALSE(__is_literal_type, __autoreleasing id);
+TRAIT_IS_FALSE(__is_literal_type, __unsafe_unretained id);
// __is_pod
TRAIT_IS_FALSE(__is_pod, __strong id);