forked from OSchip/llvm-project
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 e6393ee813
with fixed
handling for weak declarations. We now look for attributes on the most
recent declaration when determining whether a declaration is weak.
This commit is contained in:
parent
344a3d0bc0
commit
905b9ca26c
|
@ -174,6 +174,7 @@ public:
|
|||
return !(LHS == RHS);
|
||||
}
|
||||
friend llvm::hash_code hash_value(const LValueBase &Base);
|
||||
friend struct llvm::DenseMapInfo<LValueBase>;
|
||||
|
||||
private:
|
||||
PtrTy Ptr;
|
||||
|
@ -201,8 +202,7 @@ public:
|
|||
|
||||
public:
|
||||
LValuePathEntry() : Value() {}
|
||||
LValuePathEntry(BaseOrMemberType BaseOrMember)
|
||||
: Value{reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue())} {}
|
||||
LValuePathEntry(BaseOrMemberType BaseOrMember);
|
||||
static LValuePathEntry ArrayIndex(uint64_t Index) {
|
||||
LValuePathEntry Result;
|
||||
Result.Value = Index;
|
||||
|
|
|
@ -38,7 +38,7 @@ static_assert(
|
|||
"Type is insufficiently aligned");
|
||||
|
||||
APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V)
|
||||
: Ptr(P), Local{I, V} {}
|
||||
: Ptr(P ? cast<ValueDecl>(P->getCanonicalDecl()) : nullptr), Local{I, V} {}
|
||||
APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V)
|
||||
: Ptr(P), Local{I, V} {}
|
||||
|
||||
|
@ -82,13 +82,19 @@ bool operator==(const APValue::LValueBase &LHS,
|
|||
const APValue::LValueBase &RHS) {
|
||||
if (LHS.Ptr != RHS.Ptr)
|
||||
return false;
|
||||
if (LHS.is<TypeInfoLValue>())
|
||||
if (LHS.is<TypeInfoLValue>() || LHS.is<DynamicAllocLValue>())
|
||||
return true;
|
||||
return LHS.Local.CallIndex == RHS.Local.CallIndex &&
|
||||
LHS.Local.Version == RHS.Local.Version;
|
||||
}
|
||||
}
|
||||
|
||||
APValue::LValuePathEntry::LValuePathEntry(BaseOrMemberType BaseOrMember) {
|
||||
if (const Decl *D = BaseOrMember.getPointer())
|
||||
BaseOrMember.setPointer(D->getCanonicalDecl());
|
||||
Value = reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue());
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct LVBase {
|
||||
APValue::LValueBase Base;
|
||||
|
@ -113,14 +119,16 @@ APValue::LValueBase::operator bool () const {
|
|||
|
||||
clang::APValue::LValueBase
|
||||
llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
|
||||
return clang::APValue::LValueBase(
|
||||
DenseMapInfo<const ValueDecl*>::getEmptyKey());
|
||||
clang::APValue::LValueBase B;
|
||||
B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey();
|
||||
return B;
|
||||
}
|
||||
|
||||
clang::APValue::LValueBase
|
||||
llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
|
||||
return clang::APValue::LValueBase(
|
||||
DenseMapInfo<const ValueDecl*>::getTombstoneKey());
|
||||
clang::APValue::LValueBase B;
|
||||
B.Ptr = DenseMapInfo<const ValueDecl*>::getTombstoneKey();
|
||||
return B;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
|
@ -773,8 +781,10 @@ void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
|
|||
assert(isAbsent() && "Bad state change");
|
||||
MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
|
||||
Kind = MemberPointer;
|
||||
MPD->MemberAndIsDerivedMember.setPointer(Member);
|
||||
MPD->MemberAndIsDerivedMember.setPointer(
|
||||
Member ? cast<ValueDecl>(Member->getCanonicalDecl()) : nullptr);
|
||||
MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
|
||||
MPD->resizePath(Path.size());
|
||||
memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
|
||||
for (unsigned I = 0; I != Path.size(); ++I)
|
||||
MPD->getPath()[I] = Path[I]->getCanonicalDecl();
|
||||
}
|
||||
|
|
|
@ -4706,7 +4706,7 @@ char *Buffer = new (getASTContext(), 1) char[Name.size() + 1];
|
|||
void ValueDecl::anchor() {}
|
||||
|
||||
bool ValueDecl::isWeak() const {
|
||||
for (const auto *I : attrs())
|
||||
for (const auto *I : getMostRecentDecl()->attrs())
|
||||
if (isa<WeakAttr>(I) || isa<WeakRefAttr>(I))
|
||||
return true;
|
||||
|
||||
|
|
|
@ -720,7 +720,7 @@ bool Decl::isWeakImported() const {
|
|||
if (!canBeWeakImported(IsDefinition))
|
||||
return false;
|
||||
|
||||
for (const auto *A : attrs()) {
|
||||
for (const auto *A : getMostRecentDecl()->attrs()) {
|
||||
if (isa<WeakImportAttr>(A))
|
||||
return true;
|
||||
|
||||
|
|
|
@ -1978,18 +1978,11 @@ static bool HasSameBase(const LValue &A, const LValue &B) {
|
|||
return false;
|
||||
|
||||
if (A.getLValueBase().getOpaqueValue() !=
|
||||
B.getLValueBase().getOpaqueValue()) {
|
||||
const Decl *ADecl = GetLValueBaseDecl(A);
|
||||
if (!ADecl)
|
||||
return false;
|
||||
const Decl *BDecl = GetLValueBaseDecl(B);
|
||||
if (!BDecl || ADecl->getCanonicalDecl() != BDecl->getCanonicalDecl())
|
||||
return false;
|
||||
}
|
||||
B.getLValueBase().getOpaqueValue())
|
||||
return false;
|
||||
|
||||
return IsGlobalLValue(A.getLValueBase()) ||
|
||||
(A.getLValueCallIndex() == B.getLValueCallIndex() &&
|
||||
A.getLValueVersion() == B.getLValueVersion());
|
||||
return A.getLValueCallIndex() == B.getLValueCallIndex() &&
|
||||
A.getLValueVersion() == B.getLValueVersion();
|
||||
}
|
||||
|
||||
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base) {
|
||||
|
@ -3108,7 +3101,8 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
|
|||
|
||||
// If we're currently evaluating the initializer of this declaration, use that
|
||||
// in-flight value.
|
||||
if (Info.EvaluatingDecl.dyn_cast<const ValueDecl*>() == VD) {
|
||||
if (declaresSameEntity(Info.EvaluatingDecl.dyn_cast<const ValueDecl *>(),
|
||||
VD)) {
|
||||
Result = Info.EvaluatingDeclValue;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -24,11 +24,10 @@ constexpr double &ni3; // expected-error {{declaration of reference variable 'ni
|
|||
|
||||
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}}
|
||||
constexpr C nc2 = C(); // expected-error {{cannot have non-literal type 'const C'}}
|
||||
int &f(); // expected-note {{declared here}}
|
||||
int &f(); // expected-note 2{{declared here}}
|
||||
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}}
|
||||
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}}
|
||||
constexpr C nc5((C())); // expected-error {{cannot have non-literal type 'const C'}}
|
||||
int &f(); // expected-note {{here}}
|
||||
constexpr int &nc6(f()); // expected-error {{constexpr variable 'nc6' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f'}}
|
||||
|
||||
struct pixel {
|
||||
|
|
|
@ -16,6 +16,9 @@ void xxx(int argc) {
|
|||
}
|
||||
|
||||
int foo();
|
||||
#if __cplusplus >= 201103L
|
||||
// expected-note@-2 {{declared here}}
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
T foo() {
|
||||
|
@ -176,7 +179,7 @@ T foo() {
|
|||
|
||||
int foo() {
|
||||
#if __cplusplus >= 201103L
|
||||
// expected-note@-2 2 {{declared here}}
|
||||
// expected-note@-2 {{declared here}}
|
||||
#endif
|
||||
int k;
|
||||
#pragma omp for ordered
|
||||
|
|
Loading…
Reference in New Issue