|
@@ -87,9 +87,6 @@ namespace {
|
|
return D->getType();
|
|
return D->getType();
|
|
}
|
|
}
|
|
|
|
|
|
- if (TypeInfoLValue TI = B.dyn_cast<TypeInfoLValue>())
|
|
|
|
- return B.getTypeInfoType();
|
|
|
|
-
|
|
|
|
const Expr *Base = B.get<const Expr*>();
|
|
const Expr *Base = B.get<const Expr*>();
|
|
|
|
|
|
// For a materialized temporary, the type of the temporary we materialized
|
|
// For a materialized temporary, the type of the temporary we materialized
|
|
@@ -1786,9 +1783,6 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
|
|
return isa<FunctionDecl>(D);
|
|
return isa<FunctionDecl>(D);
|
|
}
|
|
}
|
|
|
|
|
|
- if (B.is<TypeInfoLValue>())
|
|
|
|
- return true;
|
|
|
|
-
|
|
|
|
const Expr *E = B.get<const Expr*>();
|
|
const Expr *E = B.get<const Expr*>();
|
|
switch (E->getStmtClass()) {
|
|
switch (E->getStmtClass()) {
|
|
default:
|
|
default:
|
|
@@ -1806,6 +1800,7 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
|
|
case Expr::PredefinedExprClass:
|
|
case Expr::PredefinedExprClass:
|
|
case Expr::ObjCStringLiteralClass:
|
|
case Expr::ObjCStringLiteralClass:
|
|
case Expr::ObjCEncodeExprClass:
|
|
case Expr::ObjCEncodeExprClass:
|
|
|
|
+ case Expr::CXXTypeidExprClass:
|
|
case Expr::CXXUuidofExprClass:
|
|
case Expr::CXXUuidofExprClass:
|
|
return true;
|
|
return true;
|
|
case Expr::ObjCBoxedExprClass:
|
|
case Expr::ObjCBoxedExprClass:
|
|
@@ -1883,9 +1878,9 @@ static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base) {
|
|
const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>();
|
|
const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>();
|
|
if (VD)
|
|
if (VD)
|
|
Info.Note(VD->getLocation(), diag::note_declared_at);
|
|
Info.Note(VD->getLocation(), diag::note_declared_at);
|
|
- else if (const Expr *E = Base.dyn_cast<const Expr*>())
|
|
|
|
- Info.Note(E->getExprLoc(), diag::note_constexpr_temporary_here);
|
|
|
|
- // We have no information to show for a typeid(T) object.
|
|
|
|
|
|
+ else
|
|
|
|
+ Info.Note(Base.get<const Expr*>()->getExprLoc(),
|
|
|
|
+ diag::note_constexpr_temporary_here);
|
|
}
|
|
}
|
|
|
|
|
|
/// Check that this reference or pointer core constant expression is a valid
|
|
/// Check that this reference or pointer core constant expression is a valid
|
|
@@ -3409,7 +3404,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
|
|
|
|
|
|
if (!Frame) {
|
|
if (!Frame) {
|
|
if (const MaterializeTemporaryExpr *MTE =
|
|
if (const MaterializeTemporaryExpr *MTE =
|
|
- dyn_cast_or_null<MaterializeTemporaryExpr>(Base)) {
|
|
|
|
|
|
+ dyn_cast<MaterializeTemporaryExpr>(Base)) {
|
|
assert(MTE->getStorageDuration() == SD_Static &&
|
|
assert(MTE->getStorageDuration() == SD_Static &&
|
|
"should have a frame for a non-global materialized temporary");
|
|
"should have a frame for a non-global materialized temporary");
|
|
|
|
|
|
@@ -3444,13 +3439,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
|
|
} else {
|
|
} else {
|
|
if (!IsAccess)
|
|
if (!IsAccess)
|
|
return CompleteObject(LVal.getLValueBase(), nullptr, BaseType);
|
|
return CompleteObject(LVal.getLValueBase(), nullptr, BaseType);
|
|
- APValue Val;
|
|
|
|
- LVal.moveInto(Val);
|
|
|
|
- Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
|
|
|
|
- << AK
|
|
|
|
- << Val.getAsString(Info.Ctx,
|
|
|
|
- Info.Ctx.getLValueReferenceType(LValType));
|
|
|
|
- NoteLValueLocation(Info, LVal.Base);
|
|
|
|
|
|
+ Info.FFDiag(E);
|
|
return CompleteObject();
|
|
return CompleteObject();
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
@@ -5788,13 +5777,13 @@ public:
|
|
// - Literals
|
|
// - Literals
|
|
// * CompoundLiteralExpr in C (and in global scope in C++)
|
|
// * CompoundLiteralExpr in C (and in global scope in C++)
|
|
// * StringLiteral
|
|
// * StringLiteral
|
|
|
|
+// * CXXTypeidExpr
|
|
// * PredefinedExpr
|
|
// * PredefinedExpr
|
|
// * ObjCStringLiteralExpr
|
|
// * ObjCStringLiteralExpr
|
|
// * ObjCEncodeExpr
|
|
// * ObjCEncodeExpr
|
|
// * AddrLabelExpr
|
|
// * AddrLabelExpr
|
|
// * BlockExpr
|
|
// * BlockExpr
|
|
// * CallExpr for a MakeStringConstant builtin
|
|
// * CallExpr for a MakeStringConstant builtin
|
|
-// - typeid(T) expressions, as TypeInfoLValues
|
|
|
|
// - Locals and temporaries
|
|
// - Locals and temporaries
|
|
// * MaterializeTemporaryExpr
|
|
// * MaterializeTemporaryExpr
|
|
// * Any Expr, with a CallIndex indicating the function in which the temporary
|
|
// * Any Expr, with a CallIndex indicating the function in which the temporary
|
|
@@ -6029,14 +6018,8 @@ LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
|
|
}
|
|
}
|
|
|
|
|
|
bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
|
|
bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
|
|
- if (!E->isPotentiallyEvaluated()) {
|
|
|
|
- TypeInfoLValue TypeInfo;
|
|
|
|
- if (E->isTypeOperand())
|
|
|
|
- TypeInfo = TypeInfoLValue(E->getTypeOperand(Info.Ctx).getTypePtr());
|
|
|
|
- else
|
|
|
|
- TypeInfo = TypeInfoLValue(E->getExprOperand()->getType().getTypePtr());
|
|
|
|
- return Success(APValue::LValueBase::getTypeInfo(TypeInfo, E->getType()));
|
|
|
|
- }
|
|
|
|
|
|
+ if (!E->isPotentiallyEvaluated())
|
|
|
|
+ return Success(E);
|
|
|
|
|
|
Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic)
|
|
Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic)
|
|
<< E->getExprOperand()->getType()
|
|
<< E->getExprOperand()->getType()
|
|
@@ -6632,11 +6615,9 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
|
|
if (const ValueDecl *VD =
|
|
if (const ValueDecl *VD =
|
|
OffsetResult.Base.dyn_cast<const ValueDecl*>()) {
|
|
OffsetResult.Base.dyn_cast<const ValueDecl*>()) {
|
|
BaseAlignment = Info.Ctx.getDeclAlign(VD);
|
|
BaseAlignment = Info.Ctx.getDeclAlign(VD);
|
|
- } else if (const Expr *E = OffsetResult.Base.dyn_cast<const Expr *>()) {
|
|
|
|
- BaseAlignment = GetAlignOfExpr(Info, E, UETT_AlignOf);
|
|
|
|
} else {
|
|
} else {
|
|
- BaseAlignment = GetAlignOfType(
|
|
|
|
- Info, OffsetResult.Base.getTypeInfoType(), UETT_AlignOf);
|
|
|
|
|
|
+ BaseAlignment = GetAlignOfExpr(
|
|
|
|
+ Info, OffsetResult.Base.get<const Expr *>(), UETT_AlignOf);
|
|
}
|
|
}
|
|
|
|
|
|
if (BaseAlignment < Align) {
|
|
if (BaseAlignment < Align) {
|
|
@@ -8354,10 +8335,6 @@ static bool EvaluateBuiltinConstantPForLValue(const APValue &LV) {
|
|
if (!isa<StringLiteral>(E))
|
|
if (!isa<StringLiteral>(E))
|
|
return false;
|
|
return false;
|
|
return LV.getLValueOffset().isZero();
|
|
return LV.getLValueOffset().isZero();
|
|
- } else if (Base.is<TypeInfoLValue>()) {
|
|
|
|
- // Surprisingly, GCC considers __builtin_constant_p(&typeid(int)) to
|
|
|
|
- // evaluate to true.
|
|
|
|
- return true;
|
|
|
|
} else {
|
|
} else {
|
|
// Any other base is not constant enough for GCC.
|
|
// Any other base is not constant enough for GCC.
|
|
return false;
|
|
return false;
|
|
@@ -8422,8 +8399,6 @@ static QualType getObjectType(APValue::LValueBase B) {
|
|
} else if (const Expr *E = B.get<const Expr*>()) {
|
|
} else if (const Expr *E = B.get<const Expr*>()) {
|
|
if (isa<CompoundLiteralExpr>(E))
|
|
if (isa<CompoundLiteralExpr>(E))
|
|
return E->getType();
|
|
return E->getType();
|
|
- } else if (B.is<TypeInfoLValue>()) {
|
|
|
|
- return B.getTypeInfoType();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
return QualType();
|
|
return QualType();
|