60#include "llvm/ADT/APFixedPoint.h"
61#include "llvm/ADT/Sequence.h"
62#include "llvm/ADT/SmallBitVector.h"
63#include "llvm/ADT/StringExtras.h"
64#include "llvm/Support/Casting.h"
65#include "llvm/Support/Debug.h"
66#include "llvm/Support/SaveAndRestore.h"
67#include "llvm/Support/SipHash.h"
68#include "llvm/Support/TimeProfiler.h"
69#include "llvm/Support/raw_ostream.h"
75#define DEBUG_TYPE "exprconstant"
78using llvm::APFixedPoint;
82using llvm::FixedPointSemantics;
89 using SourceLocExprScopeGuard =
120 static unsigned countNonVirtualBases(
const CXXRecordDecl *RD) {
121 return llvm::count_if(RD->
bases(), [](
auto &B) { return !B.isVirtual(); });
128 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
136 if (
const auto *FE = dyn_cast<FullExpr>(E))
139 if (
const auto *Cast = dyn_cast<CastExpr>(E))
140 E = Cast->getSubExpr()->IgnoreParens();
142 if (
const auto *CE = dyn_cast<CallExpr>(E))
143 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
150 const auto *E =
Base.dyn_cast<
const Expr *>();
151 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
157 static const uint64_t AssumedSizeForUnsizedArray =
158 std::numeric_limits<uint64_t>::max() / 2;
168 bool &FirstEntryIsUnsizedArray) {
171 assert(!isBaseAnAllocSizeCall(
Base) &&
172 "Unsized arrays shouldn't appear here");
173 unsigned MostDerivedLength = 0;
178 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
182 MostDerivedLength = I + 1;
185 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
186 ArraySize = CAT->getZExtSize();
188 assert(I == 0 &&
"unexpected unsized array designator");
189 FirstEntryIsUnsizedArray =
true;
190 ArraySize = AssumedSizeForUnsizedArray;
196 MostDerivedLength = I + 1;
199 Type = VT->getElementType();
200 ArraySize = VT->getNumElements();
201 MostDerivedLength = I + 1;
203 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
204 Type = FD->getType();
206 MostDerivedLength = I + 1;
214 return MostDerivedLength;
218 struct SubobjectDesignator {
222 LLVM_PREFERRED_TYPE(
bool)
226 LLVM_PREFERRED_TYPE(
bool)
227 unsigned IsOnePastTheEnd : 1;
230 LLVM_PREFERRED_TYPE(
bool)
231 unsigned FirstEntryIsAnUnsizedArray : 1;
234 LLVM_PREFERRED_TYPE(
bool)
235 unsigned MostDerivedIsArrayElement : 1;
239 unsigned MostDerivedPathLength : 28;
248 uint64_t MostDerivedArraySize;
257 SubobjectDesignator() :
Invalid(
true) {}
260 :
Invalid(
false), IsOnePastTheEnd(
false),
261 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
262 MostDerivedPathLength(0), MostDerivedArraySize(0),
263 MostDerivedType(
T.isNull() ?
QualType() :
T.getNonReferenceType()) {}
266 :
Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
267 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
268 MostDerivedPathLength(0), MostDerivedArraySize(0) {
269 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
271 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
272 llvm::append_range(Entries,
V.getLValuePath());
273 if (
V.getLValueBase()) {
274 bool IsArray =
false;
275 bool FirstIsUnsizedArray =
false;
276 MostDerivedPathLength = findMostDerivedSubobject(
277 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
278 MostDerivedType, IsArray, FirstIsUnsizedArray);
279 MostDerivedIsArrayElement = IsArray;
280 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
286 unsigned NewLength) {
290 assert(
Base &&
"cannot truncate path for null pointer");
291 assert(NewLength <= Entries.size() &&
"not a truncation");
293 if (NewLength == Entries.size())
295 Entries.resize(NewLength);
297 bool IsArray =
false;
298 bool FirstIsUnsizedArray =
false;
299 MostDerivedPathLength = findMostDerivedSubobject(
300 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
301 FirstIsUnsizedArray);
302 MostDerivedIsArrayElement = IsArray;
303 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
313 bool isMostDerivedAnUnsizedArray()
const {
314 assert(!
Invalid &&
"Calling this makes no sense on invalid designators");
315 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
320 uint64_t getMostDerivedArraySize()
const {
321 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
322 return MostDerivedArraySize;
326 bool isOnePastTheEnd()
const {
330 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
331 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
332 MostDerivedArraySize)
340 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
341 if (
Invalid || isMostDerivedAnUnsizedArray())
347 bool IsArray = MostDerivedPathLength == Entries.size() &&
348 MostDerivedIsArrayElement;
349 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
350 : (uint64_t)IsOnePastTheEnd;
352 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
353 return {ArrayIndex, ArraySize - ArrayIndex};
357 bool isValidSubobject()
const {
360 return !isOnePastTheEnd();
368 assert(!
Invalid &&
"invalid designator has no subobject type");
369 return MostDerivedPathLength == Entries.size()
380 MostDerivedIsArrayElement =
true;
382 MostDerivedPathLength = Entries.size();
386 void addUnsizedArrayUnchecked(
QualType ElemTy) {
389 MostDerivedType = ElemTy;
390 MostDerivedIsArrayElement =
true;
394 MostDerivedArraySize = AssumedSizeForUnsizedArray;
395 MostDerivedPathLength = Entries.size();
399 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
403 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
404 MostDerivedType = FD->getType();
405 MostDerivedIsArrayElement =
false;
406 MostDerivedArraySize = 0;
407 MostDerivedPathLength = Entries.size();
411 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
416 MostDerivedType = EltTy;
417 MostDerivedIsArrayElement =
true;
418 MostDerivedArraySize = 2;
419 MostDerivedPathLength = Entries.size();
422 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
425 MostDerivedType = EltTy;
426 MostDerivedPathLength = Entries.size();
427 MostDerivedArraySize = 0;
428 MostDerivedIsArrayElement =
false;
431 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
432 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
435 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
const LValue &LV);
439 enum class ScopeKind {
447 CallRef() : OrigCallee(), CallIndex(0), Version() {}
448 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
449 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
451 explicit operator bool()
const {
return OrigCallee; }
477 CallStackFrame *Caller;
499 typedef std::pair<const void *, unsigned> MapKeyTy;
500 typedef std::map<MapKeyTy, APValue>
MapTy;
512 unsigned CurTempVersion = TempVersionStack.back();
514 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
516 void pushTempVersion() {
517 TempVersionStack.push_back(++CurTempVersion);
520 void popTempVersion() {
521 TempVersionStack.pop_back();
525 return {Callee, Index, ++CurTempVersion};
536 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
537 FieldDecl *LambdaThisCaptureField =
nullptr;
539 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
545 APValue *getTemporary(
const void *Key,
unsigned Version) {
546 MapKeyTy KV(Key, Version);
547 auto LB = Temporaries.lower_bound(KV);
548 if (LB != Temporaries.end() && LB->first == KV)
554 APValue *getCurrentTemporary(
const void *Key) {
555 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
556 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
557 return &std::prev(UB)->second;
562 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
563 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
564 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
565 return std::prev(UB)->first.second;
573 template<
typename KeyT>
575 ScopeKind
Scope, LValue &LV);
580 void describe(llvm::raw_ostream &OS)
const override;
582 Frame *getCaller()
const override {
return Caller; }
583 SourceRange getCallRange()
const override {
return CallRange; }
586 bool isStdFunction()
const {
587 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
588 if (DC->isStdNamespace())
595 bool CanEvalMSConstexpr =
false;
603 class ThisOverrideRAII {
605 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
606 : Frame(Frame), OldThis(Frame.This) {
608 Frame.This = NewThis;
610 ~ThisOverrideRAII() {
611 Frame.This = OldThis;
614 CallStackFrame &Frame;
615 const LValue *OldThis;
620 class ExprTimeTraceScope {
622 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
623 : TimeScope(Name, [E, &Ctx] {
628 llvm::TimeTraceScope TimeScope;
633 struct MSConstexprContextRAII {
634 CallStackFrame &Frame;
636 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
637 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
638 Frame.CanEvalMSConstexpr =
Value;
641 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
654 llvm::PointerIntPair<APValue*, 2, ScopeKind> Value;
655 APValue::LValueBase Base;
659 Cleanup(
APValue *Val, APValue::LValueBase Base, QualType T,
661 : Value(Val, Scope), Base(Base), T(T) {}
665 bool isDestroyedAtEndOf(ScopeKind K)
const {
666 return (
int)Value.getInt() >= (
int)K;
668 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
669 if (RunDestructors) {
671 if (
const ValueDecl *VD = Base.dyn_cast<
const ValueDecl*>())
672 Loc = VD->getLocation();
673 else if (
const Expr *E = Base.dyn_cast<
const Expr*>())
674 Loc = E->getExprLoc();
677 *Value.getPointer() =
APValue();
681 bool hasSideEffect() {
682 return T.isDestructedType();
687 struct ObjectUnderConstruction {
688 APValue::LValueBase Base;
689 ArrayRef<APValue::LValuePathEntry> Path;
690 friend bool operator==(
const ObjectUnderConstruction &LHS,
691 const ObjectUnderConstruction &RHS) {
692 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
694 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
695 return llvm::hash_combine(Obj.Base, Obj.Path);
698 enum class ConstructionPhase {
709template<>
struct DenseMapInfo<ObjectUnderConstruction> {
710 using Base = DenseMapInfo<APValue::LValueBase>;
714 static bool isEqual(
const ObjectUnderConstruction &LHS,
715 const ObjectUnderConstruction &RHS) {
729 const Expr *AllocExpr =
nullptr;
740 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
741 return NE->isArray() ? ArrayNew : New;
747 struct DynAllocOrder {
748 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
770 CallStackFrame *CurrentCall;
773 unsigned CallStackDepth;
776 unsigned NextCallIndex;
785 CallStackFrame BottomFrame;
789 llvm::SmallVector<Cleanup, 16> CleanupStack;
793 APValue::LValueBase EvaluatingDecl;
795 enum class EvaluatingDeclKind {
802 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
811 SmallVector<const Stmt *> BreakContinueStack;
814 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
815 ObjectsUnderConstruction;
820 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
823 unsigned NumHeapAllocs = 0;
825 struct EvaluatingConstructorRAII {
827 ObjectUnderConstruction Object;
829 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
831 : EI(EI), Object(Object) {
833 EI.ObjectsUnderConstruction
834 .insert({Object, HasBases ? ConstructionPhase::Bases
835 : ConstructionPhase::AfterBases})
838 void finishedConstructingBases() {
839 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
841 void finishedConstructingFields() {
842 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
844 ~EvaluatingConstructorRAII() {
845 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
849 struct EvaluatingDestructorRAII {
851 ObjectUnderConstruction Object;
853 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
854 : EI(EI), Object(Object) {
855 DidInsert = EI.ObjectsUnderConstruction
856 .insert({Object, ConstructionPhase::Destroying})
859 void startedDestroyingBases() {
860 EI.ObjectsUnderConstruction[Object] =
861 ConstructionPhase::DestroyingBases;
863 ~EvaluatingDestructorRAII() {
865 EI.ObjectsUnderConstruction.erase(Object);
870 isEvaluatingCtorDtor(APValue::LValueBase Base,
871 ArrayRef<APValue::LValuePathEntry> Path) {
872 return ObjectsUnderConstruction.lookup({
Base, Path});
877 unsigned SpeculativeEvaluationDepth = 0;
883 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
884 : State(const_cast<ASTContext &>(
C), S), CurrentCall(
nullptr),
885 CallStackDepth(0), NextCallIndex(1),
886 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
887 BottomFrame(*this, SourceLocation(),
nullptr,
890 EvaluatingDecl((const ValueDecl *)
nullptr),
899 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
900 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
901 EvaluatingDecl =
Base;
902 IsEvaluatingDecl = EDK;
903 EvaluatingDeclValue = &
Value;
906 bool CheckCallLimit(SourceLocation Loc) {
909 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
911 if (NextCallIndex == 0) {
913 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
916 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
918 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
919 << getLangOpts().ConstexprCallDepth;
924 uint64_t ElemCount,
bool Diag) {
930 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
932 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
941 uint64_t Limit = getLangOpts().ConstexprStepLimit;
942 if (Limit != 0 && ElemCount > Limit) {
944 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits, 1)
945 << ElemCount << Limit;
946 Note(Loc, diag::note_constexpr_steps);
953 std::pair<CallStackFrame *, unsigned>
954 getCallFrameAndDepth(
unsigned CallIndex) {
955 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
958 unsigned Depth = CallStackDepth;
959 CallStackFrame *Frame = CurrentCall;
960 while (Frame->Index > CallIndex) {
961 Frame = Frame->Caller;
964 if (Frame->Index == CallIndex)
965 return {Frame, Depth};
969 bool nextStep(
const Stmt *S) {
970 if (getLangOpts().ConstexprStepLimit == 0)
974 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded, 1)
975 << getLangOpts().ConstexprStepLimit;
983 APValue *createHeapAlloc(
const Expr *E, QualType
T, LValue &LV);
985 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
986 std::optional<DynAlloc *>
Result;
987 auto It = HeapAllocs.find(DA);
988 if (It != HeapAllocs.end())
994 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
995 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
996 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1001 struct StdAllocatorCaller {
1002 unsigned FrameIndex;
1005 explicit operator bool()
const {
return FrameIndex != 0; };
1008 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1009 for (
const CallStackFrame *
Call = CurrentCall;
Call->Caller !=
nullptr;
1011 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1014 const IdentifierInfo *FnII = MD->getIdentifier();
1015 if (!FnII || !FnII->
isStr(FnName))
1019 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1023 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1024 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1025 if (CTSD->isInStdNamespace() && ClassII &&
1026 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1028 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1034 void performLifetimeExtension() {
1036 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1037 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1044 bool discardCleanups() {
1045 for (Cleanup &
C : CleanupStack) {
1046 if (
C.hasSideEffect() && !noteSideEffect()) {
1047 CleanupStack.clear();
1051 CleanupStack.clear();
1056 const interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1058 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1059 bool stepsLeft()
const override {
return StepsLeft > 0; }
1072 [[nodiscard]]
bool noteFailure() {
1080 bool KeepGoing = keepEvaluatingAfterFailure();
1081 EvalStatus.HasSideEffects |= KeepGoing;
1085 class ArrayInitLoopIndex {
1090 ArrayInitLoopIndex(EvalInfo &Info)
1091 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1092 Info.ArrayInitIndex = 0;
1094 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1096 operator uint64_t&() {
return Info.ArrayInitIndex; }
1101 struct FoldConstant {
1104 bool HadNoPriorDiags;
1107 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1110 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1111 Info.EvalStatus.
Diag->empty() &&
1112 !Info.EvalStatus.HasSideEffects),
1113 OldMode(Info.EvalMode) {
1115 Info.EvalMode = EvaluationMode::ConstantFold;
1117 void keepDiagnostics() { Enabled =
false; }
1119 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1120 !Info.EvalStatus.HasSideEffects) {
1121 Info.EvalStatus.Diag->clear();
1122 Info.EvalStatus.DiagEmitted =
false;
1124 Info.EvalMode = OldMode;
1130 struct IgnoreSideEffectsRAII {
1133 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1134 : Info(Info), OldMode(Info.EvalMode) {
1135 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1138 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1143 class SpeculativeEvaluationRAII {
1144 EvalInfo *Info =
nullptr;
1145 Expr::EvalStatus OldStatus;
1146 unsigned OldSpeculativeEvaluationDepth = 0;
1148 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1150 OldStatus =
Other.OldStatus;
1151 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1152 Other.Info =
nullptr;
1155 void maybeRestoreState() {
1159 Info->EvalStatus = OldStatus;
1160 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1164 SpeculativeEvaluationRAII() =
default;
1166 SpeculativeEvaluationRAII(
1167 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1168 : Info(&Info), OldStatus(Info.EvalStatus),
1169 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1170 Info.EvalStatus.Diag = NewDiag;
1171 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1174 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1175 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1176 moveFromAndCancel(std::move(
Other));
1179 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1180 maybeRestoreState();
1181 moveFromAndCancel(std::move(
Other));
1185 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1190 template<ScopeKind Kind>
1193 unsigned OldStackSize;
1195 ScopeRAII(EvalInfo &Info)
1196 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1199 Info.CurrentCall->pushTempVersion();
1201 bool destroy(
bool RunDestructors =
true) {
1202 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1203 OldStackSize = std::numeric_limits<unsigned>::max();
1207 if (OldStackSize != std::numeric_limits<unsigned>::max())
1211 Info.CurrentCall->popTempVersion();
1214 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1215 unsigned OldStackSize) {
1216 assert(OldStackSize <= Info.CleanupStack.size() &&
1217 "running cleanups out of order?");
1222 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1223 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1224 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1232 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1233 if (Kind != ScopeKind::Block)
1235 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1236 return C.isDestroyedAtEndOf(Kind);
1238 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1242 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1243 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1244 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1247bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1251 if (isOnePastTheEnd()) {
1252 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1263void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1265 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1270void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1275 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1276 Info.CCEDiag(E, diag::note_constexpr_array_index)
1278 <<
static_cast<unsigned>(getMostDerivedArraySize());
1280 Info.CCEDiag(E, diag::note_constexpr_array_index)
1285CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1286 const FunctionDecl *Callee,
const LValue *This,
1287 const Expr *CallExpr, CallRef Call)
1289 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1290 Index(Info.NextCallIndex++) {
1291 Info.CurrentCall =
this;
1292 ++Info.CallStackDepth;
1295CallStackFrame::~CallStackFrame() {
1296 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1297 --Info.CallStackDepth;
1298 Info.CurrentCall = Caller;
1323 llvm_unreachable(
"unknown access kind");
1360 llvm_unreachable(
"unknown access kind");
1364 struct ComplexValue {
1372 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1374 void makeComplexFloat() { IsInt =
false; }
1375 bool isComplexFloat()
const {
return !IsInt; }
1376 APFloat &getComplexFloatReal() {
return FloatReal; }
1377 APFloat &getComplexFloatImag() {
return FloatImag; }
1379 void makeComplexInt() { IsInt =
true; }
1380 bool isComplexInt()
const {
return IsInt; }
1381 APSInt &getComplexIntReal() {
return IntReal; }
1382 APSInt &getComplexIntImag() {
return IntImag; }
1384 void moveInto(
APValue &v)
const {
1385 if (isComplexFloat())
1386 v =
APValue(FloatReal, FloatImag);
1388 v =
APValue(IntReal, IntImag);
1390 void setFrom(
const APValue &v) {
1405 APValue::LValueBase
Base;
1407 SubobjectDesignator Designator;
1409 bool InvalidBase : 1;
1411 bool AllowConstexprUnknown =
false;
1413 const APValue::LValueBase getLValueBase()
const {
return Base; }
1414 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1415 CharUnits &getLValueOffset() {
return Offset; }
1416 CharUnits getLValueOffset()
const {
return Offset; }
1417 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1418 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1419 bool isNullPointer()
const {
return IsNullPtr;}
1421 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1422 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1424 bool pointsToCompleteClass(
const CXXRecordDecl *D)
const {
1425 if (Designator.Entries.empty())
1432 if (Designator.Invalid)
1433 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1435 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1436 V =
APValue(Base, Offset, Designator.Entries,
1437 Designator.IsOnePastTheEnd, IsNullPtr);
1439 if (AllowConstexprUnknown)
1440 V.setConstexprUnknown();
1442 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1443 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1444 Base =
V.getLValueBase();
1445 Offset =
V.getLValueOffset();
1446 InvalidBase =
false;
1447 Designator = SubobjectDesignator(Ctx,
V);
1448 IsNullPtr =
V.isNullPointer();
1449 AllowConstexprUnknown =
V.allowConstexprUnknown();
1452 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1456 const auto *E = B.
get<
const Expr *>();
1458 "Unexpected type of invalid base");
1464 InvalidBase = BInvalid;
1465 Designator = SubobjectDesignator(
getType(B));
1467 AllowConstexprUnknown =
false;
1470 void setNull(ASTContext &Ctx, QualType PointerTy) {
1471 Base = (
const ValueDecl *)
nullptr;
1474 InvalidBase =
false;
1477 AllowConstexprUnknown =
false;
1480 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1484 std::string
toString(ASTContext &Ctx, QualType
T)
const {
1486 moveInto(Printable);
1493 template <
typename GenDiagType>
1494 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1495 if (Designator.Invalid)
1499 Designator.setInvalid();
1506 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1508 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1509 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1513 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1515 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1516 if (AK == AccessKinds::AK_Dereference)
1517 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1519 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1527 Designator.checkSubobject(Info, E, CSK);
1530 void addDecl(EvalInfo &Info,
const Expr *E,
1531 const Decl *D,
bool Virtual =
false) {
1533 Designator.addDeclUnchecked(D,
Virtual);
1535 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1536 if (!Designator.Entries.empty()) {
1537 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1538 Designator.setInvalid();
1542 assert(!Base ||
getType(Base).getNonReferenceType()->isPointerType() ||
1543 getType(Base).getNonReferenceType()->isArrayType());
1544 Designator.FirstEntryIsAnUnsizedArray =
true;
1545 Designator.addUnsizedArrayUnchecked(ElemTy);
1548 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1550 Designator.addArrayUnchecked(CAT);
1552 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1554 Designator.addComplexUnchecked(EltTy, Imag);
1556 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1557 uint64_t Size, uint64_t Idx) {
1559 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1561 void clearIsNullPointer() {
1564 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1565 const APSInt &Index, CharUnits ElementSize) {
1576 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1580 Designator.adjustIndex(Info, E, Index, *
this);
1581 clearIsNullPointer();
1583 void adjustOffset(CharUnits N) {
1586 clearIsNullPointer();
1592 explicit MemberPtr(
const ValueDecl *Decl)
1593 : DeclAndIsDerivedMember(
Decl,
false) {}
1597 const ValueDecl *getDecl()
const {
1598 return DeclAndIsDerivedMember.getPointer();
1601 bool isDerivedMember()
const {
1602 return DeclAndIsDerivedMember.getInt();
1605 const CXXRecordDecl *getContainingRecord()
const {
1607 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1611 V =
APValue(getDecl(), isDerivedMember(), Path);
1614 assert(
V.isMemberPointer());
1615 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1616 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1618 llvm::append_range(Path,
V.getMemberPointerPath());
1624 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1627 SmallVector<const CXXRecordDecl*, 4> Path;
1631 bool castBack(
const CXXRecordDecl *
Class) {
1632 assert(!Path.empty());
1633 const CXXRecordDecl *Expected;
1634 if (Path.size() >= 2)
1635 Expected = Path[Path.size() - 2];
1637 Expected = getContainingRecord();
1651 bool castToDerived(
const CXXRecordDecl *Derived) {
1654 if (!isDerivedMember()) {
1655 Path.push_back(Derived);
1658 if (!castBack(Derived))
1661 DeclAndIsDerivedMember.setInt(
false);
1669 DeclAndIsDerivedMember.setInt(
true);
1670 if (isDerivedMember()) {
1671 Path.push_back(Base);
1674 return castBack(Base);
1679 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1680 if (!LHS.getDecl() || !RHS.getDecl())
1681 return !LHS.getDecl() && !RHS.getDecl();
1682 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1684 return LHS.Path == RHS.Path;
1688void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1692 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1693 if (isMostDerivedAnUnsizedArray()) {
1694 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1699 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1707 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1709 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1712 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1713 if (!Info.checkingPotentialConstantExpression() ||
1714 !LV.AllowConstexprUnknown) {
1717 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1718 (llvm::APInt &)N += ArrayIndex;
1719 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1720 diagnosePointerArithmetic(Info, E, N);
1726 ArrayIndex += TruncatedN;
1727 assert(ArrayIndex <= ArraySize &&
1728 "bounds check succeeded for out-of-bounds index");
1731 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1733 IsOnePastTheEnd = (ArrayIndex != 0);
1738 const LValue &This,
const Expr *E,
1739 bool AllowNonLiteralTypes =
false);
1741 bool InvalidBaseOK =
false);
1743 bool InvalidBaseOK =
false);
1751static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1756static std::optional<uint64_t>
1758 std::string *StringResult =
nullptr);
1775 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1776 Int = Int.extend(Int.getBitWidth() + 1);
1777 Int.setIsSigned(
true);
1782template<
typename KeyT>
1783APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType
T,
1784 ScopeKind Scope, LValue &LV) {
1785 unsigned Version = getTempVersion();
1786 APValue::LValueBase
Base(Key, Index, Version);
1788 return createLocal(Base, Key,
T, Scope);
1792APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1794 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1795 APValue::LValueBase
Base(PVD, Index, Args.Version);
1800 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1803APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1804 QualType
T, ScopeKind Scope) {
1805 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1806 unsigned Version =
Base.getVersion();
1808 assert(
Result.isAbsent() &&
"local created multiple times");
1814 if (Index <= Info.SpeculativeEvaluationDepth) {
1815 if (
T.isDestructedType())
1816 Info.noteSideEffect();
1818 Info.CleanupStack.push_back(Cleanup(&
Result, Base,
T, Scope));
1823APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType
T, LValue &LV) {
1825 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1829 DynamicAllocLValue DA(NumHeapAllocs++);
1831 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1832 std::forward_as_tuple(DA), std::tuple<>());
1833 assert(
Result.second &&
"reused a heap alloc index?");
1834 Result.first->second.AllocExpr = E;
1835 return &
Result.first->second.Value;
1839void CallStackFrame::describe(raw_ostream &Out)
const {
1840 bool IsMemberCall =
false;
1841 bool ExplicitInstanceParam =
false;
1842 clang::PrintingPolicy PrintingPolicy = Info.Ctx.getPrintingPolicy();
1845 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1847 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1851 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1854 if (This && IsMemberCall) {
1855 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1856 const Expr *
Object = MCE->getImplicitObjectArgument();
1857 Object->printPretty(Out,
nullptr, PrintingPolicy,
1859 if (
Object->getType()->isPointerType())
1863 }
else if (
const auto *OCE =
1864 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1865 OCE->getArg(0)->printPretty(Out,
nullptr, PrintingPolicy,
1870 This->moveInto(Val);
1873 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
1876 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1882 llvm::ListSeparator
Comma;
1883 for (
const ParmVarDecl *Param :
1884 Callee->parameters().slice(ExplicitInstanceParam)) {
1886 const APValue *
V = Info.getParamSlot(Arguments, Param);
1888 V->printPretty(Out, Info.Ctx, Param->getType());
1904 return Info.noteSideEffect();
1909 const auto *BaseExpr =
1910 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
1933 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1934 return VD->hasGlobalStorage();
1948 case Expr::CompoundLiteralExprClass: {
1952 case Expr::MaterializeTemporaryExprClass:
1957 case Expr::StringLiteralClass:
1958 case Expr::PredefinedExprClass:
1959 case Expr::ObjCStringLiteralClass:
1960 case Expr::ObjCEncodeExprClass:
1962 case Expr::ObjCBoxedExprClass:
1963 case Expr::ObjCArrayLiteralClass:
1964 case Expr::ObjCDictionaryLiteralClass:
1966 case Expr::CallExprClass:
1969 case Expr::AddrLabelExprClass:
1973 case Expr::BlockExprClass:
1977 case Expr::SourceLocExprClass:
1979 case Expr::ImplicitValueInitExprClass:
1989 llvm_unreachable(
"Unhandled stmt kind in switch with default?");
2006 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2011 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2012 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2020 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2021 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2022 Lit = PE->getFunctionName();
2027 AsString.
Bytes = Lit->getBytes();
2028 AsString.
CharWidth = Lit->getCharByteWidth();
2048 const LValue &RHS) {
2057 CharUnits Offset = RHS.Offset - LHS.Offset;
2058 if (Offset.isNegative()) {
2059 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2061 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2063 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2065 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2068 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2069 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2070 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2071 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2076 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2077 if (Shorter.size() + NullByte >= Longer.size())
2079 if (Longer[Shorter.size() + NullByte])
2085 return Shorter == Longer.take_front(Shorter.size());
2095 if (isa_and_nonnull<VarDecl>(
Decl)) {
2105 if (!A.getLValueBase())
2106 return !B.getLValueBase();
2107 if (!B.getLValueBase())
2110 if (A.getLValueBase().getOpaqueValue() !=
2111 B.getLValueBase().getOpaqueValue())
2114 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2115 A.getLValueVersion() == B.getLValueVersion();
2119 assert(
Base &&
"no location for a null lvalue");
2125 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2127 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2128 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2129 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2130 Idx < F->Callee->getNumParams()) {
2131 VD = F->Callee->getParamDecl(Idx);
2138 Info.Note(VD->
getLocation(), diag::note_declared_at);
2140 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2143 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2144 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2145 diag::note_constexpr_dynamic_alloc_here);
2167 bool IsCompleteClass =
true);
2179 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2188 int InvalidBaseKind = -1;
2191 InvalidBaseKind = 0;
2192 else if (isa_and_nonnull<StringLiteral>(BaseE))
2193 InvalidBaseKind = 1;
2194 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2195 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2196 InvalidBaseKind = 2;
2197 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2198 InvalidBaseKind = 3;
2199 Ident = PE->getIdentKindName();
2202 if (InvalidBaseKind != -1) {
2203 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2204 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2210 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2211 FD && FD->isImmediateFunction()) {
2212 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2214 Info.Note(FD->getLocation(), diag::note_declared_at);
2222 if (Info.getLangOpts().CPlusPlus11) {
2223 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2224 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2226 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2227 if (VarD && VarD->isConstexpr()) {
2233 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2245 assert((Info.checkingPotentialConstantExpression() ||
2246 LVal.getLValueCallIndex() == 0) &&
2247 "have call index for global lvalue");
2249 if (LVal.allowConstexprUnknown()) {
2251 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2260 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2261 << IsReferenceType << !
Designator.Entries.empty();
2267 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2269 if (Var->getTLSKind())
2278 !Var->isStaticLocal())
2282 if (Info.getLangOpts().CUDA && Var->hasAttr<HIPManagedAttr>())
2287 if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
2288 Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
2289 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2290 !Var->hasAttr<CUDAConstantAttr>() &&
2291 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2292 !Var->getType()->isCUDADeviceBuiltinTextureType()))
2296 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2308 FD->hasAttr<DLLImportAttr>())
2312 }
else if (
const auto *MTE =
2313 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2314 if (CheckedTemps.insert(MTE).second) {
2317 Info.FFDiag(MTE->getExprLoc(),
2318 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2323 APValue *
V = MTE->getOrCreateValue(
false);
2324 assert(
V &&
"evasluation result refers to uninitialised temporary");
2326 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2327 nullptr, CheckedTemps))
2334 if (!IsReferenceType)
2346 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2347 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2362 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2365 if (FD->isImmediateFunction()) {
2366 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2367 Info.Note(FD->getLocation(), diag::note_declared_at);
2371 !FD->hasAttr<DLLImportAttr>();
2377 const LValue *
This =
nullptr) {
2379 if (Info.getLangOpts().CPlusPlus23)
2398 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2402 if (Info.getLangOpts().CPlusPlus11)
2403 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2406 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2416 bool IsCompleteClass) {
2418 if (SubobjectDecl) {
2419 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2420 << 1 << SubobjectDecl;
2422 diag::note_constexpr_subobject_declared_here);
2424 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2433 Type = AT->getValueType();
2438 if (
Value.isArray()) {
2440 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2442 Value.getArrayInitializedElt(I), Kind,
2443 SubobjectDecl, CheckedTemps))
2446 if (!
Value.hasArrayFiller())
2449 Value.getArrayFiller(), Kind, SubobjectDecl,
2452 if (
Value.isUnion() &&
Value.getUnionField()) {
2455 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2457 if (
Value.isStruct()) {
2459 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2460 unsigned BaseIndex = 0;
2464 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2467 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2468 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2473 CheckedTemps,
false))
2478 for (
const auto *I : RD->fields()) {
2479 if (I->isUnnamedBitField())
2483 Value.getStructField(I->getFieldIndex()), Kind,
2488 if (IsCompleteClass) {
2489 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2490 unsigned BaseIndex = 0;
2492 assert(BS.isVirtual());
2493 const APValue &BaseValue =
Value.getStructVirtualBase(BaseIndex);
2496 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2497 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2501 BaseValue, Kind,
nullptr,
2502 CheckedTemps,
false))
2510 if (
Value.isLValue() &&
2513 LVal.setFrom(Info.Ctx,
Value);
2518 if (
Value.isMemberPointer() &&
2539 nullptr, CheckedTemps);
2549 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2555 if (!Info.HeapAllocs.empty()) {
2559 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2560 diag::note_constexpr_memory_leak)
2561 <<
unsigned(Info.HeapAllocs.size() - 1);
2569 if (!
Value.getLValueBase()) {
2622 llvm_unreachable(
"unknown APValue kind");
2628 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2638 Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType;
2639 if (
const auto *OBT = DestType->
getAs<OverflowBehaviorType>();
2640 OBT && OBT->isTrapKind()) {
2643 return Info.noteUndefinedBehavior();
2649 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2655 if (
Value.convertToInteger(
Result, llvm::APFloat::rmTowardZero, &ignored)
2656 & APFloat::opInvalidOp)
2667 llvm::RoundingMode RM =
2669 if (RM == llvm::RoundingMode::Dynamic)
2670 RM = llvm::RoundingMode::NearestTiesToEven;
2679 APFloat::opStatus St) {
2682 if (Info.InConstantContext)
2686 if ((St & APFloat::opInexact) &&
2690 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2694 if ((St != APFloat::opOK) &&
2697 FPO.getAllowFEnvAccess())) {
2698 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2702 if ((St & APFloat::opStatus::opInvalidOp) &&
2723 "HandleFloatToFloatCast has been checked with only CastExpr, "
2724 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2725 "the new expression or address the root cause of this usage.");
2727 APFloat::opStatus St;
2730 St =
Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2737 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2751 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2753 APFloat::opStatus St =
Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2759 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2761 if (!
Value.isInt()) {
2765 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2771 unsigned OldBitWidth = Int.getBitWidth();
2773 if (NewBitWidth < OldBitWidth)
2774 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2781template<
typename Operation>
2784 unsigned BitWidth, Operation Op,
2786 if (LHS.isUnsigned()) {
2791 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2794 if (Info.checkingForUndefinedBehavior())
2795 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2796 diag::warn_integer_constant_overflow)
2809 bool HandleOverflowResult =
true;
2816 std::multiplies<APSInt>(),
Result);
2819 std::plus<APSInt>(),
Result);
2822 std::minus<APSInt>(),
Result);
2823 case BO_And:
Result = LHS & RHS;
return true;
2824 case BO_Xor:
Result = LHS ^ RHS;
return true;
2825 case BO_Or:
Result = LHS | RHS;
return true;
2829 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2835 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2836 LHS.isMinSignedValue())
2838 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2839 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2840 return HandleOverflowResult;
2842 if (Info.getLangOpts().OpenCL)
2844 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2845 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2847 else if (RHS.isSigned() && RHS.isNegative()) {
2850 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2851 if (!Info.noteUndefinedBehavior())
2859 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2861 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2862 << RHS << E->
getType() << LHS.getBitWidth();
2863 if (!Info.noteUndefinedBehavior())
2865 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2870 if (LHS.isNegative()) {
2871 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2872 if (!Info.noteUndefinedBehavior())
2874 }
else if (LHS.countl_zero() < SA) {
2875 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2876 if (!Info.noteUndefinedBehavior())
2884 if (Info.getLangOpts().OpenCL)
2886 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2887 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2889 else if (RHS.isSigned() && RHS.isNegative()) {
2892 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2893 if (!Info.noteUndefinedBehavior())
2901 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2903 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2904 << RHS << E->
getType() << LHS.getBitWidth();
2905 if (!Info.noteUndefinedBehavior())
2913 case BO_LT:
Result = LHS < RHS;
return true;
2914 case BO_GT:
Result = LHS > RHS;
return true;
2915 case BO_LE:
Result = LHS <= RHS;
return true;
2916 case BO_GE:
Result = LHS >= RHS;
return true;
2917 case BO_EQ:
Result = LHS == RHS;
return true;
2918 case BO_NE:
Result = LHS != RHS;
return true;
2920 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2927 const APFloat &RHS) {
2929 APFloat::opStatus St;
2935 St = LHS.multiply(RHS, RM);
2938 St = LHS.add(RHS, RM);
2941 St = LHS.subtract(RHS, RM);
2947 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2948 St = LHS.divide(RHS, RM);
2961 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2962 return Info.noteUndefinedBehavior();
2970 const APInt &RHSValue, APInt &
Result) {
2971 bool LHS = (LHSValue != 0);
2972 bool RHS = (RHSValue != 0);
2974 if (Opcode == BO_LAnd)
2982 const APFloat &RHSValue, APInt &
Result) {
2983 bool LHS = !LHSValue.isZero();
2984 bool RHS = !RHSValue.isZero();
2986 if (Opcode == BO_LAnd)
3005template <
typename APTy>
3008 const APTy &RHSValue, APInt &
Result) {
3011 llvm_unreachable(
"unsupported binary operator");
3013 Result = (LHSValue == RHSValue);
3016 Result = (LHSValue != RHSValue);
3019 Result = (LHSValue < RHSValue);
3022 Result = (LHSValue > RHSValue);
3025 Result = (LHSValue <= RHSValue);
3028 Result = (LHSValue >= RHSValue);
3057 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3058 "Operation not supported on vector types");
3062 QualType EltTy = VT->getElementType();
3069 "A vector result that isn't a vector OR uncalculated LValue");
3075 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3079 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3084 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3094 RHSElt.
getInt(), EltResult);
3100 ResultElements.emplace_back(EltResult);
3105 "Mismatched LHS/RHS/Result Type");
3106 APFloat LHSFloat = LHSElt.
getFloat();
3114 ResultElements.emplace_back(LHSFloat);
3118 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3126 unsigned TruncatedElements) {
3127 SubobjectDesignator &D =
Result.Designator;
3130 if (TruncatedElements == D.Entries.size())
3132 assert(TruncatedElements >= D.MostDerivedPathLength &&
3133 "not casting to a derived class");
3139 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3143 if (isVirtualBaseClass(D.Entries[I]))
3149 D.Entries.resize(TruncatedElements);
3159 RL = &Info.Ctx.getASTRecordLayout(Derived);
3162 Obj.addDecl(Info, E,
Base,
false);
3163 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3175 RL = &Info.Ctx.getASTRecordLayout(Derived);
3178 Obj.addDecl(Info, E,
Base,
true);
3179 Obj.getLValueOffset() += RL->getVBaseClassOffset(
Base);
3188 if (!
Base->isVirtual())
3191 SubobjectDesignator &D = Obj.Designator;
3206 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3207 Obj.addDecl(Info, E, BaseDecl,
true);
3216 PathI != PathE; ++PathI) {
3220 Type = (*PathI)->getType();
3232 llvm_unreachable(
"Class must be derived from the passed in base class!");
3256 RL = &Info.Ctx.getASTRecordLayout(RD);
3260 LVal.addDecl(Info, E, FD);
3261 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3269 for (
const auto *
C : IFD->
chain())
3303 Size = Info.Ctx.getTypeSizeInChars(
Type);
3305 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3322 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3328 int64_t Adjustment) {
3330 APSInt::get(Adjustment));
3345 LVal.Offset += SizeOfComponent;
3347 LVal.addComplex(Info, E, EltTy, Imag);
3353 uint64_t Size, uint64_t Idx) {
3358 LVal.Offset += SizeOfElement * Idx;
3360 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3374 const VarDecl *VD, CallStackFrame *Frame,
3378 bool AllowConstexprUnknown =
3383 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3395 if (!AllowConstexprUnknown || IsLocalVariable) {
3396 if (!Info.checkingPotentialConstantExpression())
3397 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3407 Result = Frame->getTemporary(VD, Version);
3409 return CheckUninitReference(
true);
3418 "missing value for local variable");
3419 if (Info.checkingPotentialConstantExpression())
3423 "A variable in a frame should either be a local or a parameter");
3429 if (Info.EvaluatingDecl ==
Base) {
3430 Result = Info.EvaluatingDeclValue;
3431 return CheckUninitReference(
false);
3439 if (AllowConstexprUnknown) {
3446 if (!Info.checkingPotentialConstantExpression() ||
3447 !Info.CurrentCall->Callee ||
3449 if (Info.getLangOpts().CPlusPlus11) {
3450 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3471 if (!
Init && !AllowConstexprUnknown) {
3474 if (!Info.checkingPotentialConstantExpression()) {
3475 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3486 if (
Init &&
Init->isValueDependent()) {
3487 if (!Info.checkingPotentialConstantExpression()) {
3489 Info.getLangOpts().CPlusPlus11
3490 ? diag::note_constexpr_ltor_non_constexpr
3491 : diag::note_constexpr_ltor_non_integral,
3499 if (
Init->containsErrors())
3518 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3534 !AllowConstexprUnknown) ||
3535 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3538 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3548 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3555 if (!
Result && !AllowConstexprUnknown)
3558 return CheckUninitReference(
false);
3581 llvm_unreachable(
"base class missing from derived class's bases list");
3588 "SourceLocExpr should have already been converted to a StringLiteral");
3591 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3593 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3594 assert(Index <= Str.size() &&
"Index too large");
3595 return APSInt::getUnsigned(Str.c_str()[Index]);
3598 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3599 Lit = PE->getFunctionName();
3602 Info.Ctx.getAsConstantArrayType(S->
getType());
3603 assert(CAT &&
"string literal isn't an array");
3605 assert(CharType->
isIntegerType() &&
"unexpected character type");
3608 if (Index < S->getLength())
3621 AllocType.isNull() ? S->
getType() : AllocType);
3622 assert(CAT &&
"string literal isn't an array");
3624 assert(CharType->
isIntegerType() &&
"unexpected character type");
3631 if (
Result.hasArrayFiller())
3633 for (
unsigned I = 0, N =
Result.getArrayInitializedElts(); I != N; ++I) {
3641 unsigned Size =
Array.getArraySize();
3642 assert(Index < Size);
3645 unsigned OldElts =
Array.getArrayInitializedElts();
3646 unsigned NewElts = std::max(Index+1, OldElts * 2);
3647 NewElts = std::min(Size, std::max(NewElts, 8u));
3651 for (
unsigned I = 0; I != OldElts; ++I)
3653 for (
unsigned I = OldElts; I != NewElts; ++I)
3657 Array.swap(NewValue);
3664 Vec =
APValue(Elts.data(), Elts.size());
3674 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3685 for (
auto *Field : RD->
fields())
3686 if (!Field->isUnnamedBitField() &&
3690 for (
auto &BaseSpec : RD->
bases())
3701 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3708 for (
auto *Field : RD->
fields()) {
3713 if (Field->isMutable() &&
3715 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3716 Info.Note(Field->getLocation(), diag::note_declared_at);
3724 for (
auto &BaseSpec : RD->
bases())
3734 bool MutableSubobject =
false) {
3739 switch (Info.IsEvaluatingDecl) {
3740 case EvalInfo::EvaluatingDeclKind::None:
3743 case EvalInfo::EvaluatingDeclKind::Ctor:
3745 if (Info.EvaluatingDecl ==
Base)
3750 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3751 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3752 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3755 case EvalInfo::EvaluatingDeclKind::Dtor:
3760 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3766 return T.isConstQualified() ||
T->isReferenceType();
3769 llvm_unreachable(
"unknown evaluating decl kind");
3774 return Info.CheckArraySize(
3794 uint64_t IntResult = BoolResult;
3797 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3798 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3803 Info.Ctx.getIntTypeForBitwidth(64,
false),
3806 Result = std::move(Result2);
3814 DestTy,
Result.getFloat());
3820 uint64_t IntResult = BoolResult;
3839 uint64_t IntResult = BoolResult;
3846 DestTy,
Result.getInt());
3850 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3863 {&
Result, ResultType, 0}};
3866 while (!WorkList.empty() && ElI < Elements.size()) {
3867 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3883 APSInt &Int = Res->getInt();
3884 unsigned OldBitWidth = Int.getBitWidth();
3885 unsigned NewBitWidth = BitWidth;
3886 if (NewBitWidth < OldBitWidth)
3887 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3896 for (
unsigned I = 0; I < NumEl; ++I) {
3902 *Res =
APValue(Vals.data(), NumEl);
3911 for (int64_t I = Size - 1; I > -1; --I)
3912 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3918 unsigned NumBases = 0;
3919 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3920 NumBases = CXXRD->getNumBases();
3927 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3928 if (CXXRD->getNumBases() > 0) {
3929 assert(CXXRD->getNumBases() == 1);
3931 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3938 if (FD->isUnnamedBitField())
3940 if (FD->isBitField()) {
3941 FDBW = FD->getBitWidthValue();
3944 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3945 FD->getType(), FDBW);
3948 std::reverse(ReverseList.begin(), ReverseList.end());
3949 llvm::append_range(WorkList, ReverseList);
3952 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3965 assert((Elements.size() == SrcTypes.size()) &&
3966 (Elements.size() == DestTypes.size()));
3968 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
3969 APValue Original = Elements[I];
3973 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
3984 while (!WorkList.empty()) {
4007 for (uint64_t I = 0; I < ArrSize; ++I) {
4008 WorkList.push_back(ElTy);
4016 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4017 if (CXXRD->getNumBases() > 0) {
4018 assert(CXXRD->getNumBases() == 1);
4020 WorkList.push_back(BS.
getType());
4026 if (FD->isUnnamedBitField())
4028 WorkList.push_back(FD->getType());
4045 "Not a valid HLSLAggregateSplatCast.");
4065 unsigned Populated = 0;
4066 while (!WorkList.empty() && Populated < Size) {
4067 auto [Work,
Type] = WorkList.pop_back_val();
4069 if (Work.isFloat() || Work.isInt()) {
4070 Elements.push_back(Work);
4071 Types.push_back(
Type);
4075 if (Work.isVector()) {
4078 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4080 Elements.push_back(Work.getVectorElt(I));
4081 Types.push_back(ElTy);
4086 if (Work.isMatrix()) {
4089 QualType ElTy = MT->getElementType();
4091 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4093 for (
unsigned Col = 0;
4094 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4095 Elements.push_back(Work.getMatrixElt(Row, Col));
4096 Types.push_back(ElTy);
4102 if (Work.isArray()) {
4106 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4107 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4112 if (Work.isStruct()) {
4120 if (FD->isUnnamedBitField())
4122 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4126 std::reverse(ReverseList.begin(), ReverseList.end());
4127 llvm::append_range(WorkList, ReverseList);
4130 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4131 if (CXXRD->getNumBases() > 0) {
4132 assert(CXXRD->getNumBases() == 1);
4137 if (!
Base.isStruct())
4145 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4154struct CompleteObject {
4156 APValue::LValueBase
Base;
4166 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4177 if (!Info.getLangOpts().CPlusPlus14 &&
4178 AK != AccessKinds::AK_IsWithinLifetime)
4183 explicit operator bool()
const {
return !
Type.isNull(); }
4188 bool IsMutable =
false) {
4202template <
typename Sub
objectHandler>
4203static typename SubobjectHandler::result_type
4205 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4208 return handler.failed();
4209 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4210 if (Info.getLangOpts().CPlusPlus11)
4211 Info.FFDiag(E, Sub.isOnePastTheEnd()
4212 ? diag::note_constexpr_access_past_end
4213 : diag::note_constexpr_access_unsized_array)
4214 << handler.AccessKind;
4217 return handler.failed();
4223 const FieldDecl *VolatileField =
nullptr;
4226 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4237 if (!Info.checkingPotentialConstantExpression()) {
4238 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4243 return handler.failed();
4251 Info.isEvaluatingCtorDtor(
4252 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4253 ConstructionPhase::None) {
4254 ObjType = Info.Ctx.getCanonicalType(ObjType);
4263 if (Info.getLangOpts().CPlusPlus) {
4267 if (VolatileField) {
4270 Decl = VolatileField;
4273 Loc = VD->getLocation();
4280 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4281 << handler.AccessKind << DiagKind <<
Decl;
4282 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4284 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4286 return handler.failed();
4294 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4296 return handler.failed();
4300 if (!handler.found(*O, ObjType, Obj.Base))
4312 LastField =
nullptr;
4317 ObjType = Info.Ctx.getQualifiedType(AT->getValueType(),
4322 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4324 "vla in literal type?");
4325 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4326 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4327 CAT && CAT->
getSize().ule(Index)) {
4330 if (Info.getLangOpts().CPlusPlus11)
4331 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4332 << handler.AccessKind;
4335 return handler.failed();
4342 else if (!
isRead(handler.AccessKind)) {
4343 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4345 return handler.failed();
4353 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4355 if (Info.getLangOpts().CPlusPlus11)
4356 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4357 << handler.AccessKind;
4360 return handler.failed();
4366 assert(I == N - 1 &&
"extracting subobject of scalar?");
4376 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4377 unsigned NumElements = VT->getNumElements();
4378 if (Index == NumElements) {
4379 if (Info.getLangOpts().CPlusPlus11)
4380 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4381 << handler.AccessKind;
4384 return handler.failed();
4387 if (Index > NumElements) {
4388 Info.CCEDiag(E, diag::note_constexpr_array_index)
4389 << Index << 0 << NumElements;
4390 return handler.failed();
4393 ObjType = VT->getElementType();
4394 assert(I == N - 1 &&
"extracting subobject of scalar?");
4397 if (
isRead(handler.AccessKind)) {
4399 return handler.failed();
4403 assert(O->
isVector() &&
"unexpected object during vector element access");
4404 return handler.found(O->
getVectorElt(Index), ObjType, Obj.Base);
4405 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4406 if (Field->isMutable() &&
4407 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4408 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4409 << handler.AccessKind << Field;
4410 Info.Note(Field->getLocation(), diag::note_declared_at);
4411 return handler.failed();
4420 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4431 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4432 << handler.AccessKind << Field << !UnionField << UnionField;
4433 return handler.failed();
4442 if (Field->getType().isVolatileQualified())
4443 VolatileField = Field;
4451 if (BaseIndex >= NumNonVirtualBases) {
4462struct ExtractSubobjectHandler {
4468 typedef bool result_type;
4469 bool failed() {
return false; }
4470 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4480 bool found(APFloat &
Value, QualType SubobjType) {
4489 const CompleteObject &Obj,
4493 ExtractSubobjectHandler Handler = {Info, E,
Result, AK};
4498struct ModifySubobjectHandler {
4503 typedef bool result_type;
4506 bool checkConst(QualType QT) {
4509 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4515 bool failed() {
return false; }
4516 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4517 if (!checkConst(SubobjType))
4520 Subobj.
swap(NewVal);
4524 if (!checkConst(SubobjType))
4526 if (!NewVal.
isInt()) {
4534 bool found(APFloat &
Value, QualType SubobjType) {
4535 if (!checkConst(SubobjType))
4543const AccessKinds ModifySubobjectHandler::AccessKind;
4547 const CompleteObject &Obj,
4548 const SubobjectDesignator &Sub,
4550 ModifySubobjectHandler Handler = { Info, NewVal, E };
4557 const SubobjectDesignator &A,
4558 const SubobjectDesignator &B,
4559 bool &WasArrayIndex) {
4560 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4561 for (; I != N; ++I) {
4565 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4566 WasArrayIndex =
true;
4574 if (A.Entries[I].getAsBaseOrMember() !=
4575 B.Entries[I].getAsBaseOrMember()) {
4576 WasArrayIndex =
false;
4579 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4581 ObjType = FD->getType();
4587 WasArrayIndex =
false;
4594 const SubobjectDesignator &A,
4595 const SubobjectDesignator &B) {
4596 if (A.Entries.size() != B.Entries.size())
4599 bool IsArray = A.MostDerivedIsArrayElement;
4600 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4609 return CommonLength >= A.Entries.size() - IsArray;
4616 if (LVal.InvalidBase) {
4618 return CompleteObject();
4623 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4625 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4626 return CompleteObject();
4629 CallStackFrame *Frame =
nullptr;
4631 if (LVal.getLValueCallIndex()) {
4632 std::tie(Frame, Depth) =
4633 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4635 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4638 return CompleteObject();
4649 if (Info.getLangOpts().CPlusPlus)
4650 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4654 return CompleteObject();
4661 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4665 BaseVal = Info.EvaluatingDeclValue;
4668 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4671 Info.FFDiag(E, diag::note_constexpr_modify_global);
4672 return CompleteObject();
4676 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4678 return CompleteObject();
4680 return CompleteObject(LVal.Base, &
V, GD->getType());
4684 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4686 Info.FFDiag(E, diag::note_constexpr_modify_global);
4687 return CompleteObject();
4689 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4694 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4696 Info.FFDiag(E, diag::note_constexpr_modify_global);
4697 return CompleteObject();
4699 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4710 const VarDecl *VD = dyn_cast<VarDecl>(D);
4717 return CompleteObject();
4720 bool IsConstant = BaseType.isConstant(Info.Ctx);
4721 bool ConstexprVar =
false;
4722 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4734 }
else if (Info.getLangOpts().CPlusPlus14 &&
4741 Info.FFDiag(E, diag::note_constexpr_modify_global);
4742 return CompleteObject();
4745 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4747 return CompleteObject();
4750 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4751 Info.FFDiag(E, diag::note_constexpr_ltor_for_range_var) << VD;
4752 return CompleteObject();
4753 }
else if (BaseType->isIntegralOrEnumerationType()) {
4756 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4757 if (Info.getLangOpts().CPlusPlus) {
4758 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4759 Info.Note(VD->
getLocation(), diag::note_declared_at);
4763 return CompleteObject();
4765 }
else if (!IsAccess) {
4766 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4767 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4768 Info.checkingPotentialConstantExpression() &&
4769 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4771 }
else if (IsConstant) {
4775 if (Info.getLangOpts().CPlusPlus) {
4776 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4777 ? diag::note_constexpr_ltor_non_constexpr
4778 : diag::note_constexpr_ltor_non_integral, 1)
4780 Info.Note(VD->
getLocation(), diag::note_declared_at);
4786 if (Info.getLangOpts().CPlusPlus) {
4787 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4788 ? diag::note_constexpr_ltor_non_constexpr
4789 : diag::note_constexpr_ltor_non_integral, 1)
4791 Info.Note(VD->
getLocation(), diag::note_declared_at);
4795 return CompleteObject();
4804 return CompleteObject();
4809 if (!Info.checkingPotentialConstantExpression()) {
4810 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4812 Info.Note(VD->getLocation(), diag::note_declared_at);
4814 return CompleteObject();
4817 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4819 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4820 return CompleteObject();
4822 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4832 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4833 assert(MTE->getStorageDuration() ==
SD_Static &&
4834 "should have a frame for a non-global materialized temporary");
4861 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4864 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4865 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4866 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4867 return CompleteObject();
4870 BaseVal = MTE->getOrCreateValue(
false);
4871 assert(BaseVal &&
"got reference to unevaluated temporary");
4873 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4889 !CLETy.isConstant(Info.Ctx)) {
4891 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4892 return CompleteObject();
4895 BaseVal = &CLE->getStaticValue();
4898 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4901 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4904 Info.Ctx.getLValueReferenceType(LValType));
4906 return CompleteObject();
4910 assert(BaseVal &&
"missing value for temporary");
4921 unsigned VisibleDepth = Depth;
4922 if (llvm::isa_and_nonnull<ParmVarDecl>(
4925 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4926 Info.EvalStatus.HasSideEffects) ||
4927 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4928 return CompleteObject();
4930 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4949 const LValue &LVal,
APValue &RVal,
4950 bool WantObjectRepresentation =
false) {
4951 if (LVal.Designator.Invalid)
4960 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4964 assert(LVal.Designator.Entries.size() <= 1 &&
4965 "Can only read characters from string literals");
4966 if (LVal.Designator.Entries.empty()) {
4973 if (LVal.Designator.isOnePastTheEnd()) {
4974 if (Info.getLangOpts().CPlusPlus11)
4975 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4980 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4987 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
5001 LVal.setFrom(Info.Ctx, Val);
5017 if (LVal.Designator.Invalid)
5020 if (!Info.getLangOpts().CPlusPlus14) {
5030struct CompoundAssignSubobjectHandler {
5032 const CompoundAssignOperator *E;
5033 QualType PromotedLHSType;
5039 typedef bool result_type;
5041 bool checkConst(QualType QT) {
5044 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5050 bool failed() {
return false; }
5051 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5054 return found(Subobj.
getInt(), SubobjType);
5056 return found(Subobj.
getFloat(), SubobjType);
5063 return foundPointer(Subobj, SubobjType);
5065 return foundVector(Subobj, SubobjType);
5067 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5079 bool foundVector(
APValue &
Value, QualType SubobjType) {
5080 if (!checkConst(SubobjType))
5091 if (!checkConst(SubobjType))
5110 Info.Ctx.getLangOpts());
5113 PromotedLHSType, FValue) &&
5122 bool found(APFloat &
Value, QualType SubobjType) {
5123 return checkConst(SubobjType) &&
5129 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5130 if (!checkConst(SubobjType))
5133 QualType PointeeType;
5134 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5138 (Opcode != BO_Add && Opcode != BO_Sub)) {
5144 if (Opcode == BO_Sub)
5148 LVal.setFrom(Info.Ctx, Subobj);
5151 LVal.moveInto(Subobj);
5157const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5162 const LValue &LVal,
QualType LValType,
5166 if (LVal.Designator.Invalid)
5169 if (!Info.getLangOpts().CPlusPlus14) {
5175 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5177 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5181struct IncDecSubobjectHandler {
5183 const UnaryOperator *E;
5187 typedef bool result_type;
5189 bool checkConst(QualType QT) {
5192 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5198 bool failed() {
return false; }
5199 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5209 return found(Subobj.
getInt(), SubobjType);
5211 return found(Subobj.
getFloat(), SubobjType);
5214 SubobjType->
castAs<ComplexType>()->getElementType()
5218 SubobjType->
castAs<ComplexType>()->getElementType()
5221 return foundPointer(Subobj, SubobjType);
5229 if (!checkConst(SubobjType))
5251 bool WasNegative =
Value.isNegative();
5265 unsigned BitWidth =
Value.getBitWidth();
5266 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5267 ActualValue.setBit(BitWidth);
5273 bool found(APFloat &
Value, QualType SubobjType) {
5274 if (!checkConst(SubobjType))
5281 APFloat::opStatus St;
5283 St =
Value.add(One, RM);
5285 St =
Value.subtract(One, RM);
5288 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5289 if (!checkConst(SubobjType))
5292 QualType PointeeType;
5293 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5301 LVal.setFrom(Info.Ctx, Subobj);
5305 LVal.moveInto(Subobj);
5314 if (LVal.Designator.Invalid)
5317 if (!Info.getLangOpts().CPlusPlus14) {
5325 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5331 if (
Object->getType()->isPointerType() &&
Object->isPRValue())
5337 if (
Object->getType()->isLiteralType(Info.Ctx))
5340 if (
Object->getType()->isRecordType() &&
Object->isPRValue())
5343 Info.FFDiag(
Object, diag::note_constexpr_nonliteral) <<
Object->getType();
5362 bool IncludeMember =
true) {
5369 if (!MemPtr.getDecl()) {
5375 if (MemPtr.isDerivedMember()) {
5382 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5383 LV.Designator.Entries.size()) {
5387 unsigned PathLengthToMember =
5388 LV.Designator.Entries.size() - MemPtr.Path.size();
5389 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5391 LV.Designator.Entries[PathLengthToMember + I]);
5408 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5409 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5411 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5419 PathLengthToMember))
5421 }
else if (!MemPtr.Path.empty()) {
5423 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5424 MemPtr.Path.size() + IncludeMember);
5430 assert(RD &&
"member pointer access on non-class-type expression");
5432 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5440 MemPtr.getContainingRecord()))
5445 if (IncludeMember) {
5446 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5450 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5454 llvm_unreachable(
"can't construct reference to bound member function");
5458 return MemPtr.getDecl();
5464 bool IncludeMember =
true) {
5468 if (Info.noteFailure()) {
5476 BO->
getRHS(), IncludeMember);
5483 SubobjectDesignator &D =
Result.Designator;
5491 auto InvalidCast = [&]() {
5492 if (!Info.checkingPotentialConstantExpression() ||
5493 !
Result.AllowConstexprUnknown) {
5494 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5495 << D.MostDerivedType << TargetQT;
5501 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5502 return InvalidCast();
5506 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5509 if (NewEntriesSize == D.MostDerivedPathLength)
5512 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5514 return InvalidCast();
5523 bool IsCompleteClass =
true) {
5530 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5531 if (RD->isInvalidDecl()) {
5535 if (RD->isUnion()) {
5541 unsigned NonVirtualBases = countNonVirtualBases(RD);
5544 IsCompleteClass ? RD->getNumVBases() : 0);
5555 for (
const auto *I : RD->fields()) {
5556 if (I->isUnnamedBitField())
5559 I->getType(),
Result.getStructField(I->getFieldIndex()));
5562 if (IsCompleteClass) {
5565 for (
const auto &B : RD->vbases()) {
5567 Result.getStructVirtualBase(Index),
5573 assert(
Result.getStructNumVirtualBases() == 0);
5580 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5582 if (
Result.hasArrayFiller())
5593enum EvalStmtResult {
5622 if (!
Result.Designator.Invalid &&
Result.Designator.isOnePastTheEnd()) {
5640 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5641 ScopeKind::Block,
Result);
5646 return Info.noteSideEffect();
5667 const DecompositionDecl *DD);
5670 bool EvaluateConditionDecl =
false) {
5672 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5676 EvaluateConditionDecl && DD)
5686 if (
auto *VD = BD->getHoldingVar())
5694 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5703 if (Info.noteSideEffect())
5705 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5706 "reach invalid code path.");
5715 FullExpressionRAII
Scope(Info);
5722 return Scope.destroy();
5735struct TempVersionRAII {
5736 CallStackFrame &Frame;
5738 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5739 Frame.pushTempVersion();
5742 ~TempVersionRAII() {
5743 Frame.popTempVersion();
5751 const SwitchCase *SC =
nullptr);
5757 const Stmt *LoopOrSwitch,
5759 EvalStmtResult &ESR) {
5763 if (!IsSwitch && ESR == ESR_Succeeded) {
5768 if (ESR != ESR_Break && ESR != ESR_Continue)
5772 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5773 const Stmt *StackTop = Info.BreakContinueStack.back();
5774 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5775 Info.BreakContinueStack.pop_back();
5776 if (ESR == ESR_Break)
5777 ESR = ESR_Succeeded;
5782 for (BlockScopeRAII *S : Scopes) {
5783 if (!S->destroy()) {
5795 BlockScopeRAII
Scope(Info);
5798 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5807 BlockScopeRAII
Scope(Info);
5814 if (ESR != ESR_Succeeded) {
5815 if (ESR != ESR_Failed && !
Scope.destroy())
5821 FullExpressionRAII CondScope(Info);
5836 if (!CondScope.destroy())
5857 if (LHSValue <=
Value &&
Value <= RHSValue) {
5864 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5868 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5875 llvm_unreachable(
"Should have been converted to Succeeded");
5881 case ESR_CaseNotFound:
5884 Info.FFDiag(
Found->getBeginLoc(),
5885 diag::note_constexpr_stmt_expr_unsupported);
5888 llvm_unreachable(
"Invalid EvalStmtResult!");
5898 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5908 if (!Info.nextStep(S))
5915 case Stmt::CompoundStmtClass:
5919 case Stmt::LabelStmtClass:
5920 case Stmt::AttributedStmtClass:
5921 case Stmt::DoStmtClass:
5924 case Stmt::CaseStmtClass:
5925 case Stmt::DefaultStmtClass:
5930 case Stmt::IfStmtClass: {
5937 BlockScopeRAII
Scope(Info);
5943 if (ESR != ESR_CaseNotFound) {
5944 assert(ESR != ESR_Succeeded);
5955 if (ESR == ESR_Failed)
5957 if (ESR != ESR_CaseNotFound)
5958 return Scope.destroy() ? ESR : ESR_Failed;
5960 return ESR_CaseNotFound;
5963 if (ESR == ESR_Failed)
5965 if (ESR != ESR_CaseNotFound)
5966 return Scope.destroy() ? ESR : ESR_Failed;
5967 return ESR_CaseNotFound;
5970 case Stmt::WhileStmtClass: {
5971 EvalStmtResult ESR =
5975 if (ESR != ESR_Continue)
5980 case Stmt::ForStmtClass: {
5982 BlockScopeRAII
Scope(Info);
5988 if (ESR != ESR_CaseNotFound) {
5989 assert(ESR != ESR_Succeeded);
5994 EvalStmtResult ESR =
5998 if (ESR != ESR_Continue)
6000 if (
const auto *Inc = FS->
getInc()) {
6001 if (Inc->isValueDependent()) {
6005 FullExpressionRAII IncScope(Info);
6013 case Stmt::DeclStmtClass: {
6017 for (
const auto *D : DS->
decls()) {
6018 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
6021 if (VD->hasLocalStorage() && !VD->getInit())
6029 return ESR_CaseNotFound;
6033 return ESR_CaseNotFound;
6039 if (
const Expr *E = dyn_cast<Expr>(S)) {
6048 FullExpressionRAII
Scope(Info);
6052 return ESR_Succeeded;
6058 case Stmt::NullStmtClass:
6059 return ESR_Succeeded;
6061 case Stmt::DeclStmtClass: {
6063 for (
const auto *D : DS->
decls()) {
6064 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
6068 if (
const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6069 assert(ESD->getInstantiations() &&
"not expanded?");
6074 FullExpressionRAII
Scope(Info);
6076 !Info.noteFailure())
6078 if (!
Scope.destroy())
6081 return ESR_Succeeded;
6084 case Stmt::ReturnStmtClass: {
6086 FullExpressionRAII
Scope(Info);
6097 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6100 case Stmt::CompoundStmtClass: {
6101 BlockScopeRAII
Scope(Info);
6104 for (
const auto *BI : CS->
body()) {
6106 if (ESR == ESR_Succeeded)
6108 else if (ESR != ESR_CaseNotFound) {
6109 if (ESR != ESR_Failed && !
Scope.destroy())
6115 return ESR_CaseNotFound;
6116 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6119 case Stmt::IfStmtClass: {
6123 BlockScopeRAII
Scope(Info);
6126 if (ESR != ESR_Succeeded) {
6127 if (ESR != ESR_Failed && !
Scope.destroy())
6137 if (!Info.InConstantContext)
6145 if (ESR != ESR_Succeeded) {
6146 if (ESR != ESR_Failed && !
Scope.destroy())
6151 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6154 case Stmt::WhileStmtClass: {
6157 BlockScopeRAII
Scope(Info);
6169 if (ESR != ESR_Continue) {
6170 if (ESR != ESR_Failed && !
Scope.destroy())
6174 if (!
Scope.destroy())
6177 return ESR_Succeeded;
6180 case Stmt::DoStmtClass: {
6187 if (ESR != ESR_Continue)
6196 FullExpressionRAII CondScope(Info);
6198 !CondScope.destroy())
6201 return ESR_Succeeded;
6204 case Stmt::ForStmtClass: {
6206 BlockScopeRAII ForScope(Info);
6209 if (ESR != ESR_Succeeded) {
6210 if (ESR != ESR_Failed && !ForScope.destroy())
6216 BlockScopeRAII IterScope(Info);
6217 bool Continue =
true;
6223 if (!IterScope.destroy())
6231 if (ESR != ESR_Continue) {
6232 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6237 if (
const auto *Inc = FS->
getInc()) {
6238 if (Inc->isValueDependent()) {
6242 FullExpressionRAII IncScope(Info);
6248 if (!IterScope.destroy())
6251 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6254 case Stmt::CXXForRangeStmtClass: {
6256 BlockScopeRAII
Scope(Info);
6261 if (ESR != ESR_Succeeded) {
6262 if (ESR != ESR_Failed && !
Scope.destroy())
6270 if (ESR != ESR_Succeeded) {
6271 if (ESR != ESR_Failed && !
Scope.destroy())
6283 if (ESR != ESR_Succeeded) {
6284 if (ESR != ESR_Failed && !
Scope.destroy())
6289 if (ESR != ESR_Succeeded) {
6290 if (ESR != ESR_Failed && !
Scope.destroy())
6303 bool Continue =
true;
6304 FullExpressionRAII CondExpr(Info);
6312 BlockScopeRAII InnerScope(Info);
6314 if (ESR != ESR_Succeeded) {
6315 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6324 if (ESR != ESR_Continue) {
6325 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6338 if (!InnerScope.destroy())
6342 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6345 case Stmt::CXXExpansionStmtInstantiationClass: {
6346 BlockScopeRAII
Scope(Info);
6348 for (
const Stmt *PreambleStmt : Expansion->getPreambleStmts()) {
6350 if (ESR != ESR_Succeeded) {
6351 if (ESR != ESR_Failed && !
Scope.destroy())
6359 EvalStmtResult ESR = ESR_Succeeded;
6360 for (
const Stmt *Instantiation : Expansion->getInstantiations()) {
6362 if (ESR == ESR_Failed ||
6365 if (ESR != ESR_Continue) {
6367 assert(ESR == ESR_Succeeded || ESR == ESR_Returned);
6373 if (ESR == ESR_Continue)
6374 ESR = ESR_Succeeded;
6376 return Scope.destroy() ? ESR : ESR_Failed;
6379 case Stmt::SwitchStmtClass:
6382 case Stmt::ContinueStmtClass:
6383 case Stmt::BreakStmtClass: {
6385 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6389 case Stmt::LabelStmtClass:
6392 case Stmt::AttributedStmtClass: {
6394 const auto *SS = AS->getSubStmt();
6395 MSConstexprContextRAII ConstexprContext(
6399 auto LO = Info.Ctx.getLangOpts();
6400 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6401 for (
auto *
Attr : AS->getAttrs()) {
6402 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6406 auto *Assumption = AA->getAssumption();
6407 if (Assumption->isValueDependent())
6410 if (Assumption->HasSideEffects(Info.Ctx))
6417 Info.CCEDiag(Assumption->getExprLoc(),
6418 diag::note_constexpr_assumption_failed);
6427 case Stmt::CaseStmtClass:
6428 case Stmt::DefaultStmtClass:
6430 case Stmt::CXXTryStmtClass:
6442 bool IsValueInitialization) {
6449 if (!CD->
isConstexpr() && !IsValueInitialization) {
6450 if (Info.getLangOpts().CPlusPlus11) {
6453 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6455 Info.Note(CD->
getLocation(), diag::note_declared_at);
6457 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6471 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6479 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6488 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6491 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6497 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6507 StringRef Name = DiagDecl->
getName();
6509 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6511 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6516 if (Info.getLangOpts().CPlusPlus11) {
6519 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6520 if (CD && CD->isInheritingConstructor()) {
6521 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6522 if (!Inherited->isConstexpr())
6523 DiagDecl = CD = Inherited;
6529 if (CD && CD->isInheritingConstructor())
6530 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6531 << CD->getInheritedConstructor().getConstructor()->getParent();
6533 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6535 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6537 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6543struct CheckDynamicTypeHandler {
6545 typedef bool result_type;
6546 bool failed() {
return false; }
6547 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6550 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6551 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6559 if (
This.Designator.Invalid)
6571 if (
This.Designator.isOnePastTheEnd() ||
6572 This.Designator.isMostDerivedAnUnsizedArray()) {
6573 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6574 ? diag::note_constexpr_access_past_end
6575 : diag::note_constexpr_access_unsized_array)
6578 }
else if (Polymorphic) {
6581 if (!Info.checkingPotentialConstantExpression() ||
6582 !
This.AllowConstexprUnknown) {
6586 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6587 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6595 CheckDynamicTypeHandler Handler{AK};
6618 unsigned PathLength) {
6619 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6620 Designator.Entries.size() &&
"invalid path length");
6621 return (PathLength ==
Designator.MostDerivedPathLength)
6622 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6623 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6636 return std::nullopt;
6638 if (
This.Designator.Invalid)
6639 return std::nullopt;
6645 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6646 if (!Class || (!Info.getLangOpts().CPlusPlus26 && Class->getNumVBases())) {
6648 return std::nullopt;
6656 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6657 PathLength <= Path.size(); ++PathLength) {
6658 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6659 Path.slice(0, PathLength))) {
6660 case ConstructionPhase::Bases:
6661 case ConstructionPhase::DestroyingBases:
6666 case ConstructionPhase::None:
6667 case ConstructionPhase::AfterBases:
6668 case ConstructionPhase::AfterFields:
6669 case ConstructionPhase::Destroying:
6681 return std::nullopt;
6699 unsigned PathLength = DynType->PathLength;
6700 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6703 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6713 if (Callee->isPureVirtual()) {
6714 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6715 Info.Note(Callee->getLocation(), diag::note_declared_at);
6721 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6722 Found->getReturnType())) {
6723 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6724 for (
unsigned CovariantPathLength = PathLength + 1;
6725 CovariantPathLength !=
This.Designator.Entries.size();
6726 ++CovariantPathLength) {
6730 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6731 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6732 Next->getReturnType(), CovariantAdjustmentPath.back()))
6733 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6735 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6736 CovariantAdjustmentPath.back()))
6737 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6753 assert(
Result.isLValue() &&
6754 "unexpected kind of APValue for covariant return");
6755 if (
Result.isNullPointer())
6759 LVal.setFrom(Info.Ctx,
Result);
6761 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6762 for (
unsigned I = 1; I != Path.size(); ++I) {
6763 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6764 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6765 if (OldClass != NewClass &&
6768 OldClass = NewClass;
6780 if (BaseSpec.isVirtual())
6782 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6784 return BaseSpec.getAccessSpecifier() ==
AS_public;
6787 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6789 return BaseSpec.getAccessSpecifier() ==
AS_public;
6792 llvm_unreachable(
"Base is not a direct base of Derived");
6802 SubobjectDesignator &D = Ptr.Designator;
6808 if (Ptr.isNullPointer() && !E->
isGLValue())
6814 std::optional<DynamicType> DynType =
6826 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6834 Ptr.setNull(Info.Ctx, E->
getType());
6841 DynType->Type->isDerivedFrom(
C)))
6843 else if (!Paths || Paths->begin() == Paths->end())
6845 else if (Paths->isAmbiguous(CQT))
6848 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6851 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6852 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6853 << Info.Ctx.getCanonicalTagType(DynType->Type)
6861 for (
int PathLength = Ptr.Designator.Entries.size();
6862 PathLength >= (
int)DynType->PathLength; --PathLength) {
6867 if (PathLength > (
int)DynType->PathLength &&
6870 return RuntimeCheckFailed(
nullptr);
6877 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6890 return RuntimeCheckFailed(&Paths);
6894struct StartLifetimeOfUnionMemberHandler {
6896 const Expr *LHSExpr;
6897 const FieldDecl *
Field;
6899 bool Failed =
false;
6902 typedef bool result_type;
6903 bool failed() {
return Failed; }
6904 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6919 }
else if (DuringInit) {
6923 Info.FFDiag(LHSExpr,
6924 diag::note_constexpr_union_member_change_during_init);
6933 llvm_unreachable(
"wrong value kind for union object");
6935 bool found(APFloat &
Value, QualType SubobjType) {
6936 llvm_unreachable(
"wrong value kind for union object");
6941const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6948 const Expr *LHSExpr,
6949 const LValue &LHS) {
6950 if (LHS.InvalidBase || LHS.Designator.Invalid)
6956 unsigned PathLength = LHS.Designator.Entries.size();
6957 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6959 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6960 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6963 if (!FD || FD->getType()->isReferenceType())
6967 if (FD->getParent()->isUnion()) {
6972 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6973 if (!RD || RD->hasTrivialDefaultConstructor())
6974 UnionPathLengths.push_back({PathLength - 1, FD});
6980 LHS.Designator.Entries[PathLength]
6981 .getAsBaseOrMember().getPointer()));
6985 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6987 auto *
Base = ASE->getBase()->IgnoreImplicit();
6988 if (!
Base->getType()->isArrayType())
6994 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6997 if (ICE->getCastKind() == CK_NoOp)
6999 if (ICE->getCastKind() != CK_DerivedToBase &&
7000 ICE->getCastKind() != CK_UncheckedDerivedToBase)
7004 if (Elt->isVirtual()) {
7013 LHS.Designator.Entries[PathLength]
7014 .getAsBaseOrMember().getPointer()));
7024 if (UnionPathLengths.empty())
7029 CompleteObject Obj =
7033 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
7034 llvm::reverse(UnionPathLengths)) {
7036 SubobjectDesignator D = LHS.Designator;
7037 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
7039 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
7040 ConstructionPhase::AfterBases;
7041 StartLifetimeOfUnionMemberHandler StartLifetime{
7042 Info, LHSExpr, LengthAndField.second, DuringInit};
7051 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
7052 APValue **EvaluatedArg =
nullptr) {
7059 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
7060 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
7061 ScopeKind::Call, LV);
7067 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
7068 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
7081 bool RightToLeft =
false,
7082 LValue *ObjectArg =
nullptr) {
7084 llvm::SmallBitVector ForbiddenNullArgs;
7085 if (Callee->hasAttr<NonNullAttr>()) {
7086 ForbiddenNullArgs.resize(Args.size());
7087 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
7088 if (!
Attr->args_size()) {
7089 ForbiddenNullArgs.set();
7092 for (
auto Idx :
Attr->args()) {
7093 unsigned ASTIdx = Idx.getASTIndex();
7094 if (ASTIdx >= Args.size())
7096 ForbiddenNullArgs[ASTIdx] =
true;
7100 for (
unsigned I = 0; I < Args.size(); I++) {
7101 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
7103 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
7104 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
7109 if (!Info.noteFailure())
7114 ObjectArg->setFrom(Info.Ctx, *That);
7123 bool CopyObjectRepresentation) {
7125 CallStackFrame *Frame = Info.CurrentCall;
7126 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
7134 RefLValue.setFrom(Info.Ctx, *RefValue);
7137 CopyObjectRepresentation);
7143 const LValue *ObjectArg,
const Expr *E,
7145 const Stmt *Body, EvalInfo &Info,
7147 if (!Info.CheckCallLimit(CallLoc))
7160 auto IsTrivialMemoryOperation = [&](
const CXXMethodDecl *MD) {
7170 if (IsTrivialMemoryOperation(MD)) {
7183 ObjectArg->moveInto(
Result);
7192 if (!Info.checkingPotentialConstantExpression())
7194 Frame.LambdaThisCaptureField);
7197 StmtResult Ret = {
Result, ResultSlot};
7199 if (ESR == ESR_Succeeded) {
7200 if (Callee->getReturnType()->isVoidType())
7202 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7204 return ESR == ESR_Returned;
7211 bool IsCompleteClass =
true);
7217 bool IsCompleteClass =
true) {
7218 CallScopeRAII CallScope(Info);
7225 CallScope.destroy();
7233 bool IsCompleteClass) {
7236 if (!Info.CheckCallLimit(CallLoc))
7240 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7241 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7245 EvalInfo::EvaluatingConstructorRAII EvalObj(
7247 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7254 StmtResult Ret = {RetVal,
nullptr};
7259 if ((*I)->getInit()->isValueDependent()) {
7263 FullExpressionRAII InitScope(Info);
7265 !InitScope.destroy())
7288 if (!
Result.hasValue()) {
7290 unsigned NonVirtualBases = countNonVirtualBases(RD);
7302 BlockScopeRAII LifetimeExtendedScope(Info);
7305 unsigned BasesSeen = 0;
7306 unsigned VirtualBasesSeen = 0;
7307 unsigned NonVirtualBases = countNonVirtualBases(RD);
7310 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7315 assert(Indirect &&
"fields out of order?");
7321 assert(FieldIt != RD->
field_end() &&
"missing field?");
7322 if (!FieldIt->isUnnamedBitField())
7325 Result.getStructField(FieldIt->getFieldIndex()));
7330 LValue Subobject =
This;
7331 LValue SubobjectParent =
This;
7336 if (I->isBaseInitializer()) {
7337 QualType BaseType(I->getBaseClass(), 0);
7338 if (I->isBaseVirtual()) {
7339 if (
This.pointsToCompleteClass(RD)) {
7341 BaseType->getAsCXXRecordDecl(),
7344 Value = &
Result.getStructVirtualBase(VirtualBasesSeen++);
7351 BaseType->getAsCXXRecordDecl(), &Layout))
7355 }
else if ((FD = I->getMember())) {
7362 SkipToField(FD,
false);
7368 auto IndirectFieldChain = IFD->chain();
7369 for (
auto *
C : IndirectFieldChain) {
7378 (
Value->isUnion() &&
7391 if (
C == IndirectFieldChain.back())
7392 SubobjectParent = Subobject;
7398 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7399 SkipToField(FD,
true);
7404 llvm_unreachable(
"unknown base initializer kind");
7411 if (
Init->isValueDependent()) {
7415 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7417 FullExpressionRAII InitScope(Info);
7423 if (!Info.noteFailure())
7432 if (!Info.noteFailure())
7440 if (I->isBaseInitializer() && BasesSeen == NonVirtualBases)
7441 EvalObj.finishedConstructingBases();
7446 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7447 if (!FieldIt->isUnnamedBitField())
7450 Result.getStructField(FieldIt->getFieldIndex()));
7454 EvalObj.finishedConstructingFields();
7458 LifetimeExtendedScope.destroy();
7463 QualType T,
bool IsCompleteClass =
true) {
7468 if (
Value.isAbsent() && !
T->isNullPtrType()) {
7470 This.moveInto(Printable);
7472 diag::note_constexpr_destroy_out_of_lifetime)
7473 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
7489 LValue ElemLV =
This;
7490 ElemLV.addArray(Info, &LocE, CAT);
7497 if (Size && Size >
Value.getArrayInitializedElts())
7502 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7503 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7516 if (
T.isDestructedType()) {
7518 diag::note_constexpr_unsupported_destruction)
7527 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7528 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7556 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7565 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7569 EvalInfo::EvaluatingDestructorRAII EvalObj(
7571 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7572 unsigned NonVirtualBases = countNonVirtualBases(RD);
7574 unsigned BasesLeft = NonVirtualBases;
7575 if (!EvalObj.DidInsert) {
7582 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7589 StmtResult Ret = {RetVal,
nullptr};
7604 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7605 if (FD->isUnnamedBitField())
7608 LValue Subobject =
This;
7612 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7618 if (BasesLeft != 0 || NumVirtualBases != 0)
7619 EvalObj.startedDestroyingBases();
7623 if (
Base.isVirtual())
7628 LValue Subobject =
This;
7630 BaseType->getAsCXXRecordDecl(), &Layout))
7633 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7638 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7641 if (IsCompleteClass) {
7642 unsigned VirtualBasesLeft = NumVirtualBases;
7647 LValue Subobject =
This;
7649 BaseType->getAsCXXRecordDecl(),
7653 APValue *SubobjectValue = &
Value.getStructVirtualBase(VirtualBasesLeft);
7658 assert(VirtualBasesLeft == 0 &&
"NumVirtualBases was wrong?");
7667struct DestroyObjectHandler {
7673 typedef bool result_type;
7674 bool failed() {
return false; }
7675 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
7680 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7683 bool found(APFloat &
Value, QualType SubobjType) {
7684 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7705 if (Info.EvalStatus.HasSideEffects)
7716 if (Info.checkingPotentialConstantExpression() ||
7717 Info.SpeculativeEvaluationDepth)
7721 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7723 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7724 ? diag::note_constexpr_new_untyped
7725 : diag::note_constexpr_new);
7729 QualType ElemType = Caller.ElemType;
7732 diag::note_constexpr_new_not_complete_object_type)
7740 bool IsNothrow =
false;
7741 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7749 APInt Size, Remainder;
7750 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7751 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7752 if (Remainder != 0) {
7754 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7755 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7759 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7760 Size.getZExtValue(), !IsNothrow)) {
7768 QualType AllocType = Info.Ctx.getConstantArrayType(
7770 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType,
Result);
7779 return DD->isVirtual();
7786 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7797 DynAlloc::Kind DeallocKind) {
7798 auto PointerAsString = [&] {
7799 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7804 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7805 << PointerAsString();
7808 return std::nullopt;
7811 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7813 Info.FFDiag(E, diag::note_constexpr_double_delete);
7814 return std::nullopt;
7817 if (DeallocKind != (*Alloc)->getKind()) {
7819 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7820 << DeallocKind << (*Alloc)->getKind() << AllocType;
7822 return std::nullopt;
7825 bool Subobject =
false;
7826 if (DeallocKind == DynAlloc::New) {
7827 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7828 Pointer.Designator.isOnePastTheEnd();
7830 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7831 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7834 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7835 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7836 return std::nullopt;
7844 if (Info.checkingPotentialConstantExpression() ||
7845 Info.SpeculativeEvaluationDepth)
7849 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7857 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7860 if (
Pointer.Designator.Invalid)
7865 if (
Pointer.isNullPointer()) {
7866 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7882class BitCastBuffer {
7888 SmallVector<std::optional<unsigned char>, 32> Bytes;
7890 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7891 "Need at least 8 bit unsigned char");
7893 bool TargetIsLittleEndian;
7896 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7897 : Bytes(Width.getQuantity()),
7898 TargetIsLittleEndian(TargetIsLittleEndian) {}
7900 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7901 SmallVectorImpl<unsigned char> &Output)
const {
7902 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7905 if (!Bytes[I.getQuantity()])
7907 Output.push_back(*Bytes[I.getQuantity()]);
7909 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7910 std::reverse(Output.begin(), Output.end());
7914 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7915 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7916 std::reverse(Input.begin(), Input.end());
7919 for (
unsigned char Byte : Input) {
7920 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7926 size_t size() {
return Bytes.size(); }
7931class APValueToBufferConverter {
7933 BitCastBuffer Buffer;
7936 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7939 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7942 bool visit(
const APValue &Val, QualType Ty) {
7947 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7948 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7961 return visitInt(Val.
getInt(), Ty, Offset);
7963 return visitFloat(Val.
getFloat(), Ty, Offset);
7965 return visitArray(Val, Ty, Offset);
7967 return visitRecord(Val, Ty, Offset);
7969 return visitVector(Val, Ty, Offset);
7973 return visitComplex(Val, Ty, Offset);
7983 diag::note_constexpr_bit_cast_unsupported_type)
7988 llvm_unreachable(
"Unhandled APValue::ValueKind");
7991 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7995 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
7998 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7999 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8000 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8005 if (!
Base.isStruct())
8008 if (!visitRecord(Base, BS.
getType(),
8015 unsigned FieldIdx = 0;
8016 for (FieldDecl *FD : RD->
fields()) {
8017 if (FD->isBitField()) {
8019 diag::note_constexpr_bit_cast_unsupported_bitfield);
8025 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
8026 "only bit-fields can have sub-char alignment");
8027 CharUnits FieldOffset =
8028 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
8029 QualType FieldTy = FD->getType();
8038 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
8044 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
8048 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
8050 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
8057 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
8058 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
8066 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
8067 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
8069 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8074 Offset + (0 * EltSizeChars)))
8077 Offset + (1 * EltSizeChars)))
8081 Offset + (0 * EltSizeChars)))
8084 Offset + (1 * EltSizeChars)))
8091 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
8092 const VectorType *VTy = Ty->
castAs<VectorType>();
8105 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8107 llvm::APInt Res = llvm::APInt::getZero(NElts);
8108 for (
unsigned I = 0; I < NElts; ++I) {
8110 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
8111 "bool vector element must be 1-bit unsigned integer!");
8113 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
8116 SmallVector<uint8_t, 8> Bytes(NElts / 8);
8117 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
8118 Buffer.writeObject(Offset, Bytes);
8122 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8123 for (
unsigned I = 0; I < NElts; ++I) {
8124 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
8132 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
8133 APSInt AdjustedVal = Val;
8134 unsigned Width = AdjustedVal.getBitWidth();
8136 Width = Info.Ctx.getTypeSize(Ty);
8137 AdjustedVal = AdjustedVal.extend(Width);
8140 SmallVector<uint8_t, 8> Bytes(Width / 8);
8141 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
8142 Buffer.writeObject(Offset, Bytes);
8146 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
8147 APSInt AsInt(Val.bitcastToAPInt());
8148 return visitInt(AsInt, Ty, Offset);
8152 static std::optional<BitCastBuffer>
8154 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
8155 APValueToBufferConverter Converter(Info, DstSize, BCE);
8157 return std::nullopt;
8158 return Converter.Buffer;
8163class BufferToAPValueConverter {
8165 const BitCastBuffer &Buffer;
8168 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
8170 : Info(Info), Buffer(Buffer), BCE(BCE) {}
8175 std::nullopt_t unsupportedType(QualType Ty) {
8177 diag::note_constexpr_bit_cast_unsupported_type)
8179 return std::nullopt;
8182 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
8184 diag::note_constexpr_bit_cast_unrepresentable_value)
8186 return std::nullopt;
8189 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
8190 const EnumType *EnumSugar =
nullptr) {
8192 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(
T, 0));
8193 return APValue((Expr *)
nullptr,
8195 APValue::NoLValuePath{},
true);
8198 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(
T);
8204 const llvm::fltSemantics &Semantics =
8205 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8206 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8207 assert(NumBits % 8 == 0);
8213 SmallVector<uint8_t, 8> Bytes;
8214 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8217 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8221 if (!IsStdByte && !IsUChar) {
8222 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
8224 diag::note_constexpr_bit_cast_indet_dest)
8225 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8226 return std::nullopt;
8232 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8233 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8238 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(
T, 0));
8239 if (IntWidth != Val.getBitWidth()) {
8240 APSInt Truncated = Val.trunc(IntWidth);
8241 if (Truncated.extend(Val.getBitWidth()) != Val)
8242 return unrepresentableValue(QualType(
T, 0), Val);
8250 const llvm::fltSemantics &Semantics =
8251 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8255 return unsupportedType(QualType(
T, 0));
8258 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8259 const RecordDecl *RD = RTy->getAsRecordDecl();
8261 return std::nullopt;
8262 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8264 unsigned NumBases = 0;
8265 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8266 NumBases = CXXRD->getNumBases();
8271 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8272 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8273 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8276 std::optional<APValue> SubObj = visitType(
8279 return std::nullopt;
8280 ResultVal.getStructBase(I) = *SubObj;
8285 unsigned FieldIdx = 0;
8286 for (FieldDecl *FD : RD->
fields()) {
8289 if (FD->isBitField()) {
8291 diag::note_constexpr_bit_cast_unsupported_bitfield);
8292 return std::nullopt;
8296 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8298 CharUnits FieldOffset =
8301 QualType FieldTy = FD->getType();
8302 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8304 return std::nullopt;
8305 ResultVal.getStructField(FieldIdx) = *SubObj;
8312 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8313 QualType RepresentationType =
8314 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8315 assert(!RepresentationType.
isNull() &&
8316 "enum forward decl should be caught by Sema");
8317 const auto *AsBuiltin =
8321 return visit(AsBuiltin, Offset, Ty);
8324 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8326 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8328 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8329 for (
size_t I = 0; I !=
Size; ++I) {
8330 std::optional<APValue> ElementValue =
8333 return std::nullopt;
8334 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8340 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8342 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8343 bool IsInt = ElementType->isIntegerType();
8345 std::optional<APValue> Values[2];
8346 for (
unsigned I = 0; I != 2; ++I) {
8347 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8349 return std::nullopt;
8353 return APValue(Values[0]->getInt(), Values[1]->getInt());
8354 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8357 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8363 SmallVector<APValue, 4> Elts;
8364 Elts.reserve(NElts);
8374 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8376 SmallVector<uint8_t, 8> Bytes;
8377 Bytes.reserve(NElts / 8);
8379 return std::nullopt;
8381 APSInt SValInt(NElts,
true);
8382 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8384 for (
unsigned I = 0; I < NElts; ++I) {
8386 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8393 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8394 for (
unsigned I = 0; I < NElts; ++I) {
8395 std::optional<APValue> EltValue =
8396 visitType(EltTy, Offset + I * EltSizeChars);
8398 return std::nullopt;
8399 Elts.push_back(std::move(*EltValue));
8403 return APValue(Elts.data(), Elts.size());
8406 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8407 return unsupportedType(QualType(Ty, 0));
8410 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8414#define TYPE(Class, Base) \
8416 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8417#define ABSTRACT_TYPE(Class, Base)
8418#define NON_CANONICAL_TYPE(Class, Base) \
8420 llvm_unreachable("non-canonical type should be impossible!");
8421#define DEPENDENT_TYPE(Class, Base) \
8424 "dependent types aren't supported in the constant evaluator!");
8425#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8427 llvm_unreachable("either dependent or not canonical!");
8428#include "clang/AST/TypeNodes.inc"
8430 llvm_unreachable(
"Unhandled Type::TypeClass");
8435 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8437 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8442static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8443 QualType Ty, EvalInfo *Info,
8444 const ASTContext &Ctx,
8445 bool CheckingDest) {
8448 auto diag = [&](
int Reason) {
8450 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8451 << CheckingDest << (Reason == 4) << Reason;
8454 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8456 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8457 << NoteTy << Construct << Ty;
8471 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8472 for (CXXBaseSpecifier &BS : CXXRD->bases())
8473 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8477 for (FieldDecl *FD :
Record->fields()) {
8478 if (FD->getType()->isReferenceType())
8480 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8482 return note(0, FD->getType(), FD->getBeginLoc());
8488 Info, Ctx, CheckingDest))
8491 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8503 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8504 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8514 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8523static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8524 const ASTContext &Ctx,
8526 bool DestOK = checkBitCastConstexprEligibilityType(
8528 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8534static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8537 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8538 "no host or target supports non 8-bit chars");
8540 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8544 std::optional<BitCastBuffer> Buffer =
8545 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8550 std::optional<APValue> MaybeDestValue =
8551 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8552 if (!MaybeDestValue)
8555 DestValue = std::move(*MaybeDestValue);
8559static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8562 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8563 "no host or target supports non 8-bit chars");
8565 "LValueToRValueBitcast requires an lvalue operand!");
8567 LValue SourceLValue;
8569 SourceLValue.setFrom(Info.Ctx, SourceValue);
8572 SourceRValue,
true))
8575 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8578template <
class Derived>
8579class ExprEvaluatorBase
8580 :
public ConstStmtVisitor<Derived, bool> {
8582 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8583 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8584 return getDerived().Success(
V, E);
8586 bool DerivedZeroInitialization(
const Expr *E) {
8587 return getDerived().ZeroInitialization(E);
8593 template<
typename ConditionalOperator>
8594 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8595 assert(Info.checkingPotentialConstantExpression());
8598 SmallVector<PartialDiagnosticAt, 8>
Diag;
8600 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8607 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8609 Info.EvalStatus.DiagEmitted =
false;
8615 Error(E, diag::note_constexpr_conditional_never_const);
8619 template<
typename ConditionalOperator>
8620 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8623 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8624 CheckPotentialConstantConditional(E);
8627 if (Info.noteFailure()) {
8635 return StmtVisitorTy::Visit(EvalExpr);
8640 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8641 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8643 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8644 return Info.CCEDiag(E, D);
8647 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8649 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8651 return BuiltinOp != 0 &&
8652 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8656 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8658 EvalInfo &getEvalInfo() {
return Info; }
8666 bool Error(
const Expr *E) {
8667 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8670 bool VisitStmt(
const Stmt *) {
8671 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8673 bool VisitExpr(
const Expr *E) {
8677 bool VisitEmbedExpr(
const EmbedExpr *E) {
8678 const auto It = E->
begin();
8679 return StmtVisitorTy::Visit(*It);
8682 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8685 bool VisitConstantExpr(
const ConstantExpr *E) {
8689 return StmtVisitorTy::Visit(E->
getSubExpr());
8692 bool VisitParenExpr(
const ParenExpr *E)
8693 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8694 bool VisitUnaryExtension(
const UnaryOperator *E)
8695 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8696 bool VisitUnaryPlus(
const UnaryOperator *E)
8697 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8698 bool VisitChooseExpr(
const ChooseExpr *E)
8700 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8702 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8704 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8705 TempVersionRAII RAII(*Info.CurrentCall);
8706 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8707 return StmtVisitorTy::Visit(E->
getExpr());
8709 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8710 TempVersionRAII RAII(*Info.CurrentCall);
8714 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8715 return StmtVisitorTy::Visit(E->
getExpr());
8718 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8719 FullExpressionRAII Scope(Info);
8720 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8725 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8726 return StmtVisitorTy::Visit(E->
getSubExpr());
8729 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8731 CCEDiag(E, diag::note_constexpr_invalid_cast)
8732 << diag::ConstexprInvalidCastKind::Reinterpret;
8733 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8735 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8736 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8737 CCEDiag(E, diag::note_constexpr_invalid_cast)
8738 << diag::ConstexprInvalidCastKind::Dynamic;
8739 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8741 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8742 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8745 bool VisitBinaryOperator(
const BinaryOperator *E) {
8751 VisitIgnoredValue(E->
getLHS());
8752 return StmtVisitorTy::Visit(E->
getRHS());
8762 return DerivedSuccess(
Result, E);
8767 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8771 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8775 if (!
Evaluate(Info.CurrentCall->createTemporary(
8778 ScopeKind::FullExpression, CommonLV),
8782 return HandleConditionalOperator(E);
8785 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8786 bool IsBcpCall =
false;
8791 if (
const CallExpr *CallCE =
8793 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8800 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8803 FoldConstant Fold(Info, IsBcpCall);
8804 if (!HandleConditionalOperator(E)) {
8805 Fold.keepDiagnostics();
8812 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8813 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8815 return DerivedSuccess(*
Value, E);
8821 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8824 return StmtVisitorTy::Visit(Source);
8827 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8828 for (
const Expr *SemE : E->
semantics()) {
8829 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8838 if (OVE->isUnique())
8842 if (!
Evaluate(Info.CurrentCall->createTemporary(
8843 OVE, getStorageType(Info.Ctx, OVE),
8844 ScopeKind::FullExpression, LV),
8845 Info, OVE->getSourceExpr()))
8848 if (!StmtVisitorTy::Visit(SemE))
8858 bool VisitCallExpr(
const CallExpr *E) {
8860 if (!handleCallExpr(E,
Result,
nullptr))
8862 return DerivedSuccess(
Result, E);
8866 const LValue *ResultSlot) {
8867 CallScopeRAII CallScope(Info);
8870 QualType CalleeType =
Callee->getType();
8872 const FunctionDecl *FD =
nullptr;
8873 LValue *
This =
nullptr, ObjectArg;
8875 bool HasQualifier =
false;
8881 const CXXMethodDecl *
Member =
nullptr;
8882 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8886 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8888 return Error(Callee);
8890 HasQualifier = ME->hasQualifier();
8891 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8893 const ValueDecl *D =
8897 Member = dyn_cast<CXXMethodDecl>(D);
8899 return Error(Callee);
8901 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8902 if (!Info.getLangOpts().CPlusPlus20)
8903 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8907 return Error(Callee);
8914 if (!CalleeLV.getLValueOffset().isZero())
8915 return Error(Callee);
8916 if (CalleeLV.isNullPointer()) {
8917 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8918 <<
const_cast<Expr *
>(
Callee);
8921 FD = dyn_cast_or_null<FunctionDecl>(
8922 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8924 return Error(Callee);
8927 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8934 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8935 if (OCE && OCE->isAssignmentOp()) {
8936 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8937 Call = Info.CurrentCall->createCall(FD);
8938 bool HasThis =
false;
8939 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8940 HasThis = MD->isImplicitObjectMemberFunction();
8948 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8968 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8969 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8973 Args = Args.slice(1);
8979 const CXXRecordDecl *ClosureClass = MD->
getParent();
8981 ClosureClass->
captures().empty() &&
8982 "Number of captures must be zero for conversion to function-ptr");
8984 const CXXMethodDecl *LambdaCallOp =
8993 "A generic lambda's static-invoker function must be a "
8994 "template specialization");
8996 FunctionTemplateDecl *CallOpTemplate =
8998 llvm::FoldingSetInsertToken InsertToken;
8999 FunctionDecl *CorrespondingCallOpSpecialization =
9001 assert(CorrespondingCallOpSpecialization &&
9002 "We must always have a function call operator specialization "
9003 "that corresponds to our static invoker specialization");
9005 FD = CorrespondingCallOpSpecialization;
9014 return CallScope.destroy();
9024 Call = Info.CurrentCall->createCall(FD);
9030 SmallVector<QualType, 4> CovariantAdjustmentPath;
9032 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
9033 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
9036 CovariantAdjustmentPath);
9039 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
9049 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
9050 assert(This &&
"no 'this' pointer for destructor call");
9052 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
9053 CallScope.destroy();
9070 if (!CovariantAdjustmentPath.empty() &&
9072 CovariantAdjustmentPath))
9075 return CallScope.destroy();
9078 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9081 bool VisitInitListExpr(
const InitListExpr *E) {
9083 return DerivedZeroInitialization(E);
9085 return StmtVisitorTy::Visit(E->
getInit(0));
9088 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
9089 return DerivedZeroInitialization(E);
9091 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
9092 return DerivedZeroInitialization(E);
9094 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
9095 return DerivedZeroInitialization(E);
9099 bool VisitMemberExpr(
const MemberExpr *E) {
9100 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
9101 "missing temporary materialization conversion");
9102 assert(!E->
isArrow() &&
"missing call to bound member function?");
9110 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
9111 if (!FD)
return Error(E);
9115 "record / field mismatch");
9120 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
9121 SubobjectDesignator Designator(BaseTy);
9122 Designator.addDeclUnchecked(FD);
9126 DerivedSuccess(
Result, E);
9129 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
9135 SmallVector<uint32_t, 4> Indices;
9137 if (Indices.size() == 1) {
9139 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
9142 SmallVector<APValue, 4> Elts;
9143 for (
unsigned I = 0; I < Indices.size(); ++I) {
9146 APValue VecResult(Elts.data(), Indices.size());
9147 return DerivedSuccess(VecResult, E);
9154 bool VisitCastExpr(
const CastExpr *E) {
9159 case CK_AtomicToNonAtomic: {
9166 return DerivedSuccess(AtomicVal, E);
9170 case CK_UserDefinedConversion:
9171 return StmtVisitorTy::Visit(E->
getSubExpr());
9173 case CK_HLSLArrayRValue: {
9179 return DerivedSuccess(Val, E);
9190 return DerivedSuccess(RVal, E);
9192 case CK_LValueToRValue: {
9201 return DerivedSuccess(RVal, E);
9203 case CK_LValueToRValueBitCast: {
9204 APValue DestValue, SourceValue;
9207 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9209 return DerivedSuccess(DestValue, E);
9212 case CK_AddressSpaceConversion: {
9216 return DerivedSuccess(
Value, E);
9223 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9224 return VisitUnaryPostIncDec(UO);
9226 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9227 return VisitUnaryPostIncDec(UO);
9229 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9230 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9240 return DerivedSuccess(RVal, UO);
9243 bool VisitStmtExpr(
const StmtExpr *E) {
9246 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9253 BlockScopeRAII Scope(Info);
9258 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9260 Info.FFDiag((*BI)->getBeginLoc(),
9261 diag::note_constexpr_stmt_expr_unsupported);
9264 return this->Visit(FinalExpr) && Scope.destroy();
9270 if (ESR != ESR_Succeeded) {
9274 if (ESR != ESR_Failed)
9275 Info.FFDiag((*BI)->getBeginLoc(),
9276 diag::note_constexpr_stmt_expr_unsupported);
9281 llvm_unreachable(
"Return from function from the loop above.");
9284 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9289 void VisitIgnoredValue(
const Expr *E) {
9294 void VisitIgnoredBaseExpression(
const Expr *E) {
9297 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9299 VisitIgnoredValue(E);
9309template<
class Derived>
9310class LValueExprEvaluatorBase
9311 :
public ExprEvaluatorBase<Derived> {
9315 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9316 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9318 bool Success(APValue::LValueBase B) {
9323 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9328 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9330 InvalidBaseOK(InvalidBaseOK) {}
9333 Result.setFrom(this->Info.Ctx,
V);
9337 bool VisitMemberExpr(
const MemberExpr *E) {
9349 EvalOK = this->Visit(E->
getBase());
9360 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9363 "record / field mismatch");
9367 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9371 return this->
Error(E);
9383 bool VisitBinaryOperator(
const BinaryOperator *E) {
9386 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9394 bool VisitCastExpr(
const CastExpr *E) {
9397 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9399 case CK_DerivedToBase:
9400 case CK_UncheckedDerivedToBase:
9447class LValueExprEvaluator
9448 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9450 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9451 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9453 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9454 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9456 bool VisitCallExpr(
const CallExpr *E);
9457 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9458 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9459 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9460 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9461 bool VisitMemberExpr(
const MemberExpr *E);
9462 bool VisitStringLiteral(
const StringLiteral *E) {
9464 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9466 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9467 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9468 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9469 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9470 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9471 bool VisitUnaryDeref(
const UnaryOperator *E);
9472 bool VisitUnaryReal(
const UnaryOperator *E);
9473 bool VisitUnaryImag(
const UnaryOperator *E);
9474 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9475 return VisitUnaryPreIncDec(UO);
9477 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9478 return VisitUnaryPreIncDec(UO);
9480 bool VisitBinAssign(
const BinaryOperator *BO);
9481 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9483 bool VisitCastExpr(
const CastExpr *E) {
9486 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9488 case CK_LValueBitCast:
9489 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9490 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9494 Result.Designator.setInvalid();
9497 case CK_BaseToDerived:
9514 bool LValueToRValueConversion) {
9518 assert(Info.CurrentCall->This ==
nullptr &&
9519 "This should not be set for a static call operator");
9527 if (
Self->getType()->isReferenceType()) {
9528 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9530 Result.setFrom(Info.Ctx, *RefValue);
9532 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9533 CallStackFrame *Frame =
9534 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9536 unsigned Version = Info.CurrentCall->Arguments.Version;
9537 Result.set({VD, Frame->Index, Version});
9540 Result = *Info.CurrentCall->This;
9550 if (LValueToRValueConversion) {
9554 Result.setFrom(Info.Ctx, RVal);
9565 bool InvalidBaseOK) {
9569 return LValueExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
9572bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9573 const ValueDecl *D = E->
getDecl();
9585 if (Info.checkingPotentialConstantExpression())
9588 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9595 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9596 UnnamedGlobalConstantDecl>(D))
9598 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9599 return VisitVarDecl(E, VD);
9600 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9601 return Visit(BD->getBinding());
9605bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9606 CallStackFrame *Frame =
nullptr;
9607 unsigned Version = 0;
9615 CallStackFrame *CurrFrame = Info.CurrentCall;
9620 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9621 if (CurrFrame->Arguments) {
9622 VD = CurrFrame->Arguments.getOrigParam(PVD);
9624 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9625 Version = CurrFrame->Arguments.Version;
9629 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9636 Result.set({VD, Frame->Index, Version});
9642 if (!Info.getLangOpts().CPlusPlus11) {
9643 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9645 Info.Note(VD->
getLocation(), diag::note_declared_at);
9654 Result.AllowConstexprUnknown =
true;
9661bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9662 if (!IsConstantEvaluatedBuiltinCall(E))
9663 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9668 case Builtin::BIas_const:
9669 case Builtin::BIforward:
9670 case Builtin::BIforward_like:
9671 case Builtin::BImove:
9672 case Builtin::BImove_if_noexcept:
9674 return Visit(E->
getArg(0));
9678 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9681bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9682 const MaterializeTemporaryExpr *E) {
9690 for (
const Expr *E : CommaLHSs)
9699 if (Info.EvalMode == EvaluationMode::ConstantFold)
9706 Value = &Info.CurrentCall->createTemporary(
9722 for (
unsigned I = Adjustments.size(); I != 0; ) {
9724 switch (Adjustments[I].Kind) {
9729 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9735 Type = Adjustments[I].Field->getType();
9740 Adjustments[I].
Ptr.RHS))
9742 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9751LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9752 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9753 "lvalue compound literal in c++?");
9765 assert(!Info.getLangOpts().CPlusPlus);
9767 ScopeKind::Block,
Result);
9779bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9780 TypeInfoLValue TypeInfo;
9788 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9789 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9797 std::optional<DynamicType> DynType =
9802 TypeInfo = TypeInfoLValue(
9803 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9809bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9813bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9815 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9816 VisitIgnoredBaseExpression(E->
getBase());
9817 return VisitVarDecl(E, VD);
9821 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9822 if (MD->isStatic()) {
9823 VisitIgnoredBaseExpression(E->
getBase());
9829 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9832bool LValueExprEvaluator::VisitExtVectorElementExpr(
9833 const ExtVectorElementExpr *E) {
9838 if (!Info.noteFailure())
9846 if (Indices.size() > 1)
9850 Result.setFrom(Info.Ctx, Val);
9854 const auto *VT = BaseType->
castAs<VectorType>();
9856 VT->getNumElements(), Indices[0]);
9862bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9872 if (!Info.noteFailure())
9878 if (!Info.noteFailure())
9884 Result.setFrom(Info.Ctx, Val);
9886 VT->getNumElements(), Index.getZExtValue());
9894 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9895 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9897 if (!Info.noteFailure())
9907bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9918 Info.noteUndefinedBehavior();
9921bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9930bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9932 "lvalue __imag__ on scalar?");
9939bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9940 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9951bool LValueExprEvaluator::VisitCompoundAssignOperator(
9952 const CompoundAssignOperator *CAO) {
9953 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9961 if (!Info.noteFailure())
9976bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9977 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9985 if (!Info.noteFailure())
9993 if (Info.getLangOpts().CPlusPlus20 &&
10008 const LValue &LVal,
10010 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
10011 "Can't get the size of a non alloc_size function");
10012 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
10014 std::optional<llvm::APInt> Size =
10015 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
10019 Result = std::move(*Size);
10038 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
10043 if (!
Init ||
Init->getType().isNull())
10046 const Expr *E =
Init->IgnoreParens();
10047 if (!tryUnwrapAllocSizeCall(E))
10055 Result.addUnsizedArray(Info, E, Pointee);
10060class PointerExprEvaluator
10061 :
public ExprEvaluatorBase<PointerExprEvaluator> {
10063 bool InvalidBaseOK;
10065 bool Success(
const Expr *E) {
10070 bool evaluateLValue(
const Expr *E, LValue &
Result) {
10074 bool evaluatePointer(
const Expr *E, LValue &
Result) {
10078 bool visitNonBuiltinCallExpr(
const CallExpr *E);
10081 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
10083 InvalidBaseOK(InvalidBaseOK) {}
10089 bool ZeroInitialization(
const Expr *E) {
10094 bool VisitBinaryOperator(
const BinaryOperator *E);
10095 bool VisitCastExpr(
const CastExpr* E);
10096 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10097 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
10099 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
10102 if (Info.noteFailure())
10106 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
10109 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
10112 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
10114 bool VisitCallExpr(
const CallExpr *E);
10115 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
10116 bool VisitBlockExpr(
const BlockExpr *E) {
10121 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
10122 auto DiagnoseInvalidUseOfThis = [&] {
10123 if (Info.getLangOpts().CPlusPlus11)
10124 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
10130 if (Info.checkingPotentialConstantExpression())
10133 bool IsExplicitLambda =
10135 if (!IsExplicitLambda) {
10136 if (!Info.CurrentCall->This) {
10137 DiagnoseInvalidUseOfThis();
10141 Result = *Info.CurrentCall->This;
10149 if (!Info.CurrentCall->LambdaThisCaptureField) {
10150 if (IsExplicitLambda && !Info.CurrentCall->This) {
10151 DiagnoseInvalidUseOfThis();
10160 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
10166 bool VisitCXXNewExpr(
const CXXNewExpr *E);
10168 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
10169 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
10171 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
10172 Result.setFrom(Info.Ctx, LValResult);
10176 bool VisitEmbedExpr(
const EmbedExpr *E) {
10177 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
10181 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
10182 std::string ResultStr = E->
ComputeName(Info.Ctx);
10184 QualType CharTy = Info.Ctx.CharTy.withConst();
10185 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
10186 ResultStr.size() + 1);
10187 QualType ArrayTy = Info.Ctx.getConstantArrayType(
10188 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
10190 StringLiteral *SL =
10191 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
10194 evaluateLValue(SL,
Result);
10204 bool InvalidBaseOK) {
10207 return PointerExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
10210bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10213 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10215 const Expr *PExp = E->
getLHS();
10216 const Expr *IExp = E->
getRHS();
10218 std::swap(PExp, IExp);
10220 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10221 if (!EvalPtrOK && !Info.noteFailure())
10224 llvm::APSInt Offset;
10235bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10243 if (!Info.getLangOpts().CPlusPlus) {
10245 if (
const auto *Deref = dyn_cast<UnaryOperator>(Sub);
10246 Deref && Deref->getOpcode() == UO_Deref)
10247 return evaluatePointer(Deref->getSubExpr(),
Result);
10257 if (!FnII || !FnII->
isStr(
"current"))
10260 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10268bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10275 case CK_CPointerToObjCPointerCast:
10276 case CK_BlockPointerToObjCPointerCast:
10277 case CK_AnyPointerToBlockPointerCast:
10278 case CK_AddressSpaceConversion:
10279 if (!Visit(SubExpr))
10285 CCEDiag(E, diag::note_constexpr_invalid_cast)
10286 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10287 << Info.Ctx.getLangOpts().CPlusPlus;
10288 Result.Designator.setInvalid();
10296 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10298 bool VoidPtrCastMaybeOK =
10301 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10310 if (VoidPtrCastMaybeOK &&
10311 (Info.getStdAllocatorCaller(
"allocate") ||
10313 Info.getLangOpts().CPlusPlus26)) {
10317 Info.getLangOpts().CPlusPlus) {
10318 if (HasValidResult)
10319 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10320 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10321 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10324 CCEDiag(E, diag::note_constexpr_invalid_cast)
10325 << diag::ConstexprInvalidCastKind::CastFrom
10328 CCEDiag(E, diag::note_constexpr_invalid_cast)
10329 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10330 << Info.Ctx.getLangOpts().CPlusPlus;
10331 Result.Designator.setInvalid();
10335 ZeroInitialization(E);
10338 case CK_DerivedToBase:
10339 case CK_UncheckedDerivedToBase:
10351 case CK_BaseToDerived:
10363 case CK_NullToPointer:
10365 return ZeroInitialization(E);
10367 case CK_IntegralToPointer: {
10368 CCEDiag(E, diag::note_constexpr_invalid_cast)
10369 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10370 << Info.Ctx.getLangOpts().CPlusPlus;
10376 if (
Value.isInt()) {
10377 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10378 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10379 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10382 Result.Base = (Expr *)
nullptr;
10383 Result.InvalidBase =
false;
10385 Result.Designator.setInvalid();
10386 Result.IsNullPtr =
false;
10394 if (!
Value.isLValue())
10403 case CK_ArrayToPointerDecay: {
10405 if (!evaluateLValue(SubExpr,
Result))
10409 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10414 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10415 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10416 Result.addArray(Info, E, CAT);
10418 Result.addUnsizedArray(Info, E, AT->getElementType());
10422 case CK_FunctionToPointerDecay:
10423 return evaluateLValue(SubExpr,
Result);
10425 case CK_LValueToRValue: {
10434 return InvalidBaseOK &&
10440 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10444 UnaryExprOrTypeTrait ExprKind) {
10448 T =
T.getNonReferenceType();
10450 if (
T.getQualifiers().hasUnaligned())
10453 const bool AlignOfReturnsPreferred =
10459 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10462 else if (ExprKind == UETT_AlignOf)
10465 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10480 unsigned BuiltinOp) {
10504 switch (OwningTarget->
getTriple().getArch()) {
10505 case llvm::Triple::x86:
10506 case llvm::Triple::x86_64:
10519 UnaryExprOrTypeTrait ExprKind) {
10528 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10532 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10541 return Info.Ctx.getDeclAlign(VD);
10542 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10550 EvalInfo &Info,
APSInt &Alignment) {
10553 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10554 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10557 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10558 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10559 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10560 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10561 << MaxValue << ForType << Alignment;
10567 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10568 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10569 "Alignment should not be changed by ext/trunc");
10570 Alignment = ExtAlignment;
10571 assert(Alignment.getBitWidth() == SrcWidth);
10576bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10577 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10585 Result.addUnsizedArray(Info, E, PointeeTy);
10589bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10590 if (!IsConstantEvaluatedBuiltinCall(E))
10591 return visitNonBuiltinCallExpr(E);
10598 return T->isCharType() ||
T->isChar8Type();
10601bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10602 unsigned BuiltinOp) {
10606 switch (BuiltinOp) {
10607 case Builtin::BIaddressof:
10608 case Builtin::BI__addressof:
10609 case Builtin::BI__builtin_addressof:
10611 case Builtin::BI__builtin_assume_aligned: {
10618 LValue OffsetResult(
Result);
10630 int64_t AdditionalOffset = -Offset.getZExtValue();
10635 if (OffsetResult.Base) {
10638 if (BaseAlignment < Align) {
10639 Result.Designator.setInvalid();
10640 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10647 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10648 Result.Designator.setInvalid();
10652 diag::note_constexpr_baa_insufficient_alignment)
10655 diag::note_constexpr_baa_value_insufficient_alignment))
10656 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10662 case Builtin::BI__builtin_align_up:
10663 case Builtin::BI__builtin_align_down: {
10683 assert(Alignment.getBitWidth() <= 64 &&
10684 "Cannot handle > 64-bit address-space");
10685 uint64_t Alignment64 = Alignment.getZExtValue();
10687 BuiltinOp == Builtin::BI__builtin_align_down
10688 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10689 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10695 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10699 case Builtin::BI__builtin_operator_new:
10701 case Builtin::BI__builtin_launder:
10703 case Builtin::BIstrchr:
10704 case Builtin::BIwcschr:
10705 case Builtin::BImemchr:
10706 case Builtin::BIwmemchr:
10707 if (Info.getLangOpts().CPlusPlus11)
10708 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10710 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10712 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10714 case Builtin::BI__builtin_strchr:
10715 case Builtin::BI__builtin_wcschr:
10716 case Builtin::BI__builtin_memchr:
10717 case Builtin::BI__builtin_char_memchr:
10718 case Builtin::BI__builtin_wmemchr: {
10719 if (!Visit(E->
getArg(0)))
10725 if (BuiltinOp != Builtin::BIstrchr &&
10726 BuiltinOp != Builtin::BIwcschr &&
10727 BuiltinOp != Builtin::BI__builtin_strchr &&
10728 BuiltinOp != Builtin::BI__builtin_wcschr) {
10732 MaxLength = N.getZExtValue();
10735 if (MaxLength == 0u)
10736 return ZeroInitialization(E);
10737 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10738 Result.Designator.Invalid)
10740 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10741 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10742 BuiltinOp == Builtin::BI__builtin_memchr;
10743 assert(IsRawByte ||
10744 Info.Ctx.hasSameUnqualifiedType(
10748 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10754 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10755 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10761 bool StopAtNull =
false;
10762 switch (BuiltinOp) {
10763 case Builtin::BIstrchr:
10764 case Builtin::BI__builtin_strchr:
10771 return ZeroInitialization(E);
10774 case Builtin::BImemchr:
10775 case Builtin::BI__builtin_memchr:
10776 case Builtin::BI__builtin_char_memchr:
10780 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10783 case Builtin::BIwcschr:
10784 case Builtin::BI__builtin_wcschr:
10787 case Builtin::BIwmemchr:
10788 case Builtin::BI__builtin_wmemchr:
10790 DesiredVal = Desired.getZExtValue();
10794 for (; MaxLength; --MaxLength) {
10799 if (Char.
getInt().getZExtValue() == DesiredVal)
10801 if (StopAtNull && !Char.
getInt())
10807 return ZeroInitialization(E);
10810 case Builtin::BImemcpy:
10811 case Builtin::BImemmove:
10812 case Builtin::BIwmemcpy:
10813 case Builtin::BIwmemmove:
10814 if (Info.getLangOpts().CPlusPlus11)
10815 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10817 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10819 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10821 case Builtin::BI__builtin_memcpy:
10822 case Builtin::BI__builtin_memmove:
10823 case Builtin::BI__builtin_wmemcpy:
10824 case Builtin::BI__builtin_wmemmove: {
10825 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10826 BuiltinOp == Builtin::BIwmemmove ||
10827 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10828 BuiltinOp == Builtin::BI__builtin_wmemmove;
10829 bool Move = BuiltinOp == Builtin::BImemmove ||
10830 BuiltinOp == Builtin::BIwmemmove ||
10831 BuiltinOp == Builtin::BI__builtin_memmove ||
10832 BuiltinOp == Builtin::BI__builtin_wmemmove;
10835 if (!Visit(E->
getArg(0)))
10846 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10856 if (!Src.Base || !Dest.Base) {
10858 (!Src.Base ? Src : Dest).moveInto(Val);
10859 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10860 <<
Move << WChar << !!Src.Base
10864 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10870 QualType
T = Dest.Designator.getType(Info.Ctx);
10871 QualType SrcT = Src.Designator.getType(Info.Ctx);
10872 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
10874 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10878 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10881 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10882 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10887 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
10892 llvm::APInt OrigN = N;
10893 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10895 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10897 << (unsigned)TSize;
10905 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10906 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10907 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10908 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10909 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10913 uint64_t NElems = N.getZExtValue();
10919 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10920 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10921 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10924 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10932 }
else if (!Move && SrcOffset >= DestOffset &&
10933 SrcOffset - DestOffset < NBytes) {
10935 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10964 QualType AllocType);
10967 const CXXConstructExpr *CCE,
10968 QualType AllocType);
10970bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10971 if (!Info.getLangOpts().CPlusPlus20)
10972 Info.CCEDiag(E, diag::note_constexpr_new);
10975 if (Info.SpeculativeEvaluationDepth)
10980 QualType TargetType = AllocType;
10982 bool IsNothrow =
false;
10983 bool IsPlacement =
false;
10999 if (OperatorNew->isReservedGlobalPlacementOperator()) {
11000 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
11001 (Info.CurrentCall->CanEvalMSConstexpr &&
11002 OperatorNew->hasAttr<MSConstexprAttr>())) {
11005 if (
Result.Designator.Invalid)
11008 IsPlacement =
true;
11010 Info.FFDiag(E, diag::note_constexpr_new_placement)
11015 Info.FFDiag(E, diag::note_constexpr_new_placement)
11018 }
else if (!OperatorNew
11019 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
11023 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
11026 }
else if (HasNothrowArg) {
11034 const InitListExpr *ResizedArrayILE =
nullptr;
11035 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
11036 bool ValueInit =
false;
11038 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
11039 const Expr *Stripped = *ArraySize;
11040 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
11041 Stripped = ICE->getSubExpr())
11042 if (ICE->getCastKind() != CK_NoOp &&
11043 ICE->getCastKind() != CK_IntegralCast)
11056 return ZeroInitialization(E);
11058 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
11059 <<
ArrayBound << (*ArraySize)->getSourceRange();
11065 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
11070 return ZeroInitialization(E);
11082 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
11083 ResizedArrayCCE = CCE;
11085 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
11086 assert(CAT &&
"unexpected type for array initializer");
11090 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
11091 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
11092 if (InitBound.ugt(AllocBound)) {
11094 return ZeroInitialization(E);
11096 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
11097 <<
toString(AllocBound, 10,
false)
11099 << (*ArraySize)->getSourceRange();
11105 if (InitBound != AllocBound)
11109 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
11110 ArraySizeModifier::Normal, 0);
11120 "array allocation with non-array new");
11126 struct FindObjectHandler {
11129 QualType AllocType;
11133 typedef bool result_type;
11134 bool failed() {
return false; }
11135 bool checkConst(QualType QT) {
11137 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
11142 bool found(
APValue &Subobj, QualType SubobjType,
11143 APValue::LValueBase Base) {
11144 if (!checkConst(SubobjType))
11148 if (!Info.Ctx.hasSimilarType(SubobjType, AllocType)) {
11149 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
11150 << SubobjType << AllocType;
11157 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11160 bool found(APFloat &
Value, QualType SubobjType) {
11161 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11164 } Handler = {Info, E, AllocType, AK,
nullptr};
11167 Result.Designator.MostDerivedIsArrayElement &&
11168 Result.Designator.Entries.back().getAsArrayIndex() == 0) {
11173 QualType AllocElementType =
11174 Info.Ctx.getAsArrayType(AllocType)->getElementType();
11175 if (Info.Ctx.hasSimilarType(AllocElementType,
11176 Result.Designator.MostDerivedType)) {
11178 Result.Designator.MostDerivedPathLength - 1);
11186 Val = Handler.Value;
11195 Val = Info.createHeapAlloc(E, AllocType,
Result);
11201 ImplicitValueInitExpr VIE(AllocType);
11204 }
else if (ResizedArrayILE) {
11208 }
else if (ResizedArrayCCE) {
11231class MemberPointerExprEvaluator
11232 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
11235 bool Success(
const ValueDecl *D) {
11241 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
11248 bool ZeroInitialization(
const Expr *E) {
11249 return Success((
const ValueDecl*)
nullptr);
11252 bool VisitCastExpr(
const CastExpr *E);
11253 bool VisitUnaryAddrOf(
const UnaryOperator *E);
11261 return MemberPointerExprEvaluator(Info,
Result).Visit(E);
11264bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11267 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11269 case CK_NullToMemberPointer:
11271 return ZeroInitialization(E);
11273 case CK_BaseToDerivedMemberPointer: {
11281 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11283 PathI != PathE; ++PathI) {
11284 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11285 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11286 if (!
Result.castToDerived(Derived))
11290 ->
castAs<MemberPointerType>()
11291 ->getMostRecentCXXRecordDecl()))
11296 case CK_DerivedToBaseMemberPointer:
11300 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11301 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11302 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11303 if (!
Result.castToBase(Base))
11310bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11321 class RecordExprEvaluator
11322 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11323 const LValue &
This;
11327 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11334 bool ZeroInitialization(
const Expr *E) {
11335 return ZeroInitialization(E, E->
getType());
11337 bool ZeroInitialization(
const Expr *E, QualType
T);
11339 bool VisitCallExpr(
const CallExpr *E) {
11340 return handleCallExpr(E,
Result, &This);
11342 bool VisitCastExpr(
const CastExpr *E);
11343 bool VisitInitListExpr(
const InitListExpr *E);
11344 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11345 return VisitCXXConstructExpr(E, E->
getType());
11348 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11349 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
11350 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11351 bool VisitBinCmp(
const BinaryOperator *E);
11352 bool VisitTypeTraitExpr(
const TypeTraitExpr *E);
11353 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11354 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11355 ArrayRef<Expr *> Args);
11356 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
11370 bool IsCompleteClass =
true) {
11371 assert(!RD->
isUnion() &&
"Expected non-union class type");
11375 unsigned NonVirtualBases = countNonVirtualBases(CD);
11387 unsigned Index = 0;
11389 for (
const auto &B : CD->
bases()) {
11393 LValue Subobject =
This;
11397 Result.getStructBase(Index),
11404 for (
const auto *I : RD->
fields()) {
11406 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11409 LValue Subobject =
This;
11415 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11419 if (CD &&
This.pointsToCompleteClass(CD)) {
11420 unsigned Index = 0;
11421 for (
const auto &B : CD->
vbases()) {
11423 LValue Subobject =
This;
11427 Result.getStructVirtualBase(Index),
11437bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
11444 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11451 LValue Subobject =
This;
11455 ImplicitValueInitExpr VIE(I->getType());
11459 if (!Info.getLangOpts().CPlusPlus26) {
11460 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11461 CXXRD && CXXRD->getNumVBases()) {
11462 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11470bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11473 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11475 case CK_ConstructorConversion:
11478 case CK_DerivedToBase:
11479 case CK_UncheckedDerivedToBase: {
11490 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11491 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11492 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11499 case CK_HLSLAggregateSplatCast: {
11519 case CK_HLSLElementwiseCast: {
11537 LValue Subobject =
This;
11544 if (
Field->isBitField()) {
11554bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11557 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11560bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11564 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11565 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11567 EvalInfo::EvaluatingConstructorRAII EvalObj(
11569 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11570 CXXRD && CXXRD->getNumBases());
11573 const FieldDecl *
Field;
11574 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11575 Field = ILE->getInitializedFieldInUnion();
11576 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11577 Field = PLIE->getInitializedFieldInUnion();
11580 "Expression is neither an init list nor a C++ paren list");
11592 ImplicitValueInitExpr VIE(
Field->getType());
11593 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11595 LValue Subobject =
This;
11600 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11604 if (
Field->isBitField())
11614 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11616 unsigned ElementNo = 0;
11620 if (CXXRD && CXXRD->getNumBases()) {
11621 for (
const auto &Base : CXXRD->bases()) {
11622 assert(ElementNo < Args.size() &&
"missing init for base class");
11623 const Expr *
Init = Args[ElementNo];
11625 LValue Subobject =
This;
11631 if (!Info.noteFailure())
11638 EvalObj.finishedConstructingBases();
11642 for (
const auto *Field : RD->
fields()) {
11645 if (
Field->isUnnamedBitField())
11648 LValue Subobject =
This;
11650 bool HaveInit = ElementNo < Args.size();
11655 Subobject, Field, &Layout))
11660 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11661 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11668 if (
Field->getType()->isIncompleteArrayType()) {
11669 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11673 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11680 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11684 if (
Field->getType()->isReferenceType()) {
11688 if (!Info.noteFailure())
11693 (
Field->isBitField() &&
11695 if (!Info.noteFailure())
11701 EvalObj.finishedConstructingFields();
11706bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11716 return ZeroInitialization(E,
T);
11734 const Expr *SrcObj = E->
getArg(0);
11736 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11737 if (
const MaterializeTemporaryExpr *ME =
11738 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11739 return Visit(ME->getSubExpr());
11742 if (ZeroInit && !ZeroInitialization(E,
T))
11751bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11752 const CXXInheritedCtorInitExpr *E) {
11753 if (!Info.CurrentCall) {
11754 assert(Info.checkingPotentialConstantExpression());
11773bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11774 const CXXStdInitializerListExpr *E) {
11775 const ConstantArrayType *ArrayType =
11782 assert(ArrayType &&
"unexpected type for array initializer");
11785 Array.addArray(Info, E, ArrayType);
11793 assert(Field !=
Record->field_end() &&
11794 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11796 "Expected std::initializer_list first field to be const E *");
11798 assert(Field !=
Record->field_end() &&
11799 "Expected std::initializer_list to have two fields");
11801 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11806 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11808 "Expected std::initializer_list second field to be const E *");
11816 assert(++Field ==
Record->field_end() &&
11817 "Expected std::initializer_list to only have two fields");
11822bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11827 const size_t NumFields = ClosureClass->
getNumFields();
11831 "The number of lambda capture initializers should equal the number of "
11832 "fields within the closure type");
11839 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11840 for (
const auto *Field : ClosureClass->
fields()) {
11843 Expr *
const CurFieldInit = *CaptureInitIt++;
11850 LValue Subobject =
This;
11857 if (!Info.keepEvaluatingAfterFailure())
11865bool RecordExprEvaluator::VisitDesignatedInitUpdateExpr(
11866 const DesignatedInitUpdateExpr *E) {
11876 "can't evaluate expression as a record rvalue");
11877 return RecordExprEvaluator(Info,
This,
Result).Visit(E);
11888class TemporaryExprEvaluator
11889 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11891 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11892 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11895 bool VisitConstructExpr(
const Expr *E) {
11901 bool VisitCastExpr(
const CastExpr *E) {
11904 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11906 case CK_ConstructorConversion:
11910 bool VisitInitListExpr(
const InitListExpr *E) {
11911 return VisitConstructExpr(E);
11913 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11914 return VisitConstructExpr(E);
11916 bool VisitCallExpr(
const CallExpr *E) {
11917 return VisitConstructExpr(E);
11919 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11920 return VisitConstructExpr(E);
11923 return VisitConstructExpr(E);
11932 return TemporaryExprEvaluator(Info,
Result).Visit(E);
11940 class VectorExprEvaluator
11941 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11948 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11949 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11955 assert(
V.isVector());
11959 bool ZeroInitialization(
const Expr *E);
11961 bool VisitUnaryReal(
const UnaryOperator *E)
11963 bool VisitCastExpr(
const CastExpr* E);
11964 bool VisitInitListExpr(
const InitListExpr *E);
11965 bool VisitUnaryImag(
const UnaryOperator *E);
11966 bool VisitBinaryOperator(
const BinaryOperator *E);
11967 bool VisitUnaryOperator(
const UnaryOperator *E);
11968 bool VisitCallExpr(
const CallExpr *E);
11969 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11970 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11979 "not a vector prvalue");
11980 return VectorExprEvaluator(Info,
Result).Visit(E);
11984 assert(Val.
isVector() &&
"expected vector APValue");
11988 llvm::APInt
Result(NumElts, 0);
11990 for (
unsigned I = 0; I < NumElts; ++I) {
11992 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11994 if (Elt.
getInt().getBoolValue())
12001bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
12002 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
12006 QualType SETy = SE->
getType();
12009 case CK_VectorSplat: {
12015 Val =
APValue(std::move(IntResult));
12020 Val =
APValue(std::move(FloatResult));
12037 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
12038 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
12039 << Info.Ctx.getLangOpts().CPlusPlus;
12043 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
12048 case CK_HLSLVectorTruncation: {
12053 for (
unsigned I = 0; I < NElts; I++)
12057 case CK_HLSLMatrixTruncation: {
12063 for (
unsigned Row = 0;
12065 for (
unsigned Col = 0;
12070 case CK_HLSLAggregateSplatCast: {
12087 case CK_HLSLElementwiseCast: {
12100 return Success(ResultEls, E);
12102 case CK_IntegralToFloating:
12103 case CK_FloatingToIntegral:
12104 case CK_IntegralCast:
12105 case CK_FloatingCast:
12106 case CK_FloatingToBoolean:
12107 case CK_IntegralToBoolean: {
12109 assert(SETy->
isVectorType() &&
"expected vector source type");
12115 QualType SrcEltTy = SETy->
castAs<VectorType>()->getElementType();
12120 for (
unsigned I = 0; I < NElts; ++I) {
12125 return Success(ResultEls, E);
12128 return ExprEvaluatorBaseTy::VisitCastExpr(E);
12133VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
12150 unsigned CountInits = 0, CountElts = 0;
12151 while (CountElts < NumElements) {
12153 if (CountInits < NumInits
12159 for (
unsigned j = 0; j < vlen; j++)
12163 llvm::APSInt sInt(32);
12164 if (CountInits < NumInits) {
12168 sInt = Info.Ctx.MakeIntValue(0, EltTy);
12169 Elements.push_back(
APValue(sInt));
12172 llvm::APFloat f(0.0);
12173 if (CountInits < NumInits) {
12177 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
12178 Elements.push_back(
APValue(f));
12187VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
12191 if (EltTy->isIntegerType())
12192 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
12195 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
12201bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
12203 return ZeroInitialization(E);
12206bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
12208 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
12209 "Operation not supported on vector types");
12211 if (Op == BO_Comma)
12212 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
12214 Expr *LHS = E->
getLHS();
12215 Expr *RHS = E->
getRHS();
12220 "Must both be vector types");
12223 assert(LHSType->
castAs<VectorType>()->getNumElements() ==
12225 RHSType->
castAs<VectorType>()->getNumElements() ==
12227 "All operands must be the same size.");
12231 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
12232 if (!LHSOK && !Info.noteFailure())
12234 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
12256 "Vector can only be int or float type");
12264 "Vector operator ~ can only be int");
12265 Elt.
getInt().flipAllBits();
12275 "Vector can only be int or float type");
12281 EltResult.setAllBits();
12283 EltResult.clearAllBits();
12289 return std::nullopt;
12293bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
12299 const QualType ResultEltTy = VD->getElementType();
12303 if (!
Evaluate(SubExprValue, Info, SubExpr))
12316 "Vector length doesn't match type?");
12319 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
12321 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12324 ResultElements.push_back(*Elt);
12326 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12337 DestTy,
Result.getFloat());
12353 DestTy,
Result.getInt());
12357 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12358 << SourceTy << DestTy;
12363 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12372 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12373 "pack builtin LHSVecLen must equal to RHSVecLen");
12376 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12382 const unsigned SrcPerLane = 128 / SrcBits;
12383 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12386 Out.reserve(LHSVecLen + RHSVecLen);
12388 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12389 unsigned base = Lane * SrcPerLane;
12390 for (
unsigned I = 0; I != SrcPerLane; ++I)
12393 for (
unsigned I = 0; I != SrcPerLane; ++I)
12404 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12411 unsigned ShuffleMask = 0;
12413 bool IsVectorMask =
false;
12414 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12416 if (IsSingleOperand) {
12419 IsVectorMask =
true;
12428 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12438 IsVectorMask =
true;
12447 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12458 ResultElements.reserve(NumElts);
12460 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12461 if (IsVectorMask) {
12462 ShuffleMask =
static_cast<unsigned>(
12463 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12465 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12471 ResultElements.push_back(
12472 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12478 ResultElements.push_back(
APValue());
12481 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12486 Out =
APValue(ResultElements.data(), ResultElements.size());
12492 if (OrigVal.isInfinity()) {
12493 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12496 if (OrigVal.isNaN()) {
12497 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12501 APFloat Val = OrigVal;
12502 bool LosesInfo =
false;
12503 APFloat::opStatus Status = Val.convert(
12504 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12506 if (LosesInfo || Val.isDenormal()) {
12507 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12511 if (Status != APFloat::opOK) {
12512 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12521 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12522 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12529 assert(
Call->getNumArgs() == 2);
12533 Call->getArg(1)->getType()->isVectorType());
12536 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12537 unsigned DestLen = Source.getVectorLength();
12540 unsigned NumBitsInQWord = 64;
12541 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12543 Result.reserve(DestLen);
12545 uint64_t CountLQWord = 0;
12546 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12548 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12551 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12552 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12553 if (CountLQWord < DestEltWidth) {
12555 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12558 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12566 std::optional<APSInt> RoundingMode,
12568 APSInt DefaultMode(APInt(32, 4),
true);
12569 if (RoundingMode.value_or(DefaultMode) != 4)
12570 return std::nullopt;
12571 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12572 B.isInfinity() || B.isDenormal())
12573 return std::nullopt;
12574 if (A.isZero() && B.isZero())
12576 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12579bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12580 if (!IsConstantEvaluatedBuiltinCall(E))
12581 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12585 auto EvaluateBinOpExpr =
12587 APValue SourceLHS, SourceRHS;
12593 QualType DestEltTy = DestTy->getElementType();
12594 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12597 ResultElements.reserve(SourceLen);
12599 if (SourceRHS.
isInt()) {
12601 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12603 ResultElements.push_back(
12607 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12610 ResultElements.push_back(
12617 auto EvaluateFpBinOpExpr =
12618 [&](llvm::function_ref<std::optional<APFloat>(
12619 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12621 bool IsScalar =
false) {
12631 std::optional<APSInt> RoundingMode;
12636 RoundingMode = Imm;
12641 ResultElements.reserve(NumElems);
12643 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12644 if (IsScalar && EltNum > 0) {
12650 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12658 auto EvaluateScalarFpRoundMaskBinOp =
12659 [&](llvm::function_ref<std::optional<APFloat>(
12660 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12664 APSInt MaskVal, Rounding;
12675 ResultElements.reserve(NumElems);
12677 if (MaskVal.getZExtValue() & 1) {
12680 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12688 for (
unsigned I = 1; I < NumElems; ++I)
12694 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12702 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12706 for (
unsigned I = 1; I < Len; ++I)
12708 APValue V(Res.data(), Res.size());
12712 auto EvalVectorDotProduct = [&](
bool IsSaturating) ->
bool {
12713 APValue Source, OperandA, OperandB;
12722 unsigned ElemsPerLane = NumOperandElems / NumSrcElems;
12727 Result.reserve(NumSrcElems);
12728 for (
unsigned I = 0; I != NumSrcElems; ++I) {
12730 DotProduct = DotProduct.extend(64);
12731 for (
unsigned J = 0; J != ElemsPerLane; ++J) {
12738 DotProduct += OpA * OpB;
12740 if (IsSaturating) {
12741 DotProduct =
APSInt(DotProduct.truncSSat(32),
false);
12743 DotProduct =
APSInt(DotProduct.trunc(32),
false);
12751 switch (BuiltinOp) {
12754 case Builtin::BI__builtin_elementwise_popcount:
12755 case Builtin::BI__builtin_elementwise_bitreverse: {
12760 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12763 ResultElements.reserve(SourceLen);
12765 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12767 switch (BuiltinOp) {
12768 case Builtin::BI__builtin_elementwise_popcount:
12769 ResultElements.push_back(
APValue(
12770 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
12773 case Builtin::BI__builtin_elementwise_bitreverse:
12774 ResultElements.push_back(
12781 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12783 case Builtin::BI__builtin_elementwise_abs: {
12788 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12791 ResultElements.reserve(SourceLen);
12793 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12798 CurrentEle.getInt().
abs(),
12799 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12800 ResultElements.push_back(Val);
12803 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12806 case Builtin::BI__builtin_elementwise_add_sat:
12807 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12808 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12811 case Builtin::BI__builtin_elementwise_sub_sat:
12812 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12813 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12816 case X86::BI__builtin_ia32_extract128i256:
12817 case X86::BI__builtin_ia32_vextractf128_pd256:
12818 case X86::BI__builtin_ia32_vextractf128_ps256:
12819 case X86::BI__builtin_ia32_vextractf128_si256: {
12820 APValue SourceVec, SourceImm;
12829 unsigned RetLen = RetVT->getNumElements();
12830 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12833 ResultElements.reserve(RetLen);
12835 for (
unsigned I = 0; I < RetLen; I++)
12836 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12841 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12842 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12843 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12844 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12845 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12846 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12847 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12848 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12849 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12850 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12851 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12852 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12858 QualType VecTy = E->
getType();
12859 const VectorType *VT = VecTy->
castAs<VectorType>();
12862 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
12865 for (
unsigned I = 0; I != VectorLen; ++I) {
12866 bool BitSet = Mask[I];
12867 APSInt ElemVal(ElemWidth,
false);
12869 ElemVal.setAllBits();
12871 Elems.push_back(
APValue(ElemVal));
12876 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12877 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12878 case X86::BI__builtin_ia32_extracti32x4_mask:
12879 case X86::BI__builtin_ia32_extractf32x4_mask:
12880 case X86::BI__builtin_ia32_extracti32x8_mask:
12881 case X86::BI__builtin_ia32_extractf32x8_mask:
12882 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12883 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12884 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12885 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12886 case X86::BI__builtin_ia32_extracti64x4_mask:
12887 case X86::BI__builtin_ia32_extractf64x4_mask: {
12898 unsigned RetLen = RetVT->getNumElements();
12903 unsigned Lanes = SrcLen / RetLen;
12904 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12905 unsigned Base = Lane * RetLen;
12908 ResultElements.reserve(RetLen);
12909 for (
unsigned I = 0; I < RetLen; ++I) {
12911 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12915 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12918 case clang::X86::BI__builtin_ia32_pavgb128:
12919 case clang::X86::BI__builtin_ia32_pavgw128:
12920 case clang::X86::BI__builtin_ia32_pavgb256:
12921 case clang::X86::BI__builtin_ia32_pavgw256:
12922 case clang::X86::BI__builtin_ia32_pavgb512:
12923 case clang::X86::BI__builtin_ia32_pavgw512:
12924 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12926 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12927 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12928 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12929 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12930 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12931 .extractBits(16, 1);
12934 case clang::X86::BI__builtin_ia32_psadbw128:
12935 case clang::X86::BI__builtin_ia32_psadbw256:
12936 case clang::X86::BI__builtin_ia32_psadbw512: {
12937 APValue SourceLHS, SourceRHS;
12945 assert((SourceLen % 8) == 0);
12948 QualType DestEltTy = DestTy->getElementType();
12949 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12951 ResultElements.reserve(SourceLen / 8);
12953 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 8) {
12955 for (
unsigned I = 0; I != 8; ++I) {
12958 Sum += llvm::APIntOps::abdu(LHS, RHS).zext(64);
12960 ResultElements.push_back(
APValue(
APSInt(Sum, DestUnsigned)));
12963 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12966 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12967 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12968 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12969 case clang::X86::BI__builtin_ia32_pmaddwd128:
12970 case clang::X86::BI__builtin_ia32_pmaddwd256:
12971 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12972 APValue SourceLHS, SourceRHS;
12978 QualType DestEltTy = DestTy->getElementType();
12980 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12982 ResultElements.reserve(SourceLen / 2);
12984 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12989 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12991 switch (BuiltinOp) {
12992 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12993 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12994 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12995 ResultElements.push_back(
APValue(
12996 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
12997 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
13000 case clang::X86::BI__builtin_ia32_pmaddwd128:
13001 case clang::X86::BI__builtin_ia32_pmaddwd256:
13002 case clang::X86::BI__builtin_ia32_pmaddwd512:
13003 ResultElements.push_back(
13004 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
13005 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
13011 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13014 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v16hi:
13015 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v32hi:
13016 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi:
13017 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi: {
13028 APValue SourceA, SourceB, SourceC;
13035 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi ||
13037 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi;
13040 assert(SourceLen % 16 == 0 &&
"BMM operates on 256-bit lanes of 16 x i16");
13042 QualType DestEltTy = DestTy->getElementType();
13043 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13046 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 16) {
13047 for (
unsigned I = 0; I != 16; ++I) {
13052 for (
unsigned J = 0; J != 16; ++J) {
13056 unsigned Bit = (Dst >> J) & 1u;
13057 for (
unsigned K = 0; K != 16; ++K) {
13061 unsigned Product = ((A >> K) & 1u) & ((B >> J) & 1u);
13062 Bit = IsXor ? (Bit ^ Product) : (Bit | Product);
13066 ResultElements[Lane + I] =
13070 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13073 case clang::X86::BI__builtin_ia32_dbpsadbw128:
13074 case clang::X86::BI__builtin_ia32_dbpsadbw256:
13075 case clang::X86::BI__builtin_ia32_dbpsadbw512: {
13076 APValue SourceA, SourceB, SourceImm;
13083 constexpr unsigned LaneSize = 16;
13084 unsigned Imm = SourceImm.
getInt().getZExtValue();
13087 QualType DestEltTy = DestTy->getElementType();
13088 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13090 ResultElements.reserve(SourceLen / 2);
13096 for (
unsigned I = 0; I < SourceLen; I += LaneSize) {
13097 for (
unsigned J = 0; J < 4; ++J) {
13098 unsigned Part = (Imm >> (2 * J)) & 3;
13099 for (
unsigned K = 0; K < 4; ++K) {
13100 Shuffled[I + 4 * J + K] =
static_cast<uint8_t>(
13101 SourceB.
getVectorElt(I + 4 * Part + K).getInt().getZExtValue());
13109 unsigned Size = SourceLen / 2;
13110 for (
unsigned I = 0; I <
Size; I += 4) {
13111 unsigned Sad[4] = {0, 0, 0, 0};
13112 for (
unsigned J = 0; J < 4; ++J) {
13114 SourceA.
getVectorElt(2 * I + J).getInt().getZExtValue());
13116 SourceA.
getVectorElt(2 * I + J + 4).getInt().getZExtValue());
13117 uint8_t B0 = Shuffled[2 * I + J];
13118 uint8_t B1 = Shuffled[2 * I + J + 1];
13119 uint8_t B2 = Shuffled[2 * I + J + 2];
13120 uint8_t B3 = Shuffled[2 * I + J + 3];
13121 Sad[0] += (A1 > B0) ? (A1 - B0) : (B0 - A1);
13122 Sad[1] += (A1 > B1) ? (A1 - B1) : (B1 - A1);
13123 Sad[2] += (A2 > B2) ? (A2 - B2) : (B2 - A2);
13124 Sad[3] += (A2 > B3) ? (A2 - B3) : (B3 - A2);
13126 for (
unsigned R = 0;
R < 4; ++
R)
13127 ResultElements.push_back(
13131 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13134 case clang::X86::BI__builtin_ia32_mpsadbw128:
13135 case clang::X86::BI__builtin_ia32_mpsadbw256: {
13143 constexpr unsigned LaneSize = 16;
13144 assert((SourceLen == LaneSize || SourceLen == 2 * LaneSize) &&
13145 "MPSADBW operates on 128-bit or 256-bit vectors");
13146 unsigned NumLanes = SourceLen / LaneSize;
13147 unsigned Imm = SourceImm.getZExtValue();
13149 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13152 ResultElements.reserve(SourceLen / 2);
13154 for (
unsigned Lane = 0; Lane != NumLanes; ++Lane) {
13155 unsigned Ctrl = (Imm >> (3 * Lane)) & 0x7;
13156 unsigned AOff = ((Ctrl >> 2) & 1) * 4;
13157 unsigned BOff = (Ctrl & 3) * 4;
13158 for (
unsigned J = 0; J != 8; ++J) {
13160 for (
unsigned K = 0; K != 4; ++K) {
13169 Sad += (A > B) ? (A - B) : (B - A);
13174 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13177 case clang::X86::BI__builtin_ia32_pmulhuw128:
13178 case clang::X86::BI__builtin_ia32_pmulhuw256:
13179 case clang::X86::BI__builtin_ia32_pmulhuw512:
13180 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
13182 case clang::X86::BI__builtin_ia32_pmulhw128:
13183 case clang::X86::BI__builtin_ia32_pmulhw256:
13184 case clang::X86::BI__builtin_ia32_pmulhw512:
13185 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
13187 case clang::X86::BI__builtin_ia32_psllv2di:
13188 case clang::X86::BI__builtin_ia32_psllv4di:
13189 case clang::X86::BI__builtin_ia32_psllv4si:
13190 case clang::X86::BI__builtin_ia32_psllv8di:
13191 case clang::X86::BI__builtin_ia32_psllv8hi:
13192 case clang::X86::BI__builtin_ia32_psllv8si:
13193 case clang::X86::BI__builtin_ia32_psllv16hi:
13194 case clang::X86::BI__builtin_ia32_psllv16si:
13195 case clang::X86::BI__builtin_ia32_psllv32hi:
13196 case clang::X86::BI__builtin_ia32_psllwi128:
13197 case clang::X86::BI__builtin_ia32_pslldi128:
13198 case clang::X86::BI__builtin_ia32_psllqi128:
13199 case clang::X86::BI__builtin_ia32_psllwi256:
13200 case clang::X86::BI__builtin_ia32_pslldi256:
13201 case clang::X86::BI__builtin_ia32_psllqi256:
13202 case clang::X86::BI__builtin_ia32_psllwi512:
13203 case clang::X86::BI__builtin_ia32_pslldi512:
13204 case clang::X86::BI__builtin_ia32_psllqi512:
13205 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13206 if (RHS.uge(LHS.getBitWidth())) {
13207 return APInt::getZero(LHS.getBitWidth());
13209 return LHS.shl(RHS.getZExtValue());
13212 case clang::X86::BI__builtin_ia32_psrav4si:
13213 case clang::X86::BI__builtin_ia32_psrav8di:
13214 case clang::X86::BI__builtin_ia32_psrav8hi:
13215 case clang::X86::BI__builtin_ia32_psrav8si:
13216 case clang::X86::BI__builtin_ia32_psrav16hi:
13217 case clang::X86::BI__builtin_ia32_psrav16si:
13218 case clang::X86::BI__builtin_ia32_psrav32hi:
13219 case clang::X86::BI__builtin_ia32_psravq128:
13220 case clang::X86::BI__builtin_ia32_psravq256:
13221 case clang::X86::BI__builtin_ia32_psrawi128:
13222 case clang::X86::BI__builtin_ia32_psradi128:
13223 case clang::X86::BI__builtin_ia32_psraqi128:
13224 case clang::X86::BI__builtin_ia32_psrawi256:
13225 case clang::X86::BI__builtin_ia32_psradi256:
13226 case clang::X86::BI__builtin_ia32_psraqi256:
13227 case clang::X86::BI__builtin_ia32_psrawi512:
13228 case clang::X86::BI__builtin_ia32_psradi512:
13229 case clang::X86::BI__builtin_ia32_psraqi512:
13230 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13231 if (RHS.uge(LHS.getBitWidth())) {
13232 return LHS.ashr(LHS.getBitWidth() - 1);
13234 return LHS.ashr(RHS.getZExtValue());
13237 case clang::X86::BI__builtin_ia32_psrlv2di:
13238 case clang::X86::BI__builtin_ia32_psrlv4di:
13239 case clang::X86::BI__builtin_ia32_psrlv4si:
13240 case clang::X86::BI__builtin_ia32_psrlv8di:
13241 case clang::X86::BI__builtin_ia32_psrlv8hi:
13242 case clang::X86::BI__builtin_ia32_psrlv8si:
13243 case clang::X86::BI__builtin_ia32_psrlv16hi:
13244 case clang::X86::BI__builtin_ia32_psrlv16si:
13245 case clang::X86::BI__builtin_ia32_psrlv32hi:
13246 case clang::X86::BI__builtin_ia32_psrlwi128:
13247 case clang::X86::BI__builtin_ia32_psrldi128:
13248 case clang::X86::BI__builtin_ia32_psrlqi128:
13249 case clang::X86::BI__builtin_ia32_psrlwi256:
13250 case clang::X86::BI__builtin_ia32_psrldi256:
13251 case clang::X86::BI__builtin_ia32_psrlqi256:
13252 case clang::X86::BI__builtin_ia32_psrlwi512:
13253 case clang::X86::BI__builtin_ia32_psrldi512:
13254 case clang::X86::BI__builtin_ia32_psrlqi512:
13255 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13256 if (RHS.uge(LHS.getBitWidth())) {
13257 return APInt::getZero(LHS.getBitWidth());
13259 return LHS.lshr(RHS.getZExtValue());
13261 case X86::BI__builtin_ia32_packsswb128:
13262 case X86::BI__builtin_ia32_packsswb256:
13263 case X86::BI__builtin_ia32_packsswb512:
13264 case X86::BI__builtin_ia32_packssdw128:
13265 case X86::BI__builtin_ia32_packssdw256:
13266 case X86::BI__builtin_ia32_packssdw512:
13268 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
13270 case X86::BI__builtin_ia32_packusdw128:
13271 case X86::BI__builtin_ia32_packusdw256:
13272 case X86::BI__builtin_ia32_packusdw512:
13273 case X86::BI__builtin_ia32_packuswb128:
13274 case X86::BI__builtin_ia32_packuswb256:
13275 case X86::BI__builtin_ia32_packuswb512:
13277 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
13279 case clang::X86::BI__builtin_ia32_selectss_128:
13280 return EvalSelectScalar(4);
13281 case clang::X86::BI__builtin_ia32_selectsd_128:
13282 return EvalSelectScalar(2);
13283 case clang::X86::BI__builtin_ia32_selectsh_128:
13284 case clang::X86::BI__builtin_ia32_selectsbf_128:
13285 return EvalSelectScalar(8);
13286 case clang::X86::BI__builtin_ia32_pmuldq128:
13287 case clang::X86::BI__builtin_ia32_pmuldq256:
13288 case clang::X86::BI__builtin_ia32_pmuldq512:
13289 case clang::X86::BI__builtin_ia32_pmuludq128:
13290 case clang::X86::BI__builtin_ia32_pmuludq256:
13291 case clang::X86::BI__builtin_ia32_pmuludq512: {
13292 APValue SourceLHS, SourceRHS;
13299 ResultElements.reserve(SourceLen / 2);
13301 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
13305 switch (BuiltinOp) {
13306 case clang::X86::BI__builtin_ia32_pmuludq128:
13307 case clang::X86::BI__builtin_ia32_pmuludq256:
13308 case clang::X86::BI__builtin_ia32_pmuludq512:
13309 ResultElements.push_back(
13310 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
13312 case clang::X86::BI__builtin_ia32_pmuldq128:
13313 case clang::X86::BI__builtin_ia32_pmuldq256:
13314 case clang::X86::BI__builtin_ia32_pmuldq512:
13315 ResultElements.push_back(
13316 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
13321 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13324 case X86::BI__builtin_ia32_vpmadd52luq128:
13325 case X86::BI__builtin_ia32_vpmadd52luq256:
13326 case X86::BI__builtin_ia32_vpmadd52luq512: {
13335 ResultElements.reserve(ALen);
13337 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13340 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13341 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
13342 ResultElements.push_back(
APValue(ResElt));
13345 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13347 case X86::BI__builtin_ia32_vpmadd52huq128:
13348 case X86::BI__builtin_ia32_vpmadd52huq256:
13349 case X86::BI__builtin_ia32_vpmadd52huq512: {
13358 ResultElements.reserve(ALen);
13360 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13363 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13364 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
13365 ResultElements.push_back(
APValue(ResElt));
13368 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13371 case clang::X86::BI__builtin_ia32_vprotbi:
13372 case clang::X86::BI__builtin_ia32_vprotdi:
13373 case clang::X86::BI__builtin_ia32_vprotqi:
13374 case clang::X86::BI__builtin_ia32_vprotwi:
13375 case clang::X86::BI__builtin_ia32_prold128:
13376 case clang::X86::BI__builtin_ia32_prold256:
13377 case clang::X86::BI__builtin_ia32_prold512:
13378 case clang::X86::BI__builtin_ia32_prolq128:
13379 case clang::X86::BI__builtin_ia32_prolq256:
13380 case clang::X86::BI__builtin_ia32_prolq512:
13381 return EvaluateBinOpExpr(
13382 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
13384 case clang::X86::BI__builtin_ia32_prord128:
13385 case clang::X86::BI__builtin_ia32_prord256:
13386 case clang::X86::BI__builtin_ia32_prord512:
13387 case clang::X86::BI__builtin_ia32_prorq128:
13388 case clang::X86::BI__builtin_ia32_prorq256:
13389 case clang::X86::BI__builtin_ia32_prorq512:
13390 return EvaluateBinOpExpr(
13391 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
13393 case Builtin::BI__builtin_elementwise_max:
13394 case Builtin::BI__builtin_elementwise_min: {
13395 APValue SourceLHS, SourceRHS;
13400 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13407 ResultElements.reserve(SourceLen);
13409 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13412 switch (BuiltinOp) {
13413 case Builtin::BI__builtin_elementwise_max:
13414 ResultElements.push_back(
13418 case Builtin::BI__builtin_elementwise_min:
13419 ResultElements.push_back(
13426 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13428 case X86::BI__builtin_ia32_vpshldd128:
13429 case X86::BI__builtin_ia32_vpshldd256:
13430 case X86::BI__builtin_ia32_vpshldd512:
13431 case X86::BI__builtin_ia32_vpshldq128:
13432 case X86::BI__builtin_ia32_vpshldq256:
13433 case X86::BI__builtin_ia32_vpshldq512:
13434 case X86::BI__builtin_ia32_vpshldw128:
13435 case X86::BI__builtin_ia32_vpshldw256:
13436 case X86::BI__builtin_ia32_vpshldw512: {
13437 APValue SourceHi, SourceLo, SourceAmt;
13443 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13446 ResultElements.reserve(SourceLen);
13449 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13452 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
13453 ResultElements.push_back(
13457 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13459 case X86::BI__builtin_ia32_vpshrdd128:
13460 case X86::BI__builtin_ia32_vpshrdd256:
13461 case X86::BI__builtin_ia32_vpshrdd512:
13462 case X86::BI__builtin_ia32_vpshrdq128:
13463 case X86::BI__builtin_ia32_vpshrdq256:
13464 case X86::BI__builtin_ia32_vpshrdq512:
13465 case X86::BI__builtin_ia32_vpshrdw128:
13466 case X86::BI__builtin_ia32_vpshrdw256:
13467 case X86::BI__builtin_ia32_vpshrdw512: {
13469 APValue SourceHi, SourceLo, SourceAmt;
13475 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13478 ResultElements.reserve(SourceLen);
13481 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13484 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
13485 ResultElements.push_back(
13489 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13491 case X86::BI__builtin_ia32_compressdf128_mask:
13492 case X86::BI__builtin_ia32_compressdf256_mask:
13493 case X86::BI__builtin_ia32_compressdf512_mask:
13494 case X86::BI__builtin_ia32_compressdi128_mask:
13495 case X86::BI__builtin_ia32_compressdi256_mask:
13496 case X86::BI__builtin_ia32_compressdi512_mask:
13497 case X86::BI__builtin_ia32_compresshi128_mask:
13498 case X86::BI__builtin_ia32_compresshi256_mask:
13499 case X86::BI__builtin_ia32_compresshi512_mask:
13500 case X86::BI__builtin_ia32_compressqi128_mask:
13501 case X86::BI__builtin_ia32_compressqi256_mask:
13502 case X86::BI__builtin_ia32_compressqi512_mask:
13503 case X86::BI__builtin_ia32_compresssf128_mask:
13504 case X86::BI__builtin_ia32_compresssf256_mask:
13505 case X86::BI__builtin_ia32_compresssf512_mask:
13506 case X86::BI__builtin_ia32_compresssi128_mask:
13507 case X86::BI__builtin_ia32_compresssi256_mask:
13508 case X86::BI__builtin_ia32_compresssi512_mask: {
13519 ResultElements.reserve(NumElts);
13521 for (
unsigned I = 0; I != NumElts; ++I) {
13525 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
13529 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13531 case X86::BI__builtin_ia32_expanddf128_mask:
13532 case X86::BI__builtin_ia32_expanddf256_mask:
13533 case X86::BI__builtin_ia32_expanddf512_mask:
13534 case X86::BI__builtin_ia32_expanddi128_mask:
13535 case X86::BI__builtin_ia32_expanddi256_mask:
13536 case X86::BI__builtin_ia32_expanddi512_mask:
13537 case X86::BI__builtin_ia32_expandhi128_mask:
13538 case X86::BI__builtin_ia32_expandhi256_mask:
13539 case X86::BI__builtin_ia32_expandhi512_mask:
13540 case X86::BI__builtin_ia32_expandqi128_mask:
13541 case X86::BI__builtin_ia32_expandqi256_mask:
13542 case X86::BI__builtin_ia32_expandqi512_mask:
13543 case X86::BI__builtin_ia32_expandsf128_mask:
13544 case X86::BI__builtin_ia32_expandsf256_mask:
13545 case X86::BI__builtin_ia32_expandsf512_mask:
13546 case X86::BI__builtin_ia32_expandsi128_mask:
13547 case X86::BI__builtin_ia32_expandsi256_mask:
13548 case X86::BI__builtin_ia32_expandsi512_mask: {
13559 ResultElements.reserve(NumElts);
13561 unsigned SourceIdx = 0;
13562 for (
unsigned I = 0; I != NumElts; ++I) {
13564 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
13568 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13570 case X86::BI__builtin_ia32_vpconflictsi_128:
13571 case X86::BI__builtin_ia32_vpconflictsi_256:
13572 case X86::BI__builtin_ia32_vpconflictsi_512:
13573 case X86::BI__builtin_ia32_vpconflictdi_128:
13574 case X86::BI__builtin_ia32_vpconflictdi_256:
13575 case X86::BI__builtin_ia32_vpconflictdi_512: {
13583 ResultElements.reserve(SourceLen);
13586 bool DestUnsigned =
13587 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
13589 for (
unsigned I = 0; I != SourceLen; ++I) {
13592 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
13593 for (
unsigned J = 0; J != I; ++J) {
13595 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
13597 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
13599 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13601 case X86::BI__builtin_ia32_blendpd:
13602 case X86::BI__builtin_ia32_blendpd256:
13603 case X86::BI__builtin_ia32_blendps:
13604 case X86::BI__builtin_ia32_blendps256:
13605 case X86::BI__builtin_ia32_pblendw128:
13606 case X86::BI__builtin_ia32_pblendw256:
13607 case X86::BI__builtin_ia32_pblendd128:
13608 case X86::BI__builtin_ia32_pblendd256: {
13609 APValue SourceF, SourceT, SourceC;
13618 ResultElements.reserve(SourceLen);
13619 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13622 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
13625 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13628 case X86::BI__builtin_ia32_psignb128:
13629 case X86::BI__builtin_ia32_psignb256:
13630 case X86::BI__builtin_ia32_psignw128:
13631 case X86::BI__builtin_ia32_psignw256:
13632 case X86::BI__builtin_ia32_psignd128:
13633 case X86::BI__builtin_ia32_psignd256:
13634 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13635 if (BElem.isZero())
13636 return APInt::getZero(AElem.getBitWidth());
13637 if (BElem.isNegative())
13642 case X86::BI__builtin_ia32_blendvpd:
13643 case X86::BI__builtin_ia32_blendvpd256:
13644 case X86::BI__builtin_ia32_blendvps:
13645 case X86::BI__builtin_ia32_blendvps256:
13646 case X86::BI__builtin_ia32_pblendvb128:
13647 case X86::BI__builtin_ia32_pblendvb256: {
13649 APValue SourceF, SourceT, SourceC;
13657 ResultElements.reserve(SourceLen);
13659 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13663 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13664 ResultElements.push_back(M.isNegative() ?
T : F);
13667 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13669 case X86::BI__builtin_ia32_selectb_128:
13670 case X86::BI__builtin_ia32_selectb_256:
13671 case X86::BI__builtin_ia32_selectb_512:
13672 case X86::BI__builtin_ia32_selectw_128:
13673 case X86::BI__builtin_ia32_selectw_256:
13674 case X86::BI__builtin_ia32_selectw_512:
13675 case X86::BI__builtin_ia32_selectd_128:
13676 case X86::BI__builtin_ia32_selectd_256:
13677 case X86::BI__builtin_ia32_selectd_512:
13678 case X86::BI__builtin_ia32_selectq_128:
13679 case X86::BI__builtin_ia32_selectq_256:
13680 case X86::BI__builtin_ia32_selectq_512:
13681 case X86::BI__builtin_ia32_selectph_128:
13682 case X86::BI__builtin_ia32_selectph_256:
13683 case X86::BI__builtin_ia32_selectph_512:
13684 case X86::BI__builtin_ia32_selectpbf_128:
13685 case X86::BI__builtin_ia32_selectpbf_256:
13686 case X86::BI__builtin_ia32_selectpbf_512:
13687 case X86::BI__builtin_ia32_selectps_128:
13688 case X86::BI__builtin_ia32_selectps_256:
13689 case X86::BI__builtin_ia32_selectps_512:
13690 case X86::BI__builtin_ia32_selectpd_128:
13691 case X86::BI__builtin_ia32_selectpd_256:
13692 case X86::BI__builtin_ia32_selectpd_512: {
13694 APValue SourceMask, SourceLHS, SourceRHS;
13703 ResultElements.reserve(SourceLen);
13705 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13708 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13711 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13714 case X86::BI__builtin_ia32_cvtsd2ss: {
13727 Elements.push_back(ResultVal);
13730 for (
unsigned I = 1; I < NumEltsA; ++I) {
13736 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13737 APValue VecA, VecB, VecSrc, MaskValue;
13745 unsigned Mask = MaskValue.
getInt().getZExtValue();
13753 Elements.push_back(ResultVal);
13759 for (
unsigned I = 1; I < NumEltsA; ++I) {
13765 case X86::BI__builtin_ia32_cvtpd2ps:
13766 case X86::BI__builtin_ia32_cvtpd2ps256:
13767 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13768 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13770 const auto BuiltinID = BuiltinOp;
13771 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13772 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13779 unsigned Mask = 0xFFFFFFFF;
13780 bool NeedsMerge =
false;
13785 Mask = MaskValue.
getInt().getZExtValue();
13786 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13787 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13788 if (!((Mask >> I) & 1)) {
13799 unsigned NumEltsResult =
13803 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13804 if (IsMasked && !((Mask >> I) & 1)) {
13812 if (I >= NumEltsInput) {
13813 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13822 Elements.push_back(ResultVal);
13827 case X86::BI__builtin_ia32_shufps:
13828 case X86::BI__builtin_ia32_shufps256:
13829 case X86::BI__builtin_ia32_shufps512: {
13833 [](
unsigned DstIdx,
13834 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13835 constexpr unsigned LaneBits = 128u;
13836 unsigned NumElemPerLane = LaneBits / 32;
13837 unsigned NumSelectableElems = NumElemPerLane / 2;
13838 unsigned BitsPerElem = 2;
13839 unsigned IndexMask = (1u << BitsPerElem) - 1;
13840 unsigned MaskBits = 8;
13841 unsigned Lane = DstIdx / NumElemPerLane;
13842 unsigned ElemInLane = DstIdx % NumElemPerLane;
13843 unsigned LaneOffset = Lane * NumElemPerLane;
13844 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13845 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13846 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13847 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13852 case X86::BI__builtin_ia32_shufpd:
13853 case X86::BI__builtin_ia32_shufpd256:
13854 case X86::BI__builtin_ia32_shufpd512: {
13858 [](
unsigned DstIdx,
13859 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13860 constexpr unsigned LaneBits = 128u;
13861 unsigned NumElemPerLane = LaneBits / 64;
13862 unsigned NumSelectableElems = NumElemPerLane / 2;
13863 unsigned BitsPerElem = 1;
13864 unsigned IndexMask = (1u << BitsPerElem) - 1;
13865 unsigned MaskBits = 8;
13866 unsigned Lane = DstIdx / NumElemPerLane;
13867 unsigned ElemInLane = DstIdx % NumElemPerLane;
13868 unsigned LaneOffset = Lane * NumElemPerLane;
13869 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13870 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13871 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13872 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13877 case X86::BI__builtin_ia32_insertps128: {
13881 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13883 if ((Mask & (1 << DstIdx)) != 0) {
13888 unsigned SrcElem = (Mask >> 6) & 0x3;
13889 unsigned DstElem = (Mask >> 4) & 0x3;
13890 if (DstIdx == DstElem) {
13892 return {1,
static_cast<int>(SrcElem)};
13895 return {0,
static_cast<int>(DstIdx)};
13901 case X86::BI__builtin_ia32_pshufb128:
13902 case X86::BI__builtin_ia32_pshufb256:
13903 case X86::BI__builtin_ia32_pshufb512: {
13907 [](
unsigned DstIdx,
13908 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13911 return std::make_pair(0, -1);
13913 unsigned LaneBase = (DstIdx / 16) * 16;
13914 unsigned SrcOffset = Ctlb & 0x0F;
13915 unsigned SrcIdx = LaneBase + SrcOffset;
13916 return std::make_pair(0,
static_cast<int>(SrcIdx));
13922 case X86::BI__builtin_ia32_pshuflw:
13923 case X86::BI__builtin_ia32_pshuflw256:
13924 case X86::BI__builtin_ia32_pshuflw512: {
13928 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13929 constexpr unsigned LaneBits = 128u;
13930 constexpr unsigned ElemBits = 16u;
13931 constexpr unsigned LaneElts = LaneBits / ElemBits;
13932 constexpr unsigned HalfSize = 4;
13933 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13934 unsigned LaneIdx = DstIdx % LaneElts;
13935 if (LaneIdx < HalfSize) {
13936 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13937 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13939 return std::make_pair(0,
static_cast<int>(DstIdx));
13945 case X86::BI__builtin_ia32_pshufhw:
13946 case X86::BI__builtin_ia32_pshufhw256:
13947 case X86::BI__builtin_ia32_pshufhw512: {
13951 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13952 constexpr unsigned LaneBits = 128u;
13953 constexpr unsigned ElemBits = 16u;
13954 constexpr unsigned LaneElts = LaneBits / ElemBits;
13955 constexpr unsigned HalfSize = 4;
13956 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13957 unsigned LaneIdx = DstIdx % LaneElts;
13958 if (LaneIdx >= HalfSize) {
13959 unsigned Rel = LaneIdx - HalfSize;
13960 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13961 return std::make_pair(
13962 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13964 return std::make_pair(0,
static_cast<int>(DstIdx));
13970 case X86::BI__builtin_ia32_pshufd:
13971 case X86::BI__builtin_ia32_pshufd256:
13972 case X86::BI__builtin_ia32_pshufd512:
13973 case X86::BI__builtin_ia32_vpermilps:
13974 case X86::BI__builtin_ia32_vpermilps256:
13975 case X86::BI__builtin_ia32_vpermilps512: {
13979 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13980 constexpr unsigned LaneBits = 128u;
13981 constexpr unsigned ElemBits = 32u;
13982 constexpr unsigned LaneElts = LaneBits / ElemBits;
13983 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13984 unsigned LaneIdx = DstIdx % LaneElts;
13985 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13986 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13992 case X86::BI__builtin_ia32_vpermilvarpd:
13993 case X86::BI__builtin_ia32_vpermilvarpd256:
13994 case X86::BI__builtin_ia32_vpermilvarpd512: {
13998 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13999 unsigned NumElemPerLane = 2;
14000 unsigned Lane = DstIdx / NumElemPerLane;
14001 unsigned Offset = Mask & 0b10 ? 1 : 0;
14002 return std::make_pair(
14003 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14009 case X86::BI__builtin_ia32_vpermilpd:
14010 case X86::BI__builtin_ia32_vpermilpd256:
14011 case X86::BI__builtin_ia32_vpermilpd512: {
14014 unsigned NumElemPerLane = 2;
14015 unsigned BitsPerElem = 1;
14016 unsigned MaskBits = 8;
14017 unsigned IndexMask = 0x1;
14018 unsigned Lane = DstIdx / NumElemPerLane;
14019 unsigned LaneOffset = Lane * NumElemPerLane;
14020 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
14021 unsigned Index = (Control >> BitIndex) & IndexMask;
14022 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
14028 case X86::BI__builtin_ia32_permdf256:
14029 case X86::BI__builtin_ia32_permdi256: {
14034 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
14035 return std::make_pair(0,
static_cast<int>(Index));
14041 case X86::BI__builtin_ia32_vpermilvarps:
14042 case X86::BI__builtin_ia32_vpermilvarps256:
14043 case X86::BI__builtin_ia32_vpermilvarps512: {
14047 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14048 unsigned NumElemPerLane = 4;
14049 unsigned Lane = DstIdx / NumElemPerLane;
14050 unsigned Offset = Mask & 0b11;
14051 return std::make_pair(
14052 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14058 case X86::BI__builtin_ia32_vpmultishiftqb128:
14059 case X86::BI__builtin_ia32_vpmultishiftqb256:
14060 case X86::BI__builtin_ia32_vpmultishiftqb512: {
14068 unsigned NumBytesInQWord = 8;
14069 unsigned NumBitsInByte = 8;
14071 unsigned NumQWords = NumBytes / NumBytesInQWord;
14073 Result.reserve(NumBytes);
14075 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
14076 APInt BQWord(64, 0);
14077 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14078 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14080 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
14083 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14084 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14088 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
14089 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
14097 case X86::BI__builtin_ia32_phminposuw128: {
14104 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
14106 APInt MinIndex(ElemBitWidth, 0);
14108 for (
unsigned I = 1; I != SourceLen; ++I) {
14110 if (MinVal.ugt(Val)) {
14119 ->isUnsignedIntegerOrEnumerationType();
14122 Result.reserve(SourceLen);
14124 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
14125 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
14131 case X86::BI__builtin_ia32_psraq128:
14132 case X86::BI__builtin_ia32_psraq256:
14133 case X86::BI__builtin_ia32_psraq512:
14134 case X86::BI__builtin_ia32_psrad128:
14135 case X86::BI__builtin_ia32_psrad256:
14136 case X86::BI__builtin_ia32_psrad512:
14137 case X86::BI__builtin_ia32_psraw128:
14138 case X86::BI__builtin_ia32_psraw256:
14139 case X86::BI__builtin_ia32_psraw512: {
14143 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
14144 [](
const APInt &Elt,
unsigned Width) {
14145 return Elt.ashr(Width - 1);
14151 case X86::BI__builtin_ia32_psllq128:
14152 case X86::BI__builtin_ia32_psllq256:
14153 case X86::BI__builtin_ia32_psllq512:
14154 case X86::BI__builtin_ia32_pslld128:
14155 case X86::BI__builtin_ia32_pslld256:
14156 case X86::BI__builtin_ia32_pslld512:
14157 case X86::BI__builtin_ia32_psllw128:
14158 case X86::BI__builtin_ia32_psllw256:
14159 case X86::BI__builtin_ia32_psllw512: {
14163 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
14164 [](
const APInt &Elt,
unsigned Width) {
14165 return APInt::getZero(Width);
14171 case X86::BI__builtin_ia32_psrlq128:
14172 case X86::BI__builtin_ia32_psrlq256:
14173 case X86::BI__builtin_ia32_psrlq512:
14174 case X86::BI__builtin_ia32_psrld128:
14175 case X86::BI__builtin_ia32_psrld256:
14176 case X86::BI__builtin_ia32_psrld512:
14177 case X86::BI__builtin_ia32_psrlw128:
14178 case X86::BI__builtin_ia32_psrlw256:
14179 case X86::BI__builtin_ia32_psrlw512: {
14183 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
14184 [](
const APInt &Elt,
unsigned Width) {
14185 return APInt::getZero(Width);
14191 case X86::BI__builtin_ia32_pternlogd128_mask:
14192 case X86::BI__builtin_ia32_pternlogd256_mask:
14193 case X86::BI__builtin_ia32_pternlogd512_mask:
14194 case X86::BI__builtin_ia32_pternlogq128_mask:
14195 case X86::BI__builtin_ia32_pternlogq256_mask:
14196 case X86::BI__builtin_ia32_pternlogq512_mask: {
14197 APValue AValue, BValue, CValue, ImmValue, UValue;
14205 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14211 ResultElements.reserve(ResultLen);
14213 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14219 unsigned BitWidth = ALane.getBitWidth();
14220 APInt ResLane(BitWidth, 0);
14222 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14223 unsigned ABit = ALane[Bit];
14224 unsigned BBit = BLane[Bit];
14225 unsigned CBit = CLane[Bit];
14227 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14228 ResLane.setBitVal(Bit, Imm[Idx]);
14230 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14232 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
14235 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14237 case X86::BI__builtin_ia32_pternlogd128_maskz:
14238 case X86::BI__builtin_ia32_pternlogd256_maskz:
14239 case X86::BI__builtin_ia32_pternlogd512_maskz:
14240 case X86::BI__builtin_ia32_pternlogq128_maskz:
14241 case X86::BI__builtin_ia32_pternlogq256_maskz:
14242 case X86::BI__builtin_ia32_pternlogq512_maskz: {
14243 APValue AValue, BValue, CValue, ImmValue, UValue;
14251 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14257 ResultElements.reserve(ResultLen);
14259 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14264 unsigned BitWidth = ALane.getBitWidth();
14265 APInt ResLane(BitWidth, 0);
14268 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14269 unsigned ABit = ALane[Bit];
14270 unsigned BBit = BLane[Bit];
14271 unsigned CBit = CLane[Bit];
14273 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14274 ResLane.setBitVal(Bit, Imm[Idx]);
14277 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14279 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14282 case Builtin::BI__builtin_elementwise_clzg:
14283 case Builtin::BI__builtin_elementwise_ctzg: {
14285 std::optional<APValue> Fallback;
14292 Fallback = FallbackTmp;
14295 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14298 ResultElements.reserve(SourceLen);
14300 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14305 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
14307 Builtin::BI__builtin_elementwise_ctzg);
14310 ResultElements.push_back(Fallback->getVectorElt(EltNum));
14313 switch (BuiltinOp) {
14314 case Builtin::BI__builtin_elementwise_clzg:
14315 ResultElements.push_back(
APValue(
14316 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
14319 case Builtin::BI__builtin_elementwise_ctzg:
14320 ResultElements.push_back(
APValue(
14321 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
14327 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14330 case Builtin::BI__builtin_elementwise_fma: {
14331 APValue SourceX, SourceY, SourceZ;
14339 ResultElements.reserve(SourceLen);
14341 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14346 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
14349 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14352 case clang::X86::BI__builtin_ia32_phaddw128:
14353 case clang::X86::BI__builtin_ia32_phaddw256:
14354 case clang::X86::BI__builtin_ia32_phaddd128:
14355 case clang::X86::BI__builtin_ia32_phaddd256:
14356 case clang::X86::BI__builtin_ia32_phaddsw128:
14357 case clang::X86::BI__builtin_ia32_phaddsw256:
14359 case clang::X86::BI__builtin_ia32_phsubw128:
14360 case clang::X86::BI__builtin_ia32_phsubw256:
14361 case clang::X86::BI__builtin_ia32_phsubd128:
14362 case clang::X86::BI__builtin_ia32_phsubd256:
14363 case clang::X86::BI__builtin_ia32_phsubsw128:
14364 case clang::X86::BI__builtin_ia32_phsubsw256: {
14365 APValue SourceLHS, SourceRHS;
14369 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14373 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
14374 unsigned EltsPerLane = 128 / EltBits;
14376 ResultElements.reserve(NumElts);
14378 for (
unsigned LaneStart = 0; LaneStart != NumElts;
14379 LaneStart += EltsPerLane) {
14380 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14383 switch (BuiltinOp) {
14384 case clang::X86::BI__builtin_ia32_phaddw128:
14385 case clang::X86::BI__builtin_ia32_phaddw256:
14386 case clang::X86::BI__builtin_ia32_phaddd128:
14387 case clang::X86::BI__builtin_ia32_phaddd256: {
14388 APSInt Res(LHSA + LHSB, DestUnsigned);
14389 ResultElements.push_back(
APValue(Res));
14392 case clang::X86::BI__builtin_ia32_phaddsw128:
14393 case clang::X86::BI__builtin_ia32_phaddsw256: {
14394 APSInt Res(LHSA.sadd_sat(LHSB));
14395 ResultElements.push_back(
APValue(Res));
14398 case clang::X86::BI__builtin_ia32_phsubw128:
14399 case clang::X86::BI__builtin_ia32_phsubw256:
14400 case clang::X86::BI__builtin_ia32_phsubd128:
14401 case clang::X86::BI__builtin_ia32_phsubd256: {
14402 APSInt Res(LHSA - LHSB, DestUnsigned);
14403 ResultElements.push_back(
APValue(Res));
14406 case clang::X86::BI__builtin_ia32_phsubsw128:
14407 case clang::X86::BI__builtin_ia32_phsubsw256: {
14408 APSInt Res(LHSA.ssub_sat(LHSB));
14409 ResultElements.push_back(
APValue(Res));
14414 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14417 switch (BuiltinOp) {
14418 case clang::X86::BI__builtin_ia32_phaddw128:
14419 case clang::X86::BI__builtin_ia32_phaddw256:
14420 case clang::X86::BI__builtin_ia32_phaddd128:
14421 case clang::X86::BI__builtin_ia32_phaddd256: {
14422 APSInt Res(RHSA + RHSB, DestUnsigned);
14423 ResultElements.push_back(
APValue(Res));
14426 case clang::X86::BI__builtin_ia32_phaddsw128:
14427 case clang::X86::BI__builtin_ia32_phaddsw256: {
14428 APSInt Res(RHSA.sadd_sat(RHSB));
14429 ResultElements.push_back(
APValue(Res));
14432 case clang::X86::BI__builtin_ia32_phsubw128:
14433 case clang::X86::BI__builtin_ia32_phsubw256:
14434 case clang::X86::BI__builtin_ia32_phsubd128:
14435 case clang::X86::BI__builtin_ia32_phsubd256: {
14436 APSInt Res(RHSA - RHSB, DestUnsigned);
14437 ResultElements.push_back(
APValue(Res));
14440 case clang::X86::BI__builtin_ia32_phsubsw128:
14441 case clang::X86::BI__builtin_ia32_phsubsw256: {
14442 APSInt Res(RHSA.ssub_sat(RHSB));
14443 ResultElements.push_back(
APValue(Res));
14449 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14451 case clang::X86::BI__builtin_ia32_haddpd:
14452 case clang::X86::BI__builtin_ia32_haddps:
14453 case clang::X86::BI__builtin_ia32_haddps256:
14454 case clang::X86::BI__builtin_ia32_haddpd256:
14455 case clang::X86::BI__builtin_ia32_hsubpd:
14456 case clang::X86::BI__builtin_ia32_hsubps:
14457 case clang::X86::BI__builtin_ia32_hsubps256:
14458 case clang::X86::BI__builtin_ia32_hsubpd256: {
14459 APValue SourceLHS, SourceRHS;
14465 ResultElements.reserve(NumElts);
14467 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14468 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
14469 unsigned NumLanes = NumElts * EltBits / 128;
14470 unsigned NumElemsPerLane = NumElts / NumLanes;
14471 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
14473 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
14474 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14477 switch (BuiltinOp) {
14478 case clang::X86::BI__builtin_ia32_haddpd:
14479 case clang::X86::BI__builtin_ia32_haddps:
14480 case clang::X86::BI__builtin_ia32_haddps256:
14481 case clang::X86::BI__builtin_ia32_haddpd256:
14482 LHSA.add(LHSB, RM);
14484 case clang::X86::BI__builtin_ia32_hsubpd:
14485 case clang::X86::BI__builtin_ia32_hsubps:
14486 case clang::X86::BI__builtin_ia32_hsubps256:
14487 case clang::X86::BI__builtin_ia32_hsubpd256:
14488 LHSA.subtract(LHSB, RM);
14491 ResultElements.push_back(
APValue(LHSA));
14493 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14496 switch (BuiltinOp) {
14497 case clang::X86::BI__builtin_ia32_haddpd:
14498 case clang::X86::BI__builtin_ia32_haddps:
14499 case clang::X86::BI__builtin_ia32_haddps256:
14500 case clang::X86::BI__builtin_ia32_haddpd256:
14501 RHSA.add(RHSB, RM);
14503 case clang::X86::BI__builtin_ia32_hsubpd:
14504 case clang::X86::BI__builtin_ia32_hsubps:
14505 case clang::X86::BI__builtin_ia32_hsubps256:
14506 case clang::X86::BI__builtin_ia32_hsubpd256:
14507 RHSA.subtract(RHSB, RM);
14510 ResultElements.push_back(
APValue(RHSA));
14513 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14515 case clang::X86::BI__builtin_ia32_addsubpd:
14516 case clang::X86::BI__builtin_ia32_addsubps:
14517 case clang::X86::BI__builtin_ia32_addsubpd256:
14518 case clang::X86::BI__builtin_ia32_addsubps256: {
14521 APValue SourceLHS, SourceRHS;
14527 ResultElements.reserve(NumElems);
14530 for (
unsigned I = 0; I != NumElems; ++I) {
14535 LHS.subtract(RHS, RM);
14540 ResultElements.push_back(
APValue(LHS));
14542 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14544 case clang::X86::BI__builtin_ia32_pclmulqdq128:
14545 case clang::X86::BI__builtin_ia32_pclmulqdq256:
14546 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
14550 APValue SourceLHS, SourceRHS;
14560 bool SelectUpperA = (Imm8 & 0x01) != 0;
14561 bool SelectUpperB = (Imm8 & 0x10) != 0;
14565 ResultElements.reserve(NumElems);
14566 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14570 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
14579 APInt A = SelectUpperA ? A1 : A0;
14580 APInt B = SelectUpperB ? B1 : B0;
14583 APInt A128 = A.zext(128);
14584 APInt B128 = B.zext(128);
14587 APInt Result = llvm::APIntOps::clmul(A128, B128);
14590 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
14591 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
14593 ResultElements.push_back(
APValue(ResultLow));
14594 ResultElements.push_back(
APValue(ResultHigh));
14597 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14599 case Builtin::BI__builtin_elementwise_clmul:
14600 return EvaluateBinOpExpr(llvm::APIntOps::clmul);
14601 case Builtin::BI__builtin_elementwise_pext:
14602 return EvaluateBinOpExpr(llvm::APIntOps::pext);
14603 case Builtin::BI__builtin_elementwise_pdep:
14604 return EvaluateBinOpExpr(llvm::APIntOps::pdep);
14605 case Builtin::BI__builtin_elementwise_fshl:
14606 case Builtin::BI__builtin_elementwise_fshr: {
14607 APValue SourceHi, SourceLo, SourceShift;
14613 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14619 ResultElements.reserve(SourceLen);
14620 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14624 switch (BuiltinOp) {
14625 case Builtin::BI__builtin_elementwise_fshl:
14626 ResultElements.push_back(
APValue(
14627 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14629 case Builtin::BI__builtin_elementwise_fshr:
14630 ResultElements.push_back(
APValue(
14631 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14636 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14639 case X86::BI__builtin_ia32_shuf_f32x4_256:
14640 case X86::BI__builtin_ia32_shuf_i32x4_256:
14641 case X86::BI__builtin_ia32_shuf_f64x2_256:
14642 case X86::BI__builtin_ia32_shuf_i64x2_256:
14643 case X86::BI__builtin_ia32_shuf_f32x4:
14644 case X86::BI__builtin_ia32_shuf_i32x4:
14645 case X86::BI__builtin_ia32_shuf_f64x2:
14646 case X86::BI__builtin_ia32_shuf_i64x2: {
14660 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14661 unsigned LaneBits = 128u;
14662 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14663 unsigned NumElemsPerLane = LaneBits / ElemBits;
14667 ResultElements.reserve(DstLen);
14672 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14673 -> std::pair<unsigned, int> {
14675 unsigned BitsPerElem = NumLanes / 2;
14676 unsigned IndexMask = (1u << BitsPerElem) - 1;
14677 unsigned Lane = DstIdx / NumElemsPerLane;
14678 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14679 unsigned BitIdx = BitsPerElem * Lane;
14680 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14681 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14682 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14683 return {SrcIdx, IdxToPick};
14689 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14690 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14691 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14692 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14693 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14694 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14706 bool IsInverse =
false;
14707 switch (BuiltinOp) {
14708 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14709 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14710 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14715 unsigned NumBitsInByte = 8;
14716 unsigned NumBytesInQWord = 8;
14717 unsigned NumBitsInQWord = 64;
14719 unsigned NumQWords = NumBytes / NumBytesInQWord;
14721 Result.reserve(NumBytes);
14724 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14726 APInt XQWord(NumBitsInQWord, 0);
14727 APInt AQWord(NumBitsInQWord, 0);
14728 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14729 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14730 APInt XByte =
X.getVectorElt(Idx).getInt();
14732 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14733 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14736 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14738 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14747 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14748 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14749 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14760 Result.reserve(NumBytes);
14762 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14772 case X86::BI__builtin_ia32_insertf32x4_256:
14773 case X86::BI__builtin_ia32_inserti32x4_256:
14774 case X86::BI__builtin_ia32_insertf64x2_256:
14775 case X86::BI__builtin_ia32_inserti64x2_256:
14776 case X86::BI__builtin_ia32_insertf32x4:
14777 case X86::BI__builtin_ia32_inserti32x4:
14778 case X86::BI__builtin_ia32_insertf64x2_512:
14779 case X86::BI__builtin_ia32_inserti64x2_512:
14780 case X86::BI__builtin_ia32_insertf32x8:
14781 case X86::BI__builtin_ia32_inserti32x8:
14782 case X86::BI__builtin_ia32_insertf64x4:
14783 case X86::BI__builtin_ia32_inserti64x4:
14784 case X86::BI__builtin_ia32_vinsertf128_ps256:
14785 case X86::BI__builtin_ia32_vinsertf128_pd256:
14786 case X86::BI__builtin_ia32_vinsertf128_si256:
14787 case X86::BI__builtin_ia32_insert128i256: {
14788 APValue SourceDst, SourceSub;
14800 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14801 unsigned NumLanes = DstLen / SubLen;
14802 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14805 ResultElements.reserve(DstLen);
14807 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14808 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14809 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14811 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14814 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14817 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14818 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14819 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14820 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14821 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14822 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14823 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14824 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14825 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14833 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14834 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
14836 Scalar.setIsUnsigned(ElemUnsigned);
14842 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14845 Elems.reserve(NumElems);
14846 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14847 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14852 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14853 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14854 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14858 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14859 unsigned LaneBase = (DstIdx / 16) * 16;
14860 unsigned LaneIdx = DstIdx % 16;
14861 if (LaneIdx < Shift)
14862 return std::make_pair(0, -1);
14864 return std::make_pair(
14865 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14871 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14872 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14873 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14877 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14878 unsigned LaneBase = (DstIdx / 16) * 16;
14879 unsigned LaneIdx = DstIdx % 16;
14880 if (LaneIdx + Shift < 16)
14881 return std::make_pair(
14882 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14884 return std::make_pair(0, -1);
14890 case X86::BI__builtin_ia32_palignr128:
14891 case X86::BI__builtin_ia32_palignr256:
14892 case X86::BI__builtin_ia32_palignr512: {
14896 unsigned VecIdx = 1;
14899 int Lane = DstIdx / 16;
14900 int Offset = DstIdx % 16;
14903 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14904 if (ShiftedIdx < 16) {
14905 ElemIdx = ShiftedIdx + (Lane * 16);
14906 }
else if (ShiftedIdx < 32) {
14908 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14911 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14916 case X86::BI__builtin_ia32_alignd128:
14917 case X86::BI__builtin_ia32_alignd256:
14918 case X86::BI__builtin_ia32_alignd512:
14919 case X86::BI__builtin_ia32_alignq128:
14920 case X86::BI__builtin_ia32_alignq256:
14921 case X86::BI__builtin_ia32_alignq512: {
14923 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14925 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14926 unsigned Imm =
Shift & 0xFF;
14927 unsigned EffectiveShift = Imm & (NumElems - 1);
14928 unsigned SourcePos = DstIdx + EffectiveShift;
14929 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14930 unsigned ElemIdx = SourcePos & (NumElems - 1);
14932 return std::pair<unsigned, int>{
14933 VecIdx,
static_cast<int>(ElemIdx)};
14938 case X86::BI__builtin_ia32_permvarsi256:
14939 case X86::BI__builtin_ia32_permvarsf256:
14940 case X86::BI__builtin_ia32_permvardf512:
14941 case X86::BI__builtin_ia32_permvardi512:
14942 case X86::BI__builtin_ia32_permvarhi128: {
14945 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14946 int Offset = ShuffleMask & 0x7;
14947 return std::pair<unsigned, int>{0, Offset};
14952 case X86::BI__builtin_ia32_permvarqi128:
14953 case X86::BI__builtin_ia32_permvarhi256:
14954 case X86::BI__builtin_ia32_permvarsi512:
14955 case X86::BI__builtin_ia32_permvarsf512: {
14958 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14959 int Offset = ShuffleMask & 0xF;
14960 return std::pair<unsigned, int>{0, Offset};
14965 case X86::BI__builtin_ia32_permvardi256:
14966 case X86::BI__builtin_ia32_permvardf256: {
14969 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14970 int Offset = ShuffleMask & 0x3;
14971 return std::pair<unsigned, int>{0, Offset};
14976 case X86::BI__builtin_ia32_permvarqi256:
14977 case X86::BI__builtin_ia32_permvarhi512: {
14980 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14981 int Offset = ShuffleMask & 0x1F;
14982 return std::pair<unsigned, int>{0, Offset};
14987 case X86::BI__builtin_ia32_permvarqi512: {
14990 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14991 int Offset = ShuffleMask & 0x3F;
14992 return std::pair<unsigned, int>{0, Offset};
14997 case X86::BI__builtin_ia32_vpermi2varq128:
14998 case X86::BI__builtin_ia32_vpermi2varpd128: {
15001 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15002 int Offset = ShuffleMask & 0x1;
15003 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
15004 return std::pair<unsigned, int>{SrcIdx, Offset};
15009 case X86::BI__builtin_ia32_vpermi2vard128:
15010 case X86::BI__builtin_ia32_vpermi2varps128:
15011 case X86::BI__builtin_ia32_vpermi2varq256:
15012 case X86::BI__builtin_ia32_vpermi2varpd256: {
15015 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15016 int Offset = ShuffleMask & 0x3;
15017 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
15018 return std::pair<unsigned, int>{SrcIdx, Offset};
15023 case X86::BI__builtin_ia32_vpermi2varhi128:
15024 case X86::BI__builtin_ia32_vpermi2vard256:
15025 case X86::BI__builtin_ia32_vpermi2varps256:
15026 case X86::BI__builtin_ia32_vpermi2varq512:
15027 case X86::BI__builtin_ia32_vpermi2varpd512: {
15030 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15031 int Offset = ShuffleMask & 0x7;
15032 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
15033 return std::pair<unsigned, int>{SrcIdx, Offset};
15038 case X86::BI__builtin_ia32_vpermi2varqi128:
15039 case X86::BI__builtin_ia32_vpermi2varhi256:
15040 case X86::BI__builtin_ia32_vpermi2vard512:
15041 case X86::BI__builtin_ia32_vpermi2varps512: {
15044 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15045 int Offset = ShuffleMask & 0xF;
15046 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
15047 return std::pair<unsigned, int>{SrcIdx, Offset};
15052 case X86::BI__builtin_ia32_vpermi2varqi256:
15053 case X86::BI__builtin_ia32_vpermi2varhi512: {
15056 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15057 int Offset = ShuffleMask & 0x1F;
15058 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
15059 return std::pair<unsigned, int>{SrcIdx, Offset};
15064 case X86::BI__builtin_ia32_vpermi2varqi512: {
15067 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15068 int Offset = ShuffleMask & 0x3F;
15069 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
15070 return std::pair<unsigned, int>{SrcIdx, Offset};
15076 case clang::X86::BI__builtin_ia32_minps:
15077 case clang::X86::BI__builtin_ia32_minpd:
15078 case clang::X86::BI__builtin_ia32_minps256:
15079 case clang::X86::BI__builtin_ia32_minpd256:
15080 case clang::X86::BI__builtin_ia32_minps512:
15081 case clang::X86::BI__builtin_ia32_minpd512:
15082 case clang::X86::BI__builtin_ia32_minph128:
15083 case clang::X86::BI__builtin_ia32_minph256:
15084 case clang::X86::BI__builtin_ia32_minph512:
15085 return EvaluateFpBinOpExpr(
15086 [](
const APFloat &A,
const APFloat &B,
15087 std::optional<APSInt>) -> std::optional<APFloat> {
15088 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15089 B.isInfinity() || B.isDenormal())
15090 return std::nullopt;
15091 if (A.isZero() && B.isZero())
15093 return llvm::minimum(A, B);
15096 case clang::X86::BI__builtin_ia32_minss:
15097 case clang::X86::BI__builtin_ia32_minsd:
15098 return EvaluateFpBinOpExpr(
15099 [](
const APFloat &A,
const APFloat &B,
15100 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15105 case clang::X86::BI__builtin_ia32_minsd_round_mask:
15106 case clang::X86::BI__builtin_ia32_minss_round_mask:
15107 case clang::X86::BI__builtin_ia32_minsh_round_mask:
15108 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
15109 case clang::X86::BI__builtin_ia32_maxss_round_mask:
15110 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
15111 bool IsMin = BuiltinOp == clang::X86::BI__builtin_ia32_minsd_round_mask ||
15112 BuiltinOp == clang::X86::BI__builtin_ia32_minss_round_mask ||
15113 BuiltinOp == clang::X86::BI__builtin_ia32_minsh_round_mask;
15114 return EvaluateScalarFpRoundMaskBinOp(
15115 [IsMin](
const APFloat &A,
const APFloat &B,
15116 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15121 case clang::X86::BI__builtin_ia32_maxps:
15122 case clang::X86::BI__builtin_ia32_maxpd:
15123 case clang::X86::BI__builtin_ia32_maxps256:
15124 case clang::X86::BI__builtin_ia32_maxpd256:
15125 case clang::X86::BI__builtin_ia32_maxps512:
15126 case clang::X86::BI__builtin_ia32_maxpd512:
15127 case clang::X86::BI__builtin_ia32_maxph128:
15128 case clang::X86::BI__builtin_ia32_maxph256:
15129 case clang::X86::BI__builtin_ia32_maxph512:
15130 return EvaluateFpBinOpExpr(
15131 [](
const APFloat &A,
const APFloat &B,
15132 std::optional<APSInt>) -> std::optional<APFloat> {
15133 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15134 B.isInfinity() || B.isDenormal())
15135 return std::nullopt;
15136 if (A.isZero() && B.isZero())
15138 return llvm::maximum(A, B);
15141 case clang::X86::BI__builtin_ia32_maxss:
15142 case clang::X86::BI__builtin_ia32_maxsd:
15143 return EvaluateFpBinOpExpr(
15144 [](
const APFloat &A,
const APFloat &B,
15145 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15150 case clang::X86::BI__builtin_ia32_vcvtps2ph:
15151 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
15161 unsigned SrcNumElems = SrcVTy->getNumElements();
15163 unsigned DstNumElems = DstVTy->getNumElements();
15164 QualType DstElemTy = DstVTy->getElementType();
15166 const llvm::fltSemantics &HalfSem =
15167 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
15169 int ImmVal = Imm.getZExtValue();
15170 bool UseMXCSR = (ImmVal & 4) != 0;
15171 bool IsFPConstrained =
15174 llvm::RoundingMode RM;
15176 switch (ImmVal & 3) {
15178 RM = llvm::RoundingMode::NearestTiesToEven;
15181 RM = llvm::RoundingMode::TowardNegative;
15184 RM = llvm::RoundingMode::TowardPositive;
15187 RM = llvm::RoundingMode::TowardZero;
15190 llvm_unreachable(
"Invalid immediate rounding mode");
15193 RM = llvm::RoundingMode::NearestTiesToEven;
15197 ResultElements.reserve(DstNumElems);
15199 for (
unsigned I = 0; I < SrcNumElems; ++I) {
15203 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
15205 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
15206 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
15210 APSInt DstInt(SrcVal.bitcastToAPInt(),
15212 ResultElements.push_back(
APValue(DstInt));
15215 if (DstNumElems > SrcNumElems) {
15216 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
15217 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
15222 return Success(ResultElements, E);
15224 case X86::BI__builtin_ia32_vperm2f128_pd256:
15225 case X86::BI__builtin_ia32_vperm2f128_ps256:
15226 case X86::BI__builtin_ia32_vperm2f128_si256:
15227 case X86::BI__builtin_ia32_permti256: {
15228 unsigned NumElements =
15230 unsigned PreservedBitsCnt = NumElements >> 2;
15234 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
15235 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
15236 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
15238 if (ControlBits & 0b1000)
15239 return std::make_pair(0u, -1);
15241 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
15242 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
15243 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
15244 (DstIdx & PreservedBitsMask);
15245 return std::make_pair(SrcVecIdx, SrcIdx);
15250 case X86::BI__builtin_ia32_vpdpwssd128:
15251 case X86::BI__builtin_ia32_vpdpwssd256:
15252 case X86::BI__builtin_ia32_vpdpwssd512:
15253 case X86::BI__builtin_ia32_vpdpbusd128:
15254 case X86::BI__builtin_ia32_vpdpbusd256:
15255 case X86::BI__builtin_ia32_vpdpbusd512:
15256 return EvalVectorDotProduct(
false);
15257 case X86::BI__builtin_ia32_vpdpwssds128:
15258 case X86::BI__builtin_ia32_vpdpwssds256:
15259 case X86::BI__builtin_ia32_vpdpwssds512:
15260 case X86::BI__builtin_ia32_vpdpbusds128:
15261 case X86::BI__builtin_ia32_vpdpbusds256:
15262 case X86::BI__builtin_ia32_vpdpbusds512:
15263 return EvalVectorDotProduct(
true);
15264 case X86::BI__builtin_ia32_cvtpd2dq:
15265 case X86::BI__builtin_ia32_cvtps2dq:
15266 case X86::BI__builtin_ia32_cvttpd2dq:
15267 case X86::BI__builtin_ia32_cvttps2dq:
15268 case X86::BI__builtin_ia32_cvtpd2dq256:
15269 case X86::BI__builtin_ia32_cvtps2dq256:
15270 case X86::BI__builtin_ia32_cvttpd2dq256:
15271 case X86::BI__builtin_ia32_cvttps2dq256: {
15278 bool isUnsigned = EltTy->isUnsignedIntegerType();
15279 unsigned BitWidth = Info.Ctx.getIntWidth(EltTy);
15285 for (
unsigned i = 0; i != NumDstElems; ++i) {
15286 if (i < NumSrcElems) {
15288 llvm::APSInt IntResult(BitWidth,
isUnsigned);
15289 bool IsExact =
false;
15292 FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
15296 ResultElts.push_back(
APValue(IntResult));
15301 return Success(ResultElts, E);
15306bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
15312 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
15313 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
15319 ResultElements.reserve(SourceLen);
15320 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
15325 ResultElements.push_back(std::move(Elt));
15328 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15333 APValue const &VecVal2,
unsigned EltNum,
15335 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
15336 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
15339 int64_t
index = IndexVal.getExtValue();
15346 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
15352 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
15353 llvm_unreachable(
"Out of bounds shuffle index");
15355 if (
index >= TotalElementsInInputVector1)
15362bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
15367 const Expr *Vec1 = E->
getExpr(0);
15371 const Expr *Vec2 = E->
getExpr(1);
15375 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
15381 ResultElements.reserve(TotalElementsInOutputVector);
15382 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
15386 ResultElements.push_back(std::move(Elt));
15389 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15397class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
15404 bool Success(ArrayRef<APValue> M,
const Expr *E) {
15406 assert(M.size() == CMTy->getNumElementsFlattened());
15408 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
15412 assert(M.
isMatrix() &&
"expected matrix");
15417 bool VisitCastExpr(
const CastExpr *E);
15418 bool VisitInitListExpr(
const InitListExpr *E);
15424 "not a matrix prvalue");
15425 return MatrixExprEvaluator(Info,
Result).Visit(E);
15428bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15429 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15430 unsigned NumRows = MT->getNumRows();
15431 unsigned NumCols = MT->getNumColumns();
15432 unsigned NElts = NumRows * NumCols;
15433 QualType EltTy = MT->getElementType();
15437 case CK_HLSLAggregateSplatCast: {
15452 case CK_HLSLElementwiseCast: {
15465 return Success(ResultEls, E);
15468 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15472bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
15473 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15474 QualType EltTy = MT->getElementType();
15476 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
15477 "Expected number of elements in initializer list to match the number "
15478 "of matrix elements");
15481 Elements.reserve(MT->getNumElementsFlattened());
15486 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
15487 if (EltTy->isIntegerType()) {
15488 llvm::APSInt IntVal;
15491 Elements.push_back(
APValue(IntVal));
15493 llvm::APFloat FloatVal(0.0);
15496 Elements.push_back(
APValue(FloatVal));
15508 class ArrayExprEvaluator
15509 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
15510 const LValue &
This;
15514 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
15518 assert(
V.isArray() &&
"expected array");
15523 bool ZeroInitialization(
const Expr *E) {
15524 const ConstantArrayType *CAT =
15525 Info.Ctx.getAsConstantArrayType(E->
getType());
15539 if (!
Result.hasArrayFiller())
15543 LValue Subobject =
This;
15544 Subobject.addArray(Info, E, CAT);
15549 bool VisitCallExpr(
const CallExpr *E) {
15550 return handleCallExpr(E,
Result, &This);
15552 bool VisitCastExpr(
const CastExpr *E);
15553 bool VisitInitListExpr(
const InitListExpr *E,
15554 QualType AllocType = QualType());
15555 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
15556 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
15557 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
15558 const LValue &Subobject,
15560 bool VisitStringLiteral(
const StringLiteral *E,
15561 QualType AllocType = QualType()) {
15565 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
15566 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
15567 ArrayRef<Expr *> Args,
15568 const Expr *ArrayFiller,
15569 QualType AllocType = QualType());
15570 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
15578 "not an array prvalue");
15579 return ArrayExprEvaluator(Info,
This,
Result).Visit(E);
15587 "not an array prvalue");
15588 return ArrayExprEvaluator(Info,
This,
Result)
15589 .VisitInitListExpr(ILE, AllocType);
15598 "not an array prvalue");
15599 return ArrayExprEvaluator(Info,
This,
Result)
15600 .VisitCXXConstructExpr(CCE,
This, &
Result, AllocType);
15609 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
15610 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
15615 if (ILE->hasArrayFiller() &&
15624bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15629 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15630 case CK_HLSLAggregateSplatCast: {
15650 case CK_HLSLElementwiseCast: {
15667bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15668 QualType AllocType) {
15669 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15682 return VisitStringLiteral(SL, AllocType);
15687 "transparent array list initialization is not string literal init?");
15693bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15695 QualType AllocType) {
15696 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15701 unsigned NumEltsToInit = Args.size();
15706 if (NumEltsToInit != NumElts &&
15708 NumEltsToInit = NumElts;
15711 for (
auto *
Init : Args) {
15712 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15713 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15716 if (NumEltsToInit > NumElts)
15717 NumEltsToInit = NumElts;
15721 if (
Result.hasValue() && NumEltsToInit <
Result.getArrayInitializedElts())
15722 NumEltsToInit =
Result.getArrayInitializedElts();
15725 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15726 << NumEltsToInit <<
".\n");
15728 if (!
Result.hasValue()) {
15729 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15730 }
else if (
Result.getArrayInitializedElts() != NumEltsToInit) {
15741 APValue NewResult =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15743 unsigned NumOldElts =
Result.getArrayInitializedElts();
15744 for (
unsigned I = 0; I < NumOldElts; ++I) {
15746 std::move(
Result.getArrayInitializedElt(I));
15749 for (
unsigned I =
Result.getArrayInitializedElts(); I < NumEltsToInit; ++I)
15753 Result = std::move(NewResult);
15756 LValue Subobject =
This;
15757 Subobject.addArray(Info, ExprToVisit, CAT);
15758 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15759 if (
Init->isValueDependent())
15768 Subobject,
Init) ||
15771 if (!Info.noteFailure())
15777 unsigned ArrayIndex = 0;
15780 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
15781 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
15782 if (ArrayIndex >= NumEltsToInit)
15784 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
15785 StringLiteral *SL = EmbedS->getDataStringLiteral();
15786 for (
unsigned I = EmbedS->getStartingElementPos(),
15787 N = EmbedS->getDataElementCount();
15788 I != EmbedS->getStartingElementPos() + N; ++I) {
15794 const FPOptions FPO =
15795 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
15800 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
15805 if (!Eval(
Init, ArrayIndex))
15811 if (!
Result.hasArrayFiller())
15816 assert(ArrayFiller &&
"no array filler for incomplete init list");
15822bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
15825 !
Evaluate(Info.CurrentCall->createTemporary(
15828 ScopeKind::FullExpression, CommonLV),
15835 Result =
APValue(APValue::UninitArray(), Elements, Elements);
15837 LValue Subobject =
This;
15838 Subobject.addArray(Info, E, CAT);
15841 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
15850 FullExpressionRAII Scope(Info);
15856 if (!Info.noteFailure())
15868bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
15869 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
15872bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
15873 const LValue &Subobject,
15876 bool HadZeroInit =
Value->hasValue();
15878 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
15883 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
15886 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
15887 if (FinalSize == 0)
15893 LValue ArrayElt = Subobject;
15894 ArrayElt.addArray(Info, E, CAT);
15900 for (
const unsigned N : {1u, FinalSize}) {
15901 unsigned OldElts =
Value->getArrayInitializedElts();
15906 APValue NewValue(APValue::UninitArray(), N, FinalSize);
15907 for (
unsigned I = 0; I < OldElts; ++I)
15908 NewValue.getArrayInitializedElt(I).swap(
15909 Value->getArrayInitializedElt(I));
15910 Value->swap(NewValue);
15913 for (
unsigned I = OldElts; I < N; ++I)
15914 Value->getArrayInitializedElt(I) = Filler;
15916 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
15919 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15920 for (
unsigned I = OldElts; I < FinalSize; ++I)
15921 Value->getArrayInitializedElt(I) = FirstResult;
15923 for (
unsigned I = OldElts; I < N; ++I) {
15924 if (!VisitCXXConstructExpr(E, ArrayElt,
15925 &
Value->getArrayInitializedElt(I),
15932 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
15933 !Info.keepEvaluatingAfterFailure())
15942 if (!
Type->isRecordType())
15945 return RecordExprEvaluator(Info, Subobject, *
Value)
15946 .VisitCXXConstructExpr(E,
Type);
15949bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15950 const CXXParenListInitExpr *E) {
15952 "Expression result is not a constant array type");
15954 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15958bool ArrayExprEvaluator::VisitDesignatedInitUpdateExpr(
15959 const DesignatedInitUpdateExpr *E) {
15974class IntExprEvaluator
15975 :
public ExprEvaluatorBase<IntExprEvaluator> {
15978 IntExprEvaluator(EvalInfo &info,
APValue &result)
15979 : ExprEvaluatorBaseTy(
info),
Result(result) {}
15983 "Invalid evaluation result.");
15985 "Invalid evaluation result.");
15986 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15987 "Invalid evaluation result.");
15991 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
15997 "Invalid evaluation result.");
15998 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15999 "Invalid evaluation result.");
16001 Result.getInt().setIsUnsigned(
16005 bool Success(
const llvm::APInt &I,
const Expr *E) {
16011 "Invalid evaluation result.");
16019 bool Success(CharUnits Size,
const Expr *E) {
16026 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
16027 V.allowConstexprUnknown()) {
16034 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
16036 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
16043 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
16046 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
16050 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
16051 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
16052 if (CheckReferencedDecl(E, E->
getDecl()))
16055 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
16057 bool VisitMemberExpr(
const MemberExpr *E) {
16059 VisitIgnoredBaseExpression(E->
getBase());
16063 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
16066 bool VisitCallExpr(
const CallExpr *E);
16067 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
16068 bool VisitBinaryOperator(
const BinaryOperator *E);
16069 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
16070 bool VisitUnaryOperator(
const UnaryOperator *E);
16072 bool VisitCastExpr(
const CastExpr* E);
16073 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
16075 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
16079 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
16083 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
16084 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
16090 return Success(Info.ArrayInitIndex, E);
16094 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
16095 return ZeroInitialization(E);
16098 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
16107 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
16111 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
16115 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
16122 bool VisitUnaryReal(
const UnaryOperator *E);
16123 bool VisitUnaryImag(
const UnaryOperator *E);
16125 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
16126 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
16127 bool VisitSourceLocExpr(
const SourceLocExpr *E);
16128 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
16133class FixedPointExprEvaluator
16134 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
16138 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
16139 : ExprEvaluatorBaseTy(
info),
Result(result) {}
16141 bool Success(
const llvm::APInt &I,
const Expr *E) {
16143 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16148 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16152 return Success(
V.getFixedPoint(), E);
16155 bool Success(
const APFixedPoint &
V,
const Expr *E) {
16157 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
16158 "Invalid evaluation result.");
16163 bool ZeroInitialization(
const Expr *E) {
16171 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
16175 bool VisitCastExpr(
const CastExpr *E);
16176 bool VisitUnaryOperator(
const UnaryOperator *E);
16177 bool VisitBinaryOperator(
const BinaryOperator *E);
16193 return IntExprEvaluator(Info,
Result).Visit(E);
16201 if (!Val.
isInt()) {
16204 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16211bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
16213 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
16222 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
16237 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
16241 Result = APFixedPoint(Val, FXSema);
16252bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
16254 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
16256 bool SameSign = (ECD->getInitVal().isSigned()
16258 bool SameWidth = (ECD->getInitVal().
getBitWidth()
16259 == Info.Ctx.getIntWidth(E->
getType()));
16260 if (SameSign && SameWidth)
16261 return Success(ECD->getInitVal(), E);
16265 llvm::APSInt Val = ECD->getInitVal();
16267 Val.setIsSigned(!ECD->getInitVal().isSigned());
16269 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
16280 assert(!
T->isDependentType() &&
"unexpected dependent type");
16285#define TYPE(ID, BASE)
16286#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
16287#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
16288#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
16289#include "clang/AST/TypeNodes.inc"
16291 case Type::DeducedTemplateSpecialization:
16292 llvm_unreachable(
"unexpected non-canonical or dependent type");
16294 case Type::Builtin:
16296#define BUILTIN_TYPE(ID, SINGLETON_ID)
16297#define SIGNED_TYPE(ID, SINGLETON_ID) \
16298 case BuiltinType::ID: return GCCTypeClass::Integer;
16299#define FLOATING_TYPE(ID, SINGLETON_ID) \
16300 case BuiltinType::ID: return GCCTypeClass::RealFloat;
16301#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
16302 case BuiltinType::ID: break;
16303#include "clang/AST/BuiltinTypes.def"
16304 case BuiltinType::Void:
16307 case BuiltinType::Bool:
16310 case BuiltinType::Char_U:
16311 case BuiltinType::UChar:
16312 case BuiltinType::WChar_U:
16313 case BuiltinType::Char8:
16314 case BuiltinType::Char16:
16315 case BuiltinType::Char32:
16316 case BuiltinType::UShort:
16317 case BuiltinType::UInt:
16318 case BuiltinType::ULong:
16319 case BuiltinType::ULongLong:
16320 case BuiltinType::UInt128:
16323 case BuiltinType::UShortAccum:
16324 case BuiltinType::UAccum:
16325 case BuiltinType::ULongAccum:
16326 case BuiltinType::UShortFract:
16327 case BuiltinType::UFract:
16328 case BuiltinType::ULongFract:
16329 case BuiltinType::SatUShortAccum:
16330 case BuiltinType::SatUAccum:
16331 case BuiltinType::SatULongAccum:
16332 case BuiltinType::SatUShortFract:
16333 case BuiltinType::SatUFract:
16334 case BuiltinType::SatULongFract:
16337 case BuiltinType::NullPtr:
16339 case BuiltinType::ObjCId:
16340 case BuiltinType::ObjCClass:
16341 case BuiltinType::ObjCSel:
16342#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
16343 case BuiltinType::Id:
16344#include "clang/Basic/OpenCLImageTypes.def"
16345#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
16346 case BuiltinType::Id:
16347#include "clang/Basic/OpenCLExtensionTypes.def"
16348 case BuiltinType::OCLSampler:
16349 case BuiltinType::OCLEvent:
16350 case BuiltinType::OCLClkEvent:
16351 case BuiltinType::OCLQueue:
16352 case BuiltinType::OCLReserveID:
16353#define SVE_TYPE(Name, Id, SingletonId) \
16354 case BuiltinType::Id:
16355#include "clang/Basic/AArch64ACLETypes.def"
16356#define PPC_VECTOR_TYPE(Name, Id, Size) \
16357 case BuiltinType::Id:
16358#include "clang/Basic/PPCTypes.def"
16359#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16360#include "clang/Basic/RISCVVTypes.def"
16361#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16362#include "clang/Basic/WebAssemblyReferenceTypes.def"
16363#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
16364#include "clang/Basic/AMDGPUTypes.def"
16365#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16366#include "clang/Basic/HLSLIntangibleTypes.def"
16367#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16368#include "clang/Basic/SPIRVTypes.def"
16371 case BuiltinType::Dependent:
16372 llvm_unreachable(
"unexpected dependent type");
16374 llvm_unreachable(
"unexpected placeholder type");
16379 case Type::Pointer:
16380 case Type::ConstantArray:
16381 case Type::VariableArray:
16382 case Type::IncompleteArray:
16383 case Type::FunctionNoProto:
16384 case Type::FunctionProto:
16385 case Type::ArrayParameter:
16388 case Type::MemberPointer:
16393 case Type::Complex:
16406 case Type::ExtVector:
16409 case Type::BlockPointer:
16410 case Type::ConstantMatrix:
16411 case Type::ObjCObject:
16412 case Type::ObjCInterface:
16413 case Type::ObjCObjectPointer:
16415 case Type::HLSLAttributedResource:
16416 case Type::HLSLInlineSpirv:
16417 case Type::OverflowBehavior:
16425 case Type::LValueReference:
16426 case Type::RValueReference:
16427 llvm_unreachable(
"invalid type for expression");
16430 llvm_unreachable(
"unexpected type class");
16455 if (
Base.isNull()) {
16458 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
16477 SpeculativeEvaluationRAII SpeculativeEval(Info);
16482 FoldConstant Fold(Info,
true);
16500 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
16501 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
16502 ArgType->isNullPtrType()) {
16505 Fold.keepDiagnostics();
16514 return V.hasValue();
16525 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
16549 const auto *Cast = dyn_cast<CastExpr>(NoParens);
16550 if (Cast ==
nullptr)
16555 auto CastKind = Cast->getCastKind();
16557 CastKind != CK_AddressSpaceConversion)
16560 const auto *SubExpr = Cast->getSubExpr();
16582 assert(!LVal.Designator.Invalid);
16584 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
16592 auto &
Base = LVal.getLValueBase();
16593 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
16594 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
16595 if (!IsLastOrInvalidFieldDecl(FD))
16597 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
16598 for (
auto *FD : IFD->chain()) {
16607 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
16611 if (BaseType->isIncompleteArrayType())
16617 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
16618 const auto &Entry = LVal.Designator.Entries[I];
16619 if (BaseType->isArrayType()) {
16625 uint64_t Index = Entry.getAsArrayIndex();
16629 }
else if (BaseType->isAnyComplexType()) {
16630 const auto *CT = BaseType->castAs<
ComplexType>();
16631 uint64_t Index = Entry.getAsArrayIndex();
16634 BaseType = CT->getElementType();
16635 }
else if (
auto *FD = getAsField(Entry)) {
16636 if (!IsLastOrInvalidFieldDecl(FD))
16640 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
16652 if (LVal.Designator.Invalid)
16655 if (!LVal.Designator.Entries.empty())
16656 return LVal.Designator.isMostDerivedAnUnsizedArray();
16658 if (!LVal.InvalidBase)
16670 const SubobjectDesignator &
Designator = LVal.Designator;
16682 auto isFlexibleArrayMember = [&] {
16684 FAMKind StrictFlexArraysLevel =
16687 if (
Designator.isMostDerivedAnUnsizedArray())
16690 if (StrictFlexArraysLevel == FAMKind::Default)
16693 if (
Designator.getMostDerivedArraySize() == 0 &&
16694 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
16697 if (
Designator.getMostDerivedArraySize() == 1 &&
16698 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16704 return LVal.InvalidBase &&
16706 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16714 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16715 if (Int.ugt(CharUnitsMax))
16725 if (!
T.isNull() &&
T->isStructureType() &&
16726 T->castAsRecordDecl()->hasFlexibleArrayMember())
16727 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16728 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16740 unsigned Type,
const LValue &LVal,
16759 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
16761 if (
Type == 3 && !DetermineForCompleteObject)
16764 llvm::APInt APEndOffset;
16765 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16769 if (LVal.InvalidBase)
16773 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
16779 const SubobjectDesignator &
Designator = LVal.Designator;
16791 llvm::APInt APEndOffset;
16792 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16804 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
16810 int64_t ElemsRemaining;
16813 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
16814 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
16815 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
16817 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
16820 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
16830static std::optional<uint64_t>
16832 bool IsDynamic =
false) {
16840 SpeculativeEvaluationRAII SpeculativeEval(Info);
16841 IgnoreSideEffectsRAII Fold(Info);
16848 return std::nullopt;
16849 LVal.setFrom(Info.Ctx, RVal);
16852 return std::nullopt;
16857 if (LVal.getLValueOffset().isNegative())
16872 const auto *FD = ME ? dyn_cast<FieldDecl>(ME->getMemberDecl()) :
nullptr;
16874 return std::nullopt;
16879 return std::nullopt;
16883 if (EndOffset <= LVal.getLValueOffset())
16885 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
16888bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16889 if (!IsConstantEvaluatedBuiltinCall(E))
16890 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16907 Info.FFDiag(E->
getArg(0));
16913 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
16914 "Bit widths must be the same");
16921bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
16922 unsigned BuiltinOp) {
16923 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
16925 APValue SourceLHS, SourceRHS;
16933 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
16935 APInt AWide(LaneWidth * SourceLen, 0);
16936 APInt BWide(LaneWidth * SourceLen, 0);
16938 for (
unsigned I = 0; I != SourceLen; ++I) {
16941 if (ElemQT->isIntegerType()) {
16944 }
else if (ElemQT->isFloatingType()) {
16952 AWide.insertBits(ALane, I * LaneWidth);
16953 BWide.insertBits(BLane, I * LaneWidth);
16958 auto HandleMaskBinOp =
16971 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16977 uint64_t CRCVal = CRC.getZExtValue();
16981 static const uint32_t CRC32C_POLY = 0x82F63B78;
16985 for (
unsigned I = 0; I != DataBytes; ++I) {
16986 uint8_t Byte =
static_cast<uint8_t>((DataVal >> (I * 8)) & 0xFF);
16988 for (
int J = 0; J != 8; ++J) {
16996 switch (BuiltinOp) {
17000 case X86::BI__builtin_ia32_crc32qi:
17001 return HandleCRC32(1);
17002 case X86::BI__builtin_ia32_crc32hi:
17003 return HandleCRC32(2);
17004 case X86::BI__builtin_ia32_crc32si:
17005 return HandleCRC32(4);
17006 case X86::BI__builtin_ia32_crc32di:
17007 return HandleCRC32(8);
17009 case Builtin::BI__builtin_dynamic_object_size:
17010 case Builtin::BI__builtin_object_size: {
17014 assert(
Type <= 3 &&
"unexpected type");
17016 bool IsDynamic = BuiltinOp == Builtin::BI__builtin_dynamic_object_size;
17017 if (std::optional<uint64_t> Size =
17026 switch (Info.EvalMode) {
17027 case EvaluationMode::ConstantExpression:
17028 case EvaluationMode::ConstantFold:
17029 case EvaluationMode::IgnoreSideEffects:
17032 case EvaluationMode::ConstantExpressionUnevaluated:
17037 llvm_unreachable(
"unexpected EvalMode");
17040 case Builtin::BI__builtin_os_log_format_buffer_size: {
17041 analyze_os_log::OSLogBufferLayout Layout;
17046 case Builtin::BI__builtin_is_aligned: {
17054 Ptr.setFrom(Info.Ctx, Src);
17060 assert(Alignment.isPowerOf2());
17073 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
17077 assert(Src.
isInt());
17078 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
17080 case Builtin::BI__builtin_align_up: {
17088 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
17089 Src.
getInt().isUnsigned());
17090 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17091 return Success(AlignedVal, E);
17093 case Builtin::BI__builtin_align_down: {
17102 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17103 return Success(AlignedVal, E);
17106 case Builtin::BI__builtin_bitreverseg:
17107 case Builtin::BI__builtin_bitreverse8:
17108 case Builtin::BI__builtin_bitreverse16:
17109 case Builtin::BI__builtin_bitreverse32:
17110 case Builtin::BI__builtin_bitreverse64:
17111 case Builtin::BI__builtin_elementwise_bitreverse: {
17116 return Success(Val.reverseBits(), E);
17118 case Builtin::BI__builtin_bswapg:
17119 case Builtin::BI__builtin_bswap16:
17120 case Builtin::BI__builtin_bswap32:
17121 case Builtin::BI__builtin_bswap64:
17122 case Builtin::BIstdc_memreverse8u8:
17123 case Builtin::BIstdc_memreverse8u16:
17124 case Builtin::BIstdc_memreverse8u32:
17125 case Builtin::BIstdc_memreverse8u64: {
17129 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
17132 return Success(Val.byteSwap(), E);
17135 case Builtin::BI__builtin_classify_type:
17138 case Builtin::BI__builtin_clrsb:
17139 case Builtin::BI__builtin_clrsbl:
17140 case Builtin::BI__builtin_clrsbll: {
17145 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
17148 case Builtin::BI__builtin_clz:
17149 case Builtin::BI__builtin_clzl:
17150 case Builtin::BI__builtin_clzll:
17151 case Builtin::BI__builtin_clzs:
17152 case Builtin::BI__builtin_clzg:
17153 case Builtin::BI__builtin_elementwise_clzg:
17154 case Builtin::BI__lzcnt16:
17155 case Builtin::BI__lzcnt:
17156 case Builtin::BI__lzcnt64: {
17167 std::optional<APSInt> Fallback;
17168 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
17169 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
17174 Fallback = FallbackTemp;
17179 return Success(*Fallback, E);
17184 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
17185 BuiltinOp != Builtin::BI__lzcnt &&
17186 BuiltinOp != Builtin::BI__lzcnt64;
17188 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
17189 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17193 if (ZeroIsUndefined)
17197 return Success(Val.countl_zero(), E);
17200 case Builtin::BI__builtin_constant_p: {
17201 const Expr *Arg = E->
getArg(0);
17210 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17214 case Builtin::BI__noop:
17218 case Builtin::BI__builtin_is_constant_evaluated: {
17219 const auto *
Callee = Info.CurrentCall->getCallee();
17220 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
17221 (Info.CallStackDepth == 1 ||
17222 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
17223 Callee->getIdentifier() &&
17224 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
17226 if (Info.EvalStatus.Diag)
17227 Info.report((Info.CallStackDepth == 1)
17229 : Info.CurrentCall->getCallRange().getBegin(),
17230 diag::warn_is_constant_evaluated_always_true_constexpr)
17231 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
17232 :
"std::is_constant_evaluated");
17235 return Success(Info.InConstantContext, E);
17238 case Builtin::BI__builtin_is_within_lifetime:
17239 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
17243 case Builtin::BI__builtin_ctz:
17244 case Builtin::BI__builtin_ctzl:
17245 case Builtin::BI__builtin_ctzll:
17246 case Builtin::BI__builtin_ctzs:
17247 case Builtin::BI__builtin_ctzg:
17248 case Builtin::BI__builtin_elementwise_ctzg: {
17259 std::optional<APSInt> Fallback;
17260 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
17261 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
17266 Fallback = FallbackTemp;
17271 return Success(*Fallback, E);
17273 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
17274 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17280 return Success(Val.countr_zero(), E);
17283 case Builtin::BI__builtin_eh_return_data_regno: {
17285 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
17289 case Builtin::BI__builtin_elementwise_abs: {
17294 return Success(Val.abs(), E);
17297 case Builtin::BI__builtin_expect:
17298 case Builtin::BI__builtin_expect_with_probability:
17299 return Visit(E->
getArg(0));
17301 case Builtin::BI__builtin_ptrauth_string_discriminator: {
17308 case Builtin::BI__builtin_infer_alloc_token: {
17314 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
17317 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
17319 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
17320 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
17321 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
17323 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
17324 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
17326 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
17327 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
17330 case Builtin::BI__builtin_ffs:
17331 case Builtin::BI__builtin_ffsl:
17332 case Builtin::BI__builtin_ffsll: {
17337 unsigned N = Val.countr_zero();
17338 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
17341 case Builtin::BI__builtin_fpclassify: {
17346 switch (Val.getCategory()) {
17347 case APFloat::fcNaN: Arg = 0;
break;
17348 case APFloat::fcInfinity: Arg = 1;
break;
17349 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
17350 case APFloat::fcZero: Arg = 4;
break;
17352 return Visit(E->
getArg(Arg));
17355 case Builtin::BI__builtin_isinf_sign: {
17358 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
17361 case Builtin::BI__builtin_isinf: {
17364 Success(Val.isInfinity() ? 1 : 0, E);
17367 case Builtin::BI__builtin_isfinite: {
17370 Success(Val.isFinite() ? 1 : 0, E);
17373 case Builtin::BI__builtin_isnan: {
17376 Success(Val.isNaN() ? 1 : 0, E);
17379 case Builtin::BI__builtin_isnormal: {
17382 Success(Val.isNormal() ? 1 : 0, E);
17385 case Builtin::BI__builtin_issubnormal: {
17388 Success(Val.isDenormal() ? 1 : 0, E);
17391 case Builtin::BI__builtin_iszero: {
17394 Success(Val.isZero() ? 1 : 0, E);
17397 case Builtin::BI__builtin_signbit:
17398 case Builtin::BI__builtin_signbitf:
17399 case Builtin::BI__builtin_signbitl: {
17402 Success(Val.isNegative() ? 1 : 0, E);
17405 case Builtin::BI__builtin_isgreater:
17406 case Builtin::BI__builtin_isgreaterequal:
17407 case Builtin::BI__builtin_isless:
17408 case Builtin::BI__builtin_islessequal:
17409 case Builtin::BI__builtin_islessgreater:
17410 case Builtin::BI__builtin_isunordered: {
17419 switch (BuiltinOp) {
17420 case Builtin::BI__builtin_isgreater:
17422 case Builtin::BI__builtin_isgreaterequal:
17424 case Builtin::BI__builtin_isless:
17426 case Builtin::BI__builtin_islessequal:
17428 case Builtin::BI__builtin_islessgreater: {
17429 APFloat::cmpResult cmp = LHS.compare(RHS);
17430 return cmp == APFloat::cmpResult::cmpLessThan ||
17431 cmp == APFloat::cmpResult::cmpGreaterThan;
17433 case Builtin::BI__builtin_isunordered:
17434 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
17436 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
17437 "point comparison function");
17445 case Builtin::BI__builtin_issignaling: {
17448 Success(Val.isSignaling() ? 1 : 0, E);
17451 case Builtin::BI__builtin_isfpclass: {
17455 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
17458 Success((Val.classify() & Test) ? 1 : 0, E);
17461 case Builtin::BI__builtin_parity:
17462 case Builtin::BI__builtin_parityl:
17463 case Builtin::BI__builtin_parityll: {
17468 return Success(Val.popcount() % 2, E);
17471 case Builtin::BI__builtin_abs:
17472 case Builtin::BI__builtin_labs:
17473 case Builtin::BI__builtin_llabs: {
17477 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
17480 if (Val.isNegative())
17485 case Builtin::BI__builtin_popcount:
17486 case Builtin::BI__builtin_popcountl:
17487 case Builtin::BI__builtin_popcountll:
17488 case Builtin::BI__builtin_popcountg:
17489 case Builtin::BI__builtin_elementwise_popcount:
17490 case Builtin::BI__popcnt16:
17491 case Builtin::BI__popcnt:
17492 case Builtin::BI__popcnt64: {
17503 return Success(Val.popcount(), E);
17506 case Builtin::BI__builtin_rotateleft8:
17507 case Builtin::BI__builtin_rotateleft16:
17508 case Builtin::BI__builtin_rotateleft32:
17509 case Builtin::BI__builtin_rotateleft64:
17510 case Builtin::BI__builtin_rotateright8:
17511 case Builtin::BI__builtin_rotateright16:
17512 case Builtin::BI__builtin_rotateright32:
17513 case Builtin::BI__builtin_rotateright64:
17514 case Builtin::BI__builtin_stdc_rotate_left:
17515 case Builtin::BI__builtin_stdc_rotate_right:
17516 case Builtin::BIstdc_rotate_left_uc:
17517 case Builtin::BIstdc_rotate_left_us:
17518 case Builtin::BIstdc_rotate_left_ui:
17519 case Builtin::BIstdc_rotate_left_ul:
17520 case Builtin::BIstdc_rotate_left_ull:
17521 case Builtin::BIstdc_rotate_right_uc:
17522 case Builtin::BIstdc_rotate_right_us:
17523 case Builtin::BIstdc_rotate_right_ui:
17524 case Builtin::BIstdc_rotate_right_ul:
17525 case Builtin::BIstdc_rotate_right_ull:
17526 case Builtin::BI_rotl8:
17527 case Builtin::BI_rotl16:
17528 case Builtin::BI_rotl:
17529 case Builtin::BI_lrotl:
17530 case Builtin::BI_rotl64:
17531 case Builtin::BI_rotr8:
17532 case Builtin::BI_rotr16:
17533 case Builtin::BI_rotr:
17534 case Builtin::BI_lrotr:
17535 case Builtin::BI_rotr64: {
17543 switch (BuiltinOp) {
17544 case Builtin::BI__builtin_rotateright8:
17545 case Builtin::BI__builtin_rotateright16:
17546 case Builtin::BI__builtin_rotateright32:
17547 case Builtin::BI__builtin_rotateright64:
17548 case Builtin::BI__builtin_stdc_rotate_right:
17549 case Builtin::BIstdc_rotate_right_uc:
17550 case Builtin::BIstdc_rotate_right_us:
17551 case Builtin::BIstdc_rotate_right_ui:
17552 case Builtin::BIstdc_rotate_right_ul:
17553 case Builtin::BIstdc_rotate_right_ull:
17554 case Builtin::BI_rotr8:
17555 case Builtin::BI_rotr16:
17556 case Builtin::BI_rotr:
17557 case Builtin::BI_lrotr:
17558 case Builtin::BI_rotr64:
17567 case Builtin::BIstdc_leading_zeros_uc:
17568 case Builtin::BIstdc_leading_zeros_us:
17569 case Builtin::BIstdc_leading_zeros_ui:
17570 case Builtin::BIstdc_leading_zeros_ul:
17571 case Builtin::BIstdc_leading_zeros_ull:
17572 case Builtin::BIstdc_leading_ones_uc:
17573 case Builtin::BIstdc_leading_ones_us:
17574 case Builtin::BIstdc_leading_ones_ui:
17575 case Builtin::BIstdc_leading_ones_ul:
17576 case Builtin::BIstdc_leading_ones_ull:
17577 case Builtin::BIstdc_trailing_zeros_uc:
17578 case Builtin::BIstdc_trailing_zeros_us:
17579 case Builtin::BIstdc_trailing_zeros_ui:
17580 case Builtin::BIstdc_trailing_zeros_ul:
17581 case Builtin::BIstdc_trailing_zeros_ull:
17582 case Builtin::BIstdc_trailing_ones_uc:
17583 case Builtin::BIstdc_trailing_ones_us:
17584 case Builtin::BIstdc_trailing_ones_ui:
17585 case Builtin::BIstdc_trailing_ones_ul:
17586 case Builtin::BIstdc_trailing_ones_ull:
17587 case Builtin::BIstdc_first_leading_zero_uc:
17588 case Builtin::BIstdc_first_leading_zero_us:
17589 case Builtin::BIstdc_first_leading_zero_ui:
17590 case Builtin::BIstdc_first_leading_zero_ul:
17591 case Builtin::BIstdc_first_leading_zero_ull:
17592 case Builtin::BIstdc_first_leading_one_uc:
17593 case Builtin::BIstdc_first_leading_one_us:
17594 case Builtin::BIstdc_first_leading_one_ui:
17595 case Builtin::BIstdc_first_leading_one_ul:
17596 case Builtin::BIstdc_first_leading_one_ull:
17597 case Builtin::BIstdc_first_trailing_zero_uc:
17598 case Builtin::BIstdc_first_trailing_zero_us:
17599 case Builtin::BIstdc_first_trailing_zero_ui:
17600 case Builtin::BIstdc_first_trailing_zero_ul:
17601 case Builtin::BIstdc_first_trailing_zero_ull:
17602 case Builtin::BIstdc_first_trailing_one_uc:
17603 case Builtin::BIstdc_first_trailing_one_us:
17604 case Builtin::BIstdc_first_trailing_one_ui:
17605 case Builtin::BIstdc_first_trailing_one_ul:
17606 case Builtin::BIstdc_first_trailing_one_ull:
17607 case Builtin::BIstdc_count_zeros_uc:
17608 case Builtin::BIstdc_count_zeros_us:
17609 case Builtin::BIstdc_count_zeros_ui:
17610 case Builtin::BIstdc_count_zeros_ul:
17611 case Builtin::BIstdc_count_zeros_ull:
17612 case Builtin::BIstdc_count_ones_uc:
17613 case Builtin::BIstdc_count_ones_us:
17614 case Builtin::BIstdc_count_ones_ui:
17615 case Builtin::BIstdc_count_ones_ul:
17616 case Builtin::BIstdc_count_ones_ull:
17617 case Builtin::BIstdc_has_single_bit_uc:
17618 case Builtin::BIstdc_has_single_bit_us:
17619 case Builtin::BIstdc_has_single_bit_ui:
17620 case Builtin::BIstdc_has_single_bit_ul:
17621 case Builtin::BIstdc_has_single_bit_ull:
17622 case Builtin::BIstdc_bit_width_uc:
17623 case Builtin::BIstdc_bit_width_us:
17624 case Builtin::BIstdc_bit_width_ui:
17625 case Builtin::BIstdc_bit_width_ul:
17626 case Builtin::BIstdc_bit_width_ull:
17627 case Builtin::BIstdc_bit_floor_uc:
17628 case Builtin::BIstdc_bit_floor_us:
17629 case Builtin::BIstdc_bit_floor_ui:
17630 case Builtin::BIstdc_bit_floor_ul:
17631 case Builtin::BIstdc_bit_floor_ull:
17632 case Builtin::BIstdc_bit_ceil_uc:
17633 case Builtin::BIstdc_bit_ceil_us:
17634 case Builtin::BIstdc_bit_ceil_ui:
17635 case Builtin::BIstdc_bit_ceil_ul:
17636 case Builtin::BIstdc_bit_ceil_ull:
17637 case Builtin::BI__builtin_stdc_leading_zeros:
17638 case Builtin::BI__builtin_stdc_leading_ones:
17639 case Builtin::BI__builtin_stdc_trailing_zeros:
17640 case Builtin::BI__builtin_stdc_trailing_ones:
17641 case Builtin::BI__builtin_stdc_first_leading_zero:
17642 case Builtin::BI__builtin_stdc_first_leading_one:
17643 case Builtin::BI__builtin_stdc_first_trailing_zero:
17644 case Builtin::BI__builtin_stdc_first_trailing_one:
17645 case Builtin::BI__builtin_stdc_count_zeros:
17646 case Builtin::BI__builtin_stdc_count_ones:
17647 case Builtin::BI__builtin_stdc_has_single_bit:
17648 case Builtin::BI__builtin_stdc_bit_width:
17649 case Builtin::BI__builtin_stdc_bit_floor:
17650 case Builtin::BI__builtin_stdc_bit_ceil: {
17655 unsigned BitWidth = Val.getBitWidth();
17656 const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->
getType());
17658 switch (BuiltinOp) {
17659 case Builtin::BIstdc_leading_zeros_uc:
17660 case Builtin::BIstdc_leading_zeros_us:
17661 case Builtin::BIstdc_leading_zeros_ui:
17662 case Builtin::BIstdc_leading_zeros_ul:
17663 case Builtin::BIstdc_leading_zeros_ull:
17664 case Builtin::BI__builtin_stdc_leading_zeros:
17665 return Success(
APInt(ResBitWidth, Val.countl_zero()), E);
17666 case Builtin::BIstdc_leading_ones_uc:
17667 case Builtin::BIstdc_leading_ones_us:
17668 case Builtin::BIstdc_leading_ones_ui:
17669 case Builtin::BIstdc_leading_ones_ul:
17670 case Builtin::BIstdc_leading_ones_ull:
17671 case Builtin::BI__builtin_stdc_leading_ones:
17672 return Success(
APInt(ResBitWidth, Val.countl_one()), E);
17673 case Builtin::BIstdc_trailing_zeros_uc:
17674 case Builtin::BIstdc_trailing_zeros_us:
17675 case Builtin::BIstdc_trailing_zeros_ui:
17676 case Builtin::BIstdc_trailing_zeros_ul:
17677 case Builtin::BIstdc_trailing_zeros_ull:
17678 case Builtin::BI__builtin_stdc_trailing_zeros:
17679 return Success(
APInt(ResBitWidth, Val.countr_zero()), E);
17680 case Builtin::BIstdc_trailing_ones_uc:
17681 case Builtin::BIstdc_trailing_ones_us:
17682 case Builtin::BIstdc_trailing_ones_ui:
17683 case Builtin::BIstdc_trailing_ones_ul:
17684 case Builtin::BIstdc_trailing_ones_ull:
17685 case Builtin::BI__builtin_stdc_trailing_ones:
17686 return Success(
APInt(ResBitWidth, Val.countr_one()), E);
17687 case Builtin::BIstdc_first_leading_zero_uc:
17688 case Builtin::BIstdc_first_leading_zero_us:
17689 case Builtin::BIstdc_first_leading_zero_ui:
17690 case Builtin::BIstdc_first_leading_zero_ul:
17691 case Builtin::BIstdc_first_leading_zero_ull:
17692 case Builtin::BI__builtin_stdc_first_leading_zero:
17694 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
17695 case Builtin::BIstdc_first_leading_one_uc:
17696 case Builtin::BIstdc_first_leading_one_us:
17697 case Builtin::BIstdc_first_leading_one_ui:
17698 case Builtin::BIstdc_first_leading_one_ul:
17699 case Builtin::BIstdc_first_leading_one_ull:
17700 case Builtin::BI__builtin_stdc_first_leading_one:
17702 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
17703 case Builtin::BIstdc_first_trailing_zero_uc:
17704 case Builtin::BIstdc_first_trailing_zero_us:
17705 case Builtin::BIstdc_first_trailing_zero_ui:
17706 case Builtin::BIstdc_first_trailing_zero_ul:
17707 case Builtin::BIstdc_first_trailing_zero_ull:
17708 case Builtin::BI__builtin_stdc_first_trailing_zero:
17710 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
17711 case Builtin::BIstdc_first_trailing_one_uc:
17712 case Builtin::BIstdc_first_trailing_one_us:
17713 case Builtin::BIstdc_first_trailing_one_ui:
17714 case Builtin::BIstdc_first_trailing_one_ul:
17715 case Builtin::BIstdc_first_trailing_one_ull:
17716 case Builtin::BI__builtin_stdc_first_trailing_one:
17718 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
17719 case Builtin::BIstdc_count_zeros_uc:
17720 case Builtin::BIstdc_count_zeros_us:
17721 case Builtin::BIstdc_count_zeros_ui:
17722 case Builtin::BIstdc_count_zeros_ul:
17723 case Builtin::BIstdc_count_zeros_ull:
17724 case Builtin::BI__builtin_stdc_count_zeros: {
17725 APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
17728 case Builtin::BIstdc_count_ones_uc:
17729 case Builtin::BIstdc_count_ones_us:
17730 case Builtin::BIstdc_count_ones_ui:
17731 case Builtin::BIstdc_count_ones_ul:
17732 case Builtin::BIstdc_count_ones_ull:
17733 case Builtin::BI__builtin_stdc_count_ones: {
17734 APInt Cnt(ResBitWidth, Val.popcount());
17737 case Builtin::BIstdc_has_single_bit_uc:
17738 case Builtin::BIstdc_has_single_bit_us:
17739 case Builtin::BIstdc_has_single_bit_ui:
17740 case Builtin::BIstdc_has_single_bit_ul:
17741 case Builtin::BIstdc_has_single_bit_ull:
17742 case Builtin::BI__builtin_stdc_has_single_bit: {
17743 APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
17746 case Builtin::BIstdc_bit_width_uc:
17747 case Builtin::BIstdc_bit_width_us:
17748 case Builtin::BIstdc_bit_width_ui:
17749 case Builtin::BIstdc_bit_width_ul:
17750 case Builtin::BIstdc_bit_width_ull:
17751 case Builtin::BI__builtin_stdc_bit_width:
17752 return Success(
APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
17753 case Builtin::BIstdc_bit_floor_uc:
17754 case Builtin::BIstdc_bit_floor_us:
17755 case Builtin::BIstdc_bit_floor_ui:
17756 case Builtin::BIstdc_bit_floor_ul:
17757 case Builtin::BIstdc_bit_floor_ull:
17758 case Builtin::BI__builtin_stdc_bit_floor: {
17761 unsigned Exp = BitWidth - Val.countl_zero() - 1;
17763 APSInt(APInt::getOneBitSet(BitWidth, Exp),
true), E);
17765 case Builtin::BIstdc_bit_ceil_uc:
17766 case Builtin::BIstdc_bit_ceil_us:
17767 case Builtin::BIstdc_bit_ceil_ui:
17768 case Builtin::BIstdc_bit_ceil_ul:
17769 case Builtin::BIstdc_bit_ceil_ull:
17770 case Builtin::BI__builtin_stdc_bit_ceil: {
17773 APInt ValMinusOne = Val - 1;
17774 unsigned LZ = ValMinusOne.countl_zero();
17778 APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
17782 llvm_unreachable(
"Unknown stdc builtin");
17786 case Builtin::BI__builtin_elementwise_add_sat: {
17792 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
17795 case Builtin::BI__builtin_elementwise_sub_sat: {
17801 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
17804 case Builtin::BI__builtin_elementwise_max: {
17813 case Builtin::BI__builtin_elementwise_min: {
17822 case Builtin::BI__builtin_elementwise_clmul: {
17831 case Builtin::BI__builtin_elementwise_fshl:
17832 case Builtin::BI__builtin_elementwise_fshr: {
17839 switch (BuiltinOp) {
17840 case Builtin::BI__builtin_elementwise_fshl: {
17841 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
17844 case Builtin::BI__builtin_elementwise_fshr: {
17845 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
17849 llvm_unreachable(
"Fully covered switch above");
17851 case Builtin::BIstrlen:
17852 case Builtin::BIwcslen:
17854 if (Info.getLangOpts().CPlusPlus11)
17855 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17857 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17859 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17861 case Builtin::BI__builtin_strlen:
17862 case Builtin::BI__builtin_wcslen: {
17865 if (std::optional<uint64_t> StrLen =
17871 case Builtin::BIstrcmp:
17872 case Builtin::BIwcscmp:
17873 case Builtin::BIstrncmp:
17874 case Builtin::BIwcsncmp:
17875 case Builtin::BImemcmp:
17876 case Builtin::BIbcmp:
17877 case Builtin::BIwmemcmp:
17879 if (Info.getLangOpts().CPlusPlus11)
17880 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17882 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17884 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17886 case Builtin::BI__builtin_strcmp:
17887 case Builtin::BI__builtin_wcscmp:
17888 case Builtin::BI__builtin_strncmp:
17889 case Builtin::BI__builtin_wcsncmp:
17890 case Builtin::BI__builtin_memcmp:
17891 case Builtin::BI__builtin_bcmp:
17892 case Builtin::BI__builtin_wmemcmp: {
17893 LValue String1, String2;
17899 if (BuiltinOp != Builtin::BIstrcmp &&
17900 BuiltinOp != Builtin::BIwcscmp &&
17901 BuiltinOp != Builtin::BI__builtin_strcmp &&
17902 BuiltinOp != Builtin::BI__builtin_wcscmp) {
17906 MaxLength = N.getZExtValue();
17910 if (MaxLength == 0u)
17913 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17914 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17915 String1.Designator.Invalid || String2.Designator.Invalid)
17918 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
17919 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
17921 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
17922 BuiltinOp == Builtin::BIbcmp ||
17923 BuiltinOp == Builtin::BI__builtin_memcmp ||
17924 BuiltinOp == Builtin::BI__builtin_bcmp;
17926 assert(IsRawByte ||
17927 (Info.Ctx.hasSameUnqualifiedType(
17929 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
17936 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
17937 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
17942 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
17945 Char1.
isInt() && Char2.isInt();
17947 const auto &AdvanceElems = [&] {
17953 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
17954 BuiltinOp != Builtin::BIwmemcmp &&
17955 BuiltinOp != Builtin::BI__builtin_memcmp &&
17956 BuiltinOp != Builtin::BI__builtin_bcmp &&
17957 BuiltinOp != Builtin::BI__builtin_wmemcmp);
17958 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
17959 BuiltinOp == Builtin::BIwcsncmp ||
17960 BuiltinOp == Builtin::BIwmemcmp ||
17961 BuiltinOp == Builtin::BI__builtin_wcscmp ||
17962 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
17963 BuiltinOp == Builtin::BI__builtin_wmemcmp;
17965 for (; MaxLength; --MaxLength) {
17967 if (!ReadCurElems(Char1, Char2))
17975 if (StopAtNull && !Char1.
getInt())
17977 assert(!(StopAtNull && !Char2.
getInt()));
17978 if (!AdvanceElems())
17985 case Builtin::BI__atomic_always_lock_free:
17986 case Builtin::BI__atomic_is_lock_free:
17987 case Builtin::BI__c11_atomic_is_lock_free: {
18003 if (
Size.isPowerOfTwo()) {
18005 unsigned InlineWidthBits =
18006 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
18007 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
18008 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
18014 const Expr *PtrArg = E->
getArg(1);
18020 IntResult.isAligned(
Size.getAsAlign()))
18024 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
18027 if (ICE->getCastKind() == CK_BitCast)
18028 PtrArg = ICE->getSubExpr();
18031 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
18034 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
18042 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
18045 case Builtin::BI__builtin_addcb:
18046 case Builtin::BI__builtin_addcs:
18047 case Builtin::BI__builtin_addc:
18048 case Builtin::BI__builtin_addcl:
18049 case Builtin::BI__builtin_addcll:
18050 case Builtin::BI__builtin_subcb:
18051 case Builtin::BI__builtin_subcs:
18052 case Builtin::BI__builtin_subc:
18053 case Builtin::BI__builtin_subcl:
18054 case Builtin::BI__builtin_subcll: {
18055 LValue CarryOutLValue;
18067 bool FirstOverflowed =
false;
18068 bool SecondOverflowed =
false;
18069 switch (BuiltinOp) {
18071 llvm_unreachable(
"Invalid value for BuiltinOp");
18072 case Builtin::BI__builtin_addcb:
18073 case Builtin::BI__builtin_addcs:
18074 case Builtin::BI__builtin_addc:
18075 case Builtin::BI__builtin_addcl:
18076 case Builtin::BI__builtin_addcll:
18078 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
18080 case Builtin::BI__builtin_subcb:
18081 case Builtin::BI__builtin_subcs:
18082 case Builtin::BI__builtin_subc:
18083 case Builtin::BI__builtin_subcl:
18084 case Builtin::BI__builtin_subcll:
18086 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
18092 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
18098 case Builtin::BI__builtin_add_overflow:
18099 case Builtin::BI__builtin_sub_overflow:
18100 case Builtin::BI__builtin_mul_overflow:
18101 case Builtin::BI__builtin_sadd_overflow:
18102 case Builtin::BI__builtin_uadd_overflow:
18103 case Builtin::BI__builtin_uaddl_overflow:
18104 case Builtin::BI__builtin_uaddll_overflow:
18105 case Builtin::BI__builtin_usub_overflow:
18106 case Builtin::BI__builtin_usubl_overflow:
18107 case Builtin::BI__builtin_usubll_overflow:
18108 case Builtin::BI__builtin_umul_overflow:
18109 case Builtin::BI__builtin_umull_overflow:
18110 case Builtin::BI__builtin_umulll_overflow:
18111 case Builtin::BI__builtin_saddl_overflow:
18112 case Builtin::BI__builtin_saddll_overflow:
18113 case Builtin::BI__builtin_ssub_overflow:
18114 case Builtin::BI__builtin_ssubl_overflow:
18115 case Builtin::BI__builtin_ssubll_overflow:
18116 case Builtin::BI__builtin_smul_overflow:
18117 case Builtin::BI__builtin_smull_overflow:
18118 case Builtin::BI__builtin_smulll_overflow: {
18119 LValue ResultLValue;
18129 bool DidOverflow =
false;
18132 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18133 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18134 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18135 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
18137 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
18139 uint64_t LHSSize = LHS.getBitWidth();
18140 uint64_t RHSSize = RHS.getBitWidth();
18141 uint64_t ResultSize = Info.Ctx.getIntWidth(ResultType);
18142 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
18148 if (IsSigned && !AllSigned)
18151 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
18152 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
18157 switch (BuiltinOp) {
18159 llvm_unreachable(
"Invalid value for BuiltinOp");
18160 case Builtin::BI__builtin_add_overflow:
18161 case Builtin::BI__builtin_sadd_overflow:
18162 case Builtin::BI__builtin_saddl_overflow:
18163 case Builtin::BI__builtin_saddll_overflow:
18164 case Builtin::BI__builtin_uadd_overflow:
18165 case Builtin::BI__builtin_uaddl_overflow:
18166 case Builtin::BI__builtin_uaddll_overflow:
18167 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
18168 : LHS.uadd_ov(RHS, DidOverflow);
18170 case Builtin::BI__builtin_sub_overflow:
18171 case Builtin::BI__builtin_ssub_overflow:
18172 case Builtin::BI__builtin_ssubl_overflow:
18173 case Builtin::BI__builtin_ssubll_overflow:
18174 case Builtin::BI__builtin_usub_overflow:
18175 case Builtin::BI__builtin_usubl_overflow:
18176 case Builtin::BI__builtin_usubll_overflow:
18177 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
18178 : LHS.usub_ov(RHS, DidOverflow);
18180 case Builtin::BI__builtin_mul_overflow:
18181 case Builtin::BI__builtin_smul_overflow:
18182 case Builtin::BI__builtin_smull_overflow:
18183 case Builtin::BI__builtin_smulll_overflow:
18184 case Builtin::BI__builtin_umul_overflow:
18185 case Builtin::BI__builtin_umull_overflow:
18186 case Builtin::BI__builtin_umulll_overflow:
18187 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
18188 : LHS.umul_ov(RHS, DidOverflow);
18197 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getIntWidth(ResultType));
18202 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18203 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18204 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18205 if (!APSInt::isSameValue(Temp,
Result))
18206 DidOverflow =
true;
18213 return Success(DidOverflow, E);
18216 case Builtin::BI__builtin_reduce_add:
18217 case Builtin::BI__builtin_reduce_mul:
18218 case Builtin::BI__builtin_reduce_and:
18219 case Builtin::BI__builtin_reduce_or:
18220 case Builtin::BI__builtin_reduce_xor:
18221 case Builtin::BI__builtin_reduce_min:
18222 case Builtin::BI__builtin_reduce_max: {
18229 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
18230 switch (BuiltinOp) {
18233 case Builtin::BI__builtin_reduce_add: {
18236 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
18240 case Builtin::BI__builtin_reduce_mul: {
18243 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
18247 case Builtin::BI__builtin_reduce_and: {
18251 case Builtin::BI__builtin_reduce_or: {
18255 case Builtin::BI__builtin_reduce_xor: {
18259 case Builtin::BI__builtin_reduce_min: {
18263 case Builtin::BI__builtin_reduce_max: {
18273 case clang::X86::BI__builtin_ia32_addcarryx_u32:
18274 case clang::X86::BI__builtin_ia32_addcarryx_u64:
18275 case clang::X86::BI__builtin_ia32_subborrow_u32:
18276 case clang::X86::BI__builtin_ia32_subborrow_u64: {
18277 LValue ResultLValue;
18278 APSInt CarryIn, LHS, RHS;
18286 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
18287 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
18289 unsigned BitWidth = LHS.getBitWidth();
18290 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
18293 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
18294 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
18296 APInt Result = ExResult.extractBits(BitWidth, 0);
18297 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
18305 case clang::X86::BI__builtin_ia32_movmskps:
18306 case clang::X86::BI__builtin_ia32_movmskpd:
18307 case clang::X86::BI__builtin_ia32_pmovmskb128:
18308 case clang::X86::BI__builtin_ia32_pmovmskb256:
18309 case clang::X86::BI__builtin_ia32_movmskps256:
18310 case clang::X86::BI__builtin_ia32_movmskpd256: {
18317 unsigned ResultLen = Info.Ctx.getTypeSize(
18321 for (
unsigned I = 0; I != SourceLen; ++I) {
18323 if (ElemQT->isIntegerType()) {
18325 }
else if (ElemQT->isRealFloatingType()) {
18330 Result.setBitVal(I, Elem.isNegative());
18335 case clang::X86::BI__builtin_ia32_bextr_u32:
18336 case clang::X86::BI__builtin_ia32_bextr_u64:
18337 case clang::X86::BI__builtin_ia32_bextri_u32:
18338 case clang::X86::BI__builtin_ia32_bextri_u64: {
18344 unsigned BitWidth = Val.getBitWidth();
18346 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
18347 Length = Length > BitWidth ? BitWidth : Length;
18350 if (Length == 0 || Shift >= BitWidth)
18354 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
18358 case clang::X86::BI__builtin_ia32_bzhi_si:
18359 case clang::X86::BI__builtin_ia32_bzhi_di: {
18365 unsigned BitWidth = Val.getBitWidth();
18366 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
18367 if (Index < BitWidth)
18368 Val.clearHighBits(BitWidth - Index);
18372 case clang::X86::BI__builtin_ia32_ktestcqi:
18373 case clang::X86::BI__builtin_ia32_ktestchi:
18374 case clang::X86::BI__builtin_ia32_ktestcsi:
18375 case clang::X86::BI__builtin_ia32_ktestcdi: {
18381 return Success((~A & B) == 0, E);
18384 case clang::X86::BI__builtin_ia32_ktestzqi:
18385 case clang::X86::BI__builtin_ia32_ktestzhi:
18386 case clang::X86::BI__builtin_ia32_ktestzsi:
18387 case clang::X86::BI__builtin_ia32_ktestzdi: {
18393 return Success((A & B) == 0, E);
18396 case clang::X86::BI__builtin_ia32_kortestcqi:
18397 case clang::X86::BI__builtin_ia32_kortestchi:
18398 case clang::X86::BI__builtin_ia32_kortestcsi:
18399 case clang::X86::BI__builtin_ia32_kortestcdi: {
18405 return Success(~(A | B) == 0, E);
18408 case clang::X86::BI__builtin_ia32_kortestzqi:
18409 case clang::X86::BI__builtin_ia32_kortestzhi:
18410 case clang::X86::BI__builtin_ia32_kortestzsi:
18411 case clang::X86::BI__builtin_ia32_kortestzdi: {
18417 return Success((A | B) == 0, E);
18420 case clang::X86::BI__builtin_ia32_kunpckhi:
18421 case clang::X86::BI__builtin_ia32_kunpckdi:
18422 case clang::X86::BI__builtin_ia32_kunpcksi: {
18430 unsigned BW = A.getBitWidth();
18431 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
18435 case clang::X86::BI__builtin_ia32_lzcnt_u16:
18436 case clang::X86::BI__builtin_ia32_lzcnt_u32:
18437 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
18441 return Success(Val.countLeadingZeros(), E);
18444 case clang::X86::BI__builtin_ia32_tzcnt_u16:
18445 case clang::X86::BI__builtin_ia32_tzcnt_u32:
18446 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
18450 return Success(Val.countTrailingZeros(), E);
18453 case Builtin::BI__builtin_elementwise_pdep: {
18458 return Success(llvm::APIntOps::pdep(Val, Msk), E);
18461 case Builtin::BI__builtin_elementwise_pext: {
18466 return Success(llvm::APIntOps::pext(Val, Msk), E);
18469 case X86::BI__builtin_ia32_ptestz128:
18470 case X86::BI__builtin_ia32_ptestz256:
18471 case X86::BI__builtin_ia32_vtestzps:
18472 case X86::BI__builtin_ia32_vtestzps256:
18473 case X86::BI__builtin_ia32_vtestzpd:
18474 case X86::BI__builtin_ia32_vtestzpd256: {
18476 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
18478 case X86::BI__builtin_ia32_ptestc128:
18479 case X86::BI__builtin_ia32_ptestc256:
18480 case X86::BI__builtin_ia32_vtestcps:
18481 case X86::BI__builtin_ia32_vtestcps256:
18482 case X86::BI__builtin_ia32_vtestcpd:
18483 case X86::BI__builtin_ia32_vtestcpd256: {
18485 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
18487 case X86::BI__builtin_ia32_ptestnzc128:
18488 case X86::BI__builtin_ia32_ptestnzc256:
18489 case X86::BI__builtin_ia32_vtestnzcps:
18490 case X86::BI__builtin_ia32_vtestnzcps256:
18491 case X86::BI__builtin_ia32_vtestnzcpd:
18492 case X86::BI__builtin_ia32_vtestnzcpd256: {
18493 return EvalTestOp([](
const APInt &A,
const APInt &B) {
18494 return ((A & B) != 0) && ((~A & B) != 0);
18497 case X86::BI__builtin_ia32_kandqi:
18498 case X86::BI__builtin_ia32_kandhi:
18499 case X86::BI__builtin_ia32_kandsi:
18500 case X86::BI__builtin_ia32_kanddi: {
18501 return HandleMaskBinOp(
18502 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
18505 case X86::BI__builtin_ia32_kandnqi:
18506 case X86::BI__builtin_ia32_kandnhi:
18507 case X86::BI__builtin_ia32_kandnsi:
18508 case X86::BI__builtin_ia32_kandndi: {
18509 return HandleMaskBinOp(
18510 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
18513 case X86::BI__builtin_ia32_korqi:
18514 case X86::BI__builtin_ia32_korhi:
18515 case X86::BI__builtin_ia32_korsi:
18516 case X86::BI__builtin_ia32_kordi: {
18517 return HandleMaskBinOp(
18518 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
18521 case X86::BI__builtin_ia32_kxnorqi:
18522 case X86::BI__builtin_ia32_kxnorhi:
18523 case X86::BI__builtin_ia32_kxnorsi:
18524 case X86::BI__builtin_ia32_kxnordi: {
18525 return HandleMaskBinOp(
18526 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
18529 case X86::BI__builtin_ia32_kxorqi:
18530 case X86::BI__builtin_ia32_kxorhi:
18531 case X86::BI__builtin_ia32_kxorsi:
18532 case X86::BI__builtin_ia32_kxordi: {
18533 return HandleMaskBinOp(
18534 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
18537 case X86::BI__builtin_ia32_knotqi:
18538 case X86::BI__builtin_ia32_knothi:
18539 case X86::BI__builtin_ia32_knotsi:
18540 case X86::BI__builtin_ia32_knotdi: {
18548 case X86::BI__builtin_ia32_kaddqi:
18549 case X86::BI__builtin_ia32_kaddhi:
18550 case X86::BI__builtin_ia32_kaddsi:
18551 case X86::BI__builtin_ia32_kadddi: {
18552 return HandleMaskBinOp(
18553 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
18556 case X86::BI__builtin_ia32_kmovb:
18557 case X86::BI__builtin_ia32_kmovw:
18558 case X86::BI__builtin_ia32_kmovd:
18559 case X86::BI__builtin_ia32_kmovq: {
18566 case X86::BI__builtin_ia32_kshiftliqi:
18567 case X86::BI__builtin_ia32_kshiftlihi:
18568 case X86::BI__builtin_ia32_kshiftlisi:
18569 case X86::BI__builtin_ia32_kshiftlidi: {
18570 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18571 unsigned Amt = RHS.getZExtValue() & 0xFF;
18572 if (Amt >= LHS.getBitWidth())
18573 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18574 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
18578 case X86::BI__builtin_ia32_kshiftriqi:
18579 case X86::BI__builtin_ia32_kshiftrihi:
18580 case X86::BI__builtin_ia32_kshiftrisi:
18581 case X86::BI__builtin_ia32_kshiftridi: {
18582 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18583 unsigned Amt = RHS.getZExtValue() & 0xFF;
18584 if (Amt >= LHS.getBitWidth())
18585 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18586 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
18590 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
18591 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
18592 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
18593 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
18594 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
18595 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
18596 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
18597 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
18598 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
18605 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18609 case clang::X86::BI__builtin_ia32_cvtb2mask128:
18610 case clang::X86::BI__builtin_ia32_cvtb2mask256:
18611 case clang::X86::BI__builtin_ia32_cvtb2mask512:
18612 case clang::X86::BI__builtin_ia32_cvtw2mask128:
18613 case clang::X86::BI__builtin_ia32_cvtw2mask256:
18614 case clang::X86::BI__builtin_ia32_cvtw2mask512:
18615 case clang::X86::BI__builtin_ia32_cvtd2mask128:
18616 case clang::X86::BI__builtin_ia32_cvtd2mask256:
18617 case clang::X86::BI__builtin_ia32_cvtd2mask512:
18618 case clang::X86::BI__builtin_ia32_cvtq2mask128:
18619 case clang::X86::BI__builtin_ia32_cvtq2mask256:
18620 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
18627 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
18628 llvm::APInt Bits(RetWidth, 0);
18630 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
18632 unsigned MSB = A[A.getBitWidth() - 1];
18633 Bits.setBitVal(ElemNum, MSB);
18636 APSInt RetMask(Bits,
true);
18640 case clang::X86::BI__builtin_ia32_cmpb128_mask:
18641 case clang::X86::BI__builtin_ia32_cmpw128_mask:
18642 case clang::X86::BI__builtin_ia32_cmpd128_mask:
18643 case clang::X86::BI__builtin_ia32_cmpq128_mask:
18644 case clang::X86::BI__builtin_ia32_cmpb256_mask:
18645 case clang::X86::BI__builtin_ia32_cmpw256_mask:
18646 case clang::X86::BI__builtin_ia32_cmpd256_mask:
18647 case clang::X86::BI__builtin_ia32_cmpq256_mask:
18648 case clang::X86::BI__builtin_ia32_cmpb512_mask:
18649 case clang::X86::BI__builtin_ia32_cmpw512_mask:
18650 case clang::X86::BI__builtin_ia32_cmpd512_mask:
18651 case clang::X86::BI__builtin_ia32_cmpq512_mask:
18652 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
18653 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
18654 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
18655 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
18656 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
18657 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
18658 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
18659 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
18660 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
18661 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
18662 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
18663 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
18667 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
18668 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
18681 unsigned RetWidth = Mask.getBitWidth();
18683 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18685 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
18690 switch (
Opcode.getExtValue() & 0x7) {
18695 Result = IsUnsigned ? A.ult(B) : A.slt(B);
18698 Result = IsUnsigned ? A.ule(B) : A.sle(B);
18707 Result = IsUnsigned ? A.uge(B) : A.sge(B);
18710 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
18717 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
18722 case X86::BI__builtin_ia32_cvtss2si:
18723 case X86::BI__builtin_ia32_cvtsd2si:
18724 case X86::BI__builtin_ia32_cvttss2si:
18725 case X86::BI__builtin_ia32_cvttsd2si:
18726 case X86::BI__builtin_ia32_cvtss2si64:
18727 case X86::BI__builtin_ia32_cvtsd2si64:
18728 case X86::BI__builtin_ia32_cvttss2si64:
18729 case X86::BI__builtin_ia32_cvttsd2si64: {
18734 assert(ArgVal.
isVector() &&
"Expected a vector argument");
18736 unsigned BitWidth = Info.Ctx.getIntWidth(E->
getType());
18739 llvm::APSInt IntResult(BitWidth,
isUnsigned);
18740 bool IsExact =
false;
18743 FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
18748 return Success(IntResult, E);
18750 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
18751 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
18752 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
18765 unsigned NumBytesInQWord = 8;
18766 unsigned NumBitsInByte = 8;
18768 unsigned NumQWords = NumBytes / NumBytesInQWord;
18769 unsigned RetWidth = ZeroMask.getBitWidth();
18770 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18772 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
18773 APInt SourceQWord(64, 0);
18774 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18778 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
18781 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18782 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
18785 if (ZeroMask[SelIdx]) {
18786 RetMask.setBitVal(SelIdx, SourceQWord[M]);
18798 const LValue &LV) {
18801 if (!LV.getLValueBase())
18806 if (!LV.getLValueDesignator().Invalid &&
18807 !LV.getLValueDesignator().isOnePastTheEnd())
18817 if (LV.getLValueDesignator().Invalid)
18823 return LV.getLValueOffset() == Size;
18833class DataRecursiveIntBinOpEvaluator {
18834 struct EvalResult {
18836 bool Failed =
false;
18838 EvalResult() =
default;
18840 void swap(EvalResult &RHS) {
18842 Failed = RHS.Failed;
18843 RHS.Failed =
false;
18849 EvalResult LHSResult;
18850 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
18853 Job(Job &&) =
default;
18855 void startSpeculativeEval(EvalInfo &Info) {
18856 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
18860 SpeculativeEvaluationRAII SpecEvalRAII;
18863 SmallVector<Job, 16> Queue;
18865 IntExprEvaluator &IntEval;
18870 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
18871 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
18877 static bool shouldEnqueue(
const BinaryOperator *E) {
18884 bool Traverse(
const BinaryOperator *E) {
18886 EvalResult PrevResult;
18887 while (!Queue.empty())
18888 process(PrevResult);
18890 if (PrevResult.Failed)
return false;
18892 FinalResult.
swap(PrevResult.Val);
18903 bool Error(
const Expr *E) {
18904 return IntEval.Error(E);
18907 return IntEval.Error(E, D);
18910 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
18911 return Info.CCEDiag(E, D);
18915 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18916 bool &SuppressRHSDiags);
18918 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18921 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
18927 void process(EvalResult &
Result);
18929 void enqueue(
const Expr *E) {
18931 Queue.resize(Queue.size()+1);
18932 Queue.back().E = E;
18933 Queue.back().Kind = Job::AnyExprKind;
18939bool DataRecursiveIntBinOpEvaluator::
18940 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18941 bool &SuppressRHSDiags) {
18944 if (LHSResult.Failed)
18945 return Info.noteSideEffect();
18954 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
18955 Success(LHSAsBool, E, LHSResult.Val);
18959 LHSResult.Failed =
true;
18963 if (!Info.noteSideEffect())
18969 SuppressRHSDiags =
true;
18978 if (LHSResult.Failed && !Info.noteFailure())
18989 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
18991 uint64_t Offset64 = Offset.getQuantity();
18992 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
18994 : Offset64 + Index64);
18997bool DataRecursiveIntBinOpEvaluator::
18998 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
19001 if (RHSResult.Failed)
19008 bool lhsResult, rhsResult;
19023 if (rhsResult == (E->
getOpcode() == BO_LOr))
19034 if (LHSResult.Failed || RHSResult.Failed)
19037 const APValue &LHSVal = LHSResult.Val;
19038 const APValue &RHSVal = RHSResult.Val;
19062 if (!LHSExpr || !RHSExpr)
19064 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19065 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19066 if (!LHSAddrExpr || !RHSAddrExpr)
19091void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
19092 Job &job = Queue.back();
19094 switch (job.Kind) {
19095 case Job::AnyExprKind: {
19096 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
19097 if (shouldEnqueue(Bop)) {
19098 job.Kind = Job::BinOpKind;
19099 enqueue(Bop->getLHS());
19104 EvaluateExpr(job.E,
Result);
19109 case Job::BinOpKind: {
19111 bool SuppressRHSDiags =
false;
19112 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
19116 if (SuppressRHSDiags)
19117 job.startSpeculativeEval(Info);
19118 job.LHSResult.swap(
Result);
19119 job.Kind = Job::BinOpVisitedLHSKind;
19124 case Job::BinOpVisitedLHSKind: {
19128 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
19134 llvm_unreachable(
"Invalid Job::Kind!");
19138enum class CmpResult {
19147template <
class SuccessCB,
class AfterCB>
19150 SuccessCB &&
Success, AfterCB &&DoAfter) {
19155 "unsupported binary expression evaluation");
19157 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
19171 if (!LHSOK && !Info.noteFailure())
19176 return Success(CmpResult::Less, E);
19178 return Success(CmpResult::Greater, E);
19179 return Success(CmpResult::Equal, E);
19183 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
19184 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
19187 if (!LHSOK && !Info.noteFailure())
19192 return Success(CmpResult::Less, E);
19194 return Success(CmpResult::Greater, E);
19195 return Success(CmpResult::Equal, E);
19199 ComplexValue LHS, RHS;
19208 LHS.makeComplexFloat();
19209 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
19214 if (!LHSOK && !Info.noteFailure())
19220 RHS.makeComplexFloat();
19221 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
19225 if (LHS.isComplexFloat()) {
19226 APFloat::cmpResult CR_r =
19227 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
19228 APFloat::cmpResult CR_i =
19229 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
19230 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
19231 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19233 assert(IsEquality &&
"invalid complex comparison");
19234 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
19235 LHS.getComplexIntImag() == RHS.getComplexIntImag();
19236 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19242 APFloat RHS(0.0), LHS(0.0);
19245 if (!LHSOK && !Info.noteFailure())
19252 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
19253 if (!Info.InConstantContext &&
19254 APFloatCmpResult == APFloat::cmpUnordered &&
19257 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
19260 auto GetCmpRes = [&]() {
19261 switch (APFloatCmpResult) {
19262 case APFloat::cmpEqual:
19263 return CmpResult::Equal;
19264 case APFloat::cmpLessThan:
19265 return CmpResult::Less;
19266 case APFloat::cmpGreaterThan:
19267 return CmpResult::Greater;
19268 case APFloat::cmpUnordered:
19269 return CmpResult::Unordered;
19271 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
19273 return Success(GetCmpRes(), E);
19277 LValue LHSValue, RHSValue;
19280 if (!LHSOK && !Info.noteFailure())
19291 if (Info.checkingPotentialConstantExpression() &&
19292 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19294 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
19295 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19296 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19297 Info.FFDiag(E, DiagID)
19304 return DiagComparison(
19305 diag::note_constexpr_pointer_comparison_unspecified);
19311 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
19312 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
19313 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
19327 return DiagComparison(diag::note_constexpr_literal_comparison);
19329 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
19334 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
19338 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
19340 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19342 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
19344 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19350 return DiagComparison(
19351 diag::note_constexpr_pointer_comparison_zero_sized);
19352 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
19353 return DiagComparison(
19354 diag::note_constexpr_pointer_comparison_unspecified);
19356 return Success(CmpResult::Unequal, E);
19359 CharUnits LHSOffset = LHSValue.getLValueOffset();
19360 CharUnits RHSOffset = RHSValue.getLValueOffset();
19362 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19363 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19373 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
19374 bool WasArrayIndex;
19377 :
getType(LHSValue.Base).getNonReferenceType(),
19378 LHSDesignator, RHSDesignator, WasArrayIndex);
19385 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
19386 Mismatch < RHSDesignator.Entries.size()) {
19387 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
19388 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
19390 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
19392 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19393 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
19396 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19397 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
19402 diag::note_constexpr_pointer_comparison_differing_access)
19410 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
19413 assert(PtrSize <= 64 &&
"Unexpected pointer width");
19414 uint64_t Mask = ~0ULL >> (64 - PtrSize);
19415 CompareLHS &= Mask;
19416 CompareRHS &= Mask;
19421 if (!LHSValue.Base.
isNull() && IsRelational) {
19425 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
19426 uint64_t OffsetLimit = Size.getQuantity();
19427 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
19431 if (CompareLHS < CompareRHS)
19432 return Success(CmpResult::Less, E);
19433 if (CompareLHS > CompareRHS)
19434 return Success(CmpResult::Greater, E);
19435 return Success(CmpResult::Equal, E);
19439 assert(IsEquality &&
"unexpected member pointer operation");
19442 MemberPtr LHSValue, RHSValue;
19445 if (!LHSOK && !Info.noteFailure())
19453 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
19454 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19455 << LHSValue.getDecl();
19458 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
19459 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19460 << RHSValue.getDecl();
19467 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
19468 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
19469 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19474 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
19475 if (MD->isVirtual())
19476 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19477 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
19478 if (MD->isVirtual())
19479 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19485 bool Equal = LHSValue == RHSValue;
19486 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19491 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
19499 return Success(CmpResult::Equal, E);
19509 Info.Ctx.CompCategories.getInfoForType(E->
getType());
19518 ConstantExprKind::Normal);
19521bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
19525 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19528 case CmpResult::Unequal:
19529 llvm_unreachable(
"should never produce Unequal for three-way comparison");
19530 case CmpResult::Less:
19531 CCR = ComparisonCategoryResult::Less;
19533 case CmpResult::Equal:
19534 CCR = ComparisonCategoryResult::Equal;
19536 case CmpResult::Greater:
19537 CCR = ComparisonCategoryResult::Greater;
19539 case CmpResult::Unordered:
19540 CCR = ComparisonCategoryResult::Unordered;
19546 return ExprEvaluatorBaseTy::VisitBinCmp(E);
19550bool RecordExprEvaluator::VisitTypeTraitExpr(
const TypeTraitExpr *E) {
19555 "expected a strong_ordering type trait with a stored value");
19562bool RecordExprEvaluator::VisitCXXParenListInitExpr(
19563 const CXXParenListInitExpr *E) {
19564 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
19567bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19572 if (!Info.noteFailure())
19576 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
19577 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
19581 "DataRecursiveIntBinOpEvaluator should have handled integral types");
19586 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19587 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
19588 "should only produce Unequal for equality comparisons");
19589 bool IsEqual = CR == CmpResult::Equal,
19590 IsLess = CR == CmpResult::Less,
19591 IsGreater = CR == CmpResult::Greater;
19595 llvm_unreachable(
"unsupported binary operator");
19598 return Success(IsEqual == (Op == BO_EQ), E);
19602 return Success(IsGreater, E);
19604 return Success(IsEqual || IsLess, E);
19606 return Success(IsEqual || IsGreater, E);
19610 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19619 LValue LHSValue, RHSValue;
19622 if (!LHSOK && !Info.noteFailure())
19631 if (Info.checkingPotentialConstantExpression() &&
19632 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19635 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
19636 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
19638 auto DiagArith = [&](
unsigned DiagID) {
19639 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19640 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19641 Info.FFDiag(E, DiagID) << LHS << RHS;
19642 if (LHSExpr && LHSExpr == RHSExpr)
19644 diag::note_constexpr_repeated_literal_eval)
19649 if (!LHSExpr || !RHSExpr)
19650 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
19653 return DiagArith(diag::note_constexpr_literal_arith);
19655 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19656 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19657 if (!LHSAddrExpr || !RHSAddrExpr)
19665 CharUnits LHSOffset = LHSValue.getLValueOffset();
19666 CharUnits RHSOffset = RHSValue.getLValueOffset();
19668 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19669 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19675 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
19678 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
19683 CharUnits ElementSize;
19690 if (ElementSize.
isZero()) {
19691 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
19708 APSInt TrueResult = (LHS - RHS) / ElemSize;
19711 if (
Result.extend(65) != TrueResult &&
19717 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19722bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
19723 const UnaryExprOrTypeTraitExpr *E) {
19725 case UETT_PreferredAlignOf:
19726 case UETT_AlignOf: {
19735 case UETT_PtrAuthTypeDiscriminator: {
19741 case UETT_VecStep: {
19745 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
19757 case UETT_DataSizeOf:
19758 case UETT_SizeOf: {
19762 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
19773 case UETT_OpenMPRequiredSimdAlign:
19776 Info.Ctx.toCharUnitsFromBits(
19780 case UETT_VectorElements: {
19784 if (
const auto *VT = Ty->
getAs<VectorType>())
19788 if (Info.InConstantContext)
19789 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
19794 case UETT_CountOf: {
19800 if (
const auto *CAT =
19810 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
19812 if (VAT->getElementType()->isArrayType()) {
19815 if (!VAT->getSizeExpr()) {
19820 std::optional<APSInt> Res =
19821 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
19826 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
19827 Res->getZExtValue()};
19839 llvm_unreachable(
"unknown expr/type trait");
19842bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
19843 Info.Ctx.recordOffsetOfEvaluation(OOE);
19849 for (
unsigned i = 0; i != n; ++i) {
19857 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
19861 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
19864 if (IdxResult.isNegative() || IdxResult.getActiveBits() > 63)
19866 int64_t IdxVal = IdxResult.getExtValue();
19869 ElemSize > std::numeric_limits<int64_t>::max() / IdxVal)
19870 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19871 int64_t Offset = IdxVal * ElemSize;
19872 if (
Result.getQuantity() > std::numeric_limits<int64_t>::max() - Offset)
19873 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19879 FieldDecl *MemberDecl = ON.
getField();
19884 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19886 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
19893 llvm_unreachable(
"dependent __builtin_offsetof");
19896 CXXBaseSpecifier *BaseSpec = ON.
getBase();
19905 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19908 CurrentType = BaseSpec->
getType();
19922bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19942 if (Info.checkingForUndefinedBehavior())
19943 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19944 diag::warn_integer_constant_overflow)
19972bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19974 QualType DestType = E->
getType();
19975 QualType SrcType = SubExpr->
getType();
19978 case CK_BaseToDerived:
19979 case CK_DerivedToBase:
19980 case CK_UncheckedDerivedToBase:
19983 case CK_ArrayToPointerDecay:
19984 case CK_FunctionToPointerDecay:
19985 case CK_NullToPointer:
19986 case CK_NullToMemberPointer:
19987 case CK_BaseToDerivedMemberPointer:
19988 case CK_DerivedToBaseMemberPointer:
19989 case CK_ReinterpretMemberPointer:
19990 case CK_ConstructorConversion:
19991 case CK_IntegralToPointer:
19993 case CK_VectorSplat:
19994 case CK_IntegralToFloating:
19995 case CK_FloatingCast:
19996 case CK_CPointerToObjCPointerCast:
19997 case CK_BlockPointerToObjCPointerCast:
19998 case CK_AnyPointerToBlockPointerCast:
19999 case CK_ObjCObjectLValueCast:
20000 case CK_FloatingRealToComplex:
20001 case CK_FloatingComplexToReal:
20002 case CK_FloatingComplexCast:
20003 case CK_FloatingComplexToIntegralComplex:
20004 case CK_IntegralRealToComplex:
20005 case CK_IntegralComplexCast:
20006 case CK_IntegralComplexToFloatingComplex:
20007 case CK_BuiltinFnToFnPtr:
20008 case CK_ZeroToOCLOpaqueType:
20009 case CK_NonAtomicToAtomic:
20010 case CK_AddressSpaceConversion:
20011 case CK_IntToOCLSampler:
20012 case CK_FloatingToFixedPoint:
20013 case CK_FixedPointToFloating:
20014 case CK_FixedPointCast:
20015 case CK_IntegralToFixedPoint:
20016 case CK_MatrixCast:
20017 case CK_HLSLAggregateSplatCast:
20018 llvm_unreachable(
"invalid cast kind for integral value");
20022 case CK_LValueBitCast:
20023 case CK_ARCProduceObject:
20024 case CK_ARCConsumeObject:
20025 case CK_ARCReclaimReturnedObject:
20026 case CK_ARCExtendBlockObject:
20027 case CK_CopyAndAutoreleaseBlockObject:
20030 case CK_UserDefinedConversion:
20031 case CK_LValueToRValue:
20032 case CK_AtomicToNonAtomic:
20034 case CK_LValueToRValueBitCast:
20035 case CK_HLSLArrayRValue:
20036 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20038 case CK_MemberPointerToBoolean:
20039 case CK_PointerToBoolean:
20040 case CK_IntegralToBoolean:
20041 case CK_FloatingToBoolean:
20042 case CK_BooleanToSignedIntegral:
20043 case CK_FloatingComplexToBoolean:
20044 case CK_IntegralComplexToBoolean: {
20049 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
20051 return Success(IntResult, E);
20054 case CK_FixedPointToIntegral: {
20055 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
20059 llvm::APSInt
Result = Src.convertToInt(
20060 Info.Ctx.getIntWidth(DestType),
20067 case CK_FixedPointToBoolean: {
20070 if (!
Evaluate(Val, Info, SubExpr))
20075 case CK_IntegralCast: {
20076 if (!Visit(SubExpr))
20086 if (
Result.isAddrLabelDiff()) {
20087 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
20088 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
20091 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
20094 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
20106 if (!ED->isFixed()) {
20110 ED->getValueRange(
Max,
Min);
20113 if (ED->getNumNegativeBits() &&
20114 (
Max.slt(
Result.getInt().getSExtValue()) ||
20115 Min.sgt(
Result.getInt().getSExtValue())))
20116 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20117 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
20118 <<
Max.getSExtValue() << ED;
20119 else if (!ED->getNumNegativeBits() &&
20120 Max.ult(
Result.getInt().getZExtValue()))
20121 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20122 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
20123 <<
Max.getZExtValue() << ED;
20131 case CK_PointerToIntegral: {
20132 CCEDiag(E, diag::note_constexpr_invalid_cast_ptrtoint)
20133 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
20140 if (LV.getLValueBase()) {
20141 CCEDiag(E, diag::note_constexpr_has_lvalue) << E->
getSourceRange();
20146 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
20149 LV.Designator.setInvalid();
20157 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
20158 llvm_unreachable(
"Can't cast this!");
20163 case CK_IntegralComplexToReal: {
20167 return Success(
C.getComplexIntReal(), E);
20170 case CK_FloatingToIntegral: {
20180 case CK_HLSLVectorTruncation: {
20186 case CK_HLSLMatrixTruncation: {
20192 case CK_HLSLElementwiseCast: {
20205 return Success(ResultVal, E);
20209 llvm_unreachable(
"unknown cast resulting in integral value");
20212bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20217 if (!LV.isComplexInt())
20219 return Success(LV.getComplexIntReal(), E);
20225bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20230 if (!LV.isComplexInt())
20232 return Success(LV.getComplexIntImag(), E);
20239bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
20243bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
20247bool IntExprEvaluator::VisitConceptSpecializationExpr(
20248 const ConceptSpecializationExpr *E) {
20252bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
20256bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20266 if (!
Result.isFixedPoint())
20269 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
20283bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20285 QualType DestType = E->
getType();
20287 "Expected destination type to be a fixed point type");
20288 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
20291 case CK_FixedPointCast: {
20292 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20296 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
20298 if (Info.checkingForUndefinedBehavior())
20299 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20300 diag::warn_fixedpoint_constant_overflow)
20307 case CK_IntegralToFixedPoint: {
20313 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
20314 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20317 if (Info.checkingForUndefinedBehavior())
20318 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20319 diag::warn_fixedpoint_constant_overflow)
20320 << IntResult.toString() << E->
getType();
20325 return Success(IntResult, E);
20327 case CK_FloatingToFixedPoint: {
20333 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
20334 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20337 if (Info.checkingForUndefinedBehavior())
20338 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20339 diag::warn_fixedpoint_constant_overflow)
20348 case CK_LValueToRValue:
20349 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20355bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20357 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20359 const Expr *LHS = E->
getLHS();
20360 const Expr *RHS = E->
getRHS();
20362 Info.Ctx.getFixedPointSemantics(E->
getType());
20364 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
20367 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
20371 bool OpOverflow =
false, ConversionOverflow =
false;
20372 APFixedPoint
Result(LHSFX.getSemantics());
20375 Result = LHSFX.add(RHSFX, &OpOverflow)
20376 .convert(ResultFXSema, &ConversionOverflow);
20380 Result = LHSFX.sub(RHSFX, &OpOverflow)
20381 .convert(ResultFXSema, &ConversionOverflow);
20385 Result = LHSFX.mul(RHSFX, &OpOverflow)
20386 .convert(ResultFXSema, &ConversionOverflow);
20390 if (RHSFX.getValue() == 0) {
20391 Info.FFDiag(E, diag::note_expr_divide_by_zero);
20394 Result = LHSFX.div(RHSFX, &OpOverflow)
20395 .convert(ResultFXSema, &ConversionOverflow);
20401 llvm::APSInt RHSVal = RHSFX.getValue();
20404 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
20405 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
20409 if (RHSVal.isNegative())
20410 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
20411 else if (Amt != RHSVal)
20412 Info.CCEDiag(E, diag::note_constexpr_large_shift)
20413 << RHSVal << E->
getType() << ShiftBW;
20416 Result = LHSFX.shl(Amt, &OpOverflow);
20418 Result = LHSFX.shr(Amt, &OpOverflow);
20424 if (OpOverflow || ConversionOverflow) {
20425 if (Info.checkingForUndefinedBehavior())
20426 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20427 diag::warn_fixedpoint_constant_overflow)
20440class FloatExprEvaluator
20441 :
public ExprEvaluatorBase<FloatExprEvaluator> {
20444 FloatExprEvaluator(EvalInfo &info, APFloat &result)
20445 : ExprEvaluatorBaseTy(
info),
Result(result) {}
20452 bool ZeroInitialization(
const Expr *E) {
20453 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20457 bool VisitCallExpr(
const CallExpr *E);
20459 bool VisitUnaryOperator(
const UnaryOperator *E);
20460 bool VisitBinaryOperator(
const BinaryOperator *E);
20461 bool VisitFloatingLiteral(
const FloatingLiteral *E);
20462 bool VisitCastExpr(
const CastExpr *E);
20464 bool VisitUnaryReal(
const UnaryOperator *E);
20465 bool VisitUnaryImag(
const UnaryOperator *E);
20474 return FloatExprEvaluator(Info,
Result).Visit(E);
20481 llvm::APFloat &
Result) {
20486 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
20492 fill = llvm::APInt(32, 0);
20493 else if (S->
getString().getAsInteger(0, fill))
20496 if (Context.getTargetInfo().isNan2008()) {
20498 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20500 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20508 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20510 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20516bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20517 if (!IsConstantEvaluatedBuiltinCall(E))
20518 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20522 switch (BuiltinOp) {
20526 case Builtin::BI__builtin_huge_val:
20527 case Builtin::BI__builtin_huge_valf:
20528 case Builtin::BI__builtin_huge_vall:
20529 case Builtin::BI__builtin_huge_valf16:
20530 case Builtin::BI__builtin_huge_valf128:
20531 case Builtin::BI__builtin_inf:
20532 case Builtin::BI__builtin_inff:
20533 case Builtin::BI__builtin_infl:
20534 case Builtin::BI__builtin_inff16:
20535 case Builtin::BI__builtin_inff128: {
20536 const llvm::fltSemantics &Sem =
20537 Info.Ctx.getFloatTypeSemantics(E->
getType());
20538 Result = llvm::APFloat::getInf(Sem);
20542 case Builtin::BI__builtin_nans:
20543 case Builtin::BI__builtin_nansf:
20544 case Builtin::BI__builtin_nansl:
20545 case Builtin::BI__builtin_nansf16:
20546 case Builtin::BI__builtin_nansf128:
20552 case Builtin::BI__builtin_nan:
20553 case Builtin::BI__builtin_nanf:
20554 case Builtin::BI__builtin_nanl:
20555 case Builtin::BI__builtin_nanf16:
20556 case Builtin::BI__builtin_nanf128:
20564 case Builtin::BI__builtin_elementwise_abs:
20565 case Builtin::BI__builtin_fabs:
20566 case Builtin::BI__builtin_fabsf:
20567 case Builtin::BI__builtin_fabsl:
20568 case Builtin::BI__builtin_fabsf128:
20577 if (
Result.isNegative())
20581 case Builtin::BI__arithmetic_fence:
20588 case Builtin::BI__builtin_copysign:
20589 case Builtin::BI__builtin_copysignf:
20590 case Builtin::BI__builtin_copysignl:
20591 case Builtin::BI__builtin_copysignf128: {
20600 case Builtin::BI__builtin_fmax:
20601 case Builtin::BI__builtin_fmaxf:
20602 case Builtin::BI__builtin_fmaxl:
20603 case Builtin::BI__builtin_fmaxf16:
20604 case Builtin::BI__builtin_fmaxf128: {
20613 case Builtin::BI__builtin_fmin:
20614 case Builtin::BI__builtin_fminf:
20615 case Builtin::BI__builtin_fminl:
20616 case Builtin::BI__builtin_fminf16:
20617 case Builtin::BI__builtin_fminf128: {
20626 case Builtin::BI__builtin_fmaximum_num:
20627 case Builtin::BI__builtin_fmaximum_numf:
20628 case Builtin::BI__builtin_fmaximum_numl:
20629 case Builtin::BI__builtin_fmaximum_numf16:
20630 case Builtin::BI__builtin_fmaximum_numf128: {
20639 case Builtin::BI__builtin_fminimum_num:
20640 case Builtin::BI__builtin_fminimum_numf:
20641 case Builtin::BI__builtin_fminimum_numl:
20642 case Builtin::BI__builtin_fminimum_numf16:
20643 case Builtin::BI__builtin_fminimum_numf128: {
20652 case Builtin::BI__builtin_elementwise_fma: {
20657 APFloat SourceY(0.), SourceZ(0.);
20663 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
20667 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
20674 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
20680bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20692bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20702 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
20703 Result = llvm::APFloat::getZero(Sem);
20707bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20709 default:
return Error(E);
20723bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20725 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20729 if (!LHSOK && !Info.noteFailure())
20735bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
20740bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20745 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20747 case CK_HLSLAggregateSplatCast:
20748 llvm_unreachable(
"invalid cast kind for floating value");
20750 case CK_IntegralToFloating: {
20753 Info.Ctx.getLangOpts());
20759 case CK_FixedPointToFloating: {
20760 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20764 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20768 case CK_FloatingCast: {
20769 if (!Visit(SubExpr))
20775 case CK_FloatingComplexToReal: {
20779 Result =
V.getComplexFloatReal();
20782 case CK_HLSLVectorTruncation: {
20788 case CK_HLSLMatrixTruncation: {
20794 case CK_HLSLElementwiseCast: {
20808 return Success(ResultVal, E);
20818class ComplexExprEvaluator
20819 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
20823 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
20831 bool ZeroInitialization(
const Expr *E);
20837 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
20838 bool VisitCastExpr(
const CastExpr *E);
20839 bool VisitBinaryOperator(
const BinaryOperator *E);
20840 bool VisitUnaryOperator(
const UnaryOperator *E);
20841 bool VisitInitListExpr(
const InitListExpr *E);
20842 bool VisitCallExpr(
const CallExpr *E);
20850 return ComplexExprEvaluator(Info,
Result).Visit(E);
20853bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
20854 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
20856 Result.makeComplexFloat();
20857 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
20861 Result.makeComplexInt();
20862 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
20869bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
20873 Result.makeComplexFloat();
20882 "Unexpected imaginary literal.");
20884 Result.makeComplexInt();
20889 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
20894bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20898 case CK_BaseToDerived:
20899 case CK_DerivedToBase:
20900 case CK_UncheckedDerivedToBase:
20903 case CK_ArrayToPointerDecay:
20904 case CK_FunctionToPointerDecay:
20905 case CK_NullToPointer:
20906 case CK_NullToMemberPointer:
20907 case CK_BaseToDerivedMemberPointer:
20908 case CK_DerivedToBaseMemberPointer:
20909 case CK_MemberPointerToBoolean:
20910 case CK_ReinterpretMemberPointer:
20911 case CK_ConstructorConversion:
20912 case CK_IntegralToPointer:
20913 case CK_PointerToIntegral:
20914 case CK_PointerToBoolean:
20916 case CK_VectorSplat:
20917 case CK_IntegralCast:
20918 case CK_BooleanToSignedIntegral:
20919 case CK_IntegralToBoolean:
20920 case CK_IntegralToFloating:
20921 case CK_FloatingToIntegral:
20922 case CK_FloatingToBoolean:
20923 case CK_FloatingCast:
20924 case CK_CPointerToObjCPointerCast:
20925 case CK_BlockPointerToObjCPointerCast:
20926 case CK_AnyPointerToBlockPointerCast:
20927 case CK_ObjCObjectLValueCast:
20928 case CK_FloatingComplexToReal:
20929 case CK_FloatingComplexToBoolean:
20930 case CK_IntegralComplexToReal:
20931 case CK_IntegralComplexToBoolean:
20932 case CK_ARCProduceObject:
20933 case CK_ARCConsumeObject:
20934 case CK_ARCReclaimReturnedObject:
20935 case CK_ARCExtendBlockObject:
20936 case CK_CopyAndAutoreleaseBlockObject:
20937 case CK_BuiltinFnToFnPtr:
20938 case CK_ZeroToOCLOpaqueType:
20939 case CK_NonAtomicToAtomic:
20940 case CK_AddressSpaceConversion:
20941 case CK_IntToOCLSampler:
20942 case CK_FloatingToFixedPoint:
20943 case CK_FixedPointToFloating:
20944 case CK_FixedPointCast:
20945 case CK_FixedPointToBoolean:
20946 case CK_FixedPointToIntegral:
20947 case CK_IntegralToFixedPoint:
20948 case CK_MatrixCast:
20949 case CK_HLSLVectorTruncation:
20950 case CK_HLSLMatrixTruncation:
20951 case CK_HLSLElementwiseCast:
20952 case CK_HLSLAggregateSplatCast:
20953 llvm_unreachable(
"invalid cast kind for complex value");
20955 case CK_LValueToRValue:
20956 case CK_AtomicToNonAtomic:
20958 case CK_LValueToRValueBitCast:
20959 case CK_HLSLArrayRValue:
20960 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20963 case CK_LValueBitCast:
20964 case CK_UserDefinedConversion:
20967 case CK_FloatingRealToComplex: {
20972 Result.makeComplexFloat();
20977 case CK_FloatingComplexCast: {
20981 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20989 case CK_FloatingComplexToIntegralComplex: {
20993 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20996 Result.makeComplexInt();
21003 case CK_IntegralRealToComplex: {
21008 Result.makeComplexInt();
21009 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
21013 case CK_IntegralComplexCast: {
21017 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21026 case CK_IntegralComplexToFloatingComplex: {
21031 Info.Ctx.getLangOpts());
21032 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21035 Result.makeComplexFloat();
21037 To,
Result.FloatReal) &&
21043 llvm_unreachable(
"unknown cast resulting in complex value");
21049 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
21050 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
21051 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
21052 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
21053 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
21054 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
21055 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
21056 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
21057 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
21058 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
21059 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
21060 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
21061 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
21062 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
21063 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
21064 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
21065 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
21066 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
21067 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
21068 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
21069 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
21070 0xcd, 0x1a, 0x41, 0x1c};
21072 return GFInv[Byte];
21077 unsigned NumBitsInByte = 8;
21080 for (
uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21082 AQword.lshr((7 -
static_cast<int32_t>(BitIdx)) * NumBitsInByte)
21089 Product = AByte & XByte;
21094 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
21095 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
21098 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
21099 RetByte |= (Temp ^ Parity) << BitIdx;
21109 unsigned NumBitsInByte = 8;
21110 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21111 if ((BByte >> BitIdx) & 0x1) {
21112 TWord = TWord ^ (AByte << BitIdx);
21120 for (
int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
21121 if ((TWord >> BitIdx) & 0x1) {
21122 TWord = TWord ^ (0x11B << (BitIdx - 8));
21125 return (TWord & 0xFF);
21129 APFloat &ResR, APFloat &ResI) {
21135 APFloat AC = A *
C;
21136 APFloat BD = B * D;
21137 APFloat AD = A * D;
21138 APFloat BC = B *
C;
21141 if (ResR.isNaN() && ResI.isNaN()) {
21142 bool Recalc =
false;
21143 if (A.isInfinity() || B.isInfinity()) {
21144 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21146 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21149 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21151 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21154 if (
C.isInfinity() || D.isInfinity()) {
21155 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21157 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21160 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21162 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21165 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
21166 BC.isInfinity())) {
21168 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21170 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21172 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21174 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21178 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
21179 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
21185 APFloat &ResR, APFloat &ResI) {
21192 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
21193 if (MaxCD.isFinite()) {
21194 DenomLogB =
ilogb(MaxCD);
21195 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
21196 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
21198 APFloat Denom =
C *
C + D * D;
21200 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21202 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21203 if (ResR.isNaN() && ResI.isNaN()) {
21204 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
21205 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
21206 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
21207 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
21209 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21211 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21213 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
21214 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
21215 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
21216 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21218 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21220 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
21221 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
21228 APSInt NormAmt = Amount;
21229 unsigned BitWidth =
Value.getBitWidth();
21230 unsigned AmtBitWidth = NormAmt.getBitWidth();
21231 if (BitWidth == 1) {
21233 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
21234 }
else if (BitWidth == 2) {
21239 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
21242 if (AmtBitWidth > BitWidth) {
21243 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
21245 Divisor = llvm::APInt(BitWidth, BitWidth);
21246 if (AmtBitWidth < BitWidth) {
21247 NormAmt = NormAmt.extend(BitWidth);
21252 if (NormAmt.isSigned()) {
21253 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
21254 if (NormAmt.isNegative()) {
21255 APSInt SignedDivisor(Divisor,
false);
21256 NormAmt += SignedDivisor;
21259 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
21266bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
21268 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
21272 bool LHSReal =
false, RHSReal =
false;
21280 Result.makeComplexFloat();
21284 LHSOK = Visit(E->
getLHS());
21286 if (!LHSOK && !Info.noteFailure())
21292 APFloat &Real = RHS.FloatReal;
21295 RHS.makeComplexFloat();
21296 RHS.FloatImag =
APFloat(Real.getSemantics());
21300 assert(!(LHSReal && RHSReal) &&
21301 "Cannot have both operands of a complex operation be real.");
21303 default:
return Error(E);
21305 if (
Result.isComplexFloat()) {
21306 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
21307 APFloat::rmNearestTiesToEven);
21309 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21311 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
21312 APFloat::rmNearestTiesToEven);
21314 Result.getComplexIntReal() += RHS.getComplexIntReal();
21315 Result.getComplexIntImag() += RHS.getComplexIntImag();
21319 if (
Result.isComplexFloat()) {
21320 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
21321 APFloat::rmNearestTiesToEven);
21323 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21324 Result.getComplexFloatImag().changeSign();
21325 }
else if (!RHSReal) {
21326 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
21327 APFloat::rmNearestTiesToEven);
21330 Result.getComplexIntReal() -= RHS.getComplexIntReal();
21331 Result.getComplexIntImag() -= RHS.getComplexIntImag();
21335 if (
Result.isComplexFloat()) {
21340 ComplexValue LHS =
Result;
21341 APFloat &A = LHS.getComplexFloatReal();
21342 APFloat &B = LHS.getComplexFloatImag();
21343 APFloat &
C = RHS.getComplexFloatReal();
21344 APFloat &D = RHS.getComplexFloatImag();
21348 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
21356 }
else if (RHSReal) {
21368 ComplexValue LHS =
Result;
21369 Result.getComplexIntReal() =
21370 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
21371 LHS.getComplexIntImag() * RHS.getComplexIntImag());
21372 Result.getComplexIntImag() =
21373 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
21374 LHS.getComplexIntImag() * RHS.getComplexIntReal());
21378 if (
Result.isComplexFloat()) {
21383 ComplexValue LHS =
Result;
21384 APFloat &A = LHS.getComplexFloatReal();
21385 APFloat &B = LHS.getComplexFloatImag();
21386 APFloat &
C = RHS.getComplexFloatReal();
21387 APFloat &D = RHS.getComplexFloatImag();
21401 B = APFloat::getZero(A.getSemantics());
21406 ComplexValue LHS =
Result;
21407 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
21408 RHS.getComplexIntImag() * RHS.getComplexIntImag();
21410 return Error(E, diag::note_expr_divide_by_zero);
21412 Result.getComplexIntReal() =
21413 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
21414 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
21415 Result.getComplexIntImag() =
21416 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
21417 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
21425bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
21439 if (
Result.isComplexFloat()) {
21440 Result.getComplexFloatReal().changeSign();
21441 Result.getComplexFloatImag().changeSign();
21444 Result.getComplexIntReal() = -
Result.getComplexIntReal();
21445 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21449 if (
Result.isComplexFloat())
21450 Result.getComplexFloatImag().changeSign();
21452 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21457bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
21460 Result.makeComplexFloat();
21466 Result.makeComplexInt();
21474 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
21477bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
21478 if (!IsConstantEvaluatedBuiltinCall(E))
21479 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21482 case Builtin::BI__builtin_complex:
21483 Result.makeComplexFloat();
21501class AtomicExprEvaluator :
21502 public ExprEvaluatorBase<AtomicExprEvaluator> {
21503 const LValue *
This;
21506 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
21514 bool ZeroInitialization(
const Expr *E) {
21515 ImplicitValueInitExpr VIE(
21523 bool VisitCastExpr(
const CastExpr *E) {
21526 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21527 case CK_NullToPointer:
21529 return ZeroInitialization(E);
21530 case CK_NonAtomicToAtomic:
21542 return AtomicExprEvaluator(Info,
This,
Result).Visit(E);
21551class VoidExprEvaluator
21552 :
public ExprEvaluatorBase<VoidExprEvaluator> {
21554 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
21558 bool ZeroInitialization(
const Expr *E) {
return true; }
21560 bool VisitCastExpr(
const CastExpr *E) {
21563 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21570 bool VisitCallExpr(
const CallExpr *E) {
21571 if (!IsConstantEvaluatedBuiltinCall(E))
21572 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21575 case Builtin::BI__assume:
21576 case Builtin::BI__builtin_assume:
21580 case Builtin::BI__builtin_operator_delete:
21588 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
21592bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
21594 if (Info.SpeculativeEvaluationDepth)
21598 if (!OperatorDelete
21599 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21600 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21610 if (
Pointer.Designator.Invalid)
21614 if (
Pointer.isNullPointer()) {
21618 if (!Info.getLangOpts().CPlusPlus20)
21619 Info.CCEDiag(E, diag::note_constexpr_new);
21627 QualType AllocType =
Pointer.Base.getDynamicAllocType();
21633 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
21642 if (VirtualDelete &&
21644 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21645 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21652 (*Alloc)->Value, AllocType))
21655 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
21660 Info.FFDiag(E, diag::note_constexpr_double_delete);
21670 return VoidExprEvaluator(Info).Visit(E);
21682 if (E->
isGLValue() ||
T->isFunctionType()) {
21687 }
else if (
T->isVectorType()) {
21690 }
else if (
T->isConstantMatrixType()) {
21693 }
else if (
T->isIntegralOrEnumerationType()) {
21694 if (!IntExprEvaluator(Info,
Result).Visit(E))
21696 }
else if (
T->hasPointerRepresentation()) {
21701 }
else if (
T->isRealFloatingType()) {
21702 llvm::APFloat F(0.0);
21706 }
else if (
T->isAnyComplexType()) {
21711 }
else if (
T->isFixedPointType()) {
21712 if (!FixedPointExprEvaluator(Info,
Result).Visit(E))
return false;
21713 }
else if (
T->isMemberPointerType()) {
21719 }
else if (
T->isArrayType()) {
21722 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
21726 }
else if (
T->isRecordType()) {
21729 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
21733 }
else if (
T->isVoidType()) {
21734 if (!Info.getLangOpts().CPlusPlus11)
21735 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
21739 }
else if (
T->isAtomicType()) {
21740 QualType Unqual =
T.getAtomicUnqualifiedType();
21744 E, Unqual, ScopeKind::FullExpression, LV);
21752 }
else if (Info.getLangOpts().CPlusPlus11) {
21753 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
21756 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
21767 const Expr *E,
bool AllowNonLiteralTypes) {
21783 if (
T->isArrayType())
21785 else if (
T->isRecordType())
21787 else if (
T->isAtomicType()) {
21788 QualType Unqual =
T.getAtomicUnqualifiedType();
21802 assert(!Info.Ctx.getLangOpts().EnableNewConstInterp);
21816 LV.setFrom(Info.Ctx,
Result);
21823 ConstantExprKind::Normal) &&
21831 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
21833 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
21838 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
21844 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
21850 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
21856 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
21857 if (CE->hasAPValueResult()) {
21858 APValue APV = CE->getAPValueResult();
21860 Result = std::move(APV);
21936 bool InConstantContext)
const {
21938 "Expression evaluator can't be called on a dependent expression.");
21939 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
21952 Info.InConstantContext = InConstantContext;
21953 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
21957 bool InConstantContext)
const {
21959 "Expression evaluator can't be called on a dependent expression.");
21960 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
21968 bool InConstantContext)
const {
21970 "Expression evaluator can't be called on a dependent expression.");
21972 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
21974 if (!
getType()->isIntegralOrEnumerationType())
21987 if (!
Result.Val.isInt() ||
21994 Info.InConstantContext = InConstantContext;
21995 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
22000 bool InConstantContext)
const {
22002 "Expression evaluator can't be called on a dependent expression.");
22003 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
22005 if (!
getType()->isFixedPointType())
22015 if (!
Result.Val.isFixedPoint() ||
22023 Info.InConstantContext = InConstantContext;
22024 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
22029 bool InConstantContext)
const {
22031 "Expression evaluator can't be called on a dependent expression.");
22033 if (!
getType()->isRealFloatingType())
22036 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
22048 bool InConstantContext)
const {
22050 "Expression evaluator can't be called on a dependent expression.");
22052 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
22061 Info.InConstantContext = InConstantContext;
22065 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
22066 Result.HasSideEffects ||
22069 ConstantExprKind::Normal, CheckedTemps))
22072 LV.moveInto(
Result.Val);
22079 bool IsConstantDestruction) {
22080 EvalInfo Info(Ctx, EStatus,
22083 Info.setEvaluatingDecl(
Base, DestroyedValue,
22084 EvalInfo::EvaluatingDeclKind::Dtor);
22085 Info.InConstantContext = IsConstantDestruction;
22094 if (!Info.discardCleanups())
22095 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22103 "Expression evaluator can't be called on a dependent expression.");
22109 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
22118 EvalInfo Info(Ctx,
Result, EM);
22119 Info.InConstantContext =
true;
22123 if (Kind == ConstantExprKind::ClassTemplateArgument)
22139 FullExpressionRAII
Scope(Info);
22144 if (!Info.discardCleanups())
22145 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22155 if (Kind == ConstantExprKind::ClassTemplateArgument &&
22158 Result.HasSideEffects)) {
22168 bool IsConstantInitialization)
const {
22170 "Expression evaluator can't be called on a dependent expression.");
22171 assert(VD &&
"Need a valid VarDecl");
22173 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
22175 llvm::raw_string_ostream OS(Name);
22181 (IsConstantInitialization &&
22196 EvalInfo Info(Ctx, EStatus, EvalMode);
22197 Info.setEvaluatingDecl(VD, EStatus.
Val);
22198 Info.InConstantContext = IsConstantInitialization;
22213 FullExpressionRAII
Scope(Info);
22222 Info.performLifetimeExtension();
22224 if (!Info.discardCleanups())
22225 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22227 ConstantExprKind::Normal) &&
22247 EStatus.
Diag = &Notes;
22270 std::move(DestroyedValue)))
22277 getLocation(), EStatus, IsConstantDestruction) ||
22289 "Expression evaluator can't be called on a dependent expression.");
22298 "Expression evaluator can't be called on a dependent expression.");
22300 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
22306 [[maybe_unused]]
bool Result =
22308 assert(
Result &&
"Could not evaluate expression");
22309 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22311 return EVResult.Val.getInt();
22315 Info.InConstantContext =
true;
22319 assert(
Result &&
"Could not evaluate expression");
22320 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22322 return EVResult.Val.getInt();
22328 "Expression evaluator can't be called on a dependent expression.");
22330 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
22332 EVResult.Diag =
Diag;
22338 [[maybe_unused]]
bool Result =
22340 assert(
Result &&
"Could not evaluate expression");
22341 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22343 return EVResult.Val.getInt();
22347 Info.InConstantContext =
true;
22348 Info.CheckingForUndefinedBehavior =
true;
22352 assert(
Result &&
"Could not evaluate expression");
22353 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22355 return EVResult.Val.getInt();
22360 "Expression evaluator can't be called on a dependent expression.");
22362 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
22376 Info.CheckingForUndefinedBehavior =
true;
22381 assert(
Val.isLValue());
22407 IK_ICEIfUnevaluated,
22423static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
22440 Info.InConstantContext =
true;
22449 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
22454#define ABSTRACT_STMT(Node)
22455#define STMT(Node, Base) case Expr::Node##Class:
22456#define EXPR(Node, Base)
22457#include "clang/AST/StmtNodes.inc"
22458 case Expr::PredefinedExprClass:
22459 case Expr::FloatingLiteralClass:
22460 case Expr::ImaginaryLiteralClass:
22461 case Expr::StringLiteralClass:
22462 case Expr::ArraySubscriptExprClass:
22463 case Expr::MatrixSingleSubscriptExprClass:
22464 case Expr::MatrixSubscriptExprClass:
22465 case Expr::ArraySectionExprClass:
22466 case Expr::OMPArrayShapingExprClass:
22467 case Expr::OMPIteratorExprClass:
22468 case Expr::CompoundAssignOperatorClass:
22469 case Expr::CompoundLiteralExprClass:
22470 case Expr::ExtVectorElementExprClass:
22471 case Expr::MatrixElementExprClass:
22472 case Expr::DesignatedInitExprClass:
22473 case Expr::ArrayInitLoopExprClass:
22474 case Expr::ArrayInitIndexExprClass:
22475 case Expr::NoInitExprClass:
22476 case Expr::DesignatedInitUpdateExprClass:
22477 case Expr::ImplicitValueInitExprClass:
22478 case Expr::ParenListExprClass:
22479 case Expr::VAArgExprClass:
22480 case Expr::AddrLabelExprClass:
22481 case Expr::StmtExprClass:
22482 case Expr::CXXMemberCallExprClass:
22483 case Expr::CUDAKernelCallExprClass:
22484 case Expr::CXXAddrspaceCastExprClass:
22485 case Expr::CXXDynamicCastExprClass:
22486 case Expr::CXXTypeidExprClass:
22487 case Expr::CXXUuidofExprClass:
22488 case Expr::MSPropertyRefExprClass:
22489 case Expr::MSPropertySubscriptExprClass:
22490 case Expr::CXXNullPtrLiteralExprClass:
22491 case Expr::UserDefinedLiteralClass:
22492 case Expr::CXXThisExprClass:
22493 case Expr::CXXThrowExprClass:
22494 case Expr::CXXNewExprClass:
22495 case Expr::CXXDeleteExprClass:
22496 case Expr::CXXPseudoDestructorExprClass:
22497 case Expr::UnresolvedLookupExprClass:
22498 case Expr::RecoveryExprClass:
22499 case Expr::DependentScopeDeclRefExprClass:
22500 case Expr::DependentTemplateIdExprClass:
22501 case Expr::CXXConstructExprClass:
22502 case Expr::CXXInheritedCtorInitExprClass:
22503 case Expr::CXXStdInitializerListExprClass:
22504 case Expr::CXXBindTemporaryExprClass:
22505 case Expr::ExprWithCleanupsClass:
22506 case Expr::CXXTemporaryObjectExprClass:
22507 case Expr::CXXUnresolvedConstructExprClass:
22508 case Expr::CXXDependentScopeMemberExprClass:
22509 case Expr::UnresolvedMemberExprClass:
22510 case Expr::ObjCStringLiteralClass:
22511 case Expr::ObjCBoxedExprClass:
22512 case Expr::ObjCArrayLiteralClass:
22513 case Expr::ObjCDictionaryLiteralClass:
22514 case Expr::ObjCEncodeExprClass:
22515 case Expr::ObjCMessageExprClass:
22516 case Expr::ObjCSelectorExprClass:
22517 case Expr::ObjCProtocolExprClass:
22518 case Expr::ObjCIvarRefExprClass:
22519 case Expr::ObjCPropertyRefExprClass:
22520 case Expr::ObjCSubscriptRefExprClass:
22521 case Expr::ObjCIsaExprClass:
22522 case Expr::ObjCAvailabilityCheckExprClass:
22523 case Expr::ShuffleVectorExprClass:
22524 case Expr::ConvertVectorExprClass:
22525 case Expr::BlockExprClass:
22527 case Expr::OpaqueValueExprClass:
22528 case Expr::PackExpansionExprClass:
22529 case Expr::SubstNonTypeTemplateParmPackExprClass:
22530 case Expr::FunctionParmPackExprClass:
22531 case Expr::AsTypeExprClass:
22532 case Expr::ObjCIndirectCopyRestoreExprClass:
22533 case Expr::MaterializeTemporaryExprClass:
22534 case Expr::PseudoObjectExprClass:
22535 case Expr::AtomicExprClass:
22536 case Expr::LambdaExprClass:
22537 case Expr::CXXFoldExprClass:
22538 case Expr::CoawaitExprClass:
22539 case Expr::DependentCoawaitExprClass:
22540 case Expr::CoyieldExprClass:
22541 case Expr::SYCLUniqueStableNameExprClass:
22542 case Expr::CXXParenListInitExprClass:
22543 case Expr::HLSLOutArgExprClass:
22544 case Expr::CXXExpansionSelectExprClass:
22547 case Expr::MemberExprClass: {
22550 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
22553 ME = M->getBase()->IgnoreParenImpCasts();
22555 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
22557 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
22565 case Expr::InitListExprClass: {
22576 case Expr::SizeOfPackExprClass:
22577 case Expr::GNUNullExprClass:
22578 case Expr::SourceLocExprClass:
22579 case Expr::EmbedExprClass:
22580 case Expr::OpenACCAsteriskSizeExprClass:
22583 case Expr::PackIndexingExprClass:
22586 case Expr::SubstNonTypeTemplateParmExprClass:
22590 case Expr::ConstantExprClass:
22593 case Expr::ParenExprClass:
22595 case Expr::GenericSelectionExprClass:
22597 case Expr::IntegerLiteralClass:
22598 case Expr::FixedPointLiteralClass:
22599 case Expr::CharacterLiteralClass:
22600 case Expr::ObjCBoolLiteralExprClass:
22601 case Expr::CXXBoolLiteralExprClass:
22602 case Expr::CXXScalarValueInitExprClass:
22603 case Expr::TypeTraitExprClass:
22604 case Expr::ConceptSpecializationExprClass:
22605 case Expr::RequiresExprClass:
22606 case Expr::ArrayTypeTraitExprClass:
22607 case Expr::ExpressionTraitExprClass:
22608 case Expr::CXXNoexceptExprClass:
22609 case Expr::CXXReflectExprClass:
22611 case Expr::CallExprClass:
22612 case Expr::CXXOperatorCallExprClass: {
22621 case Expr::CXXRewrittenBinaryOperatorClass:
22624 case Expr::DeclRefExprClass: {
22638 const VarDecl *VD = dyn_cast<VarDecl>(D);
22645 case Expr::UnaryOperatorClass: {
22668 llvm_unreachable(
"invalid unary operator class");
22670 case Expr::OffsetOfExprClass: {
22679 case Expr::UnaryExprOrTypeTraitExprClass: {
22681 if ((Exp->
getKind() == UETT_SizeOf) &&
22684 if (Exp->
getKind() == UETT_CountOf) {
22691 if (VAT->getElementType()->isArrayType())
22703 case Expr::BinaryOperatorClass: {
22748 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
22751 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22752 if (REval.isSigned() && REval.isAllOnes()) {
22754 if (LEval.isMinSignedValue())
22755 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22763 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
22764 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22770 return Worst(LHSResult, RHSResult);
22776 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
22786 return Worst(LHSResult, RHSResult);
22789 llvm_unreachable(
"invalid binary operator kind");
22791 case Expr::ImplicitCastExprClass:
22792 case Expr::CStyleCastExprClass:
22793 case Expr::CXXFunctionalCastExprClass:
22794 case Expr::CXXStaticCastExprClass:
22795 case Expr::CXXReinterpretCastExprClass:
22796 case Expr::CXXConstCastExprClass:
22797 case Expr::ObjCBridgedCastExprClass: {
22804 APSInt IgnoredVal(DestWidth, !DestSigned);
22809 if (FL->getValue().convertToInteger(IgnoredVal,
22810 llvm::APFloat::rmTowardZero,
22811 &Ignored) & APFloat::opInvalidOp)
22817 case CK_LValueToRValue:
22818 case CK_AtomicToNonAtomic:
22819 case CK_NonAtomicToAtomic:
22821 case CK_IntegralToBoolean:
22822 case CK_IntegralCast:
22828 case Expr::BinaryConditionalOperatorClass: {
22831 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
22833 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
22834 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
22835 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
22837 return FalseResult;
22839 case Expr::ConditionalOperatorClass: {
22847 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
22850 if (CondResult.Kind == IK_NotICE)
22856 if (TrueResult.Kind == IK_NotICE)
22858 if (FalseResult.Kind == IK_NotICE)
22859 return FalseResult;
22860 if (CondResult.Kind == IK_ICEIfUnevaluated)
22862 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
22868 return FalseResult;
22871 case Expr::CXXDefaultArgExprClass:
22873 case Expr::CXXDefaultInitExprClass:
22875 case Expr::ChooseExprClass: {
22878 case Expr::BuiltinBitCastExprClass: {
22879 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
22885 llvm_unreachable(
"Invalid StmtClass!");
22891 llvm::APSInt *
Value,
22892 bool AllowRelaxedEval =
false) {
22909 "Expression evaluator can't be called on a dependent expression.");
22911 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
22917 if (D.Kind != IK_ICE)
22922std::optional<llvm::APSInt>
22924 bool AllowRelaxedEval)
const {
22927 return std::nullopt;
22935 return std::nullopt;
22939 return std::nullopt;
22953 llvm_unreachable(
"ICE cannot be evaluated!");
22959 Info.InConstantContext =
true;
22962 llvm_unreachable(
"ICE cannot be evaluated!");
22969 "Expression evaluator can't be called on a dependent expression.");
22971 return CheckICE(
this, Ctx).Kind == IK_ICE;
22975 bool AllowRelaxedEval)
const {
22977 "Expression evaluator can't be called on a dependent expression.");
22990 Status.ExtendedDiag = AllowRelaxedEval ? &MSRelaxedDiag :
nullptr;
23003 Info.discardCleanups() && !Status.HasSideEffects;
23005 return IsConstExpr && !Status.DiagEmitted;
23013 "Expression evaluator can't be called on a dependent expression.");
23015 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
23017 llvm::raw_string_ostream OS(Name);
23029 if (std::optional<bool> BoolResult =
23031 Args,
This,
this)) {
23039 Info.InConstantContext =
true;
23042 const LValue *ThisPtr =
nullptr;
23045 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
23046 assert(MD &&
"Don't provide `this` for non-methods.");
23047 assert(MD->isImplicitObjectMemberFunction() &&
23048 "Don't provide `this` for methods without an implicit object.");
23050 if (!
This->isValueDependent() &&
23052 !Info.EvalStatus.HasSideEffects)
23053 ThisPtr = &ThisVal;
23057 Info.EvalStatus.HasSideEffects =
false;
23060 CallRef
Call = Info.CurrentCall->createCall(Callee);
23063 unsigned Idx = I - Args.begin();
23064 if (Idx >= Callee->getNumParams())
23066 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
23067 if ((*I)->isValueDependent() ||
23069 Info.EvalStatus.HasSideEffects) {
23071 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
23077 Info.EvalStatus.HasSideEffects =
false;
23082 Info.discardCleanups();
23083 Info.EvalStatus.HasSideEffects =
false;
23086 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
23089 FullExpressionRAII
Scope(Info);
23091 !Info.EvalStatus.HasSideEffects;
23103 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
23105 llvm::raw_string_ostream OS(Name);
23113 Status.
Diag = &Diags;
23116 if (Ctx.getLangOpts().EnableNewConstInterp) {
23120 Ctx.getInterpContext().isPotentialConstantExpr(Settings, FD);
23121 return Diags.empty();
23125 Info.InConstantContext =
true;
23126 Info.CheckingPotentialConstantExpression =
true;
23136 This.set({&VIE, Info.CurrentCall->Index});
23144 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
23150 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
23154 return Diags.empty();
23162 "Expression evaluator can't be called on a dependent expression.");
23166 Status.
Diag = &Diags;
23174 return Diags.empty();
23178 Info.InConstantContext =
true;
23179 Info.CheckingPotentialConstantExpression =
true;
23183 nullptr, CallRef());
23187 return Diags.empty();
23191 unsigned Type)
const {
23192 if (!
getType()->isPointerType())
23193 return std::nullopt;
23206static std::optional<uint64_t>
23208 std::string *StringResult) {
23210 return std::nullopt;
23215 return std::nullopt;
23218 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
23219 String.getLValueBase().dyn_cast<
const Expr *>())) {
23221 int64_t
Off = String.Offset.getQuantity();
23222 if (
Off >= 0 && (uint64_t)
Off <= (uint64_t)Str.size()) {
23224 if (StringResult) {
23226 Str = Str.substr(
Off, *ZeroIndex);
23227 *StringResult = Str;
23230 return ZeroIndex.
value_or(Str.size());
23237 for (uint64_t Strlen = 0; ; ++Strlen) {
23241 return std::nullopt;
23244 else if (StringResult)
23245 StringResult->push_back(Char.
getInt().getExtValue());
23247 return std::nullopt;
23253 std::string StringResult;
23258 return std::nullopt;
23259 return StringResult;
23264 return StringResult;
23265 return std::nullopt;
23268template <
typename T>
23270 const Expr *SizeExpression,
23271 const Expr *PtrExpression,
23282 Info.InConstantContext =
true;
23285 FullExpressionRAII
Scope(Info);
23290 uint64_t Size = SizeValue.getZExtValue();
23293 if constexpr (std::is_same_v<APValue, T>)
23296 if (Size <
Result.max_size())
23303 for (uint64_t I = 0; I < Size; ++I) {
23309 if constexpr (std::is_same_v<APValue, T>) {
23310 Result.getArrayInitializedElt(I) = std::move(Char);
23314 assert(
C.getBitWidth() <= 8 &&
23315 "string element not representable in char");
23317 Result.push_back(
static_cast<char>(
C.getExtValue()));
23328 const Expr *SizeExpression,
23332 PtrExpression, Ctx, Status);
23336 const Expr *SizeExpression,
23340 PtrExpression, Ctx, Status);
23355struct IsWithinLifetimeHandler {
23358 using result_type = std::optional<bool>;
23359 std::optional<bool> failed() {
return std::nullopt; }
23360 template <
typename T>
23361 std::optional<bool> found(
T &Subobj,
QualType SubobjType,
23365 template <
typename T>
23366 std::optional<bool> found(
T &Subobj, QualType SubobjType) {
23371std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
23372 const CallExpr *E) {
23373 EvalInfo &Info = IEE.Info;
23378 if (!Info.InConstantContext)
23379 return std::nullopt;
23381 const Expr *Arg = E->
getArg(0);
23383 return std::nullopt;
23386 return std::nullopt;
23388 if (Val.allowConstexprUnknown())
23392 bool CalledFromStd =
false;
23393 const auto *
Callee = Info.CurrentCall->getCallee();
23394 if (Callee &&
Callee->isInStdNamespace()) {
23395 const IdentifierInfo *Identifier =
Callee->getIdentifier();
23396 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
23398 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
23400 diag::err_invalid_is_within_lifetime)
23401 << (CalledFromStd ?
"std::is_within_lifetime"
23402 :
"__builtin_is_within_lifetime")
23404 return std::nullopt;
23414 if (Val.isNullPointer() || Val.getLValueBase().isNull())
23416 QualType
T = Val.getLValueBase().getType();
23418 "Pointers to functions should have been typed as function pointers "
23419 "which would have been rejected earlier");
23422 if (Val.getLValueDesignator().isOnePastTheEnd())
23424 assert(Val.getLValueDesignator().isValidSubobject() &&
23425 "Unchecked case for valid subobject");
23429 CompleteObject CO =
23433 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
23438 IsWithinLifetimeHandler handler{Info};
23439 return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
static bool isUnsigned(SValBuilder &SVB, NonLoc Value)
Defines enum values for all the target-independent builtin functions.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr)
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
bool isTemplateArgument(ConstantExprKind Kind)
bool isOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
bool isForManglingOnly(ConstantExprKind Kind)
Determines whether the given kind of constant expression is only ever used for name mangling.
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
@ PointerToMemberFunction
static bool isRead(AccessKinds AK)
static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, Expr::EvalResult &Status)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of access valid on an indeterminate object value?
static unsigned elementwiseSize(EvalInfo &Info, QualType BaseTy)
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps, bool IsCompleteClass=true)
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result, llvm::function_ref< APInt(const APSInt &)> PackFn)
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool hlslElementwiseCastHelper(EvalInfo &Info, const Expr *E, QualType DestTy, SmallVectorImpl< APValue > &SrcVals, SmallVectorImpl< QualType > &SrcTypes)
static bool ShouldPropagateBreakContinue(EvalInfo &Info, const Stmt *LoopOrSwitch, ArrayRef< BlockScopeRAII * > Scopes, EvalStmtResult &ESR)
Helper to implement named break/continue.
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
std::optional< APFloat > EvalScalarMinMaxFp(const APFloat &A, const APFloat &B, std::optional< APSInt > RoundingMode, bool IsMin)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static bool handleScalarCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool flattenAPValue(EvalInfo &Info, const Expr *E, APValue Value, QualType BaseTy, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &Types, unsigned Size)
static bool hlslAggSplatHelper(EvalInfo &Info, const Expr *E, APValue &SrcVal, QualType &SrcTy)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
unsigned ConvertBuiltinIDToX86BuiltinID(const ASTContext &Ctx, unsigned BuiltinOp)
Convert a builtin ID to the canonical x86 builtin ID the constant evaluators dispatch on in their x86...
static bool ConvertDoubleToFloatStrict(EvalInfo &Info, const Expr *E, APFloat OrigVal, APValue &Result)
static ICEDiag Worst(ICEDiag A, ICEDiag B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, unsigned Version, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
static bool checkFloatingPointResultForConstantFolding(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given floating-point evaluation result is allowed for compile-time constant folding duri...
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, ConstantExprKind Kind, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op, APSInt &Result)
Perform the given integer operation, which is known to need at most BitWidth bits,...
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal, bool WantObjectRepresentation=false)
Perform an lvalue-to-rvalue conversion on the given glvalue.
static bool handleElementwiseCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &SrcTypes, SmallVectorImpl< QualType > &DestTypes, SmallVectorImpl< APValue > &Results)
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid)....
static bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
Determine whether the given subobject designators refer to elements of the same array object.
static bool EvaluateDecompositionDeclInit(EvalInfo &Info, const DecompositionDecl *DD)
static bool IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static bool constructAggregate(EvalInfo &Info, const FPOptions FPO, const Expr *E, APValue &Result, QualType ResultType, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &ElTypes)
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static bool evalShuffleGeneric(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< std::pair< unsigned, int >(unsigned, unsigned)> GetSourceIndex)
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleLValueDirectVirtualBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
static void expandVector(APValue &Vec, unsigned NumElements)
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
static bool IsOpaqueConstantCall(const LValue &LVal)
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
static std::optional< uint64_t > EvaluateBuiltinStrLen(const Expr *E, EvalInfo &Info, std::string *StringResult=nullptr)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T, bool IsCompleteClass=true)
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static bool EvaluateComparisonResult(EvalInfo &Info, const Expr *E, ComparisonCategoryResult CCR, APValue &Result)
static bool EvaluateMatrix(const Expr *E, APValue &Result, EvalInfo &Info)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout....
bool isGlobalLValue(const ValueDecl *D, const Expr *E)
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue. In some cases, the in-place evaluati...
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAlloc::Kind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result, bool IsCompleteClass=true)
Perform zero-initialization on an object of non-union class type. C++11 [dcl.init]p5: To zero-initial...
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value, bool AllowRelaxedEval=false)
Evaluate an expression as a C++11 integral constant expression.
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue. This can be legitimately called on expressions which are not glv...
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result, bool IsCompleteClass=true)
Evaluate a constructor call.
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static bool evalShiftWithCount(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< APInt(const APInt &, uint64_t)> ShiftOp, llvm::function_ref< APInt(const APInt &, unsigned)> OverflowOp)
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false, LValue *ObjectArg=nullptr)
Evaluate the arguments to a function call.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const LValue &LVal, llvm::APInt &Result)
Convenience function. LVal's base must be a call to an alloc_size function.
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool EvaluateInitForDeclOfReferenceType(EvalInfo &Info, const ValueDecl *D, const Expr *Init, LValue &Result, APValue &Val)
Evaluates the initializer of a reference.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned. Fails if the conversion would ...
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false, APValue **EvaluatedArg=nullptr)
llvm::SmallPtrSet< const MaterializeTemporaryExpr *, 8 > CheckedTemporaries
Materialized temporaries that we've already checked to determine if they're initializsed by a constan...
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static bool MaybeEvaluateDeferredVarDeclInit(EvalInfo &Info, const VarDecl *VD)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static bool handleDefaultInitValue(QualType T, APValue &Result, bool IsCompleteClass=true)
Get the value to use for a default-initialized object of type T.
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static std::optional< uint64_t > tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, bool IsDynamic=false)
Tries to evaluate the __builtin_object_size for E.
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
uint8_t GFNIMul(uint8_t AByte, uint8_t BByte)
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
uint8_t GFNIMultiplicativeInverse(uint8_t Byte)
uint8_t GFNIAffine(uint8_t XByte, const APInt &AQword, const APSInt &Imm, bool Inverse)
APSInt NormalizeRotateAmount(const APSInt &Value, const APSInt &Amount)
Result
Implement __builtin_bit_cast and related operations.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const Pointer &Ptr, bool InvalidBase)
Does Ptr point to the last object AND to a flexible array member?
static bool isModification(AccessKinds AK)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
static bool hasLayout(const RecordDecl *D)
Whether layout (offset and size) information can be queried for D.
a trap message and trap category.
llvm::APInt getValue() const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
unsigned getMatrixNumColumns() const
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
APValue & getStructVirtualBase(unsigned i)
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
unsigned getStructNumBases() const
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getMatrixNumRows() const
unsigned getArraySize() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
APValue & getMatrixElt(unsigned Idx)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const TargetInfo * getAuxTargetInfo() const
interp::Context & getInterpContext() const
Returns the clang bytecode interpreter context.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
const VariableArrayType * getAsVariableArrayType(QualType T) const
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
LabelDecl * getLabel() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
uint64_t getValue() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Attr - This represents one attribute.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isRelationalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
SourceLocation getExprLoc() const
static bool isAdditiveOp(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isEqualityOp(Opcode Opc)
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
const BlockDecl * getBlockDecl() const
bool isAuxBuiltinID(unsigned ID) const
Return true if the builtin ID belongs exclusively to the AuxTarget, and false if it belongs to both p...
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool isAmbiguous(CanQualType BaseType) const
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
Represents a base class of a C++ class.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
const Expr * getSubExpr() const
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
Expr * getExpr()
Get the initialization expression that will be used.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getLoopVarStmt()
DeclStmt * getRangeStmt()
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
QualType getFunctionObjectParameterReferenceType() const
Return the type of the object pointed by this.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Expr * getPlacementArg(unsigned I)
unsigned getNumPlacementArgs() const
SourceRange getSourceRange() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_range vbases()
capture_const_range captures() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
const AllocSizeAttr * getCalleeAllocSizeAttr() const
Try to get the alloc_size attribute of the callee. May return null.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
unsigned path_size() const
CastKind getCastKind() const
const FieldDecl * getTargetUnionField() const
const CXXBaseSpecifier *const * path_const_iterator
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operation.
This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
Test whether the quantity is a power of two.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
Test whether the quantity equals zero.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the correct result kind for this category.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
CompoundLiteralExpr - [C99 6.5.2.5].
bool hasStaticStorage() const
APValue & getOrCreateStaticValue(ASTContext &Ctx) const
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
body_iterator body_begin()
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
ConditionalOperator - The ?
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
unsigned getSizeBitWidth() const
Return the bit width of the size type.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
uint64_t getLimitedSize() const
Return the size zero-extended to uint64_t or UINT64_MAX if the value is larger than UINT64_MAX.
bool isZeroSize() const
Return true if the size is zero.
const Expr * getSizeExpr() const
Return a pointer to the size expression.
llvm::APInt getSize() const
Return the constant array size as an APInt.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Represents the current source location and context used to determine the value of the source location...
const Expr * getDefaultExpr() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
bool isAnyOperatorNew() const
A decomposition declaration.
auto flat_bindings() const
InitListExpr * getUpdater() const
Designator - A designator in a C99 designated initializer.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
const Expr * getBase() const
ChildElementIter< false > begin()
ExplicitCastExpr - An explicit cast written in the source code.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue &Result, bool AllowRelaxedEval=false) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsInitializer(const ASTContext &Ctx, const VarDecl *VD, EvalResult &Result, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
void EvaluateForOverflow(const ASTContext &Ctx) const
bool isArrow() const
isArrow - Return true if the base expression is a pointer to vector, return false if the base express...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool hasCXXExplicitFunctionObjectParameter() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
Expr * getResultExpr()
Return the result expression of this controlling expression.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits() const
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
StrictFlexArraysLevelKind
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompatibleWith(ClangABI Version) const
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExpressibleAsConstantInitializer() const
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
bool isWrapType() const
Returns true if it is a OverflowBehaviorType of Wrap kind.
Represents a struct/union/class.
unsigned getNumFields() const
Returns the number of fields (non-static data members) in this record.
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
bool isSatisfied() const
Whether or not the requires clause is satisfied.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
std::string printToString(const SourceManager &SM) const
CompoundStmt * getSubStmt()
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
UnsignedOrNone findZeroCodeUnit(unsigned StartIndex=0) const
Scan the string literal contents for a code unit with value 0.
unsigned getLength() const
uint32_t getCodeUnit(size_t I) const
Return the code unit at the given position.
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
StringRef getString() const
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
@ Type
The template argument is a type.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
bool isStoredAsComparisonResult() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isCountAttributedType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
SourceLocation getBeginLoc() const LLVM_READONLY
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
const APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or nullptr if the value is not yet...
CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const
If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value might be usable in a constant expression, according to the re...
EvaluatedStmt * ensureEvaluatedStmt() const
Convert the initializer for this declaration to the elaborated EvaluatedStmt form,...
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool isCXXForRangeImplicitVar() const
Whether this variable is the implicit '__range' variable in C++ range-based for loops.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Expr * getSizeExpr() const
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
std::optional< uint64_t > tryEvaluateObjectSize(const EvalSettings &Settings, const Expr *E, unsigned Kind, bool IsDynamic)
If.
bool evaluateString(const EvalSettings &Settings, const Expr *E, std::string &Result)
Evaluate.
bool evaluateDestruction(const EvalSettings &Settings, const VarDecl *VD, APValue Value)
Evaluates the destruction of a variable.
std::optional< bool > evaluateWithSubstitution(const EvalSettings &Settings, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This, const Expr *Condition)
bool evaluate(const EvalSettings &Settings, const Expr *E, APValue &Result)
Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion.
bool evaluateAsInitializer(const EvalSettings &Settings, const VarDecl *VD, const Expr *Init, APValue &Result)
Evaluates a toplevel initializer.
bool evaluateAsRValue(const EvalSettings &Settings, const Expr *E, APValue &Result)
Evaluates a toplevel expression as an rvalue.
bool evaluateCharRange(const EvalSettings &Settings, const Expr *SizeExpr, const Expr *PtrExpr, APValue &Result)
std::optional< uint64_t > evaluateStrlen(const EvalSettings &Settings, const Expr *E)
Evalute.
void isPotentialConstantExprUnevaluated(const EvalSettings &Settings, const Expr *E, const FunctionDecl *FD)
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
uint32_t Literal
Literals are represented as positive integers.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
std::optional< llvm::AllocTokenMetadata > getAllocTokenMetadata(QualType T, const ASTContext &Ctx)
Get the information required for construction of an allocation token ID.
QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx, const CastExpr *CastE)
Infer the possible allocated type from an allocation call expression.
bool Sub(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool This(InterpState &S, CodePtr OpPC)
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
void info(bool Verbose, unsigned Level, const char *Fmt, Ts &&...Args)
Prints an indented note to stderr when Verbose is set.
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
const Expr * findStructFieldAccess(const Expr *E, const Expr **OutArrayIndex=nullptr, QualType *OutArrayElementTy=nullptr)
Walk E through parens, implicit casts, unary &/*, array subscripts and comma operators to find the he...
bool hasSpecificAttr(const Container &container)
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
Expr::ConstantExprKind ConstantExprKind
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
CheckSubobjectKind
The order of this enum is important for diagnostics.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
@ Off
Never emit colors regardless of the output stream.
@ Type
The name was classified as a type.
CastKind
CastKind - The kind of operation required for a conversion.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ ConstantFold
Fold the expression to a constant.
@ ConstantExpressionUnevaluated
Evaluate as a constant expression.
@ ConstantExpression
Evaluate as a constant expression.
@ IgnoreSideEffects
Evaluate in any way we know how.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ ArrayBound
Array bound in array declarator or new-expression.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
ActionResult< Stmt * > StmtResult
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::dependencies::ModuleID &ID)
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_t __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_t __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 uint16_t
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_t __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
unsigned PathLength
The corresponding path length in the lvalue.
const CXXRecordDecl * Type
The dynamic class type of the object.
std::string ObjCEncodeStorage
Represents an element in a path from a derived class to a base class.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool isGlobalLValue() const
Return true if the evaluated lvalue expression is global.
EvalStatus is a struct with detailed info about an evaluation in progress.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
bool HasSideEffects
Whether the evaluated expression has side effects.
unsigned SuppressLambdaBody
Whether to suppress printing the body of a lambda.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
bool CheckingForUndefinedBehavior
bool CheckingPotentialConstantExpression
DenseMapInfo< APValue::LValueBase > Base
static unsigned getHashValue(const ObjectUnderConstruction &Object)
static bool isEqual(const ObjectUnderConstruction &LHS, const ObjectUnderConstruction &RHS)