Skip to content

Commit 913f600

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. Recommit of e6393ee, most recently reverted in 9a33f02 due to a bug caused by ObjCInterfaceDecls not propagating availability attributes along their redeclaration chains; that bug was fixed in e2d4174.
1 parent e2d4174 commit 913f600

File tree

9 files changed

+51
-31
lines changed

9 files changed

+51
-31
lines changed

clang/include/clang/AST/APValue.h

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

181182
private:
182183
PtrTy Ptr;
@@ -204,8 +205,7 @@ class APValue {
204205

205206
public:
206207
LValuePathEntry() : Value() {}
207-
LValuePathEntry(BaseOrMemberType BaseOrMember)
208-
: Value{reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue())} {}
208+
LValuePathEntry(BaseOrMemberType BaseOrMember);
209209
static LValuePathEntry ArrayIndex(uint64_t Index) {
210210
LValuePathEntry Result;
211211
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

@@ -90,13 +90,19 @@ bool operator==(const APValue::LValueBase &LHS,
9090
const APValue::LValueBase &RHS) {
9191
if (LHS.Ptr != RHS.Ptr)
9292
return false;
93-
if (LHS.is<TypeInfoLValue>())
93+
if (LHS.is<TypeInfoLValue>() || LHS.is<DynamicAllocLValue>())
9494
return true;
9595
return LHS.Local.CallIndex == RHS.Local.CallIndex &&
9696
LHS.Local.Version == RHS.Local.Version;
9797
}
9898
}
9999

100+
APValue::LValuePathEntry::LValuePathEntry(BaseOrMemberType BaseOrMember) {
101+
if (const Decl *D = BaseOrMember.getPointer())
102+
BaseOrMember.setPointer(D->getCanonicalDecl());
103+
Value = reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue());
104+
}
105+
100106
void APValue::LValuePathEntry::profile(llvm::FoldingSetNodeID &ID) const {
101107
ID.AddInteger(Value);
102108
}
@@ -125,14 +131,16 @@ APValue::LValueBase::operator bool () const {
125131

126132
clang::APValue::LValueBase
127133
llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
128-
return clang::APValue::LValueBase(
129-
DenseMapInfo<const ValueDecl*>::getEmptyKey());
134+
clang::APValue::LValueBase B;
135+
B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey();
136+
return B;
130137
}
131138

132139
clang::APValue::LValueBase
133140
llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
134-
return clang::APValue::LValueBase(
135-
DenseMapInfo<const ValueDecl*>::getTombstoneKey());
141+
clang::APValue::LValueBase B;
142+
B.Ptr = DenseMapInfo<const ValueDecl*>::getTombstoneKey();
143+
return B;
136144
}
137145

138146
namespace clang {
@@ -926,8 +934,10 @@ void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
926934
assert(isAbsent() && "Bad state change");
927935
MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
928936
Kind = MemberPointer;
929-
MPD->MemberAndIsDerivedMember.setPointer(Member);
937+
MPD->MemberAndIsDerivedMember.setPointer(
938+
Member ? cast<ValueDecl>(Member->getCanonicalDecl()) : nullptr);
930939
MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
931940
MPD->resizePath(Path.size());
932-
memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
941+
for (unsigned I = 0; I != Path.size(); ++I)
942+
MPD->getPath()[I] = Path[I]->getCanonicalDecl();
933943
}

clang/lib/AST/Decl.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4686,11 +4686,9 @@ char *Buffer = new (getASTContext(), 1) char[Name.size() + 1];
46864686
void ValueDecl::anchor() {}
46874687

46884688
bool ValueDecl::isWeak() const {
4689-
for (const auto *I : attrs())
4690-
if (isa<WeakAttr>(I) || isa<WeakRefAttr>(I))
4691-
return true;
4692-
4693-
return isWeakImported();
4689+
auto *MostRecent = getMostRecentDecl();
4690+
return MostRecent->hasAttr<WeakAttr>() ||
4691+
MostRecent->hasAttr<WeakRefAttr>() || isWeakImported();
46944692
}
46954693

46964694
void ImplicitParamDecl::anchor() {}

clang/lib/AST/DeclBase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ bool Decl::isWeakImported() const {
720720
if (!canBeWeakImported(IsDefinition))
721721
return false;
722722

723-
for (const auto *A : attrs()) {
723+
for (const auto *A : getMostRecentDecl()->attrs()) {
724724
if (isa<WeakImportAttr>(A))
725725
return true;
726726

clang/lib/AST/ExprConstant.cpp

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

19841984
if (A.getLValueBase().getOpaqueValue() !=
1985-
B.getLValueBase().getOpaqueValue()) {
1986-
const Decl *ADecl = GetLValueBaseDecl(A);
1987-
if (!ADecl)
1988-
return false;
1989-
const Decl *BDecl = GetLValueBaseDecl(B);
1990-
if (!BDecl || ADecl->getCanonicalDecl() != BDecl->getCanonicalDecl())
1991-
return false;
1992-
}
1985+
B.getLValueBase().getOpaqueValue())
1986+
return false;
19931987

1994-
return IsGlobalLValue(A.getLValueBase()) ||
1995-
(A.getLValueCallIndex() == B.getLValueCallIndex() &&
1996-
A.getLValueVersion() == B.getLValueVersion());
1988+
return A.getLValueCallIndex() == B.getLValueCallIndex() &&
1989+
A.getLValueVersion() == B.getLValueVersion();
19971990
}
19981991

19991992
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base) {
@@ -3163,7 +3156,8 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
31633156

31643157
// If we're currently evaluating the initializer of this declaration, use that
31653158
// in-flight value.
3166-
if (Info.EvaluatingDecl.dyn_cast<const ValueDecl*>() == VD) {
3159+
if (declaresSameEntity(Info.EvaluatingDecl.dyn_cast<const ValueDecl *>(),
3160+
VD)) {
31673161
Result = Info.EvaluatingDeclValue;
31683162
return true;
31693163
}

clang/lib/CodeGen/CGExprConstant.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,6 +1877,10 @@ ConstantLValue
18771877
ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
18781878
// Handle values.
18791879
if (const ValueDecl *D = base.dyn_cast<const ValueDecl*>()) {
1880+
// The constant always points to the canonical declaration. We want to look
1881+
// at properties of the most recent declaration at the point of emission.
1882+
D = cast<ValueDecl>(D->getMostRecentDecl());
1883+
18801884
if (D->hasAttr<WeakRefAttr>())
18811885
return CGM.GetWeakRefReference(D).getPointer();
18821886

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/CodeGenCXX/weak-external.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,15 @@ class _LIBCPP_EXCEPTION_ABI runtime_error
6464
void dummysymbol() {
6565
throw(std::runtime_error("string"));
6666
}
67+
68+
namespace not_weak_on_first {
69+
int func();
70+
// CHECK: {{.*}} extern_weak {{.*}} @_ZN17not_weak_on_first4funcEv(
71+
int func() __attribute__ ((weak));
72+
73+
typedef int (*FuncT)();
74+
75+
extern const FuncT table[] = {
76+
func,
77+
};
78+
}

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)