Author: Richard Smith Date: 2020-10-21T13:21:41-07:00 New Revision: 0c417d4bef1e78b0716c546101462f6d8962f358
URL: https://github.com/llvm/llvm-project/commit/0c417d4bef1e78b0716c546101462f6d8962f358 DIFF: https://github.com/llvm/llvm-project/commit/0c417d4bef1e78b0716c546101462f6d8962f358.diff LOG: Add more test coverage for APValue serialization / deserialization and fix a few exposed bugs. Added: Modified: clang/include/clang/AST/APValue.h clang/include/clang/AST/DeclTemplate.h clang/lib/AST/APValue.cpp clang/lib/AST/ExprConstant.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/test/PCH/cxx20-template-args.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 04892d43e4a0..6cda588ffe74 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -594,11 +594,7 @@ class APValue { void setLValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> 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 7a175db8cb16..641647659c17 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -3318,7 +3318,7 @@ class TemplateParamObjectDecl : public ValueDecl, 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 919cd86ea9cf..8d367a305168 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 7a933e3eaafb..00f9d4205581 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 4017e65118d9..8bff982d66be 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<SubstNonTypeTemplateParmExpr>(InnerArg)) - InnerArg = SNTTP->getReplacement(); + Expr *InnerArg = Arg->IgnoreParenImpCasts(); if (ParamType->isRecordType() && isa<DeclRefExpr>(InnerArg) && Context.hasSameUnqualifiedType(ParamType, InnerArg->getType())) { NamedDecl *ND = cast<DeclRefExpr>(InnerArg)->getDecl(); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 79fabfec54b4..4cd76c0bba94 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 bbc8248ae22e..b23e04279d29 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 f95ec52dca27..f9ac35ba53a4 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<A a> constexpr const A &get = a; constexpr const A &v = get<A{}>; +constexpr const A &w = get<A{1, &g, &A::n, "hello"}>; #else /*included pch*/ template<A a> constexpr const A &get2 = a; constexpr const A &v2 = get2<A{}>; +constexpr const A &w2 = get2<A{1, &g, &A::n, "hello\0\0\0\0\0"}>; 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<A{.n = 0}>; +constexpr const A &x = get2<A{.m = 0}>; + +static_assert(&v == &v3); +static_assert(&v != &x); #endif // HEADER _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits