aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2012-05-01 00:38:49 +0000
committerJohn McCall <rjmccall@apple.com>2012-05-01 00:38:49 +0000
commit8d59deec807ed53efcd07855199cdc9c979f447f (patch)
tree536045b85ea5ed434b12de37ef4bae22a0c35c61 /lib/AST/ExprConstant.cpp
parent88db6a2daa8bb55fe924773805f42616c8a4f314 (diff)
My first effort to do this more subtly failed, so elaborately
test for an invalid declaration at every single place in the constant evaluator that's about to request a struct layout. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155868 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp90
1 files changed, 59 insertions, 31 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 950ea9b403..5362320f49 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1282,6 +1282,7 @@ static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result,
// Truncate the path to the subobject, and remove any derived-to-base offsets.
const RecordDecl *RD = TruncatedType;
for (unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
+ if (RD->isInvalidDecl()) return false;
const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
const CXXRecordDecl *Base = getAsBaseClass(D.Entries[I]);
if (isVirtualBaseClass(D.Entries[I]))
@@ -1294,13 +1295,18 @@ static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result,
return true;
}
-static void HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj,
+static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj,
const CXXRecordDecl *Derived,
const CXXRecordDecl *Base,
const ASTRecordLayout *RL = 0) {
- if (!RL) RL = &Info.Ctx.getASTRecordLayout(Derived);
+ if (!RL) {
+ if (Derived->isInvalidDecl()) return false;
+ RL = &Info.Ctx.getASTRecordLayout(Derived);
+ }
+
Obj.getLValueOffset() += RL->getBaseClassOffset(Base);
Obj.addDecl(Info, E, Base, /*Virtual*/ false);
+ return true;
}
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj,
@@ -1308,10 +1314,8 @@ static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj,
const CXXBaseSpecifier *Base) {
const CXXRecordDecl *BaseDecl = Base->getType()->getAsCXXRecordDecl();
- if (!Base->isVirtual()) {
- HandleLValueDirectBase(Info, E, Obj, DerivedDecl, BaseDecl);
- return true;
- }
+ if (!Base->isVirtual())
+ return HandleLValueDirectBase(Info, E, Obj, DerivedDecl, BaseDecl);
SubobjectDesignator &D = Obj.Designator;
if (D.Invalid)
@@ -1323,6 +1327,7 @@ static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj,
return false;
// Find the virtual base class.
+ if (DerivedDecl->isInvalidDecl()) return false;
const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
Obj.getLValueOffset() += Layout.getVBaseClassOffset(BaseDecl);
Obj.addDecl(Info, E, BaseDecl, /*Virtual*/ true);
@@ -1331,24 +1336,29 @@ static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj,
/// Update LVal to refer to the given field, which must be a member of the type
/// currently described by LVal.
-static void HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal,
+static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal,
const FieldDecl *FD,
const ASTRecordLayout *RL = 0) {
- if (!RL)
+ if (!RL) {
+ if (FD->getParent()->isInvalidDecl()) return false;
RL = &Info.Ctx.getASTRecordLayout(FD->getParent());
+ }
unsigned I = FD->getFieldIndex();
LVal.Offset += Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I));
LVal.addDecl(Info, E, FD);
+ return true;
}
/// Update LVal to refer to the given indirect field.
-static void HandleLValueIndirectMember(EvalInfo &Info, const Expr *E,
+static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E,
LValue &LVal,
const IndirectFieldDecl *IFD) {
for (IndirectFieldDecl::chain_iterator C = IFD->chain_begin(),
CE = IFD->chain_end(); C != CE; ++C)
- HandleLValueMember(Info, E, LVal, cast<FieldDecl>(*C));
+ if (!HandleLValueMember(Info, E, LVal, cast<FieldDecl>(*C)))
+ return false;
+ return true;
}
/// Get the size of the given type in char units.
@@ -1952,22 +1962,27 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info,
// The first class in the path is that of the lvalue.
for (unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
const CXXRecordDecl *Base = MemPtr.Path[N - I - 1];
- HandleLValueDirectBase(Info, BO, LV, RD, Base);
+ if (!HandleLValueDirectBase(Info, BO, LV, RD, Base))
+ return 0;
RD = Base;
}
// Finally cast to the class containing the member.
- HandleLValueDirectBase(Info, BO, LV, RD, MemPtr.getContainingRecord());
+ if (!HandleLValueDirectBase(Info, BO, LV, RD, MemPtr.getContainingRecord()))
+ return 0;
}
// Add the member. Note that we cannot build bound member functions here.
if (IncludeMember) {
- if (const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl()))
- HandleLValueMember(Info, BO, LV, FD);
- else if (const IndirectFieldDecl *IFD =
- dyn_cast<IndirectFieldDecl>(MemPtr.getDecl()))
- HandleLValueIndirectMember(Info, BO, LV, IFD);
- else
+ if (const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
+ if (!HandleLValueMember(Info, BO, LV, FD))
+ return 0;
+ } else if (const IndirectFieldDecl *IFD =
+ dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
+ if (!HandleLValueIndirectMember(Info, BO, LV, IFD))
+ return 0;
+ } else {
llvm_unreachable("can't construct reference to bound member function");
+ }
}
return MemPtr.getDecl();
@@ -2189,6 +2204,7 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
Result = APValue(APValue::UninitStruct(), RD->getNumBases(),
std::distance(RD->field_begin(), RD->field_end()));
+ if (RD->isInvalidDecl()) return false;
const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
bool Success = true;
@@ -2212,11 +2228,13 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
"base class initializers not in expected order");
++BaseIt;
#endif
- HandleLValueDirectBase(Info, (*I)->getInit(), Subobject, RD,
- BaseType->getAsCXXRecordDecl(), &Layout);
+ if (!HandleLValueDirectBase(Info, (*I)->getInit(), Subobject, RD,
+ BaseType->getAsCXXRecordDecl(), &Layout))
+ return false;
Value = &Result.getStructBase(BasesSeen++);
} else if (FieldDecl *FD = (*I)->getMember()) {
- HandleLValueMember(Info, (*I)->getInit(), Subobject, FD, &Layout);
+ if (!HandleLValueMember(Info, (*I)->getInit(), Subobject, FD, &Layout))
+ return false;
if (RD->isUnion()) {
Result = APValue(FD);
Value = &Result.getUnionValue();
@@ -2244,7 +2262,8 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
*Value = APValue(APValue::UninitStruct(), CD->getNumBases(),
std::distance(CD->field_begin(), CD->field_end()));
}
- HandleLValueMember(Info, (*I)->getInit(), Subobject, FD);
+ if (!HandleLValueMember(Info, (*I)->getInit(), Subobject, FD))
+ return false;
if (CD->isUnion())
Value = &Value->getUnionValue();
else
@@ -2773,9 +2792,11 @@ public:
assert(BaseTy->getAs<RecordType>()->getDecl()->getCanonicalDecl() ==
FD->getParent()->getCanonicalDecl() && "record / field mismatch");
(void)BaseTy;
- HandleLValueMember(this->Info, E, Result, FD);
+ if (!HandleLValueMember(this->Info, E, Result, FD))
+ return false;
} else if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
- HandleLValueIndirectMember(this->Info, E, Result, IFD);
+ if (!HandleLValueIndirectMember(this->Info, E, Result, IFD))
+ return false;
} else
return this->Error(E);
@@ -3373,6 +3394,7 @@ static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E,
Result = APValue(APValue::UninitStruct(), CD ? CD->getNumBases() : 0,
std::distance(RD->field_begin(), RD->field_end()));
+ if (RD->isInvalidDecl()) return false;
const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
if (CD) {
@@ -3381,7 +3403,8 @@ static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E,
End = CD->bases_end(); I != End; ++I, ++Index) {
const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
LValue Subobject = This;
- HandleLValueDirectBase(Info, E, Subobject, CD, Base, &Layout);
+ if (!HandleLValueDirectBase(Info, E, Subobject, CD, Base, &Layout))
+ return false;
if (!HandleClassZeroInitialization(Info, E, Base, Subobject,
Result.getStructBase(Index)))
return false;
@@ -3395,7 +3418,8 @@ static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E,
continue;
LValue Subobject = This;
- HandleLValueMember(Info, E, Subobject, &*I, &Layout);
+ if (!HandleLValueMember(Info, E, Subobject, &*I, &Layout))
+ return false;
ImplicitValueInitExpr VIE(I->getType());
if (!EvaluateInPlace(
@@ -3419,7 +3443,8 @@ bool RecordExprEvaluator::ZeroInitialization(const Expr *E) {
}
LValue Subobject = This;
- HandleLValueMember(Info, E, Subobject, &*I);
+ if (!HandleLValueMember(Info, E, Subobject, &*I))
+ return false;
Result = APValue(&*I);
ImplicitValueInitExpr VIE(I->getType());
return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
@@ -3472,7 +3497,6 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
const RecordDecl *RD = E->getType()->castAs<RecordType>()->getDecl();
if (RD->isInvalidDecl()) return false;
-
const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
if (RD->isUnion()) {
@@ -3487,7 +3511,8 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
const Expr *InitExpr = E->getNumInits() ? E->getInit(0) : &VIE;
LValue Subobject = This;
- HandleLValueMember(Info, InitExpr, Subobject, Field, &Layout);
+ if (!HandleLValueMember(Info, InitExpr, Subobject, Field, &Layout))
+ return false;
return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr);
}
@@ -3510,8 +3535,9 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
// FIXME: Diagnostics here should point to the end of the initializer
// list, not the start.
- HandleLValueMember(Info, HaveInit ? E->getInit(ElementNo) : E, Subobject,
- &*Field, &Layout);
+ if (!HandleLValueMember(Info, HaveInit ? E->getInit(ElementNo) : E,
+ Subobject, &*Field, &Layout))
+ return false;
// Perform an implicit value-initialization for members beyond the end of
// the initializer list.
@@ -5285,6 +5311,7 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
if (!RT)
return Error(OOE);
RecordDecl *RD = RT->getDecl();
+ if (RD->isInvalidDecl()) return false;
const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
unsigned i = MemberDecl->getFieldIndex();
assert(i < RL.getFieldCount() && "offsetof field in wrong type");
@@ -5306,6 +5333,7 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
if (!RT)
return Error(OOE);
RecordDecl *RD = RT->getDecl();
+ if (RD->isInvalidDecl()) return false;
const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
// Find the base class itself.