@@ -87,6 +87,9 @@ namespace {
87
87
return D->getType();
88
88
}
89
89
90
+ if (TypeInfoLValue TI = B.dyn_cast<TypeInfoLValue>())
91
+ return B.getTypeInfoType();
92
+
90
93
const Expr *Base = B.get<const Expr*>();
91
94
92
95
// For a materialized temporary, the type of the temporary we materialized
@@ -1783,6 +1786,9 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
1783
1786
return isa<FunctionDecl>(D);
1784
1787
}
1785
1788
1789
+ if (B.is<TypeInfoLValue>())
1790
+ return true;
1791
+
1786
1792
const Expr *E = B.get<const Expr*>();
1787
1793
switch (E->getStmtClass()) {
1788
1794
default:
@@ -1800,7 +1806,6 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
1800
1806
case Expr::PredefinedExprClass:
1801
1807
case Expr::ObjCStringLiteralClass:
1802
1808
case Expr::ObjCEncodeExprClass:
1803
- case Expr::CXXTypeidExprClass:
1804
1809
case Expr::CXXUuidofExprClass:
1805
1810
return true;
1806
1811
case Expr::ObjCBoxedExprClass:
@@ -1878,9 +1883,9 @@ static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base) {
1878
1883
const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>();
1879
1884
if (VD)
1880
1885
Info.Note(VD->getLocation(), diag::note_declared_at);
1881
- else
1882
- Info.Note(Base.get<const Expr*>() ->getExprLoc(),
1883
- diag::note_constexpr_temporary_here);
1886
+ else if (const Expr *E = Base.dyn_cast<const Expr*>())
1887
+ Info.Note(E ->getExprLoc(), diag::note_constexpr_temporary_here);
1888
+ // We have no information to show for a typeid(T) object.
1884
1889
}
1885
1890
1886
1891
/// Check that this reference or pointer core constant expression is a valid
@@ -3404,7 +3409,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
3404
3409
3405
3410
if (!Frame) {
3406
3411
if (const MaterializeTemporaryExpr *MTE =
3407
- dyn_cast <MaterializeTemporaryExpr>(Base)) {
3412
+ dyn_cast_or_null <MaterializeTemporaryExpr>(Base)) {
3408
3413
assert(MTE->getStorageDuration() == SD_Static &&
3409
3414
"should have a frame for a non-global materialized temporary");
3410
3415
@@ -3439,7 +3444,13 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
3439
3444
} else {
3440
3445
if (!IsAccess)
3441
3446
return CompleteObject(LVal.getLValueBase(), nullptr, BaseType);
3442
- Info.FFDiag(E);
3447
+ APValue Val;
3448
+ LVal.moveInto(Val);
3449
+ Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
3450
+ << AK
3451
+ << Val.getAsString(Info.Ctx,
3452
+ Info.Ctx.getLValueReferenceType(LValType));
3453
+ NoteLValueLocation(Info, LVal.Base);
3443
3454
return CompleteObject();
3444
3455
}
3445
3456
} else {
@@ -5777,13 +5788,13 @@ class LValueExprEvaluatorBase
5777
5788
// - Literals
5778
5789
// * CompoundLiteralExpr in C (and in global scope in C++)
5779
5790
// * StringLiteral
5780
- // * CXXTypeidExpr
5781
5791
// * PredefinedExpr
5782
5792
// * ObjCStringLiteralExpr
5783
5793
// * ObjCEncodeExpr
5784
5794
// * AddrLabelExpr
5785
5795
// * BlockExpr
5786
5796
// * CallExpr for a MakeStringConstant builtin
5797
+ // - typeid(T) expressions, as TypeInfoLValues
5787
5798
// - Locals and temporaries
5788
5799
// * MaterializeTemporaryExpr
5789
5800
// * Any Expr, with a CallIndex indicating the function in which the temporary
@@ -6018,8 +6029,14 @@ LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
6018
6029
}
6019
6030
6020
6031
bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
6021
- if (!E->isPotentiallyEvaluated())
6022
- return Success(E);
6032
+ if (!E->isPotentiallyEvaluated()) {
6033
+ TypeInfoLValue TypeInfo;
6034
+ if (E->isTypeOperand())
6035
+ TypeInfo = TypeInfoLValue(E->getTypeOperand(Info.Ctx).getTypePtr());
6036
+ else
6037
+ TypeInfo = TypeInfoLValue(E->getExprOperand()->getType().getTypePtr());
6038
+ return Success(APValue::LValueBase::getTypeInfo(TypeInfo, E->getType()));
6039
+ }
6023
6040
6024
6041
Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic)
6025
6042
<< E->getExprOperand()->getType()
@@ -6615,9 +6632,11 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
6615
6632
if (const ValueDecl *VD =
6616
6633
OffsetResult.Base.dyn_cast<const ValueDecl*>()) {
6617
6634
BaseAlignment = Info.Ctx.getDeclAlign(VD);
6635
+ } else if (const Expr *E = OffsetResult.Base.dyn_cast<const Expr *>()) {
6636
+ BaseAlignment = GetAlignOfExpr(Info, E, UETT_AlignOf);
6618
6637
} else {
6619
- BaseAlignment = GetAlignOfExpr (
6620
- Info, OffsetResult.Base.get<const Expr *> (), UETT_AlignOf);
6638
+ BaseAlignment = GetAlignOfType (
6639
+ Info, OffsetResult.Base.getTypeInfoType (), UETT_AlignOf);
6621
6640
}
6622
6641
6623
6642
if (BaseAlignment < Align) {
@@ -8335,6 +8354,10 @@ static bool EvaluateBuiltinConstantPForLValue(const APValue &LV) {
8335
8354
if (!isa<StringLiteral>(E))
8336
8355
return false;
8337
8356
return LV.getLValueOffset().isZero();
8357
+ } else if (Base.is<TypeInfoLValue>()) {
8358
+ // Surprisingly, GCC considers __builtin_constant_p(&typeid(int)) to
8359
+ // evaluate to true.
8360
+ return true;
8338
8361
} else {
8339
8362
// Any other base is not constant enough for GCC.
8340
8363
return false;
@@ -8399,6 +8422,8 @@ static QualType getObjectType(APValue::LValueBase B) {
8399
8422
} else if (const Expr *E = B.get<const Expr*>()) {
8400
8423
if (isa<CompoundLiteralExpr>(E))
8401
8424
return E->getType();
8425
+ } else if (B.is<TypeInfoLValue>()) {
8426
+ return B.getTypeInfoType();
8402
8427
}
8403
8428
8404
8429
return QualType();
0 commit comments