Skip to content

Commit e6393ee

Browse files
committed
Canonicalize declaration pointers when forming APValues.
References to different declarations of the same entity aren't different values, so shouldn't have different representations.
1 parent 3d54976 commit e6393ee

File tree

5 files changed

+31
-25
lines changed

5 files changed

+31
-25
lines changed

clang/include/clang/AST/APValue.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class APValue {
174174
return !(LHS == RHS);
175175
}
176176
friend llvm::hash_code hash_value(const LValueBase &Base);
177+
friend struct llvm::DenseMapInfo<LValueBase>;
177178

178179
private:
179180
PtrTy Ptr;
@@ -201,8 +202,7 @@ class APValue {
201202

202203
public:
203204
LValuePathEntry() : Value() {}
204-
LValuePathEntry(BaseOrMemberType BaseOrMember)
205-
: Value{reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue())} {}
205+
LValuePathEntry(BaseOrMemberType BaseOrMember);
206206
static LValuePathEntry ArrayIndex(uint64_t Index) {
207207
LValuePathEntry Result;
208208
Result.Value = Index;

clang/lib/AST/APValue.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ static_assert(
3838
"Type is insufficiently aligned");
3939

4040
APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V)
41-
: Ptr(P), Local{I, V} {}
41+
: Ptr(P ? cast<ValueDecl>(P->getCanonicalDecl()) : nullptr), Local{I, V} {}
4242
APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V)
4343
: Ptr(P), Local{I, V} {}
4444

@@ -82,13 +82,19 @@ bool operator==(const APValue::LValueBase &LHS,
8282
const APValue::LValueBase &RHS) {
8383
if (LHS.Ptr != RHS.Ptr)
8484
return false;
85-
if (LHS.is<TypeInfoLValue>())
85+
if (LHS.is<TypeInfoLValue>() || LHS.is<DynamicAllocLValue>())
8686
return true;
8787
return LHS.Local.CallIndex == RHS.Local.CallIndex &&
8888
LHS.Local.Version == RHS.Local.Version;
8989
}
9090
}
9191

92+
APValue::LValuePathEntry::LValuePathEntry(BaseOrMemberType BaseOrMember) {
93+
if (const Decl *D = BaseOrMember.getPointer())
94+
BaseOrMember.setPointer(D->getCanonicalDecl());
95+
Value = reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue());
96+
}
97+
9298
namespace {
9399
struct LVBase {
94100
APValue::LValueBase Base;
@@ -113,14 +119,16 @@ APValue::LValueBase::operator bool () const {
113119

114120
clang::APValue::LValueBase
115121
llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
116-
return clang::APValue::LValueBase(
117-
DenseMapInfo<const ValueDecl*>::getEmptyKey());
122+
clang::APValue::LValueBase B;
123+
B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey();
124+
return B;
118125
}
119126

120127
clang::APValue::LValueBase
121128
llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
122-
return clang::APValue::LValueBase(
123-
DenseMapInfo<const ValueDecl*>::getTombstoneKey());
129+
clang::APValue::LValueBase B;
130+
B.Ptr = DenseMapInfo<const ValueDecl*>::getTombstoneKey();
131+
return B;
124132
}
125133

126134
namespace clang {
@@ -757,8 +765,10 @@ void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
757765
assert(isAbsent() && "Bad state change");
758766
MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
759767
Kind = MemberPointer;
760-
MPD->MemberAndIsDerivedMember.setPointer(Member);
768+
MPD->MemberAndIsDerivedMember.setPointer(
769+
Member ? cast<ValueDecl>(Member->getCanonicalDecl()) : nullptr);
761770
MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
762771
MPD->resizePath(Path.size());
763-
memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
772+
for (unsigned I = 0; I != Path.size(); ++I)
773+
MPD->getPath()[I] = Path[I]->getCanonicalDecl();
764774
}

clang/lib/AST/ExprConstant.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,18 +1978,11 @@ static bool HasSameBase(const LValue &A, const LValue &B) {
19781978
return false;
19791979

19801980
if (A.getLValueBase().getOpaqueValue() !=
1981-
B.getLValueBase().getOpaqueValue()) {
1982-
const Decl *ADecl = GetLValueBaseDecl(A);
1983-
if (!ADecl)
1984-
return false;
1985-
const Decl *BDecl = GetLValueBaseDecl(B);
1986-
if (!BDecl || ADecl->getCanonicalDecl() != BDecl->getCanonicalDecl())
1987-
return false;
1988-
}
1981+
B.getLValueBase().getOpaqueValue())
1982+
return false;
19891983

1990-
return IsGlobalLValue(A.getLValueBase()) ||
1991-
(A.getLValueCallIndex() == B.getLValueCallIndex() &&
1992-
A.getLValueVersion() == B.getLValueVersion());
1984+
return A.getLValueCallIndex() == B.getLValueCallIndex() &&
1985+
A.getLValueVersion() == B.getLValueVersion();
19931986
}
19941987

19951988
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base) {
@@ -3108,7 +3101,8 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
31083101

31093102
// If we're currently evaluating the initializer of this declaration, use that
31103103
// in-flight value.
3111-
if (Info.EvaluatingDecl.dyn_cast<const ValueDecl*>() == VD) {
3104+
if (declaresSameEntity(Info.EvaluatingDecl.dyn_cast<const ValueDecl *>(),
3105+
VD)) {
31123106
Result = Info.EvaluatingDeclValue;
31133107
return true;
31143108
}

clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,10 @@ constexpr double &ni3; // expected-error {{declaration of reference variable 'ni
2424

2525
constexpr int nc1 = i; // expected-error {{constexpr variable 'nc1' must be initialized by a constant expression}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
2626
constexpr C nc2 = C(); // expected-error {{cannot have non-literal type 'const C'}}
27-
int &f(); // expected-note {{declared here}}
27+
int &f(); // expected-note 2{{declared here}}
2828
constexpr int &nc3 = f(); // expected-error {{constexpr variable 'nc3' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f' cannot be used in a constant expression}}
2929
constexpr int nc4(i); // expected-error {{constexpr variable 'nc4' must be initialized by a constant expression}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
3030
constexpr C nc5((C())); // expected-error {{cannot have non-literal type 'const C'}}
31-
int &f(); // expected-note {{here}}
3231
constexpr int &nc6(f()); // expected-error {{constexpr variable 'nc6' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f'}}
3332

3433
struct pixel {

clang/test/OpenMP/ordered_messages.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ void xxx(int argc) {
1616
}
1717

1818
int foo();
19+
#if __cplusplus >= 201103L
20+
// expected-note@-2 {{declared here}}
21+
#endif
1922

2023
template <class T>
2124
T foo() {
@@ -176,7 +179,7 @@ T foo() {
176179

177180
int foo() {
178181
#if __cplusplus >= 201103L
179-
// expected-note@-2 2 {{declared here}}
182+
// expected-note@-2 {{declared here}}
180183
#endif
181184
int k;
182185
#pragma omp for ordered

0 commit comments

Comments
 (0)