Add more test coverage for APValue serialization / deserialization and
authorRichard Smith <richard@metafoo.co.uk>
Wed, 21 Oct 2020 19:59:08 +0000 (12:59 -0700)
committerRichard Smith <richard@metafoo.co.uk>
Wed, 21 Oct 2020 20:21:41 +0000 (13:21 -0700)
fix a few exposed bugs.

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

index 04892d4..6cda588 100644 (file)
@@ -594,11 +594,7 @@ public:
   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;
index 7a175db..6416476 100644 (file)
@@ -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());
index 919cd86..8d367a3 100644 (file)
@@ -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 =
index 7a933e3..00f9d42 100644 (file)
@@ -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;
index 4017e65..8bff982 100644 (file)
@@ -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();
index 79fabfe..4cd76c0 100644 (file)
@@ -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: {
index bbc8248..b23e042 100644 (file)
@@ -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());
index f95ec52..f9ac35b 100644 (file)
@@ -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