Author: Richard Smith Date: 2020-10-12T19:32:57-07:00 New Revision: 913f6005669cfb590c99865a90bc51ed0983d09d
URL: https://github.com/llvm/llvm-project/commit/913f6005669cfb590c99865a90bc51ed0983d09d DIFF: https://github.com/llvm/llvm-project/commit/913f6005669cfb590c99865a90bc51ed0983d09d.diff LOG: 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 e6393ee813178e9d3306b8e3c6949a4f32f8a2cb, most recently reverted in 9a33f027ac7d73e14ae287e78ab554142d1cbc8f due to a bug caused by ObjCInterfaceDecls not propagating availability attributes along their redeclaration chains; that bug was fixed in e2d4174e9c66251d1b408234b53f53d0903c0285. Added: Modified: clang/include/clang/AST/APValue.h clang/lib/AST/APValue.cpp clang/lib/AST/Decl.cpp clang/lib/AST/DeclBase.cpp clang/lib/AST/ExprConstant.cpp clang/lib/CodeGen/CGExprConstant.cpp clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp clang/test/CodeGenCXX/weak-external.cpp clang/test/OpenMP/ordered_messages.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 9e9468645fe7..ac8ed0818af0 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -177,6 +177,7 @@ class APValue { return !(LHS == RHS); } friend llvm::hash_code hash_value(const LValueBase &Base); + friend struct llvm::DenseMapInfo<LValueBase>; private: PtrTy Ptr; @@ -204,8 +205,7 @@ class APValue { 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; diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 22145beafd8d..7efd0caf3f1d 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -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} {} @@ -90,13 +90,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()); +} + void APValue::LValuePathEntry::profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Value); } @@ -125,14 +131,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 { @@ -926,8 +934,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(); } diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 6bb8aa026ad8..a6c7f30528eb 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -4686,11 +4686,9 @@ char *Buffer = new (getASTContext(), 1) char[Name.size() + 1]; void ValueDecl::anchor() {} bool ValueDecl::isWeak() const { - for (const auto *I : attrs()) - if (isa<WeakAttr>(I) || isa<WeakRefAttr>(I)) - return true; - - return isWeakImported(); + auto *MostRecent = getMostRecentDecl(); + return MostRecent->hasAttr<WeakAttr>() || + MostRecent->hasAttr<WeakRefAttr>() || isWeakImported(); } void ImplicitParamDecl::anchor() {} diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index f4314d0bd961..ab2b55c0762e 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -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; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 67ca5271929f..639a5733b34b 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1982,18 +1982,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) { @@ -3163,7 +3156,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; } diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index b0a37531dfe1..bff4a0c38af9 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1877,6 +1877,10 @@ ConstantLValue ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) { // Handle values. if (const ValueDecl *D = base.dyn_cast<const ValueDecl*>()) { + // The constant always points to the canonical declaration. We want to look + // at properties of the most recent declaration at the point of emission. + D = cast<ValueDecl>(D->getMostRecentDecl()); + if (D->hasAttr<WeakRefAttr>()) return CGM.GetWeakRefReference(D).getPointer(); diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp index 8d51dbde7177..3720b277af7a 100644 --- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp @@ -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 { diff --git a/clang/test/CodeGenCXX/weak-external.cpp b/clang/test/CodeGenCXX/weak-external.cpp index a2c53a59dcd5..433fb3c80624 100644 --- a/clang/test/CodeGenCXX/weak-external.cpp +++ b/clang/test/CodeGenCXX/weak-external.cpp @@ -64,3 +64,15 @@ class _LIBCPP_EXCEPTION_ABI runtime_error void dummysymbol() { throw(std::runtime_error("string")); } + +namespace not_weak_on_first { + int func(); + // CHECK: {{.*}} extern_weak {{.*}} @_ZN17not_weak_on_first4funcEv( + int func() __attribute__ ((weak)); + + typedef int (*FuncT)(); + + extern const FuncT table[] = { + func, + }; +} diff --git a/clang/test/OpenMP/ordered_messages.cpp b/clang/test/OpenMP/ordered_messages.cpp index f6b9dbd6d27f..8a3a86443eb8 100644 --- a/clang/test/OpenMP/ordered_messages.cpp +++ b/clang/test/OpenMP/ordered_messages.cpp @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits