+ Function *F = BB ? BB->getParent() : nullptr;
+
+ // The scopes for variables and !dbg attachments must agree.
+ DILocalVariable *Var = DII.getVariable();
+ DILocation *Loc = DII.getDebugLoc();
+ Assert(Loc, "llvm.dbg." + Kind + " intrinsic requires a !dbg attachment",
+ &DII, BB, F);
+
+ DISubprogram *VarSP = getSubprogram(Var->getRawScope());
+ DISubprogram *LocSP = getSubprogram(Loc->getRawScope());
+ if (!VarSP || !LocSP)
+ return; // Broken scope chains are checked elsewhere.
+
+ Assert(VarSP == LocSP, "mismatched subprogram between llvm.dbg." + Kind +
+ " variable and !dbg attachment",
+ &DII, BB, F, Var, Var->getScope()->getSubprogram(), Loc,
+ Loc->getScope()->getSubprogram());
+}
+
+template <class MapTy>
+static uint64_t getVariableSize(const DILocalVariable &V, const MapTy &Map) {
+ // Be careful of broken types (checked elsewhere).
+ const Metadata *RawType = V.getRawType();
+ while (RawType) {
+ // Try to get the size directly.
+ if (auto *T = dyn_cast<DIType>(RawType))
+ if (uint64_t Size = T->getSizeInBits())
+ return Size;
+
+ if (auto *DT = dyn_cast<DIDerivedType>(RawType)) {
+ // Look at the base type.
+ RawType = DT->getRawBaseType();
+ continue;
+ }
+
+ if (auto *S = dyn_cast<MDString>(RawType)) {
+ // Don't error on missing types (checked elsewhere).
+ RawType = Map.lookup(S);
+ continue;
+ }
+
+ // Missing type or size.
+ break;
+ }
+
+ // Fail gracefully.
+ return 0;
+}
+
+template <class MapTy>
+void Verifier::verifyBitPieceExpression(const DbgInfoIntrinsic &I,
+ const MapTy &TypeRefs) {
+ DILocalVariable *V;
+ DIExpression *E;
+ if (auto *DVI = dyn_cast<DbgValueInst>(&I)) {
+ V = dyn_cast_or_null<DILocalVariable>(DVI->getRawVariable());
+ E = dyn_cast_or_null<DIExpression>(DVI->getRawExpression());
+ } else {
+ auto *DDI = cast<DbgDeclareInst>(&I);
+ V = dyn_cast_or_null<DILocalVariable>(DDI->getRawVariable());
+ E = dyn_cast_or_null<DIExpression>(DDI->getRawExpression());
+ }
+
+ // We don't know whether this intrinsic verified correctly.
+ if (!V || !E || !E->isValid())
+ return;
+
+ // Nothing to do if this isn't a bit piece expression.
+ if (!E->isBitPiece())
+ return;
+
+ // The frontend helps out GDB by emitting the members of local anonymous
+ // unions as artificial local variables with shared storage. When SROA splits
+ // the storage for artificial local variables that are smaller than the entire
+ // union, the overhang piece will be outside of the allotted space for the
+ // variable and this check fails.
+ // FIXME: Remove this check as soon as clang stops doing this; it hides bugs.
+ if (V->isArtificial())
+ return;
+
+ // If there's no size, the type is broken, but that should be checked
+ // elsewhere.
+ uint64_t VarSize = getVariableSize(*V, TypeRefs);
+ if (!VarSize)
+ return;
+
+ unsigned PieceSize = E->getBitPieceSize();
+ unsigned PieceOffset = E->getBitPieceOffset();
+ Assert(PieceSize + PieceOffset <= VarSize,
+ "piece is larger than or outside of variable", &I, V, E);
+ Assert(PieceSize != VarSize, "piece covers entire variable", &I, V, E);