From 0c417d4bef1e78b0716c546101462f6d8962f358 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 21 Oct 2020 12:59:08 -0700 Subject: [PATCH] Add more test coverage for APValue serialization / deserialization and fix a few exposed bugs. --- clang/include/clang/AST/APValue.h | 6 +----- clang/include/clang/AST/DeclTemplate.h | 2 +- clang/lib/AST/APValue.cpp | 9 ++++++++- clang/lib/AST/ExprConstant.cpp | 2 +- clang/lib/Sema/SemaTemplate.cpp | 4 +--- clang/lib/Serialization/ASTReader.cpp | 2 ++ clang/lib/Serialization/ASTWriter.cpp | 2 ++ clang/test/PCH/cxx20-template-args.cpp | 17 ++++++++++++++++- 8 files changed, 32 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 04892d4..6cda588 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -594,11 +594,7 @@ public: void setLValue(LValueBase B, const CharUnits &O, ArrayRef Path, bool OnePastTheEnd, bool IsNullPtr); - void setUnion(const FieldDecl *Field, const APValue &Value) { - assert(isUnion() && "Invalid accessor"); - ((UnionData*)(char*)Data.buffer)->Field = Field; - *((UnionData*)(char*)Data.buffer)->Value = Value; - } + void setUnion(const FieldDecl *Field, const APValue &Value); void setAddrLabelDiff(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) { ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr; diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 7a175db..6416476 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -3318,7 +3318,7 @@ public: static void Profile(llvm::FoldingSetNodeID &ID, QualType T, const APValue &V) { ID.AddPointer(T.getCanonicalType().getAsOpaquePtr()); - V.profile(ID); + V.Profile(ID); } void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getType(), getValue()); diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 919cd86..8d367a3 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -441,7 +441,7 @@ void APValue::Profile(llvm::FoldingSetNodeID &ID) const { ID.AddPointer(nullptr); return; } - ID.AddPointer(getUnionField()->getCanonicalDecl()); + ID.AddPointer(getUnionField()); getUnionValue().Profile(ID); return; @@ -904,6 +904,13 @@ void APValue::setLValue(LValueBase B, const CharUnits &O, Path.size() * sizeof(LValuePathEntry)); } +void APValue::setUnion(const FieldDecl *Field, const APValue &Value) { + assert(isUnion() && "Invalid accessor"); + ((UnionData *)(char *)Data.buffer)->Field = + Field ? Field->getCanonicalDecl() : nullptr; + *((UnionData*)(char*)Data.buffer)->Value = Value; +} + const ValueDecl *APValue::getMemberPointerDecl() const { assert(isMemberPointer() && "Invalid accessor"); const MemberPointerData &MPD = diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 7a933e3..00f9d42 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1603,7 +1603,7 @@ namespace { } void setNull(ASTContext &Ctx, QualType PointerTy) { - Base = (Expr *)nullptr; + Base = (const ValueDecl *)nullptr; Offset = CharUnits::fromQuantity(Ctx.getTargetNullPointerValue(PointerTy)); InvalidBase = false; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 4017e65..8bff982 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -6929,9 +6929,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // // Similarly, don't inject a call to a copy constructor when initializing // from a template parameter of the same type. - Expr *InnerArg = Arg; - while (auto *SNTTP = dyn_cast(InnerArg)) - InnerArg = SNTTP->getReplacement(); + Expr *InnerArg = Arg->IgnoreParenImpCasts(); if (ParamType->isRecordType() && isa(InnerArg) && Context.hasSameUnqualifiedType(ParamType, InnerArg->getType())) { NamedDecl *ND = cast(InnerArg)->getDecl(); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 79fabfe..4cd76c0 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -9007,6 +9007,8 @@ APValue ASTRecordReader::readAPValue() { Result.MakeArray(InitLength, TotalLength); for (unsigned LoopIdx = 0; LoopIdx < InitLength; LoopIdx++) Result.getArrayInitializedElt(LoopIdx) = asImpl().readAPValue(); + if (Result.hasArrayFiller()) + Result.getArrayFiller() = asImpl().readAPValue(); return Result; } case APValue::Struct: { diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index bbc8248..b23e042 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -5175,6 +5175,8 @@ void ASTRecordWriter::AddAPValue(const APValue &Value) { push_back(Value.getArraySize()); for (unsigned Idx = 0; Idx < Value.getArrayInitializedElts(); Idx++) AddAPValue(Value.getArrayInitializedElt(Idx)); + if (Value.hasArrayFiller()) + AddAPValue(Value.getArrayFiller()); return; case APValue::Struct: push_back(Value.getStructNumBases()); diff --git a/clang/test/PCH/cxx20-template-args.cpp b/clang/test/PCH/cxx20-template-args.cpp index f95ec52..f9ac35b 100644 --- a/clang/test/PCH/cxx20-template-args.cpp +++ b/clang/test/PCH/cxx20-template-args.cpp @@ -8,18 +8,33 @@ #ifndef HEADER #define HEADER -struct A { int n; }; +int g; +struct A { union { int n, m; }; int *p; int A::*q; char buffer[32]; }; template constexpr const A &get = a; constexpr const A &v = get; +constexpr const A &w = get; #else /*included pch*/ template constexpr const A &get2 = a; constexpr const A &v2 = get2; +constexpr const A &w2 = get2; static_assert(&v == &v2); +static_assert(&w == &w2); + +static_assert(&v != &w); +static_assert(&v2 != &w); +static_assert(&v != &w2); +static_assert(&v2 != &w2); + +constexpr const A &v3 = get2; +constexpr const A &x = get2; + +static_assert(&v == &v3); +static_assert(&v != &x); #endif // HEADER -- 2.7.4