fix a few exposed bugs.
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;
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());
ID.AddPointer(nullptr);
return;
}
- ID.AddPointer(getUnionField()->getCanonicalDecl());
+ ID.AddPointer(getUnionField());
getUnionValue().Profile(ID);
return;
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 =
}
void setNull(ASTContext &Ctx, QualType PointerTy) {
- Base = (Expr *)nullptr;
+ Base = (const ValueDecl *)nullptr;
Offset =
CharUnits::fromQuantity(Ctx.getTargetNullPointerValue(PointerTy));
InvalidBase = false;
//
// 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();
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: {
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());
#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