diff options
author | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 17:16:04 +0900 |
---|---|---|
committer | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 17:16:04 +0900 |
commit | 0aa930a41f2d1ebf1fa90ec42da8f96d15a4dcbb (patch) | |
tree | 6a77b463f700e090df586672c26b9fe765fd115b /clang/lib/AST/ByteCode/InterpBuiltin.cpp | |
parent | ec6892d1c979ce0b84c86918d5cdbb03037b409a (diff) | |
parent | 6d16b1c5c468a79ecf867293023c89ac518ecdda (diff) | |
download | llvm-users/chapuni/cov/single/nextcount-base.zip llvm-users/chapuni/cov/single/nextcount-base.tar.gz llvm-users/chapuni/cov/single/nextcount-base.tar.bz2 |
Merge branch 'users/chapuni/cov/single/pair' into users/chapuni/cov/single/nextcount-baseusers/chapuni/cov/single/nextcount-base
Diffstat (limited to 'clang/lib/AST/ByteCode/InterpBuiltin.cpp')
-rw-r--r-- | clang/lib/AST/ByteCode/InterpBuiltin.cpp | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 2ae91fe..0d52083 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -17,6 +17,7 @@ #include "clang/Basic/Builtins.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/SipHash.h" namespace clang { @@ -154,7 +155,7 @@ static void diagnoseNonConstexprBuiltin(InterpState &S, CodePtr OpPC, if (S.getLangOpts().CPlusPlus11) S.CCEDiag(Loc, diag::note_constexpr_invalid_function) << /*isConstexpr=*/0 << /*isConstructor=*/0 - << ("'" + S.getASTContext().BuiltinInfo.getName(ID) + "'").str(); + << S.getASTContext().BuiltinInfo.getQuotedName(ID); else S.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr); } @@ -1543,9 +1544,10 @@ static bool interp__builtin_constant_p(InterpState &S, CodePtr OpPC, if (Res.isInvalid()) { C.cleanup(); Stk.clear(); + return returnInt(false); } - if (!Res.isInvalid() && !Res.empty()) { + if (!Res.empty()) { const APValue &LV = Res.toAPValue(); if (LV.isLValue()) { APValue::LValueBase Base = LV.getLValueBase(); @@ -1837,6 +1839,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, assert(Call->getNumArgs() == 3); unsigned ID = Func->getBuiltinID(); Pointer DestPtr = getParam<Pointer>(Frame, 0); + const ASTContext &ASTCtx = S.getASTContext(); const Pointer &SrcPtr = getParam<Pointer>(Frame, 1); const APSInt &Size = peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2))); @@ -1857,34 +1860,63 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, Pointer DiagPtr = (SrcPtr.isZero() ? SrcPtr : DestPtr); S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_null) << /*IsMove=*/Move << /*IsWchar=*/false << !SrcPtr.isZero() - << DiagPtr.toDiagnosticString(S.getASTContext()); + << DiagPtr.toDiagnosticString(ASTCtx); return false; } - QualType ElemType; - if (DestPtr.getFieldDesc()->isArray()) - ElemType = DestPtr.getFieldDesc()->getElemQualType(); - else - ElemType = DestPtr.getType(); + // Can't read from dummy pointers. + if (DestPtr.isDummy() || SrcPtr.isDummy()) + return false; - unsigned ElemSize = - S.getASTContext().getTypeSizeInChars(ElemType).getQuantity(); - if (Size.urem(ElemSize) != 0) { + QualType DestElemType; + size_t RemainingDestElems; + if (DestPtr.getFieldDesc()->isArray()) { + DestElemType = DestPtr.getFieldDesc()->getElemQualType(); + RemainingDestElems = DestPtr.isUnknownSizeArray() + ? 0 + : (DestPtr.getNumElems() - DestPtr.getIndex()); + } else { + DestElemType = DestPtr.getType(); + RemainingDestElems = 1; + } + unsigned DestElemSize = ASTCtx.getTypeSizeInChars(DestElemType).getQuantity(); + + if (Size.urem(DestElemSize) != 0) { S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_unsupported) - << Move << /*IsWchar=*/false << 0 << ElemType << Size << ElemSize; + << Move << /*IsWchar=*/false << 0 << DestElemType << Size + << DestElemSize; return false; } QualType SrcElemType; - if (SrcPtr.getFieldDesc()->isArray()) + size_t RemainingSrcElems; + if (SrcPtr.getFieldDesc()->isArray()) { SrcElemType = SrcPtr.getFieldDesc()->getElemQualType(); - else + RemainingSrcElems = SrcPtr.isUnknownSizeArray() + ? 0 + : (SrcPtr.getNumElems() - SrcPtr.getIndex()); + } else { SrcElemType = SrcPtr.getType(); + RemainingSrcElems = 1; + } + unsigned SrcElemSize = ASTCtx.getTypeSizeInChars(SrcElemType).getQuantity(); - if (!S.getASTContext().hasSameUnqualifiedType(ElemType, SrcElemType)) { + if (!ASTCtx.hasSameUnqualifiedType(DestElemType, SrcElemType)) { S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_type_pun) - << Move << SrcElemType << ElemType; + << Move << SrcElemType << DestElemType; + return false; + } + + // Check if we have enough elements to read from and write to/ + size_t RemainingDestBytes = RemainingDestElems * DestElemSize; + size_t RemainingSrcBytes = RemainingSrcElems * SrcElemSize; + if (Size.ugt(RemainingDestBytes) || Size.ugt(RemainingSrcBytes)) { + APInt N = Size.udiv(DestElemSize); + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_memcpy_unsupported) + << Move << /*IsWChar*/ false << (Size.ugt(RemainingSrcBytes) ? 1 : 2) + << DestElemType << toString(N, 10, /*Signed=*/false); return false; } @@ -1902,10 +1934,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, } } - // As a last resort, reject dummy pointers. - if (DestPtr.isDummy() || SrcPtr.isDummy()) - return false; - assert(Size.getZExtValue() % ElemSize == 0); + assert(Size.getZExtValue() % DestElemSize == 0); if (!DoMemcpy(S, OpPC, SrcPtr, DestPtr, Bytes(Size.getZExtValue()).toBits())) return false; @@ -1948,7 +1977,7 @@ static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC, !isOneByteCharacterType(PtrB.getType()))) { S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcmp_unsupported) - << ("'" + ASTCtx.BuiltinInfo.getName(ID) + "'").str() << PtrA.getType() + << ASTCtx.BuiltinInfo.getQuotedName(ID) << PtrA.getType() << PtrB.getType(); return false; } |