Skip to content

Commit a971003

Browse files
committed
Revert Refactor constant evaluation of typeid(T) to track a symbolic type_info object rather than tracking the originating expression.
This reverts r360974 (git commit 7ee4307) llvm-svn: 360988
1 parent a5a4124 commit a971003

File tree

11 files changed

+47
-196
lines changed

11 files changed

+47
-196
lines changed

clang/include/clang/AST/APValue.h

Lines changed: 27 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -24,52 +24,14 @@ namespace clang {
2424
class AddrLabelExpr;
2525
class ASTContext;
2626
class CharUnits;
27-
class CXXRecordDecl;
28-
class Decl;
2927
class DiagnosticBuilder;
3028
class Expr;
3129
class FieldDecl;
32-
struct PrintingPolicy;
33-
class Type;
30+
class Decl;
3431
class ValueDecl;
32+
class CXXRecordDecl;
33+
class QualType;
3534

36-
/// Symbolic representation of typeid(T) for some type T.
37-
class TypeInfoLValue {
38-
const Type *T;
39-
40-
public:
41-
TypeInfoLValue() : T() {}
42-
explicit TypeInfoLValue(const Type *T);
43-
44-
const Type *getType() const { return T; }
45-
explicit operator bool() const { return T; }
46-
47-
void *getOpaqueValue() { return const_cast<Type*>(T); }
48-
static TypeInfoLValue getFromOpaqueValue(void *Value) {
49-
TypeInfoLValue V;
50-
V.T = reinterpret_cast<const Type*>(Value);
51-
return V;
52-
}
53-
54-
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
55-
};
56-
}
57-
58-
namespace llvm {
59-
template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
60-
static void *getAsVoidPointer(clang::TypeInfoLValue V) {
61-
return V.getOpaqueValue();
62-
}
63-
static clang::TypeInfoLValue getFromVoidPointer(void *P) {
64-
return clang::TypeInfoLValue::getFromOpaqueValue(P);
65-
}
66-
// Validated by static_assert in APValue.cpp; hardcoded to avoid needing
67-
// to include Type.h.
68-
static constexpr int NumLowBitsAvailable = 3;
69-
};
70-
}
71-
72-
namespace clang {
7335
/// APValue - This class implements a discriminated union of [uninitialized]
7436
/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
7537
/// [Vector: N * APValue], [Array: N * APValue]
@@ -95,18 +57,13 @@ class APValue {
9557

9658
class LValueBase {
9759
public:
98-
typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue>
99-
PtrTy;
60+
typedef llvm::PointerUnion<const ValueDecl *, const Expr *> PtrTy;
10061

101-
LValueBase() : Local{} {}
62+
LValueBase() : CallIndex(0), Version(0) {}
10263

10364
template <class T>
104-
LValueBase(T P, unsigned I = 0, unsigned V = 0) : Ptr(P), Local{I, V} {
105-
assert(!is<TypeInfoLValue>() &&
106-
"don't use this constructor to form a type_info lvalue");
107-
}
108-
109-
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
65+
LValueBase(T P, unsigned I = 0, unsigned V = 0)
66+
: Ptr(P), CallIndex(I), Version(V) {}
11067

11168
template <class T>
11269
bool is() const { return Ptr.is<T>(); }
@@ -121,30 +78,36 @@ class APValue {
12178

12279
bool isNull() const;
12380

124-
explicit operator bool() const;
81+
explicit operator bool () const;
12582

126-
PtrTy getPointer() const { return Ptr; }
83+
PtrTy getPointer() const {
84+
return Ptr;
85+
}
86+
87+
unsigned getCallIndex() const {
88+
return CallIndex;
89+
}
12790

128-
unsigned getCallIndex() const;
129-
unsigned getVersion() const;
130-
QualType getTypeInfoType() const;
91+
void setCallIndex(unsigned Index) {
92+
CallIndex = Index;
93+
}
13194

132-
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
95+
unsigned getVersion() const {
96+
return Version;
97+
}
98+
99+
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS) {
100+
return LHS.Ptr == RHS.Ptr && LHS.CallIndex == RHS.CallIndex &&
101+
LHS.Version == RHS.Version;
102+
}
133103
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
134104
return !(LHS == RHS);
135105
}
136106
friend llvm::hash_code hash_value(const LValueBase &Base);
137107

138108
private:
139109
PtrTy Ptr;
140-
struct LocalState {
141-
unsigned CallIndex, Version;
142-
};
143-
union {
144-
LocalState Local;
145-
/// The type std::type_info, if this is a TypeInfoLValue.
146-
void *TypeInfoType;
147-
};
110+
unsigned CallIndex, Version;
148111
};
149112

150113
/// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we

clang/include/clang/Basic/DiagnosticASTKinds.td

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,6 @@ def note_constexpr_access_static_temporary : Note<
160160
"dynamic_cast of}0 temporary "
161161
"is not allowed in a constant expression outside the expression that "
162162
"created the temporary">;
163-
def note_constexpr_access_unreadable_object : Note<
164-
"%select{read of|assignment to|increment of|decrement of|member call on|"
165-
"dynamic_cast of}0 object '%1' whose value is not known">;
166163
def note_constexpr_modify_global : Note<
167164
"a constant expression cannot modify an object that is visible outside "
168165
"that expression">;

clang/lib/AST/APValue.cpp

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -20,56 +20,6 @@
2020
#include "llvm/Support/raw_ostream.h"
2121
using namespace clang;
2222

23-
/// The identity of a type_info object depends on the canonical unqualified
24-
/// type only.
25-
TypeInfoLValue::TypeInfoLValue(const Type *T)
26-
: T(T->getCanonicalTypeUnqualified().getTypePtr()) {}
27-
28-
void TypeInfoLValue::print(llvm::raw_ostream &Out,
29-
const PrintingPolicy &Policy) const {
30-
Out << "typeid(";
31-
QualType(getType(), 0).print(Out, Policy);
32-
Out << ")";
33-
}
34-
35-
static_assert(
36-
1 << llvm::PointerLikeTypeTraits<TypeInfoLValue>::NumLowBitsAvailable <=
37-
alignof(const Type *),
38-
"Type is insufficiently aligned");
39-
40-
APValue::LValueBase APValue::LValueBase::getTypeInfo(TypeInfoLValue LV,
41-
QualType TypeInfo) {
42-
LValueBase Base;
43-
Base.Ptr = LV;
44-
Base.TypeInfoType = TypeInfo.getAsOpaquePtr();
45-
return Base;
46-
}
47-
48-
unsigned APValue::LValueBase::getCallIndex() const {
49-
return is<TypeInfoLValue>() ? 0 : Local.CallIndex;
50-
}
51-
52-
unsigned APValue::LValueBase::getVersion() const {
53-
return is<TypeInfoLValue>() ? 0 : Local.Version;
54-
}
55-
56-
QualType APValue::LValueBase::getTypeInfoType() const {
57-
assert(is<TypeInfoLValue>() && "not a type_info lvalue");
58-
return QualType::getFromOpaquePtr(TypeInfoType);
59-
}
60-
61-
namespace clang {
62-
bool operator==(const APValue::LValueBase &LHS,
63-
const APValue::LValueBase &RHS) {
64-
if (LHS.Ptr != RHS.Ptr)
65-
return false;
66-
if (LHS.is<TypeInfoLValue>())
67-
return true;
68-
return LHS.Local.CallIndex == RHS.Local.CallIndex &&
69-
LHS.Local.Version == RHS.Local.Version;
70-
}
71-
}
72-
7323
namespace {
7424
struct LVBase {
7525
APValue::LValueBase Base;
@@ -110,8 +60,6 @@ llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
11060

11161
namespace clang {
11262
llvm::hash_code hash_value(const APValue::LValueBase &Base) {
113-
if (Base.is<TypeInfoLValue>())
114-
return llvm::hash_value(Base.getOpaqueValue());
11563
return llvm::hash_combine(Base.getOpaqueValue(), Base.getCallIndex(),
11664
Base.getVersion());
11765
}
@@ -522,9 +470,7 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
522470

523471
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
524472
Out << *VD;
525-
else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
526-
TI.print(Out, Ctx.getPrintingPolicy());
527-
} else {
473+
else {
528474
assert(Base.get<const Expr *>() != nullptr &&
529475
"Expecting non-null Expr");
530476
Base.get<const Expr*>()->printPretty(Out, nullptr,
@@ -549,9 +495,6 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
549495
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
550496
Out << *VD;
551497
ElemTy = VD->getType();
552-
} else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
553-
TI.print(Out, Ctx.getPrintingPolicy());
554-
ElemTy = Base.getTypeInfoType();
555498
} else {
556499
const Expr *E = Base.get<const Expr*>();
557500
assert(E != nullptr && "Expecting non-null Expr");

clang/lib/AST/ExprConstant.cpp

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,6 @@ namespace {
8787
return D->getType();
8888
}
8989

90-
if (TypeInfoLValue TI = B.dyn_cast<TypeInfoLValue>())
91-
return B.getTypeInfoType();
92-
9390
const Expr *Base = B.get<const Expr*>();
9491

9592
// For a materialized temporary, the type of the temporary we materialized
@@ -1786,9 +1783,6 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
17861783
return isa<FunctionDecl>(D);
17871784
}
17881785

1789-
if (B.is<TypeInfoLValue>())
1790-
return true;
1791-
17921786
const Expr *E = B.get<const Expr*>();
17931787
switch (E->getStmtClass()) {
17941788
default:
@@ -1806,6 +1800,7 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
18061800
case Expr::PredefinedExprClass:
18071801
case Expr::ObjCStringLiteralClass:
18081802
case Expr::ObjCEncodeExprClass:
1803+
case Expr::CXXTypeidExprClass:
18091804
case Expr::CXXUuidofExprClass:
18101805
return true;
18111806
case Expr::ObjCBoxedExprClass:
@@ -1883,9 +1878,9 @@ static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base) {
18831878
const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>();
18841879
if (VD)
18851880
Info.Note(VD->getLocation(), diag::note_declared_at);
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.
1881+
else
1882+
Info.Note(Base.get<const Expr*>()->getExprLoc(),
1883+
diag::note_constexpr_temporary_here);
18891884
}
18901885

18911886
/// Check that this reference or pointer core constant expression is a valid
@@ -3409,7 +3404,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
34093404

34103405
if (!Frame) {
34113406
if (const MaterializeTemporaryExpr *MTE =
3412-
dyn_cast_or_null<MaterializeTemporaryExpr>(Base)) {
3407+
dyn_cast<MaterializeTemporaryExpr>(Base)) {
34133408
assert(MTE->getStorageDuration() == SD_Static &&
34143409
"should have a frame for a non-global materialized temporary");
34153410

@@ -3444,13 +3439,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
34443439
} else {
34453440
if (!IsAccess)
34463441
return CompleteObject(LVal.getLValueBase(), nullptr, BaseType);
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);
3442+
Info.FFDiag(E);
34543443
return CompleteObject();
34553444
}
34563445
} else {
@@ -5788,13 +5777,13 @@ class LValueExprEvaluatorBase
57885777
// - Literals
57895778
// * CompoundLiteralExpr in C (and in global scope in C++)
57905779
// * StringLiteral
5780+
// * CXXTypeidExpr
57915781
// * PredefinedExpr
57925782
// * ObjCStringLiteralExpr
57935783
// * ObjCEncodeExpr
57945784
// * AddrLabelExpr
57955785
// * BlockExpr
57965786
// * CallExpr for a MakeStringConstant builtin
5797-
// - typeid(T) expressions, as TypeInfoLValues
57985787
// - Locals and temporaries
57995788
// * MaterializeTemporaryExpr
58005789
// * Any Expr, with a CallIndex indicating the function in which the temporary
@@ -6029,14 +6018,8 @@ LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
60296018
}
60306019

60316020
bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *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-
}
6021+
if (!E->isPotentiallyEvaluated())
6022+
return Success(E);
60406023

60416024
Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic)
60426025
<< E->getExprOperand()->getType()
@@ -6632,11 +6615,9 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
66326615
if (const ValueDecl *VD =
66336616
OffsetResult.Base.dyn_cast<const ValueDecl*>()) {
66346617
BaseAlignment = Info.Ctx.getDeclAlign(VD);
6635-
} else if (const Expr *E = OffsetResult.Base.dyn_cast<const Expr *>()) {
6636-
BaseAlignment = GetAlignOfExpr(Info, E, UETT_AlignOf);
66376618
} else {
6638-
BaseAlignment = GetAlignOfType(
6639-
Info, OffsetResult.Base.getTypeInfoType(), UETT_AlignOf);
6619+
BaseAlignment = GetAlignOfExpr(
6620+
Info, OffsetResult.Base.get<const Expr *>(), UETT_AlignOf);
66406621
}
66416622

66426623
if (BaseAlignment < Align) {
@@ -8354,10 +8335,6 @@ static bool EvaluateBuiltinConstantPForLValue(const APValue &LV) {
83548335
if (!isa<StringLiteral>(E))
83558336
return false;
83568337
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;
83618338
} else {
83628339
// Any other base is not constant enough for GCC.
83638340
return false;
@@ -8422,8 +8399,6 @@ static QualType getObjectType(APValue::LValueBase B) {
84228399
} else if (const Expr *E = B.get<const Expr*>()) {
84238400
if (isa<CompoundLiteralExpr>(E))
84248401
return E->getType();
8425-
} else if (B.is<TypeInfoLValue>()) {
8426-
return B.getTypeInfoType();
84278402
}
84288403

84298404
return QualType();

clang/lib/CodeGen/CGExprConstant.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,17 +1735,6 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
17351735
return nullptr;
17361736
}
17371737

1738-
// Handle typeid(T).
1739-
if (TypeInfoLValue TI = base.dyn_cast<TypeInfoLValue>()) {
1740-
llvm::Type *StdTypeInfoPtrTy =
1741-
CGM.getTypes().ConvertType(base.getTypeInfoType())->getPointerTo();
1742-
llvm::Constant *TypeInfo =
1743-
CGM.GetAddrOfRTTIDescriptor(QualType(TI.getType(), 0));
1744-
if (TypeInfo->getType() != StdTypeInfoPtrTy)
1745-
TypeInfo = llvm::ConstantExpr::getBitCast(TypeInfo, StdTypeInfoPtrTy);
1746-
return TypeInfo;
1747-
}
1748-
17491738
// Otherwise, it must be an expression.
17501739
return Visit(base.get<const Expr*>());
17511740
}

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6424,18 +6424,17 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
64246424
// -- a string literal
64256425
// -- the result of a typeid expression, or
64266426
// -- a predefined __func__ variable
6427-
APValue::LValueBase Base = Value.getLValueBase();
6428-
auto *VD = const_cast<ValueDecl *>(Base.dyn_cast<const ValueDecl *>());
6429-
if (Base && !VD) {
6430-
auto *E = Base.dyn_cast<const Expr *>();
6431-
if (E && isa<CXXUuidofExpr>(E)) {
6427+
if (auto *E = Value.getLValueBase().dyn_cast<const Expr*>()) {
6428+
if (isa<CXXUuidofExpr>(E)) {
64326429
Converted = TemplateArgument(ArgResult.get()->IgnoreImpCasts());
64336430
break;
64346431
}
64356432
Diag(Arg->getBeginLoc(), diag::err_template_arg_not_decl_ref)
64366433
<< Arg->getSourceRange();
64376434
return ExprError();
64386435
}
6436+
auto *VD = const_cast<ValueDecl *>(
6437+
Value.getLValueBase().dyn_cast<const ValueDecl *>());
64396438
// -- a subobject
64406439
if (Value.hasLValuePath() && Value.getLValuePath().size() == 1 &&
64416440
VD && VD->getType()->isArrayType() &&

0 commit comments

Comments
 (0)