58#include "llvm/ADT/APFixedPoint.h"
59#include "llvm/ADT/Sequence.h"
60#include "llvm/ADT/SmallBitVector.h"
61#include "llvm/ADT/StringExtras.h"
62#include "llvm/Support/Casting.h"
63#include "llvm/Support/Debug.h"
64#include "llvm/Support/SaveAndRestore.h"
65#include "llvm/Support/SipHash.h"
66#include "llvm/Support/TimeProfiler.h"
67#include "llvm/Support/raw_ostream.h"
73#define DEBUG_TYPE "exprconstant"
76using llvm::APFixedPoint;
80using llvm::FixedPointSemantics;
87 using SourceLocExprScopeGuard =
122 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
130 if (
const auto *FE = dyn_cast<FullExpr>(E))
133 if (
const auto *Cast = dyn_cast<CastExpr>(E))
134 E = Cast->getSubExpr()->IgnoreParens();
136 if (
const auto *CE = dyn_cast<CallExpr>(E))
137 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
144 const auto *E =
Base.dyn_cast<
const Expr *>();
145 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
153 case ConstantExprKind::Normal:
154 case ConstantExprKind::ClassTemplateArgument:
155 case ConstantExprKind::ImmediateInvocation:
160 case ConstantExprKind::NonClassTemplateArgument:
163 llvm_unreachable(
"unknown ConstantExprKind");
168 case ConstantExprKind::Normal:
169 case ConstantExprKind::ImmediateInvocation:
172 case ConstantExprKind::ClassTemplateArgument:
173 case ConstantExprKind::NonClassTemplateArgument:
176 llvm_unreachable(
"unknown ConstantExprKind");
182 static const uint64_t AssumedSizeForUnsizedArray =
183 std::numeric_limits<uint64_t>::max() / 2;
193 bool &FirstEntryIsUnsizedArray) {
196 assert(!isBaseAnAllocSizeCall(
Base) &&
197 "Unsized arrays shouldn't appear here");
198 unsigned MostDerivedLength = 0;
203 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
207 MostDerivedLength = I + 1;
210 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
211 ArraySize = CAT->getZExtSize();
213 assert(I == 0 &&
"unexpected unsized array designator");
214 FirstEntryIsUnsizedArray =
true;
215 ArraySize = AssumedSizeForUnsizedArray;
221 MostDerivedLength = I + 1;
224 Type = VT->getElementType();
225 ArraySize = VT->getNumElements();
226 MostDerivedLength = I + 1;
228 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
229 Type = FD->getType();
231 MostDerivedLength = I + 1;
239 return MostDerivedLength;
243 struct SubobjectDesignator {
247 LLVM_PREFERRED_TYPE(
bool)
251 LLVM_PREFERRED_TYPE(
bool)
252 unsigned IsOnePastTheEnd : 1;
255 LLVM_PREFERRED_TYPE(
bool)
256 unsigned FirstEntryIsAnUnsizedArray : 1;
259 LLVM_PREFERRED_TYPE(
bool)
260 unsigned MostDerivedIsArrayElement : 1;
264 unsigned MostDerivedPathLength : 28;
273 uint64_t MostDerivedArraySize;
282 SubobjectDesignator() :
Invalid(
true) {}
284 explicit SubobjectDesignator(
QualType T)
285 :
Invalid(
false), IsOnePastTheEnd(
false),
286 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
287 MostDerivedPathLength(0), MostDerivedArraySize(0),
291 :
Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
292 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
293 MostDerivedPathLength(0), MostDerivedArraySize(0) {
294 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
296 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
297 llvm::append_range(Entries,
V.getLValuePath());
298 if (
V.getLValueBase()) {
299 bool IsArray =
false;
300 bool FirstIsUnsizedArray =
false;
301 MostDerivedPathLength = findMostDerivedSubobject(
302 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
303 MostDerivedType, IsArray, FirstIsUnsizedArray);
304 MostDerivedIsArrayElement = IsArray;
305 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
311 unsigned NewLength) {
315 assert(
Base &&
"cannot truncate path for null pointer");
316 assert(NewLength <= Entries.size() &&
"not a truncation");
318 if (NewLength == Entries.size())
320 Entries.resize(NewLength);
322 bool IsArray =
false;
323 bool FirstIsUnsizedArray =
false;
324 MostDerivedPathLength = findMostDerivedSubobject(
325 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
326 FirstIsUnsizedArray);
327 MostDerivedIsArrayElement = IsArray;
328 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
338 bool isMostDerivedAnUnsizedArray()
const {
339 assert(!
Invalid &&
"Calling this makes no sense on invalid designators");
340 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
345 uint64_t getMostDerivedArraySize()
const {
346 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
347 return MostDerivedArraySize;
351 bool isOnePastTheEnd()
const {
355 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
356 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
357 MostDerivedArraySize)
365 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
366 if (
Invalid || isMostDerivedAnUnsizedArray())
372 bool IsArray = MostDerivedPathLength == Entries.size() &&
373 MostDerivedIsArrayElement;
374 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
375 : (uint64_t)IsOnePastTheEnd;
377 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
378 return {ArrayIndex, ArraySize - ArrayIndex};
382 bool isValidSubobject()
const {
385 return !isOnePastTheEnd();
393 assert(!
Invalid &&
"invalid designator has no subobject type");
394 return MostDerivedPathLength == Entries.size()
405 MostDerivedIsArrayElement =
true;
407 MostDerivedPathLength = Entries.size();
411 void addUnsizedArrayUnchecked(
QualType ElemTy) {
414 MostDerivedType = ElemTy;
415 MostDerivedIsArrayElement =
true;
419 MostDerivedArraySize = AssumedSizeForUnsizedArray;
420 MostDerivedPathLength = Entries.size();
424 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
428 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
429 MostDerivedType = FD->getType();
430 MostDerivedIsArrayElement =
false;
431 MostDerivedArraySize = 0;
432 MostDerivedPathLength = Entries.size();
436 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
441 MostDerivedType = EltTy;
442 MostDerivedIsArrayElement =
true;
443 MostDerivedArraySize = 2;
444 MostDerivedPathLength = Entries.size();
447 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
450 MostDerivedType = EltTy;
451 MostDerivedPathLength = Entries.size();
452 MostDerivedArraySize = 0;
453 MostDerivedIsArrayElement =
false;
456 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
457 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
460 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
const LValue &LV);
464 enum class ScopeKind {
472 CallRef() : OrigCallee(), CallIndex(0), Version() {}
473 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
474 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
476 explicit operator bool()
const {
return OrigCallee; }
502 CallStackFrame *Caller;
524 typedef std::pair<const void *, unsigned> MapKeyTy;
525 typedef std::map<MapKeyTy, APValue>
MapTy;
537 unsigned CurTempVersion = TempVersionStack.back();
539 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
541 void pushTempVersion() {
542 TempVersionStack.push_back(++CurTempVersion);
545 void popTempVersion() {
546 TempVersionStack.pop_back();
550 return {Callee, Index, ++CurTempVersion};
561 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
562 FieldDecl *LambdaThisCaptureField =
nullptr;
564 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
570 APValue *getTemporary(
const void *Key,
unsigned Version) {
571 MapKeyTy KV(Key, Version);
572 auto LB = Temporaries.lower_bound(KV);
573 if (LB != Temporaries.end() && LB->first == KV)
579 APValue *getCurrentTemporary(
const void *Key) {
580 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
581 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
582 return &std::prev(UB)->second;
587 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
588 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
589 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
590 return std::prev(UB)->first.second;
598 template<
typename KeyT>
600 ScopeKind
Scope, LValue &LV);
605 void describe(llvm::raw_ostream &OS)
const override;
607 Frame *getCaller()
const override {
return Caller; }
608 SourceRange getCallRange()
const override {
return CallRange; }
611 bool isStdFunction()
const {
612 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
613 if (DC->isStdNamespace())
620 bool CanEvalMSConstexpr =
false;
628 class ThisOverrideRAII {
630 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
631 : Frame(Frame), OldThis(Frame.This) {
633 Frame.This = NewThis;
635 ~ThisOverrideRAII() {
636 Frame.This = OldThis;
639 CallStackFrame &Frame;
640 const LValue *OldThis;
645 class ExprTimeTraceScope {
647 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
648 : TimeScope(Name, [E, &Ctx] {
653 llvm::TimeTraceScope TimeScope;
658 struct MSConstexprContextRAII {
659 CallStackFrame &Frame;
661 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
662 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
663 Frame.CanEvalMSConstexpr =
Value;
666 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
679 llvm::PointerIntPair<APValue*, 2, ScopeKind> Value;
680 APValue::LValueBase Base;
684 Cleanup(
APValue *Val, APValue::LValueBase Base, QualType T,
686 : Value(Val, Scope), Base(Base), T(T) {}
690 bool isDestroyedAtEndOf(ScopeKind K)
const {
691 return (
int)Value.getInt() >= (
int)K;
693 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
694 if (RunDestructors) {
696 if (
const ValueDecl *VD = Base.dyn_cast<
const ValueDecl*>())
697 Loc = VD->getLocation();
698 else if (
const Expr *E = Base.dyn_cast<
const Expr*>())
699 Loc = E->getExprLoc();
702 *Value.getPointer() =
APValue();
706 bool hasSideEffect() {
707 return T.isDestructedType();
712 struct ObjectUnderConstruction {
713 APValue::LValueBase Base;
714 ArrayRef<APValue::LValuePathEntry> Path;
715 friend bool operator==(
const ObjectUnderConstruction &LHS,
716 const ObjectUnderConstruction &RHS) {
717 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
719 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
720 return llvm::hash_combine(Obj.Base, Obj.Path);
723 enum class ConstructionPhase {
734template<>
struct DenseMapInfo<ObjectUnderConstruction> {
735 using Base = DenseMapInfo<APValue::LValueBase>;
737 return {Base::getEmptyKey(), {}}; }
739 return {Base::getTombstoneKey(), {}};
744 static bool isEqual(
const ObjectUnderConstruction &LHS,
745 const ObjectUnderConstruction &RHS) {
759 const Expr *AllocExpr =
nullptr;
770 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
771 return NE->isArray() ? ArrayNew : New;
777 struct DynAllocOrder {
778 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
800 CallStackFrame *CurrentCall;
803 unsigned CallStackDepth;
806 unsigned NextCallIndex;
815 bool EnableNewConstInterp;
819 CallStackFrame BottomFrame;
823 llvm::SmallVector<Cleanup, 16> CleanupStack;
827 APValue::LValueBase EvaluatingDecl;
829 enum class EvaluatingDeclKind {
836 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
845 SmallVector<const Stmt *> BreakContinueStack;
848 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
849 ObjectsUnderConstruction;
854 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
857 unsigned NumHeapAllocs = 0;
859 struct EvaluatingConstructorRAII {
861 ObjectUnderConstruction Object;
863 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
865 : EI(EI), Object(Object) {
867 EI.ObjectsUnderConstruction
868 .insert({Object, HasBases ? ConstructionPhase::Bases
869 : ConstructionPhase::AfterBases})
872 void finishedConstructingBases() {
873 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
875 void finishedConstructingFields() {
876 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
878 ~EvaluatingConstructorRAII() {
879 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
883 struct EvaluatingDestructorRAII {
885 ObjectUnderConstruction Object;
887 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
888 : EI(EI), Object(Object) {
889 DidInsert = EI.ObjectsUnderConstruction
890 .insert({Object, ConstructionPhase::Destroying})
893 void startedDestroyingBases() {
894 EI.ObjectsUnderConstruction[Object] =
895 ConstructionPhase::DestroyingBases;
897 ~EvaluatingDestructorRAII() {
899 EI.ObjectsUnderConstruction.erase(Object);
904 isEvaluatingCtorDtor(APValue::LValueBase Base,
905 ArrayRef<APValue::LValuePathEntry> Path) {
906 return ObjectsUnderConstruction.lookup({
Base, Path});
911 unsigned SpeculativeEvaluationDepth = 0;
917 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
918 : State(const_cast<ASTContext &>(
C), S), CurrentCall(
nullptr),
919 CallStackDepth(0), NextCallIndex(1),
920 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
921 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
922 BottomFrame(*this, SourceLocation(),
nullptr,
925 EvaluatingDecl((const ValueDecl *)
nullptr),
934 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
935 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
936 EvaluatingDecl =
Base;
937 IsEvaluatingDecl = EDK;
938 EvaluatingDeclValue = &
Value;
941 bool CheckCallLimit(SourceLocation Loc) {
944 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
946 if (NextCallIndex == 0) {
948 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
951 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
953 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
954 << getLangOpts().ConstexprCallDepth;
959 uint64_t ElemCount,
bool Diag) {
965 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
967 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
976 uint64_t Limit = getLangOpts().ConstexprStepLimit;
977 if (Limit != 0 && ElemCount > Limit) {
979 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
980 << ElemCount << Limit;
986 std::pair<CallStackFrame *, unsigned>
987 getCallFrameAndDepth(
unsigned CallIndex) {
988 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
991 unsigned Depth = CallStackDepth;
992 CallStackFrame *Frame = CurrentCall;
993 while (Frame->Index > CallIndex) {
994 Frame = Frame->Caller;
997 if (Frame->Index == CallIndex)
998 return {Frame, Depth};
1002 bool nextStep(
const Stmt *S) {
1003 if (getLangOpts().ConstexprStepLimit == 0)
1007 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1014 APValue *createHeapAlloc(
const Expr *E, QualType T, LValue &LV);
1016 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1017 std::optional<DynAlloc *>
Result;
1018 auto It = HeapAllocs.find(DA);
1019 if (It != HeapAllocs.end())
1025 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1026 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1027 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1032 struct StdAllocatorCaller {
1033 unsigned FrameIndex;
1036 explicit operator bool()
const {
return FrameIndex != 0; };
1039 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1040 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1042 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1045 const IdentifierInfo *FnII = MD->getIdentifier();
1046 if (!FnII || !FnII->
isStr(FnName))
1050 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1054 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1055 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1056 if (CTSD->isInStdNamespace() && ClassII &&
1057 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1059 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1065 void performLifetimeExtension() {
1067 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1068 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1075 bool discardCleanups() {
1076 for (Cleanup &
C : CleanupStack) {
1077 if (
C.hasSideEffect() && !noteSideEffect()) {
1078 CleanupStack.clear();
1082 CleanupStack.clear();
1087 const interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1088 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1090 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1091 bool stepsLeft()
const override {
return StepsLeft > 0; }
1104 [[nodiscard]]
bool noteFailure() {
1112 bool KeepGoing = keepEvaluatingAfterFailure();
1113 EvalStatus.HasSideEffects |= KeepGoing;
1117 class ArrayInitLoopIndex {
1122 ArrayInitLoopIndex(EvalInfo &Info)
1123 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1124 Info.ArrayInitIndex = 0;
1126 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1128 operator uint64_t&() {
return Info.ArrayInitIndex; }
1133 struct FoldConstant {
1136 bool HadNoPriorDiags;
1139 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1142 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1143 Info.EvalStatus.
Diag->empty() &&
1144 !Info.EvalStatus.HasSideEffects),
1145 OldMode(Info.EvalMode) {
1147 Info.EvalMode = EvaluationMode::ConstantFold;
1149 void keepDiagnostics() { Enabled =
false; }
1151 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1152 !Info.EvalStatus.HasSideEffects)
1153 Info.EvalStatus.Diag->clear();
1154 Info.EvalMode = OldMode;
1160 struct IgnoreSideEffectsRAII {
1163 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1164 : Info(Info), OldMode(Info.EvalMode) {
1165 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1168 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1173 class SpeculativeEvaluationRAII {
1174 EvalInfo *Info =
nullptr;
1175 Expr::EvalStatus OldStatus;
1176 unsigned OldSpeculativeEvaluationDepth = 0;
1178 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1180 OldStatus =
Other.OldStatus;
1181 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1182 Other.Info =
nullptr;
1185 void maybeRestoreState() {
1189 Info->EvalStatus = OldStatus;
1190 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1194 SpeculativeEvaluationRAII() =
default;
1196 SpeculativeEvaluationRAII(
1197 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1198 : Info(&Info), OldStatus(Info.EvalStatus),
1199 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1200 Info.EvalStatus.Diag = NewDiag;
1201 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1204 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1205 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1206 moveFromAndCancel(std::move(
Other));
1209 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1210 maybeRestoreState();
1211 moveFromAndCancel(std::move(
Other));
1215 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1220 template<ScopeKind Kind>
1223 unsigned OldStackSize;
1225 ScopeRAII(EvalInfo &Info)
1226 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1229 Info.CurrentCall->pushTempVersion();
1231 bool destroy(
bool RunDestructors =
true) {
1232 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1233 OldStackSize = std::numeric_limits<unsigned>::max();
1237 if (OldStackSize != std::numeric_limits<unsigned>::max())
1241 Info.CurrentCall->popTempVersion();
1244 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1245 unsigned OldStackSize) {
1246 assert(OldStackSize <= Info.CleanupStack.size() &&
1247 "running cleanups out of order?");
1252 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1253 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1254 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1262 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1263 if (Kind != ScopeKind::Block)
1265 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1266 return C.isDestroyedAtEndOf(Kind);
1268 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1272 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1273 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1274 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1277bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1281 if (isOnePastTheEnd()) {
1282 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1293void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1295 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1300void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1305 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1306 Info.CCEDiag(E, diag::note_constexpr_array_index)
1308 <<
static_cast<unsigned>(getMostDerivedArraySize());
1310 Info.CCEDiag(E, diag::note_constexpr_array_index)
1315CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1316 const FunctionDecl *Callee,
const LValue *This,
1317 const Expr *CallExpr, CallRef Call)
1319 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1320 Index(Info.NextCallIndex++) {
1321 Info.CurrentCall =
this;
1322 ++Info.CallStackDepth;
1325CallStackFrame::~CallStackFrame() {
1326 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1327 --Info.CallStackDepth;
1328 Info.CurrentCall = Caller;
1353 llvm_unreachable(
"unknown access kind");
1390 llvm_unreachable(
"unknown access kind");
1394 struct ComplexValue {
1402 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1404 void makeComplexFloat() { IsInt =
false; }
1405 bool isComplexFloat()
const {
return !IsInt; }
1406 APFloat &getComplexFloatReal() {
return FloatReal; }
1407 APFloat &getComplexFloatImag() {
return FloatImag; }
1409 void makeComplexInt() { IsInt =
true; }
1410 bool isComplexInt()
const {
return IsInt; }
1411 APSInt &getComplexIntReal() {
return IntReal; }
1412 APSInt &getComplexIntImag() {
return IntImag; }
1414 void moveInto(
APValue &v)
const {
1415 if (isComplexFloat())
1416 v =
APValue(FloatReal, FloatImag);
1418 v =
APValue(IntReal, IntImag);
1420 void setFrom(
const APValue &v) {
1435 APValue::LValueBase
Base;
1437 SubobjectDesignator Designator;
1439 bool InvalidBase : 1;
1441 bool AllowConstexprUnknown =
false;
1443 const APValue::LValueBase getLValueBase()
const {
return Base; }
1444 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1445 CharUnits &getLValueOffset() {
return Offset; }
1446 const CharUnits &getLValueOffset()
const {
return Offset; }
1447 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1448 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1449 bool isNullPointer()
const {
return IsNullPtr;}
1451 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1452 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1455 if (Designator.Invalid)
1456 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1458 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1459 V =
APValue(Base, Offset, Designator.Entries,
1460 Designator.IsOnePastTheEnd, IsNullPtr);
1462 if (AllowConstexprUnknown)
1463 V.setConstexprUnknown();
1465 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1466 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1467 Base =
V.getLValueBase();
1468 Offset =
V.getLValueOffset();
1469 InvalidBase =
false;
1470 Designator = SubobjectDesignator(Ctx,
V);
1471 IsNullPtr =
V.isNullPointer();
1472 AllowConstexprUnknown =
V.allowConstexprUnknown();
1475 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1479 const auto *E = B.
get<
const Expr *>();
1481 "Unexpected type of invalid base");
1487 InvalidBase = BInvalid;
1488 Designator = SubobjectDesignator(
getType(B));
1490 AllowConstexprUnknown =
false;
1493 void setNull(ASTContext &Ctx, QualType PointerTy) {
1494 Base = (
const ValueDecl *)
nullptr;
1497 InvalidBase =
false;
1500 AllowConstexprUnknown =
false;
1503 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1507 std::string
toString(ASTContext &Ctx, QualType T)
const {
1509 moveInto(Printable);
1516 template <
typename GenDiagType>
1517 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1518 if (Designator.Invalid)
1522 Designator.setInvalid();
1529 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1531 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1532 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1536 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1538 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1539 if (AK == AccessKinds::AK_Dereference)
1540 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1542 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1550 Designator.checkSubobject(Info, E, CSK);
1553 void addDecl(EvalInfo &Info,
const Expr *E,
1554 const Decl *D,
bool Virtual =
false) {
1556 Designator.addDeclUnchecked(D,
Virtual);
1558 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1559 if (!Designator.Entries.empty()) {
1560 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1561 Designator.setInvalid();
1565 assert(
getType(Base).getNonReferenceType()->isPointerType() ||
1566 getType(Base).getNonReferenceType()->isArrayType());
1567 Designator.FirstEntryIsAnUnsizedArray =
true;
1568 Designator.addUnsizedArrayUnchecked(ElemTy);
1571 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1573 Designator.addArrayUnchecked(CAT);
1575 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1577 Designator.addComplexUnchecked(EltTy, Imag);
1579 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1580 uint64_t Size, uint64_t Idx) {
1582 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1584 void clearIsNullPointer() {
1587 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1588 const APSInt &Index, CharUnits ElementSize) {
1599 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1603 Designator.adjustIndex(Info, E, Index, *
this);
1604 clearIsNullPointer();
1606 void adjustOffset(CharUnits N) {
1609 clearIsNullPointer();
1615 explicit MemberPtr(
const ValueDecl *Decl)
1616 : DeclAndIsDerivedMember(
Decl,
false) {}
1620 const ValueDecl *getDecl()
const {
1621 return DeclAndIsDerivedMember.getPointer();
1624 bool isDerivedMember()
const {
1625 return DeclAndIsDerivedMember.getInt();
1628 const CXXRecordDecl *getContainingRecord()
const {
1630 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1634 V =
APValue(getDecl(), isDerivedMember(), Path);
1637 assert(
V.isMemberPointer());
1638 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1639 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1641 llvm::append_range(Path,
V.getMemberPointerPath());
1647 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1650 SmallVector<const CXXRecordDecl*, 4> Path;
1654 bool castBack(
const CXXRecordDecl *
Class) {
1655 assert(!Path.empty());
1656 const CXXRecordDecl *Expected;
1657 if (Path.size() >= 2)
1658 Expected = Path[Path.size() - 2];
1660 Expected = getContainingRecord();
1674 bool castToDerived(
const CXXRecordDecl *Derived) {
1677 if (!isDerivedMember()) {
1678 Path.push_back(Derived);
1681 if (!castBack(Derived))
1684 DeclAndIsDerivedMember.setInt(
false);
1692 DeclAndIsDerivedMember.setInt(
true);
1693 if (isDerivedMember()) {
1694 Path.push_back(Base);
1697 return castBack(Base);
1702 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1703 if (!LHS.getDecl() || !RHS.getDecl())
1704 return !LHS.getDecl() && !RHS.getDecl();
1705 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1707 return LHS.Path == RHS.Path;
1711void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1715 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1716 if (isMostDerivedAnUnsizedArray()) {
1717 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1722 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1730 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1732 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1735 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1736 if (!Info.checkingPotentialConstantExpression() ||
1737 !LV.AllowConstexprUnknown) {
1740 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1741 (llvm::APInt &)N += ArrayIndex;
1742 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1743 diagnosePointerArithmetic(Info, E, N);
1749 ArrayIndex += TruncatedN;
1750 assert(ArrayIndex <= ArraySize &&
1751 "bounds check succeeded for out-of-bounds index");
1754 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1756 IsOnePastTheEnd = (ArrayIndex != 0);
1761 const LValue &This,
const Expr *E,
1762 bool AllowNonLiteralTypes =
false);
1764 bool InvalidBaseOK =
false);
1766 bool InvalidBaseOK =
false);
1774static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1779static std::optional<uint64_t>
1781 std::string *StringResult =
nullptr);
1798 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1799 Int = Int.extend(Int.getBitWidth() + 1);
1800 Int.setIsSigned(
true);
1805template<
typename KeyT>
1806APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType T,
1807 ScopeKind Scope, LValue &LV) {
1808 unsigned Version = getTempVersion();
1809 APValue::LValueBase
Base(Key, Index, Version);
1811 return createLocal(Base, Key, T, Scope);
1815APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1817 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1818 APValue::LValueBase
Base(PVD, Index, Args.Version);
1823 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1826APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1827 QualType T, ScopeKind Scope) {
1828 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1829 unsigned Version =
Base.getVersion();
1831 assert(
Result.isAbsent() &&
"local created multiple times");
1837 if (Index <= Info.SpeculativeEvaluationDepth) {
1839 Info.noteSideEffect();
1841 Info.CleanupStack.push_back(Cleanup(&
Result, Base, T, Scope));
1846APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType T, LValue &LV) {
1848 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1852 DynamicAllocLValue DA(NumHeapAllocs++);
1854 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1855 std::forward_as_tuple(DA), std::tuple<>());
1856 assert(
Result.second &&
"reused a heap alloc index?");
1857 Result.first->second.AllocExpr = E;
1858 return &
Result.first->second.Value;
1862void CallStackFrame::describe(raw_ostream &Out)
const {
1863 bool IsMemberCall =
false;
1864 bool ExplicitInstanceParam =
false;
1865 clang::PrintingPolicy PrintingPolicy = Info.Ctx.getPrintingPolicy();
1868 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1870 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1874 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1877 if (This && IsMemberCall) {
1878 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1879 const Expr *
Object = MCE->getImplicitObjectArgument();
1880 Object->printPretty(Out,
nullptr, PrintingPolicy,
1882 if (
Object->getType()->isPointerType())
1886 }
else if (
const auto *OCE =
1887 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1888 OCE->getArg(0)->printPretty(Out,
nullptr, PrintingPolicy,
1893 This->moveInto(Val);
1896 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
1899 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1905 llvm::ListSeparator
Comma;
1906 for (
const ParmVarDecl *Param :
1907 Callee->parameters().slice(ExplicitInstanceParam)) {
1909 const APValue *
V = Info.getParamSlot(Arguments, Param);
1911 V->printPretty(Out, Info.Ctx, Param->getType());
1927 return Info.noteSideEffect();
1934 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1935 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
1936 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
1937 Builtin == Builtin::BI__builtin_function_start);
1941 const auto *BaseExpr =
1942 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
1957 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1958 return VD->hasGlobalStorage();
1974 case Expr::CompoundLiteralExprClass: {
1978 case Expr::MaterializeTemporaryExprClass:
1983 case Expr::StringLiteralClass:
1984 case Expr::PredefinedExprClass:
1985 case Expr::ObjCStringLiteralClass:
1986 case Expr::ObjCEncodeExprClass:
1988 case Expr::ObjCBoxedExprClass:
1989 case Expr::ObjCArrayLiteralClass:
1990 case Expr::ObjCDictionaryLiteralClass:
1992 case Expr::CallExprClass:
1995 case Expr::AddrLabelExprClass:
1999 case Expr::BlockExprClass:
2003 case Expr::SourceLocExprClass:
2005 case Expr::ImplicitValueInitExprClass:
2030 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2035 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2036 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2044 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2045 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2046 Lit = PE->getFunctionName();
2051 AsString.
Bytes = Lit->getBytes();
2052 AsString.
CharWidth = Lit->getCharByteWidth();
2072 const LValue &RHS) {
2081 CharUnits Offset = RHS.Offset - LHS.Offset;
2082 if (Offset.isNegative()) {
2083 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2085 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2087 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2089 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2092 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2093 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2094 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2095 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2100 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2101 if (Shorter.size() + NullByte >= Longer.size())
2103 if (Longer[Shorter.size() + NullByte])
2109 return Shorter == Longer.take_front(Shorter.size());
2119 if (isa_and_nonnull<VarDecl>(
Decl)) {
2129 if (!A.getLValueBase())
2130 return !B.getLValueBase();
2131 if (!B.getLValueBase())
2134 if (A.getLValueBase().getOpaqueValue() !=
2135 B.getLValueBase().getOpaqueValue())
2138 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2139 A.getLValueVersion() == B.getLValueVersion();
2143 assert(
Base &&
"no location for a null lvalue");
2149 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2151 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2152 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2153 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2154 Idx < F->Callee->getNumParams()) {
2155 VD = F->Callee->getParamDecl(Idx);
2162 Info.Note(VD->
getLocation(), diag::note_declared_at);
2164 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2167 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2168 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2169 diag::note_constexpr_dynamic_alloc_here);
2202 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2210 if (isTemplateArgument(Kind)) {
2211 int InvalidBaseKind = -1;
2214 InvalidBaseKind = 0;
2215 else if (isa_and_nonnull<StringLiteral>(BaseE))
2216 InvalidBaseKind = 1;
2217 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2218 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2219 InvalidBaseKind = 2;
2220 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2221 InvalidBaseKind = 3;
2222 Ident = PE->getIdentKindName();
2225 if (InvalidBaseKind != -1) {
2226 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2227 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2233 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2234 FD && FD->isImmediateFunction()) {
2235 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2237 Info.Note(FD->getLocation(), diag::note_declared_at);
2245 if (Info.getLangOpts().CPlusPlus11) {
2246 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2247 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2249 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2250 if (VarD && VarD->isConstexpr()) {
2256 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2268 assert((Info.checkingPotentialConstantExpression() ||
2269 LVal.getLValueCallIndex() == 0) &&
2270 "have call index for global lvalue");
2272 if (LVal.allowConstexprUnknown()) {
2274 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2283 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2284 << IsReferenceType << !
Designator.Entries.empty();
2290 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2292 if (Var->getTLSKind())
2300 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>() &&
2301 !Var->isStaticLocal())
2306 if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
2307 Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
2308 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2309 !Var->hasAttr<CUDAConstantAttr>() &&
2310 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2311 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2312 Var->hasAttr<HIPManagedAttr>())
2316 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2327 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2328 FD->hasAttr<DLLImportAttr>())
2332 }
else if (
const auto *MTE =
2333 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2334 if (CheckedTemps.insert(MTE).second) {
2337 Info.FFDiag(MTE->getExprLoc(),
2338 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2343 APValue *
V = MTE->getOrCreateValue(
false);
2344 assert(
V &&
"evasluation result refers to uninitialised temporary");
2346 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2347 nullptr, CheckedTemps))
2354 if (!IsReferenceType)
2366 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2367 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2382 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2385 if (FD->isImmediateFunction()) {
2386 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2387 Info.Note(FD->getLocation(), diag::note_declared_at);
2390 return isForManglingOnly(Kind) || FD->isVirtual() ||
2391 !FD->hasAttr<DLLImportAttr>();
2397 const LValue *
This =
nullptr) {
2399 if (Info.getLangOpts().CPlusPlus23)
2418 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2422 if (Info.getLangOpts().CPlusPlus11)
2423 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2426 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2437 if (SubobjectDecl) {
2438 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2439 << 1 << SubobjectDecl;
2441 diag::note_constexpr_subobject_declared_here);
2443 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2452 Type = AT->getValueType();
2457 if (
Value.isArray()) {
2459 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2461 Value.getArrayInitializedElt(I), Kind,
2462 SubobjectDecl, CheckedTemps))
2465 if (!
Value.hasArrayFiller())
2468 Value.getArrayFiller(), Kind, SubobjectDecl,
2471 if (
Value.isUnion() &&
Value.getUnionField()) {
2474 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2476 if (
Value.isStruct()) {
2478 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2479 unsigned BaseIndex = 0;
2481 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2484 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2485 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2495 for (
const auto *I : RD->fields()) {
2496 if (I->isUnnamedBitField())
2500 Value.getStructField(I->getFieldIndex()), Kind,
2506 if (
Value.isLValue() &&
2509 LVal.setFrom(Info.Ctx,
Value);
2514 if (
Value.isMemberPointer() &&
2535 nullptr, CheckedTemps);
2545 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2551 if (!Info.HeapAllocs.empty()) {
2555 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2556 diag::note_constexpr_memory_leak)
2557 <<
unsigned(Info.HeapAllocs.size() - 1);
2565 if (!
Value.getLValueBase()) {
2618 llvm_unreachable(
"unknown APValue kind");
2624 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2633 const T &SrcValue,
QualType DestType) {
2634 Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType;
2635 if (
const auto *OBT = DestType->
getAs<OverflowBehaviorType>();
2636 OBT && OBT->isTrapKind()) {
2639 return Info.noteUndefinedBehavior();
2645 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2651 if (
Value.convertToInteger(
Result, llvm::APFloat::rmTowardZero, &ignored)
2652 & APFloat::opInvalidOp)
2663 llvm::RoundingMode RM =
2665 if (RM == llvm::RoundingMode::Dynamic)
2666 RM = llvm::RoundingMode::NearestTiesToEven;
2672 APFloat::opStatus St) {
2675 if (Info.InConstantContext)
2679 if ((St & APFloat::opInexact) &&
2683 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2687 if ((St != APFloat::opOK) &&
2690 FPO.getAllowFEnvAccess())) {
2691 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2695 if ((St & APFloat::opStatus::opInvalidOp) &&
2716 "HandleFloatToFloatCast has been checked with only CastExpr, "
2717 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2718 "the new expression or address the root cause of this usage.");
2720 APFloat::opStatus St;
2723 St =
Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2730 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2744 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2746 APFloat::opStatus St =
Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2752 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2754 if (!
Value.isInt()) {
2758 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2764 unsigned OldBitWidth = Int.getBitWidth();
2766 if (NewBitWidth < OldBitWidth)
2767 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2774template<
typename Operation>
2777 unsigned BitWidth, Operation Op,
2779 if (LHS.isUnsigned()) {
2784 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2787 if (Info.checkingForUndefinedBehavior())
2788 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2789 diag::warn_integer_constant_overflow)
2802 bool HandleOverflowResult =
true;
2809 std::multiplies<APSInt>(),
Result);
2812 std::plus<APSInt>(),
Result);
2815 std::minus<APSInt>(),
Result);
2816 case BO_And:
Result = LHS & RHS;
return true;
2817 case BO_Xor:
Result = LHS ^ RHS;
return true;
2818 case BO_Or:
Result = LHS | RHS;
return true;
2822 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2828 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2829 LHS.isMinSignedValue())
2831 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2832 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2833 return HandleOverflowResult;
2835 if (Info.getLangOpts().OpenCL)
2837 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2838 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2840 else if (RHS.isSigned() && RHS.isNegative()) {
2843 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2844 if (!Info.noteUndefinedBehavior())
2852 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2854 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2855 << RHS << E->
getType() << LHS.getBitWidth();
2856 if (!Info.noteUndefinedBehavior())
2858 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2863 if (LHS.isNegative()) {
2864 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2865 if (!Info.noteUndefinedBehavior())
2867 }
else if (LHS.countl_zero() < SA) {
2868 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2869 if (!Info.noteUndefinedBehavior())
2877 if (Info.getLangOpts().OpenCL)
2879 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2880 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2882 else if (RHS.isSigned() && RHS.isNegative()) {
2885 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2886 if (!Info.noteUndefinedBehavior())
2894 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2896 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2897 << RHS << E->
getType() << LHS.getBitWidth();
2898 if (!Info.noteUndefinedBehavior())
2906 case BO_LT:
Result = LHS < RHS;
return true;
2907 case BO_GT:
Result = LHS > RHS;
return true;
2908 case BO_LE:
Result = LHS <= RHS;
return true;
2909 case BO_GE:
Result = LHS >= RHS;
return true;
2910 case BO_EQ:
Result = LHS == RHS;
return true;
2911 case BO_NE:
Result = LHS != RHS;
return true;
2913 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2920 const APFloat &RHS) {
2922 APFloat::opStatus St;
2928 St = LHS.multiply(RHS, RM);
2931 St = LHS.add(RHS, RM);
2934 St = LHS.subtract(RHS, RM);
2940 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2941 St = LHS.divide(RHS, RM);
2950 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2951 return Info.noteUndefinedBehavior();
2959 const APInt &RHSValue, APInt &
Result) {
2960 bool LHS = (LHSValue != 0);
2961 bool RHS = (RHSValue != 0);
2963 if (Opcode == BO_LAnd)
2971 const APFloat &RHSValue, APInt &
Result) {
2972 bool LHS = !LHSValue.isZero();
2973 bool RHS = !RHSValue.isZero();
2975 if (Opcode == BO_LAnd)
2994template <
typename APTy>
2997 const APTy &RHSValue, APInt &
Result) {
3000 llvm_unreachable(
"unsupported binary operator");
3002 Result = (LHSValue == RHSValue);
3005 Result = (LHSValue != RHSValue);
3008 Result = (LHSValue < RHSValue);
3011 Result = (LHSValue > RHSValue);
3014 Result = (LHSValue <= RHSValue);
3017 Result = (LHSValue >= RHSValue);
3046 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3047 "Operation not supported on vector types");
3051 QualType EltTy = VT->getElementType();
3058 "A vector result that isn't a vector OR uncalculated LValue");
3064 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3068 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3073 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3083 RHSElt.
getInt(), EltResult);
3089 ResultElements.emplace_back(EltResult);
3094 "Mismatched LHS/RHS/Result Type");
3095 APFloat LHSFloat = LHSElt.
getFloat();
3103 ResultElements.emplace_back(LHSFloat);
3107 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3115 unsigned TruncatedElements) {
3116 SubobjectDesignator &D =
Result.Designator;
3119 if (TruncatedElements == D.Entries.size())
3121 assert(TruncatedElements >= D.MostDerivedPathLength &&
3122 "not casting to a derived class");
3128 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3132 if (isVirtualBaseClass(D.Entries[I]))
3138 D.Entries.resize(TruncatedElements);
3148 RL = &Info.Ctx.getASTRecordLayout(Derived);
3151 Obj.addDecl(Info, E,
Base,
false);
3152 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3161 if (!
Base->isVirtual())
3164 SubobjectDesignator &D = Obj.Designator;
3179 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3180 Obj.addDecl(Info, E, BaseDecl,
true);
3189 PathI != PathE; ++PathI) {
3193 Type = (*PathI)->getType();
3205 llvm_unreachable(
"Class must be derived from the passed in base class!");
3220 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3224 LVal.addDecl(Info, E, FD);
3225 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3233 for (
const auto *
C : IFD->
chain())
3267 Size = Info.Ctx.getTypeSizeInChars(
Type);
3269 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3286 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3292 int64_t Adjustment) {
3294 APSInt::get(Adjustment));
3309 LVal.Offset += SizeOfComponent;
3311 LVal.addComplex(Info, E, EltTy, Imag);
3317 uint64_t Size, uint64_t Idx) {
3322 LVal.Offset += SizeOfElement * Idx;
3324 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3338 const VarDecl *VD, CallStackFrame *Frame,
3342 bool AllowConstexprUnknown =
3347 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3359 if (!AllowConstexprUnknown || IsLocalVariable) {
3360 if (!Info.checkingPotentialConstantExpression())
3361 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3371 Result = Frame->getTemporary(VD, Version);
3373 return CheckUninitReference(
true);
3382 "missing value for local variable");
3383 if (Info.checkingPotentialConstantExpression())
3387 "A variable in a frame should either be a local or a parameter");
3393 if (Info.EvaluatingDecl ==
Base) {
3394 Result = Info.EvaluatingDeclValue;
3395 return CheckUninitReference(
false);
3403 if (AllowConstexprUnknown) {
3410 if (!Info.checkingPotentialConstantExpression() ||
3411 !Info.CurrentCall->Callee ||
3413 if (Info.getLangOpts().CPlusPlus11) {
3414 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3435 if (!
Init && !AllowConstexprUnknown) {
3438 if (!Info.checkingPotentialConstantExpression()) {
3439 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3450 if (
Init &&
Init->isValueDependent()) {
3457 if (!Info.checkingPotentialConstantExpression()) {
3458 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3459 ? diag::note_constexpr_ltor_non_constexpr
3460 : diag::note_constexpr_ltor_non_integral, 1)
3474 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3490 !AllowConstexprUnknown) ||
3491 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3494 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3504 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3511 if (!
Result && !AllowConstexprUnknown)
3514 return CheckUninitReference(
false);
3524 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3525 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3529 llvm_unreachable(
"base class missing from derived class's bases list");
3536 "SourceLocExpr should have already been converted to a StringLiteral");
3539 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3541 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3542 assert(Index <= Str.size() &&
"Index too large");
3543 return APSInt::getUnsigned(Str.c_str()[Index]);
3546 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3547 Lit = PE->getFunctionName();
3550 Info.Ctx.getAsConstantArrayType(S->
getType());
3551 assert(CAT &&
"string literal isn't an array");
3553 assert(CharType->
isIntegerType() &&
"unexpected character type");
3556 if (Index < S->getLength())
3569 AllocType.isNull() ? S->
getType() : AllocType);
3570 assert(CAT &&
"string literal isn't an array");
3572 assert(CharType->
isIntegerType() &&
"unexpected character type");
3579 if (
Result.hasArrayFiller())
3581 for (
unsigned I = 0, N =
Result.getArrayInitializedElts(); I != N; ++I) {
3589 unsigned Size =
Array.getArraySize();
3590 assert(Index < Size);
3593 unsigned OldElts =
Array.getArrayInitializedElts();
3594 unsigned NewElts = std::max(Index+1, OldElts * 2);
3595 NewElts = std::min(Size, std::max(NewElts, 8u));
3599 for (
unsigned I = 0; I != OldElts; ++I)
3601 for (
unsigned I = OldElts; I != NewElts; ++I)
3605 Array.swap(NewValue);
3612 Vec =
APValue(Elts.data(), Elts.size());
3622 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3633 for (
auto *Field : RD->
fields())
3634 if (!Field->isUnnamedBitField() &&
3638 for (
auto &BaseSpec : RD->
bases())
3649 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3656 for (
auto *Field : RD->
fields()) {
3661 if (Field->isMutable() &&
3663 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3664 Info.Note(Field->getLocation(), diag::note_declared_at);
3672 for (
auto &BaseSpec : RD->
bases())
3682 bool MutableSubobject =
false) {
3687 switch (Info.IsEvaluatingDecl) {
3688 case EvalInfo::EvaluatingDeclKind::None:
3691 case EvalInfo::EvaluatingDeclKind::Ctor:
3693 if (Info.EvaluatingDecl ==
Base)
3698 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3699 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3700 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3703 case EvalInfo::EvaluatingDeclKind::Dtor:
3708 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3714 return T.isConstQualified() || T->isReferenceType();
3717 llvm_unreachable(
"unknown evaluating decl kind");
3722 return Info.CheckArraySize(
3742 uint64_t IntResult = BoolResult;
3745 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3746 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3751 Info.Ctx.getIntTypeForBitwidth(64,
false),
3754 Result = std::move(Result2);
3762 DestTy,
Result.getFloat());
3768 uint64_t IntResult = BoolResult;
3787 uint64_t IntResult = BoolResult;
3794 DestTy,
Result.getInt());
3798 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3811 {&
Result, ResultType, 0}};
3814 while (!WorkList.empty() && ElI < Elements.size()) {
3815 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3831 APSInt &Int = Res->getInt();
3832 unsigned OldBitWidth = Int.getBitWidth();
3833 unsigned NewBitWidth = BitWidth;
3834 if (NewBitWidth < OldBitWidth)
3835 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3844 for (
unsigned I = 0; I < NumEl; ++I) {
3850 *Res =
APValue(Vals.data(), NumEl);
3859 for (int64_t I = Size - 1; I > -1; --I)
3860 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3866 unsigned NumBases = 0;
3867 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3868 NumBases = CXXRD->getNumBases();
3875 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3876 if (CXXRD->getNumBases() > 0) {
3877 assert(CXXRD->getNumBases() == 1);
3879 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3886 if (FD->isUnnamedBitField())
3888 if (FD->isBitField()) {
3889 FDBW = FD->getBitWidthValue();
3892 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3893 FD->getType(), FDBW);
3896 std::reverse(ReverseList.begin(), ReverseList.end());
3897 llvm::append_range(WorkList, ReverseList);
3900 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3913 assert((Elements.size() == SrcTypes.size()) &&
3914 (Elements.size() == DestTypes.size()));
3916 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
3917 APValue Original = Elements[I];
3921 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
3932 while (!WorkList.empty()) {
3955 for (uint64_t I = 0; I < ArrSize; ++I) {
3956 WorkList.push_back(ElTy);
3964 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3965 if (CXXRD->getNumBases() > 0) {
3966 assert(CXXRD->getNumBases() == 1);
3968 WorkList.push_back(BS.
getType());
3974 if (FD->isUnnamedBitField())
3976 WorkList.push_back(FD->getType());
3993 "Not a valid HLSLAggregateSplatCast.");
4013 unsigned Populated = 0;
4014 while (!WorkList.empty() && Populated < Size) {
4015 auto [Work,
Type] = WorkList.pop_back_val();
4017 if (Work.isFloat() || Work.isInt()) {
4018 Elements.push_back(Work);
4019 Types.push_back(
Type);
4023 if (Work.isVector()) {
4026 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4028 Elements.push_back(Work.getVectorElt(I));
4029 Types.push_back(ElTy);
4034 if (Work.isMatrix()) {
4037 QualType ElTy = MT->getElementType();
4039 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4041 for (
unsigned Col = 0;
4042 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4043 Elements.push_back(Work.getMatrixElt(Row, Col));
4044 Types.push_back(ElTy);
4050 if (Work.isArray()) {
4054 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4055 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4060 if (Work.isStruct()) {
4068 if (FD->isUnnamedBitField())
4070 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4074 std::reverse(ReverseList.begin(), ReverseList.end());
4075 llvm::append_range(WorkList, ReverseList);
4078 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4079 if (CXXRD->getNumBases() > 0) {
4080 assert(CXXRD->getNumBases() == 1);
4085 if (!
Base.isStruct())
4093 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4102struct CompleteObject {
4104 APValue::LValueBase
Base;
4114 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4125 if (!Info.getLangOpts().CPlusPlus14 &&
4126 AK != AccessKinds::AK_IsWithinLifetime)
4131 explicit operator bool()
const {
return !
Type.isNull(); }
4136 bool IsMutable =
false) {
4150template <
typename Sub
objectHandler>
4151static typename SubobjectHandler::result_type
4153 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4156 return handler.failed();
4157 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4158 if (Info.getLangOpts().CPlusPlus11)
4159 Info.FFDiag(E, Sub.isOnePastTheEnd()
4160 ? diag::note_constexpr_access_past_end
4161 : diag::note_constexpr_access_unsized_array)
4162 << handler.AccessKind;
4165 return handler.failed();
4171 const FieldDecl *VolatileField =
nullptr;
4174 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4185 if (!Info.checkingPotentialConstantExpression()) {
4186 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4191 return handler.failed();
4199 Info.isEvaluatingCtorDtor(
4200 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4201 ConstructionPhase::None) {
4202 ObjType = Info.Ctx.getCanonicalType(ObjType);
4211 if (Info.getLangOpts().CPlusPlus) {
4215 if (VolatileField) {
4218 Decl = VolatileField;
4221 Loc = VD->getLocation();
4228 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4229 << handler.AccessKind << DiagKind <<
Decl;
4230 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4232 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4234 return handler.failed();
4242 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4244 return handler.failed();
4248 if (!handler.found(*O, ObjType, Obj.Base))
4260 LastField =
nullptr;
4263 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4265 "vla in literal type?");
4266 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4267 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4268 CAT && CAT->
getSize().ule(Index)) {
4271 if (Info.getLangOpts().CPlusPlus11)
4272 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4273 << handler.AccessKind;
4276 return handler.failed();
4283 else if (!
isRead(handler.AccessKind)) {
4284 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4286 return handler.failed();
4294 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4296 if (Info.getLangOpts().CPlusPlus11)
4297 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4298 << handler.AccessKind;
4301 return handler.failed();
4307 assert(I == N - 1 &&
"extracting subobject of scalar?");
4317 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4318 unsigned NumElements = VT->getNumElements();
4319 if (Index == NumElements) {
4320 if (Info.getLangOpts().CPlusPlus11)
4321 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4322 << handler.AccessKind;
4325 return handler.failed();
4328 if (Index > NumElements) {
4329 Info.CCEDiag(E, diag::note_constexpr_array_index)
4330 << Index << 0 << NumElements;
4331 return handler.failed();
4334 ObjType = VT->getElementType();
4335 assert(I == N - 1 &&
"extracting subobject of scalar?");
4338 if (
isRead(handler.AccessKind)) {
4340 return handler.failed();
4344 assert(O->
isVector() &&
"unexpected object during vector element access");
4345 return handler.found(O->
getVectorElt(Index), ObjType, Obj.Base);
4346 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4347 if (Field->isMutable() &&
4348 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4349 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4350 << handler.AccessKind << Field;
4351 Info.Note(Field->getLocation(), diag::note_declared_at);
4352 return handler.failed();
4361 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4372 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4373 << handler.AccessKind << Field << !UnionField << UnionField;
4374 return handler.failed();
4383 if (Field->getType().isVolatileQualified())
4384 VolatileField = Field;
4397struct ExtractSubobjectHandler {
4403 typedef bool result_type;
4404 bool failed() {
return false; }
4405 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4415 bool found(APFloat &
Value, QualType SubobjType) {
4424 const CompleteObject &Obj,
4428 ExtractSubobjectHandler Handler = {Info, E,
Result, AK};
4433struct ModifySubobjectHandler {
4438 typedef bool result_type;
4441 bool checkConst(QualType QT) {
4444 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4450 bool failed() {
return false; }
4451 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4452 if (!checkConst(SubobjType))
4455 Subobj.
swap(NewVal);
4459 if (!checkConst(SubobjType))
4461 if (!NewVal.
isInt()) {
4469 bool found(APFloat &
Value, QualType SubobjType) {
4470 if (!checkConst(SubobjType))
4478const AccessKinds ModifySubobjectHandler::AccessKind;
4482 const CompleteObject &Obj,
4483 const SubobjectDesignator &Sub,
4485 ModifySubobjectHandler Handler = { Info, NewVal, E };
4492 const SubobjectDesignator &A,
4493 const SubobjectDesignator &B,
4494 bool &WasArrayIndex) {
4495 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4496 for (; I != N; ++I) {
4500 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4501 WasArrayIndex =
true;
4509 if (A.Entries[I].getAsBaseOrMember() !=
4510 B.Entries[I].getAsBaseOrMember()) {
4511 WasArrayIndex =
false;
4514 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4516 ObjType = FD->getType();
4522 WasArrayIndex =
false;
4529 const SubobjectDesignator &A,
4530 const SubobjectDesignator &B) {
4531 if (A.Entries.size() != B.Entries.size())
4534 bool IsArray = A.MostDerivedIsArrayElement;
4535 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4544 return CommonLength >= A.Entries.size() - IsArray;
4551 if (LVal.InvalidBase) {
4553 return CompleteObject();
4558 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4560 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4561 return CompleteObject();
4564 CallStackFrame *Frame =
nullptr;
4566 if (LVal.getLValueCallIndex()) {
4567 std::tie(Frame, Depth) =
4568 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4570 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4573 return CompleteObject();
4584 if (Info.getLangOpts().CPlusPlus)
4585 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4589 return CompleteObject();
4596 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4600 BaseVal = Info.EvaluatingDeclValue;
4603 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4606 Info.FFDiag(E, diag::note_constexpr_modify_global);
4607 return CompleteObject();
4611 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4613 return CompleteObject();
4615 return CompleteObject(LVal.Base, &
V, GD->getType());
4619 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4621 Info.FFDiag(E, diag::note_constexpr_modify_global);
4622 return CompleteObject();
4624 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4629 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4631 Info.FFDiag(E, diag::note_constexpr_modify_global);
4632 return CompleteObject();
4634 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4645 const VarDecl *VD = dyn_cast<VarDecl>(D);
4652 return CompleteObject();
4655 bool IsConstant = BaseType.isConstant(Info.Ctx);
4656 bool ConstexprVar =
false;
4657 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4669 }
else if (Info.getLangOpts().CPlusPlus14 &&
4676 Info.FFDiag(E, diag::note_constexpr_modify_global);
4677 return CompleteObject();
4680 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4682 return CompleteObject();
4683 }
else if (BaseType->isIntegralOrEnumerationType()) {
4686 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4687 if (Info.getLangOpts().CPlusPlus) {
4688 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4689 Info.Note(VD->
getLocation(), diag::note_declared_at);
4693 return CompleteObject();
4695 }
else if (!IsAccess) {
4696 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4697 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4698 Info.checkingPotentialConstantExpression() &&
4699 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4701 }
else if (IsConstant) {
4705 if (Info.getLangOpts().CPlusPlus) {
4706 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4707 ? diag::note_constexpr_ltor_non_constexpr
4708 : diag::note_constexpr_ltor_non_integral, 1)
4710 Info.Note(VD->
getLocation(), diag::note_declared_at);
4716 if (Info.getLangOpts().CPlusPlus) {
4717 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4718 ? diag::note_constexpr_ltor_non_constexpr
4719 : diag::note_constexpr_ltor_non_integral, 1)
4721 Info.Note(VD->
getLocation(), diag::note_declared_at);
4725 return CompleteObject();
4734 return CompleteObject();
4739 if (!Info.checkingPotentialConstantExpression()) {
4740 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4742 Info.Note(VD->getLocation(), diag::note_declared_at);
4744 return CompleteObject();
4747 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4749 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4750 return CompleteObject();
4752 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4762 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4763 assert(MTE->getStorageDuration() ==
SD_Static &&
4764 "should have a frame for a non-global materialized temporary");
4791 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4794 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4795 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4796 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4797 return CompleteObject();
4800 BaseVal = MTE->getOrCreateValue(
false);
4801 assert(BaseVal &&
"got reference to unevaluated temporary");
4803 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4819 !CLETy.isConstant(Info.Ctx)) {
4821 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4822 return CompleteObject();
4825 BaseVal = &CLE->getStaticValue();
4828 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4831 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4834 Info.Ctx.getLValueReferenceType(LValType));
4836 return CompleteObject();
4840 assert(BaseVal &&
"missing value for temporary");
4851 unsigned VisibleDepth = Depth;
4852 if (llvm::isa_and_nonnull<ParmVarDecl>(
4855 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4856 Info.EvalStatus.HasSideEffects) ||
4857 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4858 return CompleteObject();
4860 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4879 const LValue &LVal,
APValue &RVal,
4880 bool WantObjectRepresentation =
false) {
4881 if (LVal.Designator.Invalid)
4890 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4894 assert(LVal.Designator.Entries.size() <= 1 &&
4895 "Can only read characters from string literals");
4896 if (LVal.Designator.Entries.empty()) {
4903 if (LVal.Designator.isOnePastTheEnd()) {
4904 if (Info.getLangOpts().CPlusPlus11)
4905 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4910 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4917 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4931 LVal.setFrom(Info.Ctx, Val);
4947 if (LVal.Designator.Invalid)
4950 if (!Info.getLangOpts().CPlusPlus14) {
4960struct CompoundAssignSubobjectHandler {
4962 const CompoundAssignOperator *E;
4963 QualType PromotedLHSType;
4969 typedef bool result_type;
4971 bool checkConst(QualType QT) {
4974 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4980 bool failed() {
return false; }
4981 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4984 return found(Subobj.
getInt(), SubobjType);
4986 return found(Subobj.
getFloat(), SubobjType);
4993 return foundPointer(Subobj, SubobjType);
4995 return foundVector(Subobj, SubobjType);
4997 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5009 bool foundVector(
APValue &
Value, QualType SubobjType) {
5010 if (!checkConst(SubobjType))
5021 if (!checkConst(SubobjType))
5040 Info.Ctx.getLangOpts());
5043 PromotedLHSType, FValue) &&
5052 bool found(APFloat &
Value, QualType SubobjType) {
5053 return checkConst(SubobjType) &&
5059 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5060 if (!checkConst(SubobjType))
5063 QualType PointeeType;
5064 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5068 (Opcode != BO_Add && Opcode != BO_Sub)) {
5074 if (Opcode == BO_Sub)
5078 LVal.setFrom(Info.Ctx, Subobj);
5081 LVal.moveInto(Subobj);
5087const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5092 const LValue &LVal,
QualType LValType,
5096 if (LVal.Designator.Invalid)
5099 if (!Info.getLangOpts().CPlusPlus14) {
5105 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5107 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5111struct IncDecSubobjectHandler {
5113 const UnaryOperator *E;
5117 typedef bool result_type;
5119 bool checkConst(QualType QT) {
5122 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5128 bool failed() {
return false; }
5129 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5139 return found(Subobj.
getInt(), SubobjType);
5141 return found(Subobj.
getFloat(), SubobjType);
5144 SubobjType->
castAs<ComplexType>()->getElementType()
5148 SubobjType->
castAs<ComplexType>()->getElementType()
5151 return foundPointer(Subobj, SubobjType);
5159 if (!checkConst(SubobjType))
5181 bool WasNegative =
Value.isNegative();
5195 unsigned BitWidth =
Value.getBitWidth();
5196 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5197 ActualValue.setBit(BitWidth);
5203 bool found(APFloat &
Value, QualType SubobjType) {
5204 if (!checkConst(SubobjType))
5211 APFloat::opStatus St;
5213 St =
Value.add(One, RM);
5215 St =
Value.subtract(One, RM);
5218 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5219 if (!checkConst(SubobjType))
5222 QualType PointeeType;
5223 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5231 LVal.setFrom(Info.Ctx, Subobj);
5235 LVal.moveInto(Subobj);
5244 if (LVal.Designator.Invalid)
5247 if (!Info.getLangOpts().CPlusPlus14) {
5255 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5261 if (
Object->getType()->isPointerType() &&
Object->isPRValue())
5267 if (
Object->getType()->isLiteralType(Info.Ctx))
5270 if (
Object->getType()->isRecordType() &&
Object->isPRValue())
5273 Info.FFDiag(
Object, diag::note_constexpr_nonliteral) <<
Object->getType();
5292 bool IncludeMember =
true) {
5299 if (!MemPtr.getDecl()) {
5305 if (MemPtr.isDerivedMember()) {
5312 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5313 LV.Designator.Entries.size()) {
5317 unsigned PathLengthToMember =
5318 LV.Designator.Entries.size() - MemPtr.Path.size();
5319 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5321 LV.Designator.Entries[PathLengthToMember + I]);
5338 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5339 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5341 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5349 PathLengthToMember))
5351 }
else if (!MemPtr.Path.empty()) {
5353 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5354 MemPtr.Path.size() + IncludeMember);
5360 assert(RD &&
"member pointer access on non-class-type expression");
5362 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5370 MemPtr.getContainingRecord()))
5375 if (IncludeMember) {
5376 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5380 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5384 llvm_unreachable(
"can't construct reference to bound member function");
5388 return MemPtr.getDecl();
5394 bool IncludeMember =
true) {
5398 if (Info.noteFailure()) {
5406 BO->
getRHS(), IncludeMember);
5413 SubobjectDesignator &D =
Result.Designator;
5421 auto InvalidCast = [&]() {
5422 if (!Info.checkingPotentialConstantExpression() ||
5423 !
Result.AllowConstexprUnknown) {
5424 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5425 << D.MostDerivedType << TargetQT;
5431 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5432 return InvalidCast();
5436 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5439 if (NewEntriesSize == D.MostDerivedPathLength)
5442 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5444 return InvalidCast();
5459 if (
auto *RD = T->getAsCXXRecordDecl()) {
5460 if (RD->isInvalidDecl()) {
5464 if (RD->isUnion()) {
5473 End = RD->bases_end();
5474 I != End; ++I, ++Index)
5478 for (
const auto *I : RD->fields()) {
5479 if (I->isUnnamedBitField())
5482 I->getType(),
Result.getStructField(I->getFieldIndex()));
5488 dyn_cast_or_null<ConstantArrayType>(T->getAsArrayTypeUnsafe())) {
5490 if (
Result.hasArrayFiller())
5502enum EvalStmtResult {
5531 if (!
Result.Designator.Invalid &&
Result.Designator.isOnePastTheEnd()) {
5549 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5550 ScopeKind::Block,
Result);
5555 return Info.noteSideEffect();
5576 const DecompositionDecl *DD);
5579 bool EvaluateConditionDecl =
false) {
5581 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5585 EvaluateConditionDecl && DD)
5595 if (
auto *VD = BD->getHoldingVar())
5603 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5612 if (Info.noteSideEffect())
5614 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5615 "reach invalid code path.");
5622 if (
Cond->isValueDependent())
5624 FullExpressionRAII
Scope(Info);
5631 return Scope.destroy();
5644struct TempVersionRAII {
5645 CallStackFrame &Frame;
5647 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5648 Frame.pushTempVersion();
5651 ~TempVersionRAII() {
5652 Frame.popTempVersion();
5660 const SwitchCase *SC =
nullptr);
5666 const Stmt *LoopOrSwitch,
5668 EvalStmtResult &ESR) {
5672 if (!IsSwitch && ESR == ESR_Succeeded) {
5677 if (ESR != ESR_Break && ESR != ESR_Continue)
5681 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5682 const Stmt *StackTop = Info.BreakContinueStack.back();
5683 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5684 Info.BreakContinueStack.pop_back();
5685 if (ESR == ESR_Break)
5686 ESR = ESR_Succeeded;
5691 for (BlockScopeRAII *S : Scopes) {
5692 if (!S->destroy()) {
5704 BlockScopeRAII
Scope(Info);
5707 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5716 BlockScopeRAII
Scope(Info);
5723 if (ESR != ESR_Succeeded) {
5724 if (ESR != ESR_Failed && !
Scope.destroy())
5730 FullExpressionRAII CondScope(Info);
5745 if (!CondScope.destroy())
5766 if (LHSValue <=
Value &&
Value <= RHSValue) {
5773 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5777 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5784 llvm_unreachable(
"Should have been converted to Succeeded");
5790 case ESR_CaseNotFound:
5793 Info.FFDiag(
Found->getBeginLoc(),
5794 diag::note_constexpr_stmt_expr_unsupported);
5797 llvm_unreachable(
"Invalid EvalStmtResult!");
5807 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5817 if (!Info.nextStep(S))
5824 case Stmt::CompoundStmtClass:
5828 case Stmt::LabelStmtClass:
5829 case Stmt::AttributedStmtClass:
5830 case Stmt::DoStmtClass:
5833 case Stmt::CaseStmtClass:
5834 case Stmt::DefaultStmtClass:
5839 case Stmt::IfStmtClass: {
5846 BlockScopeRAII
Scope(Info);
5852 if (ESR != ESR_CaseNotFound) {
5853 assert(ESR != ESR_Succeeded);
5864 if (ESR == ESR_Failed)
5866 if (ESR != ESR_CaseNotFound)
5867 return Scope.destroy() ? ESR : ESR_Failed;
5869 return ESR_CaseNotFound;
5872 if (ESR == ESR_Failed)
5874 if (ESR != ESR_CaseNotFound)
5875 return Scope.destroy() ? ESR : ESR_Failed;
5876 return ESR_CaseNotFound;
5879 case Stmt::WhileStmtClass: {
5880 EvalStmtResult ESR =
5884 if (ESR != ESR_Continue)
5889 case Stmt::ForStmtClass: {
5891 BlockScopeRAII
Scope(Info);
5897 if (ESR != ESR_CaseNotFound) {
5898 assert(ESR != ESR_Succeeded);
5903 EvalStmtResult ESR =
5907 if (ESR != ESR_Continue)
5909 if (
const auto *Inc = FS->
getInc()) {
5910 if (Inc->isValueDependent()) {
5914 FullExpressionRAII IncScope(Info);
5922 case Stmt::DeclStmtClass: {
5926 for (
const auto *D : DS->
decls()) {
5927 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5930 if (VD->hasLocalStorage() && !VD->getInit())
5938 return ESR_CaseNotFound;
5942 return ESR_CaseNotFound;
5948 if (
const Expr *E = dyn_cast<Expr>(S)) {
5957 FullExpressionRAII
Scope(Info);
5961 return ESR_Succeeded;
5967 case Stmt::NullStmtClass:
5968 return ESR_Succeeded;
5970 case Stmt::DeclStmtClass: {
5972 for (
const auto *D : DS->
decls()) {
5973 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
5977 FullExpressionRAII
Scope(Info);
5979 !Info.noteFailure())
5981 if (!
Scope.destroy())
5984 return ESR_Succeeded;
5987 case Stmt::ReturnStmtClass: {
5989 FullExpressionRAII
Scope(Info);
6000 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6003 case Stmt::CompoundStmtClass: {
6004 BlockScopeRAII
Scope(Info);
6007 for (
const auto *BI : CS->
body()) {
6009 if (ESR == ESR_Succeeded)
6011 else if (ESR != ESR_CaseNotFound) {
6012 if (ESR != ESR_Failed && !
Scope.destroy())
6018 return ESR_CaseNotFound;
6019 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6022 case Stmt::IfStmtClass: {
6026 BlockScopeRAII
Scope(Info);
6029 if (ESR != ESR_Succeeded) {
6030 if (ESR != ESR_Failed && !
Scope.destroy())
6040 if (!Info.InConstantContext)
6048 if (ESR != ESR_Succeeded) {
6049 if (ESR != ESR_Failed && !
Scope.destroy())
6054 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6057 case Stmt::WhileStmtClass: {
6060 BlockScopeRAII
Scope(Info);
6072 if (ESR != ESR_Continue) {
6073 if (ESR != ESR_Failed && !
Scope.destroy())
6077 if (!
Scope.destroy())
6080 return ESR_Succeeded;
6083 case Stmt::DoStmtClass: {
6090 if (ESR != ESR_Continue)
6099 FullExpressionRAII CondScope(Info);
6101 !CondScope.destroy())
6104 return ESR_Succeeded;
6107 case Stmt::ForStmtClass: {
6109 BlockScopeRAII ForScope(Info);
6112 if (ESR != ESR_Succeeded) {
6113 if (ESR != ESR_Failed && !ForScope.destroy())
6119 BlockScopeRAII IterScope(Info);
6120 bool Continue =
true;
6126 if (!IterScope.destroy())
6134 if (ESR != ESR_Continue) {
6135 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6140 if (
const auto *Inc = FS->
getInc()) {
6141 if (Inc->isValueDependent()) {
6145 FullExpressionRAII IncScope(Info);
6151 if (!IterScope.destroy())
6154 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6157 case Stmt::CXXForRangeStmtClass: {
6159 BlockScopeRAII
Scope(Info);
6164 if (ESR != ESR_Succeeded) {
6165 if (ESR != ESR_Failed && !
Scope.destroy())
6173 if (ESR != ESR_Succeeded) {
6174 if (ESR != ESR_Failed && !
Scope.destroy())
6186 if (ESR != ESR_Succeeded) {
6187 if (ESR != ESR_Failed && !
Scope.destroy())
6192 if (ESR != ESR_Succeeded) {
6193 if (ESR != ESR_Failed && !
Scope.destroy())
6206 bool Continue =
true;
6207 FullExpressionRAII CondExpr(Info);
6215 BlockScopeRAII InnerScope(Info);
6217 if (ESR != ESR_Succeeded) {
6218 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6227 if (ESR != ESR_Continue) {
6228 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6241 if (!InnerScope.destroy())
6245 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6248 case Stmt::SwitchStmtClass:
6251 case Stmt::ContinueStmtClass:
6252 case Stmt::BreakStmtClass: {
6254 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6258 case Stmt::LabelStmtClass:
6261 case Stmt::AttributedStmtClass: {
6263 const auto *SS = AS->getSubStmt();
6264 MSConstexprContextRAII ConstexprContext(
6268 auto LO = Info.Ctx.getLangOpts();
6269 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6270 for (
auto *
Attr : AS->getAttrs()) {
6271 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6275 auto *Assumption = AA->getAssumption();
6276 if (Assumption->isValueDependent())
6279 if (Assumption->HasSideEffects(Info.Ctx))
6286 Info.CCEDiag(Assumption->getExprLoc(),
6287 diag::note_constexpr_assumption_failed);
6296 case Stmt::CaseStmtClass:
6297 case Stmt::DefaultStmtClass:
6299 case Stmt::CXXTryStmtClass:
6311 bool IsValueInitialization) {
6318 if (!CD->
isConstexpr() && !IsValueInitialization) {
6319 if (Info.getLangOpts().CPlusPlus11) {
6322 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6324 Info.Note(CD->
getLocation(), diag::note_declared_at);
6326 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6340 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6348 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6357 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6360 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6366 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6376 StringRef Name = DiagDecl->
getName();
6378 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6380 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6385 if (Info.getLangOpts().CPlusPlus11) {
6388 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6389 if (CD && CD->isInheritingConstructor()) {
6390 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6391 if (!Inherited->isConstexpr())
6392 DiagDecl = CD = Inherited;
6398 if (CD && CD->isInheritingConstructor())
6399 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6400 << CD->getInheritedConstructor().getConstructor()->getParent();
6402 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6404 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6406 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6412struct CheckDynamicTypeHandler {
6414 typedef bool result_type;
6415 bool failed() {
return false; }
6416 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6419 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6420 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6428 if (
This.Designator.Invalid)
6440 if (
This.Designator.isOnePastTheEnd() ||
6441 This.Designator.isMostDerivedAnUnsizedArray()) {
6442 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6443 ? diag::note_constexpr_access_past_end
6444 : diag::note_constexpr_access_unsized_array)
6447 }
else if (Polymorphic) {
6450 if (!Info.checkingPotentialConstantExpression() ||
6451 !
This.AllowConstexprUnknown) {
6455 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6456 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6464 CheckDynamicTypeHandler Handler{AK};
6487 unsigned PathLength) {
6488 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6489 Designator.Entries.size() &&
"invalid path length");
6490 return (PathLength ==
Designator.MostDerivedPathLength)
6491 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6492 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6505 return std::nullopt;
6507 if (
This.Designator.Invalid)
6508 return std::nullopt;
6517 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6518 if (!Class || Class->getNumVBases()) {
6520 return std::nullopt;
6528 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6529 PathLength <= Path.size(); ++PathLength) {
6530 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6531 Path.slice(0, PathLength))) {
6532 case ConstructionPhase::Bases:
6533 case ConstructionPhase::DestroyingBases:
6538 case ConstructionPhase::None:
6539 case ConstructionPhase::AfterBases:
6540 case ConstructionPhase::AfterFields:
6541 case ConstructionPhase::Destroying:
6553 return std::nullopt;
6571 unsigned PathLength = DynType->PathLength;
6572 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6575 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6585 if (Callee->isPureVirtual()) {
6586 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6587 Info.Note(Callee->getLocation(), diag::note_declared_at);
6593 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6594 Found->getReturnType())) {
6595 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6596 for (
unsigned CovariantPathLength = PathLength + 1;
6597 CovariantPathLength !=
This.Designator.Entries.size();
6598 ++CovariantPathLength) {
6602 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6603 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6604 Next->getReturnType(), CovariantAdjustmentPath.back()))
6605 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6607 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6608 CovariantAdjustmentPath.back()))
6609 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6625 assert(
Result.isLValue() &&
6626 "unexpected kind of APValue for covariant return");
6627 if (
Result.isNullPointer())
6631 LVal.setFrom(Info.Ctx,
Result);
6633 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6634 for (
unsigned I = 1; I != Path.size(); ++I) {
6635 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6636 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6637 if (OldClass != NewClass &&
6640 OldClass = NewClass;
6652 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6654 return BaseSpec.getAccessSpecifier() ==
AS_public;
6656 llvm_unreachable(
"Base is not a direct base of Derived");
6666 SubobjectDesignator &D = Ptr.Designator;
6672 if (Ptr.isNullPointer() && !E->
isGLValue())
6678 std::optional<DynamicType> DynType =
6690 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6698 Ptr.setNull(Info.Ctx, E->
getType());
6705 DynType->Type->isDerivedFrom(
C)))
6707 else if (!Paths || Paths->begin() == Paths->end())
6709 else if (Paths->isAmbiguous(CQT))
6712 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6715 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6716 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6717 << Info.Ctx.getCanonicalTagType(DynType->Type)
6725 for (
int PathLength = Ptr.Designator.Entries.size();
6726 PathLength >= (
int)DynType->PathLength; --PathLength) {
6731 if (PathLength > (
int)DynType->PathLength &&
6734 return RuntimeCheckFailed(
nullptr);
6741 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6754 return RuntimeCheckFailed(&Paths);
6758struct StartLifetimeOfUnionMemberHandler {
6760 const Expr *LHSExpr;
6761 const FieldDecl *
Field;
6763 bool Failed =
false;
6766 typedef bool result_type;
6767 bool failed() {
return Failed; }
6768 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6783 }
else if (DuringInit) {
6787 Info.FFDiag(LHSExpr,
6788 diag::note_constexpr_union_member_change_during_init);
6797 llvm_unreachable(
"wrong value kind for union object");
6799 bool found(APFloat &
Value, QualType SubobjType) {
6800 llvm_unreachable(
"wrong value kind for union object");
6805const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6812 const Expr *LHSExpr,
6813 const LValue &LHS) {
6814 if (LHS.InvalidBase || LHS.Designator.Invalid)
6820 unsigned PathLength = LHS.Designator.Entries.size();
6821 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6823 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6824 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6827 if (!FD || FD->getType()->isReferenceType())
6831 if (FD->getParent()->isUnion()) {
6836 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6837 if (!RD || RD->hasTrivialDefaultConstructor())
6838 UnionPathLengths.push_back({PathLength - 1, FD});
6844 LHS.Designator.Entries[PathLength]
6845 .getAsBaseOrMember().getPointer()));
6849 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6851 auto *
Base = ASE->getBase()->IgnoreImplicit();
6852 if (!
Base->getType()->isArrayType())
6858 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6861 if (ICE->getCastKind() == CK_NoOp)
6863 if (ICE->getCastKind() != CK_DerivedToBase &&
6864 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6868 if (Elt->isVirtual()) {
6877 LHS.Designator.Entries[PathLength]
6878 .getAsBaseOrMember().getPointer()));
6888 if (UnionPathLengths.empty())
6893 CompleteObject Obj =
6897 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6898 llvm::reverse(UnionPathLengths)) {
6900 SubobjectDesignator D = LHS.Designator;
6901 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6903 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6904 ConstructionPhase::AfterBases;
6905 StartLifetimeOfUnionMemberHandler StartLifetime{
6906 Info, LHSExpr, LengthAndField.second, DuringInit};
6915 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6916 APValue **EvaluatedArg =
nullptr) {
6923 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6924 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6925 ScopeKind::Call, LV);
6931 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6932 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6945 bool RightToLeft =
false,
6946 LValue *ObjectArg =
nullptr) {
6948 llvm::SmallBitVector ForbiddenNullArgs;
6949 if (Callee->hasAttr<NonNullAttr>()) {
6950 ForbiddenNullArgs.resize(Args.size());
6951 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6952 if (!
Attr->args_size()) {
6953 ForbiddenNullArgs.set();
6956 for (
auto Idx :
Attr->args()) {
6957 unsigned ASTIdx = Idx.getASTIndex();
6958 if (ASTIdx >= Args.size())
6960 ForbiddenNullArgs[ASTIdx] =
true;
6964 for (
unsigned I = 0; I < Args.size(); I++) {
6965 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6967 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6968 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6973 if (!Info.noteFailure())
6978 ObjectArg->setFrom(Info.Ctx, *That);
6987 bool CopyObjectRepresentation) {
6989 CallStackFrame *Frame = Info.CurrentCall;
6990 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6998 RefLValue.setFrom(Info.Ctx, *RefValue);
7001 CopyObjectRepresentation);
7007 const LValue *ObjectArg,
const Expr *E,
7009 const Stmt *Body, EvalInfo &Info,
7011 if (!Info.CheckCallLimit(CallLoc))
7040 ObjectArg->moveInto(
Result);
7049 if (!Info.checkingPotentialConstantExpression())
7051 Frame.LambdaThisCaptureField);
7054 StmtResult Ret = {
Result, ResultSlot};
7056 if (ESR == ESR_Succeeded) {
7057 if (Callee->getReturnType()->isVoidType())
7059 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7061 return ESR == ESR_Returned;
7070 if (!Info.CheckCallLimit(CallLoc))
7075 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7079 EvalInfo::EvaluatingConstructorRAII EvalObj(
7081 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7088 StmtResult Ret = {RetVal,
nullptr};
7093 if ((*I)->getInit()->isValueDependent()) {
7097 FullExpressionRAII InitScope(Info);
7099 !InitScope.destroy())
7122 if (!
Result.hasValue()) {
7135 BlockScopeRAII LifetimeExtendedScope(Info);
7138 unsigned BasesSeen = 0;
7143 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7148 assert(Indirect &&
"fields out of order?");
7154 assert(FieldIt != RD->
field_end() &&
"missing field?");
7155 if (!FieldIt->isUnnamedBitField())
7158 Result.getStructField(FieldIt->getFieldIndex()));
7163 LValue Subobject =
This;
7164 LValue SubobjectParent =
This;
7169 if (I->isBaseInitializer()) {
7170 QualType BaseType(I->getBaseClass(), 0);
7174 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
7175 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
7176 "base class initializers not in expected order");
7180 BaseType->getAsCXXRecordDecl(), &Layout))
7183 }
else if ((FD = I->getMember())) {
7190 SkipToField(FD,
false);
7196 auto IndirectFieldChain = IFD->chain();
7197 for (
auto *
C : IndirectFieldChain) {
7206 (
Value->isUnion() &&
7219 if (
C == IndirectFieldChain.back())
7220 SubobjectParent = Subobject;
7226 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7227 SkipToField(FD,
true);
7232 llvm_unreachable(
"unknown base initializer kind");
7239 if (
Init->isValueDependent()) {
7243 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7245 FullExpressionRAII InitScope(Info);
7251 if (!Info.noteFailure())
7260 if (!Info.noteFailure())
7268 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
7269 EvalObj.finishedConstructingBases();
7274 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7275 if (!FieldIt->isUnnamedBitField())
7278 Result.getStructField(FieldIt->getFieldIndex()));
7282 EvalObj.finishedConstructingFields();
7286 LifetimeExtendedScope.destroy();
7293 CallScopeRAII CallScope(Info);
7299 CallScope.destroy();
7309 if (
Value.isAbsent() && !T->isNullPtrType()) {
7311 This.moveInto(Printable);
7313 diag::note_constexpr_destroy_out_of_lifetime)
7314 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(T));
7330 LValue ElemLV =
This;
7331 ElemLV.addArray(Info, &LocE, CAT);
7338 if (Size && Size >
Value.getArrayInitializedElts())
7343 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7344 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7357 if (T.isDestructedType()) {
7359 diag::note_constexpr_unsupported_destruction)
7369 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7394 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7403 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7408 EvalInfo::EvaluatingDestructorRAII EvalObj(
7410 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7411 if (!EvalObj.DidInsert) {
7418 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7425 StmtResult Ret = {RetVal,
nullptr};
7438 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7439 if (FD->isUnnamedBitField())
7442 LValue Subobject =
This;
7446 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7453 EvalObj.startedDestroyingBases();
7460 LValue Subobject =
This;
7462 BaseType->getAsCXXRecordDecl(), &Layout))
7465 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7470 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7478struct DestroyObjectHandler {
7484 typedef bool result_type;
7485 bool failed() {
return false; }
7486 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
7491 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7494 bool found(APFloat &
Value, QualType SubobjType) {
7495 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7516 if (Info.EvalStatus.HasSideEffects)
7527 if (Info.checkingPotentialConstantExpression() ||
7528 Info.SpeculativeEvaluationDepth)
7532 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7534 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7535 ? diag::note_constexpr_new_untyped
7536 : diag::note_constexpr_new);
7540 QualType ElemType = Caller.ElemType;
7543 diag::note_constexpr_new_not_complete_object_type)
7551 bool IsNothrow =
false;
7552 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7560 APInt Size, Remainder;
7561 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7562 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7563 if (Remainder != 0) {
7565 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7566 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7570 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7571 Size.getZExtValue(), !IsNothrow)) {
7579 QualType AllocType = Info.Ctx.getConstantArrayType(
7581 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType,
Result);
7590 return DD->isVirtual();
7597 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7608 DynAlloc::Kind DeallocKind) {
7609 auto PointerAsString = [&] {
7610 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7615 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7616 << PointerAsString();
7619 return std::nullopt;
7622 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7624 Info.FFDiag(E, diag::note_constexpr_double_delete);
7625 return std::nullopt;
7628 if (DeallocKind != (*Alloc)->getKind()) {
7630 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7631 << DeallocKind << (*Alloc)->getKind() << AllocType;
7633 return std::nullopt;
7636 bool Subobject =
false;
7637 if (DeallocKind == DynAlloc::New) {
7638 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7639 Pointer.Designator.isOnePastTheEnd();
7641 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7642 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7645 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7646 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7647 return std::nullopt;
7655 if (Info.checkingPotentialConstantExpression() ||
7656 Info.SpeculativeEvaluationDepth)
7660 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7668 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7671 if (
Pointer.Designator.Invalid)
7676 if (
Pointer.isNullPointer()) {
7677 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7693class BitCastBuffer {
7699 SmallVector<std::optional<unsigned char>, 32> Bytes;
7701 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7702 "Need at least 8 bit unsigned char");
7704 bool TargetIsLittleEndian;
7707 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7708 : Bytes(Width.getQuantity()),
7709 TargetIsLittleEndian(TargetIsLittleEndian) {}
7711 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7712 SmallVectorImpl<unsigned char> &Output)
const {
7713 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7716 if (!Bytes[I.getQuantity()])
7718 Output.push_back(*Bytes[I.getQuantity()]);
7720 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7721 std::reverse(Output.begin(), Output.end());
7725 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7726 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7727 std::reverse(Input.begin(), Input.end());
7730 for (
unsigned char Byte : Input) {
7731 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7737 size_t size() {
return Bytes.size(); }
7742class APValueToBufferConverter {
7744 BitCastBuffer Buffer;
7747 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7750 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7753 bool visit(
const APValue &Val, QualType Ty) {
7758 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7759 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7772 return visitInt(Val.
getInt(), Ty, Offset);
7774 return visitFloat(Val.
getFloat(), Ty, Offset);
7776 return visitArray(Val, Ty, Offset);
7778 return visitRecord(Val, Ty, Offset);
7780 return visitVector(Val, Ty, Offset);
7784 return visitComplex(Val, Ty, Offset);
7794 diag::note_constexpr_bit_cast_unsupported_type)
7799 llvm_unreachable(
"Unhandled APValue::ValueKind");
7802 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7804 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
7807 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7808 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7809 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7814 if (!
Base.isStruct())
7817 if (!visitRecord(Base, BS.
getType(),
7824 unsigned FieldIdx = 0;
7825 for (FieldDecl *FD : RD->
fields()) {
7826 if (FD->isBitField()) {
7828 diag::note_constexpr_bit_cast_unsupported_bitfield);
7834 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7835 "only bit-fields can have sub-char alignment");
7836 CharUnits FieldOffset =
7837 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7838 QualType FieldTy = FD->getType();
7847 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7853 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
7857 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7859 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7866 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7867 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7875 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7876 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7878 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7883 Offset + (0 * EltSizeChars)))
7886 Offset + (1 * EltSizeChars)))
7890 Offset + (0 * EltSizeChars)))
7893 Offset + (1 * EltSizeChars)))
7900 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7901 const VectorType *VTy = Ty->
castAs<VectorType>();
7914 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7916 llvm::APInt Res = llvm::APInt::getZero(NElts);
7917 for (
unsigned I = 0; I < NElts; ++I) {
7919 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7920 "bool vector element must be 1-bit unsigned integer!");
7922 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7925 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7926 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7927 Buffer.writeObject(Offset, Bytes);
7931 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7932 for (
unsigned I = 0; I < NElts; ++I) {
7933 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7941 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
7942 APSInt AdjustedVal = Val;
7943 unsigned Width = AdjustedVal.getBitWidth();
7945 Width = Info.Ctx.getTypeSize(Ty);
7946 AdjustedVal = AdjustedVal.extend(Width);
7949 SmallVector<uint8_t, 8> Bytes(Width / 8);
7950 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7951 Buffer.writeObject(Offset, Bytes);
7955 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
7956 APSInt AsInt(Val.bitcastToAPInt());
7957 return visitInt(AsInt, Ty, Offset);
7961 static std::optional<BitCastBuffer>
7963 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
7964 APValueToBufferConverter Converter(Info, DstSize, BCE);
7966 return std::nullopt;
7967 return Converter.Buffer;
7972class BufferToAPValueConverter {
7974 const BitCastBuffer &Buffer;
7977 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7979 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7984 std::nullopt_t unsupportedType(QualType Ty) {
7986 diag::note_constexpr_bit_cast_unsupported_type)
7988 return std::nullopt;
7991 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
7993 diag::note_constexpr_bit_cast_unrepresentable_value)
7995 return std::nullopt;
7998 std::optional<APValue> visit(
const BuiltinType *T, CharUnits Offset,
7999 const EnumType *EnumSugar =
nullptr) {
8001 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(T, 0));
8002 return APValue((Expr *)
nullptr,
8004 APValue::NoLValuePath{},
true);
8007 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(T);
8013 const llvm::fltSemantics &Semantics =
8014 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8015 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8016 assert(NumBits % 8 == 0);
8022 SmallVector<uint8_t, 8> Bytes;
8023 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8026 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8030 if (!IsStdByte && !IsUChar) {
8031 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar : T, 0);
8033 diag::note_constexpr_bit_cast_indet_dest)
8034 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8035 return std::nullopt;
8041 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8042 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8047 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(T, 0));
8048 if (IntWidth != Val.getBitWidth()) {
8049 APSInt Truncated = Val.trunc(IntWidth);
8050 if (Truncated.extend(Val.getBitWidth()) != Val)
8051 return unrepresentableValue(QualType(T, 0), Val);
8059 const llvm::fltSemantics &Semantics =
8060 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8064 return unsupportedType(QualType(T, 0));
8067 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8068 const RecordDecl *RD = RTy->getAsRecordDecl();
8069 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8071 unsigned NumBases = 0;
8072 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8073 NumBases = CXXRD->getNumBases();
8078 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8079 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8080 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8083 std::optional<APValue> SubObj = visitType(
8086 return std::nullopt;
8087 ResultVal.getStructBase(I) = *SubObj;
8092 unsigned FieldIdx = 0;
8093 for (FieldDecl *FD : RD->
fields()) {
8096 if (FD->isBitField()) {
8098 diag::note_constexpr_bit_cast_unsupported_bitfield);
8099 return std::nullopt;
8103 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8105 CharUnits FieldOffset =
8108 QualType FieldTy = FD->getType();
8109 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8111 return std::nullopt;
8112 ResultVal.getStructField(FieldIdx) = *SubObj;
8119 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8120 QualType RepresentationType =
8121 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8122 assert(!RepresentationType.
isNull() &&
8123 "enum forward decl should be caught by Sema");
8124 const auto *AsBuiltin =
8128 return visit(AsBuiltin, Offset, Ty);
8131 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8133 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8135 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8136 for (
size_t I = 0; I !=
Size; ++I) {
8137 std::optional<APValue> ElementValue =
8140 return std::nullopt;
8141 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8147 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8149 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8152 std::optional<APValue> Values[2];
8153 for (
unsigned I = 0; I != 2; ++I) {
8154 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8156 return std::nullopt;
8160 return APValue(Values[0]->getInt(), Values[1]->getInt());
8161 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8164 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8170 SmallVector<APValue, 4> Elts;
8171 Elts.reserve(NElts);
8181 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8183 SmallVector<uint8_t, 8> Bytes;
8184 Bytes.reserve(NElts / 8);
8186 return std::nullopt;
8188 APSInt SValInt(NElts,
true);
8189 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8191 for (
unsigned I = 0; I < NElts; ++I) {
8193 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8200 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8201 for (
unsigned I = 0; I < NElts; ++I) {
8202 std::optional<APValue> EltValue =
8203 visitType(EltTy, Offset + I * EltSizeChars);
8205 return std::nullopt;
8206 Elts.push_back(std::move(*EltValue));
8210 return APValue(Elts.data(), Elts.size());
8213 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8214 return unsupportedType(QualType(Ty, 0));
8217 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8221#define TYPE(Class, Base) \
8223 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8224#define ABSTRACT_TYPE(Class, Base)
8225#define NON_CANONICAL_TYPE(Class, Base) \
8227 llvm_unreachable("non-canonical type should be impossible!");
8228#define DEPENDENT_TYPE(Class, Base) \
8231 "dependent types aren't supported in the constant evaluator!");
8232#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8234 llvm_unreachable("either dependent or not canonical!");
8235#include "clang/AST/TypeNodes.inc"
8237 llvm_unreachable(
"Unhandled Type::TypeClass");
8242 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8244 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8249static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8250 QualType Ty, EvalInfo *Info,
8251 const ASTContext &Ctx,
8252 bool CheckingDest) {
8255 auto diag = [&](
int Reason) {
8257 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8258 << CheckingDest << (Reason == 4) << Reason;
8261 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8263 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8264 << NoteTy << Construct << Ty;
8278 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8279 for (CXXBaseSpecifier &BS : CXXRD->bases())
8280 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8284 for (FieldDecl *FD :
Record->fields()) {
8285 if (FD->getType()->isReferenceType())
8287 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8289 return note(0, FD->getType(), FD->getBeginLoc());
8295 Info, Ctx, CheckingDest))
8298 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8310 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8311 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8321 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8330static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8331 const ASTContext &Ctx,
8333 bool DestOK = checkBitCastConstexprEligibilityType(
8335 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8341static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8344 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8345 "no host or target supports non 8-bit chars");
8347 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8351 std::optional<BitCastBuffer> Buffer =
8352 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8357 std::optional<APValue> MaybeDestValue =
8358 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8359 if (!MaybeDestValue)
8362 DestValue = std::move(*MaybeDestValue);
8366static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8369 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8370 "no host or target supports non 8-bit chars");
8372 "LValueToRValueBitcast requires an lvalue operand!");
8374 LValue SourceLValue;
8376 SourceLValue.setFrom(Info.Ctx, SourceValue);
8379 SourceRValue,
true))
8382 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8385template <
class Derived>
8386class ExprEvaluatorBase
8387 :
public ConstStmtVisitor<Derived, bool> {
8389 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8390 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8391 return getDerived().Success(
V, E);
8393 bool DerivedZeroInitialization(
const Expr *E) {
8394 return getDerived().ZeroInitialization(E);
8400 template<
typename ConditionalOperator>
8401 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8402 assert(Info.checkingPotentialConstantExpression());
8405 SmallVector<PartialDiagnosticAt, 8>
Diag;
8407 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8414 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8421 Error(E, diag::note_constexpr_conditional_never_const);
8425 template<
typename ConditionalOperator>
8426 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8429 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8430 CheckPotentialConstantConditional(E);
8433 if (Info.noteFailure()) {
8441 return StmtVisitorTy::Visit(EvalExpr);
8446 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8447 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8449 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8450 return Info.CCEDiag(E, D);
8453 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8455 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8457 return BuiltinOp != 0 &&
8458 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8462 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8464 EvalInfo &getEvalInfo() {
return Info; }
8472 bool Error(
const Expr *E) {
8473 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8476 bool VisitStmt(
const Stmt *) {
8477 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8479 bool VisitExpr(
const Expr *E) {
8483 bool VisitEmbedExpr(
const EmbedExpr *E) {
8484 const auto It = E->
begin();
8485 return StmtVisitorTy::Visit(*It);
8488 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8491 bool VisitConstantExpr(
const ConstantExpr *E) {
8495 return StmtVisitorTy::Visit(E->
getSubExpr());
8498 bool VisitParenExpr(
const ParenExpr *E)
8499 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8500 bool VisitUnaryExtension(
const UnaryOperator *E)
8501 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8502 bool VisitUnaryPlus(
const UnaryOperator *E)
8503 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8504 bool VisitChooseExpr(
const ChooseExpr *E)
8506 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8508 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8510 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8511 TempVersionRAII RAII(*Info.CurrentCall);
8512 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8513 return StmtVisitorTy::Visit(E->
getExpr());
8515 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8516 TempVersionRAII RAII(*Info.CurrentCall);
8520 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8521 return StmtVisitorTy::Visit(E->
getExpr());
8524 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8525 FullExpressionRAII Scope(Info);
8526 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8531 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8532 return StmtVisitorTy::Visit(E->
getSubExpr());
8535 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8536 CCEDiag(E, diag::note_constexpr_invalid_cast)
8537 << diag::ConstexprInvalidCastKind::Reinterpret;
8538 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8540 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8541 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8542 CCEDiag(E, diag::note_constexpr_invalid_cast)
8543 << diag::ConstexprInvalidCastKind::Dynamic;
8544 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8546 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8547 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8550 bool VisitBinaryOperator(
const BinaryOperator *E) {
8556 VisitIgnoredValue(E->
getLHS());
8557 return StmtVisitorTy::Visit(E->
getRHS());
8567 return DerivedSuccess(
Result, E);
8572 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8576 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8580 if (!
Evaluate(Info.CurrentCall->createTemporary(
8583 ScopeKind::FullExpression, CommonLV),
8587 return HandleConditionalOperator(E);
8590 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8591 bool IsBcpCall =
false;
8596 if (
const CallExpr *CallCE =
8598 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8605 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8608 FoldConstant Fold(Info, IsBcpCall);
8609 if (!HandleConditionalOperator(E)) {
8610 Fold.keepDiagnostics();
8617 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8618 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8620 return DerivedSuccess(*
Value, E);
8626 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8629 return StmtVisitorTy::Visit(Source);
8632 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8633 for (
const Expr *SemE : E->
semantics()) {
8634 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8643 if (OVE->isUnique())
8647 if (!
Evaluate(Info.CurrentCall->createTemporary(
8648 OVE, getStorageType(Info.Ctx, OVE),
8649 ScopeKind::FullExpression, LV),
8650 Info, OVE->getSourceExpr()))
8653 if (!StmtVisitorTy::Visit(SemE))
8663 bool VisitCallExpr(
const CallExpr *E) {
8665 if (!handleCallExpr(E,
Result,
nullptr))
8667 return DerivedSuccess(
Result, E);
8671 const LValue *ResultSlot) {
8672 CallScopeRAII CallScope(Info);
8675 QualType CalleeType =
Callee->getType();
8677 const FunctionDecl *FD =
nullptr;
8678 LValue *
This =
nullptr, ObjectArg;
8680 bool HasQualifier =
false;
8686 const CXXMethodDecl *
Member =
nullptr;
8687 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8691 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8693 return Error(Callee);
8695 HasQualifier = ME->hasQualifier();
8696 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8698 const ValueDecl *D =
8702 Member = dyn_cast<CXXMethodDecl>(D);
8704 return Error(Callee);
8706 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8707 if (!Info.getLangOpts().CPlusPlus20)
8708 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8712 return Error(Callee);
8719 if (!CalleeLV.getLValueOffset().isZero())
8720 return Error(Callee);
8721 if (CalleeLV.isNullPointer()) {
8722 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8723 <<
const_cast<Expr *
>(
Callee);
8726 FD = dyn_cast_or_null<FunctionDecl>(
8727 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8729 return Error(Callee);
8732 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8739 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8740 if (OCE && OCE->isAssignmentOp()) {
8741 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8742 Call = Info.CurrentCall->createCall(FD);
8743 bool HasThis =
false;
8744 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8745 HasThis = MD->isImplicitObjectMemberFunction();
8753 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8773 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8774 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8778 Args = Args.slice(1);
8784 const CXXRecordDecl *ClosureClass = MD->
getParent();
8786 ClosureClass->
captures().empty() &&
8787 "Number of captures must be zero for conversion to function-ptr");
8789 const CXXMethodDecl *LambdaCallOp =
8798 "A generic lambda's static-invoker function must be a "
8799 "template specialization");
8801 FunctionTemplateDecl *CallOpTemplate =
8803 void *InsertPos =
nullptr;
8804 FunctionDecl *CorrespondingCallOpSpecialization =
8806 assert(CorrespondingCallOpSpecialization &&
8807 "We must always have a function call operator specialization "
8808 "that corresponds to our static invoker specialization");
8810 FD = CorrespondingCallOpSpecialization;
8819 return CallScope.destroy();
8829 Call = Info.CurrentCall->createCall(FD);
8835 SmallVector<QualType, 4> CovariantAdjustmentPath;
8837 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8838 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8841 CovariantAdjustmentPath);
8844 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8854 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8855 assert(This &&
"no 'this' pointer for destructor call");
8857 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
8858 CallScope.destroy();
8875 if (!CovariantAdjustmentPath.empty() &&
8877 CovariantAdjustmentPath))
8880 return CallScope.destroy();
8883 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8886 bool VisitInitListExpr(
const InitListExpr *E) {
8888 return DerivedZeroInitialization(E);
8890 return StmtVisitorTy::Visit(E->
getInit(0));
8893 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8894 return DerivedZeroInitialization(E);
8896 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8897 return DerivedZeroInitialization(E);
8899 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8900 return DerivedZeroInitialization(E);
8904 bool VisitMemberExpr(
const MemberExpr *E) {
8905 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8906 "missing temporary materialization conversion");
8907 assert(!E->
isArrow() &&
"missing call to bound member function?");
8915 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8916 if (!FD)
return Error(E);
8920 "record / field mismatch");
8925 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8926 SubobjectDesignator Designator(BaseTy);
8927 Designator.addDeclUnchecked(FD);
8931 DerivedSuccess(
Result, E);
8934 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
8940 SmallVector<uint32_t, 4> Indices;
8942 if (Indices.size() == 1) {
8944 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
8947 SmallVector<APValue, 4> Elts;
8948 for (
unsigned I = 0; I < Indices.size(); ++I) {
8951 APValue VecResult(Elts.data(), Indices.size());
8952 return DerivedSuccess(VecResult, E);
8959 bool VisitCastExpr(
const CastExpr *E) {
8964 case CK_AtomicToNonAtomic: {
8971 return DerivedSuccess(AtomicVal, E);
8975 case CK_UserDefinedConversion:
8976 return StmtVisitorTy::Visit(E->
getSubExpr());
8978 case CK_HLSLArrayRValue: {
8984 return DerivedSuccess(Val, E);
8995 return DerivedSuccess(RVal, E);
8997 case CK_LValueToRValue: {
9006 return DerivedSuccess(RVal, E);
9008 case CK_LValueToRValueBitCast: {
9009 APValue DestValue, SourceValue;
9012 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9014 return DerivedSuccess(DestValue, E);
9017 case CK_AddressSpaceConversion: {
9021 return DerivedSuccess(
Value, E);
9028 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9029 return VisitUnaryPostIncDec(UO);
9031 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9032 return VisitUnaryPostIncDec(UO);
9034 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9035 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9045 return DerivedSuccess(RVal, UO);
9048 bool VisitStmtExpr(
const StmtExpr *E) {
9051 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9058 BlockScopeRAII Scope(Info);
9063 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9065 Info.FFDiag((*BI)->getBeginLoc(),
9066 diag::note_constexpr_stmt_expr_unsupported);
9069 return this->Visit(FinalExpr) && Scope.destroy();
9075 if (ESR != ESR_Succeeded) {
9079 if (ESR != ESR_Failed)
9080 Info.FFDiag((*BI)->getBeginLoc(),
9081 diag::note_constexpr_stmt_expr_unsupported);
9086 llvm_unreachable(
"Return from function from the loop above.");
9089 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9094 void VisitIgnoredValue(
const Expr *E) {
9099 void VisitIgnoredBaseExpression(
const Expr *E) {
9102 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9104 VisitIgnoredValue(E);
9114template<
class Derived>
9115class LValueExprEvaluatorBase
9116 :
public ExprEvaluatorBase<Derived> {
9120 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9121 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9123 bool Success(APValue::LValueBase B) {
9128 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9133 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9135 InvalidBaseOK(InvalidBaseOK) {}
9138 Result.setFrom(this->Info.Ctx,
V);
9142 bool VisitMemberExpr(
const MemberExpr *E) {
9154 EvalOK = this->Visit(E->
getBase());
9165 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9168 "record / field mismatch");
9172 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9176 return this->
Error(E);
9188 bool VisitBinaryOperator(
const BinaryOperator *E) {
9191 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9199 bool VisitCastExpr(
const CastExpr *E) {
9202 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9204 case CK_DerivedToBase:
9205 case CK_UncheckedDerivedToBase:
9252class LValueExprEvaluator
9253 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9255 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9256 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9258 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9259 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9261 bool VisitCallExpr(
const CallExpr *E);
9262 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9263 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9264 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9265 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9266 bool VisitMemberExpr(
const MemberExpr *E);
9267 bool VisitStringLiteral(
const StringLiteral *E) {
9269 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9271 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9272 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9273 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9274 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9275 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9276 bool VisitUnaryDeref(
const UnaryOperator *E);
9277 bool VisitUnaryReal(
const UnaryOperator *E);
9278 bool VisitUnaryImag(
const UnaryOperator *E);
9279 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9280 return VisitUnaryPreIncDec(UO);
9282 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9283 return VisitUnaryPreIncDec(UO);
9285 bool VisitBinAssign(
const BinaryOperator *BO);
9286 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9288 bool VisitCastExpr(
const CastExpr *E) {
9291 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9293 case CK_LValueBitCast:
9294 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9295 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9296 << Info.Ctx.getLangOpts().CPlusPlus;
9299 Result.Designator.setInvalid();
9302 case CK_BaseToDerived:
9319 bool LValueToRValueConversion) {
9323 assert(Info.CurrentCall->This ==
nullptr &&
9324 "This should not be set for a static call operator");
9332 if (
Self->getType()->isReferenceType()) {
9333 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9335 Result.setFrom(Info.Ctx, *RefValue);
9337 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9338 CallStackFrame *Frame =
9339 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9341 unsigned Version = Info.CurrentCall->Arguments.Version;
9342 Result.set({VD, Frame->Index, Version});
9345 Result = *Info.CurrentCall->This;
9355 if (LValueToRValueConversion) {
9359 Result.setFrom(Info.Ctx, RVal);
9370 bool InvalidBaseOK) {
9374 return LValueExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
9377bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9378 const ValueDecl *D = E->
getDecl();
9390 if (Info.checkingPotentialConstantExpression())
9393 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9400 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9401 UnnamedGlobalConstantDecl>(D))
9403 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9404 return VisitVarDecl(E, VD);
9405 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9406 return Visit(BD->getBinding());
9410bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9411 CallStackFrame *Frame =
nullptr;
9412 unsigned Version = 0;
9420 CallStackFrame *CurrFrame = Info.CurrentCall;
9425 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9426 if (CurrFrame->Arguments) {
9427 VD = CurrFrame->Arguments.getOrigParam(PVD);
9429 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9430 Version = CurrFrame->Arguments.Version;
9434 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9441 Result.set({VD, Frame->Index, Version});
9447 if (!Info.getLangOpts().CPlusPlus11) {
9448 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9450 Info.Note(VD->
getLocation(), diag::note_declared_at);
9459 Result.AllowConstexprUnknown =
true;
9466bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9467 if (!IsConstantEvaluatedBuiltinCall(E))
9468 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9473 case Builtin::BIas_const:
9474 case Builtin::BIforward:
9475 case Builtin::BIforward_like:
9476 case Builtin::BImove:
9477 case Builtin::BImove_if_noexcept:
9479 return Visit(E->
getArg(0));
9483 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9486bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9487 const MaterializeTemporaryExpr *E) {
9495 for (
const Expr *E : CommaLHSs)
9504 if (Info.EvalMode == EvaluationMode::ConstantFold)
9511 Value = &Info.CurrentCall->createTemporary(
9527 for (
unsigned I = Adjustments.size(); I != 0; ) {
9529 switch (Adjustments[I].Kind) {
9534 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9540 Type = Adjustments[I].Field->getType();
9545 Adjustments[I].Ptr.RHS))
9547 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9556LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9557 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9558 "lvalue compound literal in c++?");
9570 assert(!Info.getLangOpts().CPlusPlus);
9572 ScopeKind::Block,
Result);
9584bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9585 TypeInfoLValue TypeInfo;
9593 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9594 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9602 std::optional<DynamicType> DynType =
9607 TypeInfo = TypeInfoLValue(
9608 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9614bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9618bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9620 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9621 VisitIgnoredBaseExpression(E->
getBase());
9622 return VisitVarDecl(E, VD);
9626 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9627 if (MD->isStatic()) {
9628 VisitIgnoredBaseExpression(E->
getBase());
9634 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9637bool LValueExprEvaluator::VisitExtVectorElementExpr(
9638 const ExtVectorElementExpr *E) {
9643 if (!Info.noteFailure())
9651 if (Indices.size() > 1)
9655 Result.setFrom(Info.Ctx, Val);
9659 const auto *VT = BaseType->
castAs<VectorType>();
9661 VT->getNumElements(), Indices[0]);
9667bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9677 if (!Info.noteFailure())
9683 if (!Info.noteFailure())
9689 Result.setFrom(Info.Ctx, Val);
9691 VT->getNumElements(), Index.getZExtValue());
9699 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9700 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9702 if (!Info.noteFailure())
9712bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9723 Info.noteUndefinedBehavior();
9726bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9735bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9737 "lvalue __imag__ on scalar?");
9744bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9745 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9756bool LValueExprEvaluator::VisitCompoundAssignOperator(
9757 const CompoundAssignOperator *CAO) {
9758 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9766 if (!Info.noteFailure())
9781bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9782 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9790 if (!Info.noteFailure())
9798 if (Info.getLangOpts().CPlusPlus20 &&
9815 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9816 "Can't get the size of a non alloc_size function");
9817 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9819 std::optional<llvm::APInt> Size =
9820 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9824 Result = std::move(*Size);
9843 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9848 if (!
Init ||
Init->getType().isNull())
9851 const Expr *E =
Init->IgnoreParens();
9852 if (!tryUnwrapAllocSizeCall(E))
9860 Result.addUnsizedArray(Info, E, Pointee);
9865class PointerExprEvaluator
9866 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9875 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9879 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9883 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9886 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9888 InvalidBaseOK(InvalidBaseOK) {}
9894 bool ZeroInitialization(
const Expr *E) {
9899 bool VisitBinaryOperator(
const BinaryOperator *E);
9900 bool VisitCastExpr(
const CastExpr* E);
9901 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9902 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9904 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9907 if (Info.noteFailure())
9911 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
9914 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
9917 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9919 bool VisitCallExpr(
const CallExpr *E);
9920 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9921 bool VisitBlockExpr(
const BlockExpr *E) {
9926 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9927 auto DiagnoseInvalidUseOfThis = [&] {
9928 if (Info.getLangOpts().CPlusPlus11)
9929 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9935 if (Info.checkingPotentialConstantExpression())
9938 bool IsExplicitLambda =
9940 if (!IsExplicitLambda) {
9941 if (!Info.CurrentCall->This) {
9942 DiagnoseInvalidUseOfThis();
9946 Result = *Info.CurrentCall->This;
9954 if (!Info.CurrentCall->LambdaThisCaptureField) {
9955 if (IsExplicitLambda && !Info.CurrentCall->This) {
9956 DiagnoseInvalidUseOfThis();
9965 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9971 bool VisitCXXNewExpr(
const CXXNewExpr *E);
9973 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
9974 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
9976 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
9977 Result.setFrom(Info.Ctx, LValResult);
9981 bool VisitEmbedExpr(
const EmbedExpr *E) {
9982 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9986 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
9989 QualType CharTy = Info.Ctx.CharTy.withConst();
9990 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9991 ResultStr.size() + 1);
9992 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9993 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9996 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
9999 evaluateLValue(SL,
Result);
10009 bool InvalidBaseOK) {
10012 return PointerExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
10015bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10018 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10020 const Expr *PExp = E->
getLHS();
10021 const Expr *IExp = E->
getRHS();
10023 std::swap(PExp, IExp);
10025 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10026 if (!EvalPtrOK && !Info.noteFailure())
10029 llvm::APSInt Offset;
10040bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10049 if (!FnII || !FnII->
isStr(
"current"))
10052 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10060bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10067 case CK_CPointerToObjCPointerCast:
10068 case CK_BlockPointerToObjCPointerCast:
10069 case CK_AnyPointerToBlockPointerCast:
10070 case CK_AddressSpaceConversion:
10071 if (!Visit(SubExpr))
10077 CCEDiag(E, diag::note_constexpr_invalid_cast)
10078 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10079 << Info.Ctx.getLangOpts().CPlusPlus;
10080 Result.Designator.setInvalid();
10088 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10090 bool VoidPtrCastMaybeOK =
10093 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10102 if (VoidPtrCastMaybeOK &&
10103 (Info.getStdAllocatorCaller(
"allocate") ||
10105 Info.getLangOpts().CPlusPlus26)) {
10109 Info.getLangOpts().CPlusPlus) {
10110 if (HasValidResult)
10111 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10112 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10113 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10116 CCEDiag(E, diag::note_constexpr_invalid_cast)
10117 << diag::ConstexprInvalidCastKind::CastFrom
10120 CCEDiag(E, diag::note_constexpr_invalid_cast)
10121 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10122 << Info.Ctx.getLangOpts().CPlusPlus;
10123 Result.Designator.setInvalid();
10127 ZeroInitialization(E);
10130 case CK_DerivedToBase:
10131 case CK_UncheckedDerivedToBase:
10143 case CK_BaseToDerived:
10155 case CK_NullToPointer:
10157 return ZeroInitialization(E);
10159 case CK_IntegralToPointer: {
10160 CCEDiag(E, diag::note_constexpr_invalid_cast)
10161 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10162 << Info.Ctx.getLangOpts().CPlusPlus;
10168 if (
Value.isInt()) {
10169 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10170 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10171 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10174 Result.Base = (Expr *)
nullptr;
10175 Result.InvalidBase =
false;
10177 Result.Designator.setInvalid();
10178 Result.IsNullPtr =
false;
10186 if (!
Value.isLValue())
10195 case CK_ArrayToPointerDecay: {
10197 if (!evaluateLValue(SubExpr,
Result))
10201 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10206 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10207 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10208 Result.addArray(Info, E, CAT);
10210 Result.addUnsizedArray(Info, E, AT->getElementType());
10214 case CK_FunctionToPointerDecay:
10215 return evaluateLValue(SubExpr,
Result);
10217 case CK_LValueToRValue: {
10226 return InvalidBaseOK &&
10232 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10240 T = T.getNonReferenceType();
10242 if (T.getQualifiers().hasUnaligned())
10245 const bool AlignOfReturnsPreferred =
10246 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
10251 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10254 else if (ExprKind == UETT_AlignOf)
10257 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10270 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10274 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10283 return Info.Ctx.getDeclAlign(VD);
10284 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10292 EvalInfo &Info,
APSInt &Alignment) {
10295 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10296 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10299 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10300 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10301 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10302 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10303 << MaxValue << ForType << Alignment;
10309 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10310 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10311 "Alignment should not be changed by ext/trunc");
10312 Alignment = ExtAlignment;
10313 assert(Alignment.getBitWidth() == SrcWidth);
10318bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10319 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10327 Result.addUnsizedArray(Info, E, PointeeTy);
10331bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10332 if (!IsConstantEvaluatedBuiltinCall(E))
10333 return visitNonBuiltinCallExpr(E);
10340 return T->isCharType() || T->isChar8Type();
10343bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10344 unsigned BuiltinOp) {
10348 switch (BuiltinOp) {
10349 case Builtin::BIaddressof:
10350 case Builtin::BI__addressof:
10351 case Builtin::BI__builtin_addressof:
10353 case Builtin::BI__builtin_assume_aligned: {
10360 LValue OffsetResult(
Result);
10372 int64_t AdditionalOffset = -Offset.getZExtValue();
10377 if (OffsetResult.Base) {
10380 if (BaseAlignment < Align) {
10381 Result.Designator.setInvalid();
10382 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10389 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10390 Result.Designator.setInvalid();
10394 diag::note_constexpr_baa_insufficient_alignment)
10397 diag::note_constexpr_baa_value_insufficient_alignment))
10398 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10404 case Builtin::BI__builtin_align_up:
10405 case Builtin::BI__builtin_align_down: {
10425 assert(Alignment.getBitWidth() <= 64 &&
10426 "Cannot handle > 64-bit address-space");
10427 uint64_t Alignment64 = Alignment.getZExtValue();
10429 BuiltinOp == Builtin::BI__builtin_align_down
10430 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10431 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10437 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10441 case Builtin::BI__builtin_operator_new:
10443 case Builtin::BI__builtin_launder:
10445 case Builtin::BIstrchr:
10446 case Builtin::BIwcschr:
10447 case Builtin::BImemchr:
10448 case Builtin::BIwmemchr:
10449 if (Info.getLangOpts().CPlusPlus11)
10450 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10452 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10454 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10456 case Builtin::BI__builtin_strchr:
10457 case Builtin::BI__builtin_wcschr:
10458 case Builtin::BI__builtin_memchr:
10459 case Builtin::BI__builtin_char_memchr:
10460 case Builtin::BI__builtin_wmemchr: {
10461 if (!Visit(E->
getArg(0)))
10467 if (BuiltinOp != Builtin::BIstrchr &&
10468 BuiltinOp != Builtin::BIwcschr &&
10469 BuiltinOp != Builtin::BI__builtin_strchr &&
10470 BuiltinOp != Builtin::BI__builtin_wcschr) {
10474 MaxLength = N.getZExtValue();
10477 if (MaxLength == 0u)
10478 return ZeroInitialization(E);
10479 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10480 Result.Designator.Invalid)
10482 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10483 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10484 BuiltinOp == Builtin::BI__builtin_memchr;
10485 assert(IsRawByte ||
10486 Info.Ctx.hasSameUnqualifiedType(
10490 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10496 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10497 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10503 bool StopAtNull =
false;
10504 switch (BuiltinOp) {
10505 case Builtin::BIstrchr:
10506 case Builtin::BI__builtin_strchr:
10513 return ZeroInitialization(E);
10516 case Builtin::BImemchr:
10517 case Builtin::BI__builtin_memchr:
10518 case Builtin::BI__builtin_char_memchr:
10522 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10525 case Builtin::BIwcschr:
10526 case Builtin::BI__builtin_wcschr:
10529 case Builtin::BIwmemchr:
10530 case Builtin::BI__builtin_wmemchr:
10532 DesiredVal = Desired.getZExtValue();
10536 for (; MaxLength; --MaxLength) {
10541 if (Char.
getInt().getZExtValue() == DesiredVal)
10543 if (StopAtNull && !Char.
getInt())
10549 return ZeroInitialization(E);
10552 case Builtin::BImemcpy:
10553 case Builtin::BImemmove:
10554 case Builtin::BIwmemcpy:
10555 case Builtin::BIwmemmove:
10556 if (Info.getLangOpts().CPlusPlus11)
10557 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10559 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10561 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10563 case Builtin::BI__builtin_memcpy:
10564 case Builtin::BI__builtin_memmove:
10565 case Builtin::BI__builtin_wmemcpy:
10566 case Builtin::BI__builtin_wmemmove: {
10567 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10568 BuiltinOp == Builtin::BIwmemmove ||
10569 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10570 BuiltinOp == Builtin::BI__builtin_wmemmove;
10571 bool Move = BuiltinOp == Builtin::BImemmove ||
10572 BuiltinOp == Builtin::BIwmemmove ||
10573 BuiltinOp == Builtin::BI__builtin_memmove ||
10574 BuiltinOp == Builtin::BI__builtin_wmemmove;
10577 if (!Visit(E->
getArg(0)))
10588 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10598 if (!Src.Base || !Dest.Base) {
10600 (!Src.Base ? Src : Dest).moveInto(Val);
10601 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10602 <<
Move << WChar << !!Src.Base
10606 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10612 QualType T = Dest.Designator.getType(Info.Ctx);
10613 QualType SrcT = Src.Designator.getType(Info.Ctx);
10614 if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) {
10616 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT << T;
10620 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move << T;
10624 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move << T;
10629 uint64_t TSize = Info.Ctx.getTypeSizeInChars(T).getQuantity();
10634 llvm::APInt OrigN = N;
10635 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10637 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10638 <<
Move << WChar << 0 << T <<
toString(OrigN, 10,
false)
10639 << (unsigned)TSize;
10647 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10648 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10649 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10650 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10651 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) << T
10655 uint64_t NElems = N.getZExtValue();
10661 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10662 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10663 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10666 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10674 }
else if (!Move && SrcOffset >= DestOffset &&
10675 SrcOffset - DestOffset < NBytes) {
10677 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10706 QualType AllocType);
10709 const CXXConstructExpr *CCE,
10710 QualType AllocType);
10712bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10713 if (!Info.getLangOpts().CPlusPlus20)
10714 Info.CCEDiag(E, diag::note_constexpr_new);
10717 if (Info.SpeculativeEvaluationDepth)
10722 QualType TargetType = AllocType;
10724 bool IsNothrow =
false;
10725 bool IsPlacement =
false;
10743 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10744 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10745 (Info.CurrentCall->CanEvalMSConstexpr &&
10746 OperatorNew->hasAttr<MSConstexprAttr>())) {
10749 if (
Result.Designator.Invalid)
10752 IsPlacement =
true;
10754 Info.FFDiag(E, diag::note_constexpr_new_placement)
10759 Info.FFDiag(E, diag::note_constexpr_new_placement)
10762 }
else if (!OperatorNew
10763 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10764 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10770 const InitListExpr *ResizedArrayILE =
nullptr;
10771 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10772 bool ValueInit =
false;
10774 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10775 const Expr *Stripped = *ArraySize;
10776 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10777 Stripped = ICE->getSubExpr())
10778 if (ICE->getCastKind() != CK_NoOp &&
10779 ICE->getCastKind() != CK_IntegralCast)
10792 return ZeroInitialization(E);
10794 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10795 <<
ArrayBound << (*ArraySize)->getSourceRange();
10801 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10806 return ZeroInitialization(E);
10818 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10819 ResizedArrayCCE = CCE;
10821 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10822 assert(CAT &&
"unexpected type for array initializer");
10826 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10827 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10828 if (InitBound.ugt(AllocBound)) {
10830 return ZeroInitialization(E);
10832 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10833 <<
toString(AllocBound, 10,
false)
10835 << (*ArraySize)->getSourceRange();
10841 if (InitBound != AllocBound)
10845 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
10846 ArraySizeModifier::Normal, 0);
10849 "array allocation with non-array new");
10855 struct FindObjectHandler {
10858 QualType AllocType;
10862 typedef bool result_type;
10863 bool failed() {
return false; }
10864 bool checkConst(QualType QT) {
10866 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10871 bool found(
APValue &Subobj, QualType SubobjType,
10872 APValue::LValueBase Base) {
10873 if (!checkConst(SubobjType))
10877 unsigned SubobjectSize = 1;
10878 unsigned AllocSize = 1;
10879 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10881 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10883 if (SubobjectSize < AllocSize ||
10884 !Info.Ctx.hasSimilarType(Info.Ctx.getBaseElementType(SubobjType),
10885 Info.Ctx.getBaseElementType(AllocType))) {
10886 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10887 << SubobjType << AllocType;
10894 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10897 bool found(APFloat &
Value, QualType SubobjType) {
10898 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10901 } Handler = {Info, E, AllocType, AK,
nullptr};
10907 Val = Handler.Value;
10916 Val = Info.createHeapAlloc(E, AllocType,
Result);
10922 ImplicitValueInitExpr VIE(AllocType);
10925 }
else if (ResizedArrayILE) {
10929 }
else if (ResizedArrayCCE) {
10952class MemberPointerExprEvaluator
10953 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10956 bool Success(
const ValueDecl *D) {
10962 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
10969 bool ZeroInitialization(
const Expr *E) {
10970 return Success((
const ValueDecl*)
nullptr);
10973 bool VisitCastExpr(
const CastExpr *E);
10974 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10982 return MemberPointerExprEvaluator(Info,
Result).Visit(E);
10985bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10988 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10990 case CK_NullToMemberPointer:
10992 return ZeroInitialization(E);
10994 case CK_BaseToDerivedMemberPointer: {
11002 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11004 PathI != PathE; ++PathI) {
11005 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11006 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11007 if (!
Result.castToDerived(Derived))
11011 ->
castAs<MemberPointerType>()
11012 ->getMostRecentCXXRecordDecl()))
11017 case CK_DerivedToBaseMemberPointer:
11021 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11022 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11023 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11024 if (!
Result.castToBase(Base))
11031bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11042 class RecordExprEvaluator
11043 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11044 const LValue &
This;
11048 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11055 bool ZeroInitialization(
const Expr *E) {
11056 return ZeroInitialization(E, E->
getType());
11058 bool ZeroInitialization(
const Expr *E, QualType T);
11060 bool VisitCallExpr(
const CallExpr *E) {
11061 return handleCallExpr(E,
Result, &This);
11063 bool VisitCastExpr(
const CastExpr *E);
11064 bool VisitInitListExpr(
const InitListExpr *E);
11065 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11066 return VisitCXXConstructExpr(E, E->
getType());
11069 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11070 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType T);
11071 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11072 bool VisitBinCmp(
const BinaryOperator *E);
11073 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11074 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11075 ArrayRef<Expr *> Args);
11076 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
11090 assert(!RD->
isUnion() &&
"Expected non-union class type");
11099 unsigned Index = 0;
11101 End = CD->
bases_end(); I != End; ++I, ++Index) {
11103 LValue Subobject =
This;
11107 Result.getStructBase(Index)))
11112 for (
const auto *I : RD->
fields()) {
11114 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11117 LValue Subobject =
This;
11123 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11130bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType T) {
11137 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11144 LValue Subobject =
This;
11148 ImplicitValueInitExpr VIE(I->getType());
11153 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11160bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11163 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11165 case CK_ConstructorConversion:
11168 case CK_DerivedToBase:
11169 case CK_UncheckedDerivedToBase: {
11180 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11181 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11182 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11189 case CK_HLSLAggregateSplatCast: {
11209 case CK_HLSLElementwiseCast: {
11227 LValue Subobject =
This;
11234 if (
Field->isBitField()) {
11244bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11247 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11250bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11254 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11255 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11257 EvalInfo::EvaluatingConstructorRAII EvalObj(
11259 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11260 CXXRD && CXXRD->getNumBases());
11263 const FieldDecl *
Field;
11264 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11265 Field = ILE->getInitializedFieldInUnion();
11266 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11267 Field = PLIE->getInitializedFieldInUnion();
11270 "Expression is neither an init list nor a C++ paren list");
11282 ImplicitValueInitExpr VIE(
Field->getType());
11283 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11285 LValue Subobject =
This;
11290 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11294 if (
Field->isBitField())
11304 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11306 unsigned ElementNo = 0;
11310 if (CXXRD && CXXRD->getNumBases()) {
11311 for (
const auto &Base : CXXRD->bases()) {
11312 assert(ElementNo < Args.size() &&
"missing init for base class");
11313 const Expr *
Init = Args[ElementNo];
11315 LValue Subobject =
This;
11321 if (!Info.noteFailure())
11328 EvalObj.finishedConstructingBases();
11332 for (
const auto *Field : RD->
fields()) {
11335 if (
Field->isUnnamedBitField())
11338 LValue Subobject =
This;
11340 bool HaveInit = ElementNo < Args.size();
11345 Subobject, Field, &Layout))
11350 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11351 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11358 if (
Field->getType()->isIncompleteArrayType()) {
11359 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11363 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11370 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11374 if (
Field->getType()->isReferenceType()) {
11378 if (!Info.noteFailure())
11383 (
Field->isBitField() &&
11385 if (!Info.noteFailure())
11391 EvalObj.finishedConstructingFields();
11396bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11406 return ZeroInitialization(E, T);
11424 const Expr *SrcObj = E->
getArg(0);
11426 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11427 if (
const MaterializeTemporaryExpr *ME =
11428 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11429 return Visit(ME->getSubExpr());
11432 if (ZeroInit && !ZeroInitialization(E, T))
11441bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11442 const CXXInheritedCtorInitExpr *E) {
11443 if (!Info.CurrentCall) {
11444 assert(Info.checkingPotentialConstantExpression());
11463bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11464 const CXXStdInitializerListExpr *E) {
11465 const ConstantArrayType *ArrayType =
11472 assert(ArrayType &&
"unexpected type for array initializer");
11475 Array.addArray(Info, E, ArrayType);
11483 assert(Field !=
Record->field_end() &&
11484 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11486 "Expected std::initializer_list first field to be const E *");
11488 assert(Field !=
Record->field_end() &&
11489 "Expected std::initializer_list to have two fields");
11491 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11496 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11498 "Expected std::initializer_list second field to be const E *");
11506 assert(++Field ==
Record->field_end() &&
11507 "Expected std::initializer_list to only have two fields");
11512bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11517 const size_t NumFields = ClosureClass->
getNumFields();
11521 "The number of lambda capture initializers should equal the number of "
11522 "fields within the closure type");
11529 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11530 for (
const auto *Field : ClosureClass->
fields()) {
11533 Expr *
const CurFieldInit = *CaptureInitIt++;
11540 LValue Subobject =
This;
11547 if (!Info.keepEvaluatingAfterFailure())
11555bool RecordExprEvaluator::VisitDesignatedInitUpdateExpr(
11556 const DesignatedInitUpdateExpr *E) {
11566 "can't evaluate expression as a record rvalue");
11567 return RecordExprEvaluator(Info,
This,
Result).Visit(E);
11578class TemporaryExprEvaluator
11579 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11581 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11582 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11585 bool VisitConstructExpr(
const Expr *E) {
11591 bool VisitCastExpr(
const CastExpr *E) {
11594 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11596 case CK_ConstructorConversion:
11600 bool VisitInitListExpr(
const InitListExpr *E) {
11601 return VisitConstructExpr(E);
11603 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11604 return VisitConstructExpr(E);
11606 bool VisitCallExpr(
const CallExpr *E) {
11607 return VisitConstructExpr(E);
11609 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11610 return VisitConstructExpr(E);
11613 return VisitConstructExpr(E);
11622 return TemporaryExprEvaluator(Info,
Result).Visit(E);
11630 class VectorExprEvaluator
11631 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11638 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11639 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11645 assert(
V.isVector());
11649 bool ZeroInitialization(
const Expr *E);
11651 bool VisitUnaryReal(
const UnaryOperator *E)
11653 bool VisitCastExpr(
const CastExpr* E);
11654 bool VisitInitListExpr(
const InitListExpr *E);
11655 bool VisitUnaryImag(
const UnaryOperator *E);
11656 bool VisitBinaryOperator(
const BinaryOperator *E);
11657 bool VisitUnaryOperator(
const UnaryOperator *E);
11658 bool VisitCallExpr(
const CallExpr *E);
11659 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11660 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11669 "not a vector prvalue");
11670 return VectorExprEvaluator(Info,
Result).Visit(E);
11674 assert(Val.
isVector() &&
"expected vector APValue");
11678 llvm::APInt
Result(NumElts, 0);
11680 for (
unsigned I = 0; I < NumElts; ++I) {
11682 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11684 if (Elt.
getInt().getBoolValue())
11691bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11692 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11696 QualType SETy = SE->
getType();
11699 case CK_VectorSplat: {
11705 Val =
APValue(std::move(IntResult));
11710 Val =
APValue(std::move(FloatResult));
11727 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11728 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11729 << Info.Ctx.getLangOpts().CPlusPlus;
11733 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11738 case CK_HLSLVectorTruncation: {
11743 for (
unsigned I = 0; I < NElts; I++)
11747 case CK_HLSLMatrixTruncation: {
11753 for (
unsigned Row = 0;
11755 for (
unsigned Col = 0;
11760 case CK_HLSLAggregateSplatCast: {
11777 case CK_HLSLElementwiseCast: {
11790 return Success(ResultEls, E);
11792 case CK_IntegralToFloating:
11793 case CK_FloatingToIntegral:
11794 case CK_IntegralCast:
11795 case CK_FloatingCast:
11796 case CK_FloatingToBoolean:
11797 case CK_IntegralToBoolean: {
11799 assert(SETy->
isVectorType() &&
"expected vector source type");
11805 QualType SrcEltTy = SETy->
castAs<VectorType>()->getElementType();
11810 for (
unsigned I = 0; I < NElts; ++I) {
11815 return Success(ResultEls, E);
11818 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11823VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11840 unsigned CountInits = 0, CountElts = 0;
11841 while (CountElts < NumElements) {
11843 if (CountInits < NumInits
11849 for (
unsigned j = 0; j < vlen; j++)
11853 llvm::APSInt sInt(32);
11854 if (CountInits < NumInits) {
11858 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11859 Elements.push_back(
APValue(sInt));
11862 llvm::APFloat f(0.0);
11863 if (CountInits < NumInits) {
11867 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11868 Elements.push_back(
APValue(f));
11877VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
11881 if (EltTy->isIntegerType())
11882 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
11885 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
11891bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11893 return ZeroInitialization(E);
11896bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11898 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11899 "Operation not supported on vector types");
11901 if (Op == BO_Comma)
11902 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11904 Expr *LHS = E->
getLHS();
11905 Expr *RHS = E->
getRHS();
11908 "Must both be vector types");
11911 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
11915 "All operands must be the same size.");
11919 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11920 if (!LHSOK && !Info.noteFailure())
11922 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11944 "Vector can only be int or float type");
11952 "Vector operator ~ can only be int");
11953 Elt.
getInt().flipAllBits();
11963 "Vector can only be int or float type");
11969 EltResult.setAllBits();
11971 EltResult.clearAllBits();
11977 return std::nullopt;
11981bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11987 const QualType ResultEltTy = VD->getElementType();
11991 if (!
Evaluate(SubExprValue, Info, SubExpr))
12004 "Vector length doesn't match type?");
12007 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
12009 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12012 ResultElements.push_back(*Elt);
12014 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12025 DestTy,
Result.getFloat());
12041 DestTy,
Result.getInt());
12045 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12046 << SourceTy << DestTy;
12051 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12060 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12061 "pack builtin LHSVecLen must equal to RHSVecLen");
12064 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12070 const unsigned SrcPerLane = 128 / SrcBits;
12071 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12074 Out.reserve(LHSVecLen + RHSVecLen);
12076 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12077 unsigned base = Lane * SrcPerLane;
12078 for (
unsigned I = 0; I != SrcPerLane; ++I)
12081 for (
unsigned I = 0; I != SrcPerLane; ++I)
12092 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12099 unsigned ShuffleMask = 0;
12101 bool IsVectorMask =
false;
12102 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12104 if (IsSingleOperand) {
12107 IsVectorMask =
true;
12116 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12126 IsVectorMask =
true;
12135 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12146 ResultElements.reserve(NumElts);
12148 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12149 if (IsVectorMask) {
12150 ShuffleMask =
static_cast<unsigned>(
12151 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12153 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12159 ResultElements.push_back(
12160 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12166 ResultElements.push_back(
APValue());
12169 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12174 Out =
APValue(ResultElements.data(), ResultElements.size());
12180 if (OrigVal.isInfinity()) {
12181 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12184 if (OrigVal.isNaN()) {
12185 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12189 APFloat Val = OrigVal;
12190 bool LosesInfo =
false;
12191 APFloat::opStatus Status = Val.convert(
12192 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12194 if (LosesInfo || Val.isDenormal()) {
12195 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12199 if (Status != APFloat::opOK) {
12200 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12209 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12210 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12217 assert(
Call->getNumArgs() == 2);
12221 Call->getArg(1)->getType()->isVectorType());
12224 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12225 unsigned DestLen = Source.getVectorLength();
12228 unsigned NumBitsInQWord = 64;
12229 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12231 Result.reserve(DestLen);
12233 uint64_t CountLQWord = 0;
12234 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12236 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12239 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12240 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12241 if (CountLQWord < DestEltWidth) {
12243 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12246 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12254 std::optional<APSInt> RoundingMode,
12256 APSInt DefaultMode(APInt(32, 4),
true);
12257 if (RoundingMode.value_or(DefaultMode) != 4)
12258 return std::nullopt;
12259 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12260 B.isInfinity() || B.isDenormal())
12261 return std::nullopt;
12262 if (A.isZero() && B.isZero())
12264 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12267bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12268 if (!IsConstantEvaluatedBuiltinCall(E))
12269 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12271 auto EvaluateBinOpExpr =
12273 APValue SourceLHS, SourceRHS;
12279 QualType DestEltTy = DestTy->getElementType();
12280 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12283 ResultElements.reserve(SourceLen);
12285 if (SourceRHS.
isInt()) {
12287 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12289 ResultElements.push_back(
12293 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12296 ResultElements.push_back(
12303 auto EvaluateFpBinOpExpr =
12304 [&](llvm::function_ref<std::optional<APFloat>(
12305 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12307 bool IsScalar =
false) {
12317 std::optional<APSInt> RoundingMode;
12322 RoundingMode = Imm;
12327 ResultElements.reserve(NumElems);
12329 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12330 if (IsScalar && EltNum > 0) {
12336 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12344 auto EvaluateScalarFpRoundMaskBinOp =
12345 [&](llvm::function_ref<std::optional<APFloat>(
12346 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12350 APSInt MaskVal, Rounding;
12361 ResultElements.reserve(NumElems);
12363 if (MaskVal.getZExtValue() & 1) {
12366 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12374 for (
unsigned I = 1; I < NumElems; ++I)
12380 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12388 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12392 for (
unsigned I = 1; I < Len; ++I)
12394 APValue V(Res.data(), Res.size());
12401 case Builtin::BI__builtin_elementwise_popcount:
12402 case Builtin::BI__builtin_elementwise_bitreverse: {
12407 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12410 ResultElements.reserve(SourceLen);
12412 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12415 case Builtin::BI__builtin_elementwise_popcount:
12416 ResultElements.push_back(
APValue(
12417 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
12420 case Builtin::BI__builtin_elementwise_bitreverse:
12421 ResultElements.push_back(
12428 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12430 case Builtin::BI__builtin_elementwise_abs: {
12435 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12438 ResultElements.reserve(SourceLen);
12440 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12445 CurrentEle.getInt().
abs(),
12446 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12447 ResultElements.push_back(Val);
12450 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12453 case Builtin::BI__builtin_elementwise_add_sat:
12454 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12455 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12458 case Builtin::BI__builtin_elementwise_sub_sat:
12459 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12460 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12463 case X86::BI__builtin_ia32_extract128i256:
12464 case X86::BI__builtin_ia32_vextractf128_pd256:
12465 case X86::BI__builtin_ia32_vextractf128_ps256:
12466 case X86::BI__builtin_ia32_vextractf128_si256: {
12467 APValue SourceVec, SourceImm;
12476 unsigned RetLen = RetVT->getNumElements();
12477 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12480 ResultElements.reserve(RetLen);
12482 for (
unsigned I = 0; I < RetLen; I++)
12483 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12488 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12489 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12490 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12491 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12492 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12493 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12494 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12495 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12496 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12497 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12498 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12499 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12505 QualType VecTy = E->
getType();
12506 const VectorType *VT = VecTy->
castAs<VectorType>();
12509 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
12512 for (
unsigned I = 0; I != VectorLen; ++I) {
12513 bool BitSet = Mask[I];
12514 APSInt ElemVal(ElemWidth,
false);
12516 ElemVal.setAllBits();
12518 Elems.push_back(
APValue(ElemVal));
12523 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12524 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12525 case X86::BI__builtin_ia32_extracti32x4_mask:
12526 case X86::BI__builtin_ia32_extractf32x4_mask:
12527 case X86::BI__builtin_ia32_extracti32x8_mask:
12528 case X86::BI__builtin_ia32_extractf32x8_mask:
12529 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12530 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12531 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12532 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12533 case X86::BI__builtin_ia32_extracti64x4_mask:
12534 case X86::BI__builtin_ia32_extractf64x4_mask: {
12545 unsigned RetLen = RetVT->getNumElements();
12550 unsigned Lanes = SrcLen / RetLen;
12551 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12552 unsigned Base = Lane * RetLen;
12555 ResultElements.reserve(RetLen);
12556 for (
unsigned I = 0; I < RetLen; ++I) {
12558 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12562 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12565 case clang::X86::BI__builtin_ia32_pavgb128:
12566 case clang::X86::BI__builtin_ia32_pavgw128:
12567 case clang::X86::BI__builtin_ia32_pavgb256:
12568 case clang::X86::BI__builtin_ia32_pavgw256:
12569 case clang::X86::BI__builtin_ia32_pavgb512:
12570 case clang::X86::BI__builtin_ia32_pavgw512:
12571 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12573 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12574 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12575 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12576 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12577 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12578 .extractBits(16, 1);
12581 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12582 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12583 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12584 case clang::X86::BI__builtin_ia32_pmaddwd128:
12585 case clang::X86::BI__builtin_ia32_pmaddwd256:
12586 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12587 APValue SourceLHS, SourceRHS;
12593 QualType DestEltTy = DestTy->getElementType();
12595 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12597 ResultElements.reserve(SourceLen / 2);
12599 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12604 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12607 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12608 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12609 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12610 ResultElements.push_back(
APValue(
12611 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
12612 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
12615 case clang::X86::BI__builtin_ia32_pmaddwd128:
12616 case clang::X86::BI__builtin_ia32_pmaddwd256:
12617 case clang::X86::BI__builtin_ia32_pmaddwd512:
12618 ResultElements.push_back(
12619 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
12620 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
12626 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12629 case clang::X86::BI__builtin_ia32_dbpsadbw128:
12630 case clang::X86::BI__builtin_ia32_dbpsadbw256:
12631 case clang::X86::BI__builtin_ia32_dbpsadbw512: {
12632 APValue SourceA, SourceB, SourceImm;
12639 constexpr unsigned LaneSize = 16;
12640 unsigned Imm = SourceImm.
getInt().getZExtValue();
12643 QualType DestEltTy = DestTy->getElementType();
12644 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12646 ResultElements.reserve(SourceLen / 2);
12652 for (
unsigned I = 0; I < SourceLen; I += LaneSize) {
12653 for (
unsigned J = 0; J < 4; ++J) {
12654 unsigned Part = (Imm >> (2 * J)) & 3;
12655 for (
unsigned K = 0; K < 4; ++K) {
12656 Shuffled[I + 4 * J + K] =
static_cast<uint8_t
>(
12657 SourceB.
getVectorElt(I + 4 * Part + K).getInt().getZExtValue());
12665 unsigned Size = SourceLen / 2;
12666 for (
unsigned I = 0; I <
Size; I += 4) {
12667 unsigned Sad[4] = {0, 0, 0, 0};
12668 for (
unsigned J = 0; J < 4; ++J) {
12669 uint8_t A1 =
static_cast<uint8_t
>(
12670 SourceA.
getVectorElt(2 * I + J).getInt().getZExtValue());
12671 uint8_t A2 =
static_cast<uint8_t
>(
12672 SourceA.
getVectorElt(2 * I + J + 4).getInt().getZExtValue());
12673 uint8_t B0 = Shuffled[2 * I + J];
12674 uint8_t B1 = Shuffled[2 * I + J + 1];
12675 uint8_t B2 = Shuffled[2 * I + J + 2];
12676 uint8_t B3 = Shuffled[2 * I + J + 3];
12677 Sad[0] += (A1 > B0) ? (A1 - B0) : (B0 - A1);
12678 Sad[1] += (A1 > B1) ? (A1 - B1) : (B1 - A1);
12679 Sad[2] += (A2 > B2) ? (A2 - B2) : (B2 - A2);
12680 Sad[3] += (A2 > B3) ? (A2 - B3) : (B3 - A2);
12682 for (
unsigned R = 0;
R < 4; ++
R)
12683 ResultElements.push_back(
12687 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12690 case clang::X86::BI__builtin_ia32_pmulhuw128:
12691 case clang::X86::BI__builtin_ia32_pmulhuw256:
12692 case clang::X86::BI__builtin_ia32_pmulhuw512:
12693 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
12695 case clang::X86::BI__builtin_ia32_pmulhw128:
12696 case clang::X86::BI__builtin_ia32_pmulhw256:
12697 case clang::X86::BI__builtin_ia32_pmulhw512:
12698 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
12700 case clang::X86::BI__builtin_ia32_psllv2di:
12701 case clang::X86::BI__builtin_ia32_psllv4di:
12702 case clang::X86::BI__builtin_ia32_psllv4si:
12703 case clang::X86::BI__builtin_ia32_psllv8di:
12704 case clang::X86::BI__builtin_ia32_psllv8hi:
12705 case clang::X86::BI__builtin_ia32_psllv8si:
12706 case clang::X86::BI__builtin_ia32_psllv16hi:
12707 case clang::X86::BI__builtin_ia32_psllv16si:
12708 case clang::X86::BI__builtin_ia32_psllv32hi:
12709 case clang::X86::BI__builtin_ia32_psllwi128:
12710 case clang::X86::BI__builtin_ia32_pslldi128:
12711 case clang::X86::BI__builtin_ia32_psllqi128:
12712 case clang::X86::BI__builtin_ia32_psllwi256:
12713 case clang::X86::BI__builtin_ia32_pslldi256:
12714 case clang::X86::BI__builtin_ia32_psllqi256:
12715 case clang::X86::BI__builtin_ia32_psllwi512:
12716 case clang::X86::BI__builtin_ia32_pslldi512:
12717 case clang::X86::BI__builtin_ia32_psllqi512:
12718 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12719 if (RHS.uge(LHS.getBitWidth())) {
12720 return APInt::getZero(LHS.getBitWidth());
12722 return LHS.shl(RHS.getZExtValue());
12725 case clang::X86::BI__builtin_ia32_psrav4si:
12726 case clang::X86::BI__builtin_ia32_psrav8di:
12727 case clang::X86::BI__builtin_ia32_psrav8hi:
12728 case clang::X86::BI__builtin_ia32_psrav8si:
12729 case clang::X86::BI__builtin_ia32_psrav16hi:
12730 case clang::X86::BI__builtin_ia32_psrav16si:
12731 case clang::X86::BI__builtin_ia32_psrav32hi:
12732 case clang::X86::BI__builtin_ia32_psravq128:
12733 case clang::X86::BI__builtin_ia32_psravq256:
12734 case clang::X86::BI__builtin_ia32_psrawi128:
12735 case clang::X86::BI__builtin_ia32_psradi128:
12736 case clang::X86::BI__builtin_ia32_psraqi128:
12737 case clang::X86::BI__builtin_ia32_psrawi256:
12738 case clang::X86::BI__builtin_ia32_psradi256:
12739 case clang::X86::BI__builtin_ia32_psraqi256:
12740 case clang::X86::BI__builtin_ia32_psrawi512:
12741 case clang::X86::BI__builtin_ia32_psradi512:
12742 case clang::X86::BI__builtin_ia32_psraqi512:
12743 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12744 if (RHS.uge(LHS.getBitWidth())) {
12745 return LHS.ashr(LHS.getBitWidth() - 1);
12747 return LHS.ashr(RHS.getZExtValue());
12750 case clang::X86::BI__builtin_ia32_psrlv2di:
12751 case clang::X86::BI__builtin_ia32_psrlv4di:
12752 case clang::X86::BI__builtin_ia32_psrlv4si:
12753 case clang::X86::BI__builtin_ia32_psrlv8di:
12754 case clang::X86::BI__builtin_ia32_psrlv8hi:
12755 case clang::X86::BI__builtin_ia32_psrlv8si:
12756 case clang::X86::BI__builtin_ia32_psrlv16hi:
12757 case clang::X86::BI__builtin_ia32_psrlv16si:
12758 case clang::X86::BI__builtin_ia32_psrlv32hi:
12759 case clang::X86::BI__builtin_ia32_psrlwi128:
12760 case clang::X86::BI__builtin_ia32_psrldi128:
12761 case clang::X86::BI__builtin_ia32_psrlqi128:
12762 case clang::X86::BI__builtin_ia32_psrlwi256:
12763 case clang::X86::BI__builtin_ia32_psrldi256:
12764 case clang::X86::BI__builtin_ia32_psrlqi256:
12765 case clang::X86::BI__builtin_ia32_psrlwi512:
12766 case clang::X86::BI__builtin_ia32_psrldi512:
12767 case clang::X86::BI__builtin_ia32_psrlqi512:
12768 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12769 if (RHS.uge(LHS.getBitWidth())) {
12770 return APInt::getZero(LHS.getBitWidth());
12772 return LHS.lshr(RHS.getZExtValue());
12774 case X86::BI__builtin_ia32_packsswb128:
12775 case X86::BI__builtin_ia32_packsswb256:
12776 case X86::BI__builtin_ia32_packsswb512:
12777 case X86::BI__builtin_ia32_packssdw128:
12778 case X86::BI__builtin_ia32_packssdw256:
12779 case X86::BI__builtin_ia32_packssdw512:
12781 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
12783 case X86::BI__builtin_ia32_packusdw128:
12784 case X86::BI__builtin_ia32_packusdw256:
12785 case X86::BI__builtin_ia32_packusdw512:
12786 case X86::BI__builtin_ia32_packuswb128:
12787 case X86::BI__builtin_ia32_packuswb256:
12788 case X86::BI__builtin_ia32_packuswb512:
12790 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
12792 case clang::X86::BI__builtin_ia32_selectss_128:
12793 return EvalSelectScalar(4);
12794 case clang::X86::BI__builtin_ia32_selectsd_128:
12795 return EvalSelectScalar(2);
12796 case clang::X86::BI__builtin_ia32_selectsh_128:
12797 case clang::X86::BI__builtin_ia32_selectsbf_128:
12798 return EvalSelectScalar(8);
12799 case clang::X86::BI__builtin_ia32_pmuldq128:
12800 case clang::X86::BI__builtin_ia32_pmuldq256:
12801 case clang::X86::BI__builtin_ia32_pmuldq512:
12802 case clang::X86::BI__builtin_ia32_pmuludq128:
12803 case clang::X86::BI__builtin_ia32_pmuludq256:
12804 case clang::X86::BI__builtin_ia32_pmuludq512: {
12805 APValue SourceLHS, SourceRHS;
12812 ResultElements.reserve(SourceLen / 2);
12814 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12819 case clang::X86::BI__builtin_ia32_pmuludq128:
12820 case clang::X86::BI__builtin_ia32_pmuludq256:
12821 case clang::X86::BI__builtin_ia32_pmuludq512:
12822 ResultElements.push_back(
12823 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
12825 case clang::X86::BI__builtin_ia32_pmuldq128:
12826 case clang::X86::BI__builtin_ia32_pmuldq256:
12827 case clang::X86::BI__builtin_ia32_pmuldq512:
12828 ResultElements.push_back(
12829 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
12834 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12837 case X86::BI__builtin_ia32_vpmadd52luq128:
12838 case X86::BI__builtin_ia32_vpmadd52luq256:
12839 case X86::BI__builtin_ia32_vpmadd52luq512: {
12848 ResultElements.reserve(ALen);
12850 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12853 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12854 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
12855 ResultElements.push_back(
APValue(ResElt));
12858 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12860 case X86::BI__builtin_ia32_vpmadd52huq128:
12861 case X86::BI__builtin_ia32_vpmadd52huq256:
12862 case X86::BI__builtin_ia32_vpmadd52huq512: {
12871 ResultElements.reserve(ALen);
12873 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12876 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12877 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
12878 ResultElements.push_back(
APValue(ResElt));
12881 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12884 case clang::X86::BI__builtin_ia32_vprotbi:
12885 case clang::X86::BI__builtin_ia32_vprotdi:
12886 case clang::X86::BI__builtin_ia32_vprotqi:
12887 case clang::X86::BI__builtin_ia32_vprotwi:
12888 case clang::X86::BI__builtin_ia32_prold128:
12889 case clang::X86::BI__builtin_ia32_prold256:
12890 case clang::X86::BI__builtin_ia32_prold512:
12891 case clang::X86::BI__builtin_ia32_prolq128:
12892 case clang::X86::BI__builtin_ia32_prolq256:
12893 case clang::X86::BI__builtin_ia32_prolq512:
12894 return EvaluateBinOpExpr(
12895 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
12897 case clang::X86::BI__builtin_ia32_prord128:
12898 case clang::X86::BI__builtin_ia32_prord256:
12899 case clang::X86::BI__builtin_ia32_prord512:
12900 case clang::X86::BI__builtin_ia32_prorq128:
12901 case clang::X86::BI__builtin_ia32_prorq256:
12902 case clang::X86::BI__builtin_ia32_prorq512:
12903 return EvaluateBinOpExpr(
12904 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
12906 case Builtin::BI__builtin_elementwise_max:
12907 case Builtin::BI__builtin_elementwise_min: {
12908 APValue SourceLHS, SourceRHS;
12913 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12920 ResultElements.reserve(SourceLen);
12922 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12926 case Builtin::BI__builtin_elementwise_max:
12927 ResultElements.push_back(
12931 case Builtin::BI__builtin_elementwise_min:
12932 ResultElements.push_back(
12939 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12941 case X86::BI__builtin_ia32_vpshldd128:
12942 case X86::BI__builtin_ia32_vpshldd256:
12943 case X86::BI__builtin_ia32_vpshldd512:
12944 case X86::BI__builtin_ia32_vpshldq128:
12945 case X86::BI__builtin_ia32_vpshldq256:
12946 case X86::BI__builtin_ia32_vpshldq512:
12947 case X86::BI__builtin_ia32_vpshldw128:
12948 case X86::BI__builtin_ia32_vpshldw256:
12949 case X86::BI__builtin_ia32_vpshldw512: {
12950 APValue SourceHi, SourceLo, SourceAmt;
12956 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12959 ResultElements.reserve(SourceLen);
12962 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12965 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
12966 ResultElements.push_back(
12970 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12972 case X86::BI__builtin_ia32_vpshrdd128:
12973 case X86::BI__builtin_ia32_vpshrdd256:
12974 case X86::BI__builtin_ia32_vpshrdd512:
12975 case X86::BI__builtin_ia32_vpshrdq128:
12976 case X86::BI__builtin_ia32_vpshrdq256:
12977 case X86::BI__builtin_ia32_vpshrdq512:
12978 case X86::BI__builtin_ia32_vpshrdw128:
12979 case X86::BI__builtin_ia32_vpshrdw256:
12980 case X86::BI__builtin_ia32_vpshrdw512: {
12982 APValue SourceHi, SourceLo, SourceAmt;
12988 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12991 ResultElements.reserve(SourceLen);
12994 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12997 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
12998 ResultElements.push_back(
13002 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13004 case X86::BI__builtin_ia32_compressdf128_mask:
13005 case X86::BI__builtin_ia32_compressdf256_mask:
13006 case X86::BI__builtin_ia32_compressdf512_mask:
13007 case X86::BI__builtin_ia32_compressdi128_mask:
13008 case X86::BI__builtin_ia32_compressdi256_mask:
13009 case X86::BI__builtin_ia32_compressdi512_mask:
13010 case X86::BI__builtin_ia32_compresshi128_mask:
13011 case X86::BI__builtin_ia32_compresshi256_mask:
13012 case X86::BI__builtin_ia32_compresshi512_mask:
13013 case X86::BI__builtin_ia32_compressqi128_mask:
13014 case X86::BI__builtin_ia32_compressqi256_mask:
13015 case X86::BI__builtin_ia32_compressqi512_mask:
13016 case X86::BI__builtin_ia32_compresssf128_mask:
13017 case X86::BI__builtin_ia32_compresssf256_mask:
13018 case X86::BI__builtin_ia32_compresssf512_mask:
13019 case X86::BI__builtin_ia32_compresssi128_mask:
13020 case X86::BI__builtin_ia32_compresssi256_mask:
13021 case X86::BI__builtin_ia32_compresssi512_mask: {
13032 ResultElements.reserve(NumElts);
13034 for (
unsigned I = 0; I != NumElts; ++I) {
13038 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
13042 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13044 case X86::BI__builtin_ia32_expanddf128_mask:
13045 case X86::BI__builtin_ia32_expanddf256_mask:
13046 case X86::BI__builtin_ia32_expanddf512_mask:
13047 case X86::BI__builtin_ia32_expanddi128_mask:
13048 case X86::BI__builtin_ia32_expanddi256_mask:
13049 case X86::BI__builtin_ia32_expanddi512_mask:
13050 case X86::BI__builtin_ia32_expandhi128_mask:
13051 case X86::BI__builtin_ia32_expandhi256_mask:
13052 case X86::BI__builtin_ia32_expandhi512_mask:
13053 case X86::BI__builtin_ia32_expandqi128_mask:
13054 case X86::BI__builtin_ia32_expandqi256_mask:
13055 case X86::BI__builtin_ia32_expandqi512_mask:
13056 case X86::BI__builtin_ia32_expandsf128_mask:
13057 case X86::BI__builtin_ia32_expandsf256_mask:
13058 case X86::BI__builtin_ia32_expandsf512_mask:
13059 case X86::BI__builtin_ia32_expandsi128_mask:
13060 case X86::BI__builtin_ia32_expandsi256_mask:
13061 case X86::BI__builtin_ia32_expandsi512_mask: {
13072 ResultElements.reserve(NumElts);
13074 unsigned SourceIdx = 0;
13075 for (
unsigned I = 0; I != NumElts; ++I) {
13077 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
13081 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13083 case X86::BI__builtin_ia32_vpconflictsi_128:
13084 case X86::BI__builtin_ia32_vpconflictsi_256:
13085 case X86::BI__builtin_ia32_vpconflictsi_512:
13086 case X86::BI__builtin_ia32_vpconflictdi_128:
13087 case X86::BI__builtin_ia32_vpconflictdi_256:
13088 case X86::BI__builtin_ia32_vpconflictdi_512: {
13096 ResultElements.reserve(SourceLen);
13099 bool DestUnsigned =
13100 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
13102 for (
unsigned I = 0; I != SourceLen; ++I) {
13105 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
13106 for (
unsigned J = 0; J != I; ++J) {
13108 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
13110 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
13112 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13114 case X86::BI__builtin_ia32_blendpd:
13115 case X86::BI__builtin_ia32_blendpd256:
13116 case X86::BI__builtin_ia32_blendps:
13117 case X86::BI__builtin_ia32_blendps256:
13118 case X86::BI__builtin_ia32_pblendw128:
13119 case X86::BI__builtin_ia32_pblendw256:
13120 case X86::BI__builtin_ia32_pblendd128:
13121 case X86::BI__builtin_ia32_pblendd256: {
13122 APValue SourceF, SourceT, SourceC;
13131 ResultElements.reserve(SourceLen);
13132 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13135 ResultElements.push_back(
C[EltNum % 8] ? T : F);
13138 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13141 case X86::BI__builtin_ia32_psignb128:
13142 case X86::BI__builtin_ia32_psignb256:
13143 case X86::BI__builtin_ia32_psignw128:
13144 case X86::BI__builtin_ia32_psignw256:
13145 case X86::BI__builtin_ia32_psignd128:
13146 case X86::BI__builtin_ia32_psignd256:
13147 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13148 if (BElem.isZero())
13149 return APInt::getZero(AElem.getBitWidth());
13150 if (BElem.isNegative())
13155 case X86::BI__builtin_ia32_blendvpd:
13156 case X86::BI__builtin_ia32_blendvpd256:
13157 case X86::BI__builtin_ia32_blendvps:
13158 case X86::BI__builtin_ia32_blendvps256:
13159 case X86::BI__builtin_ia32_pblendvb128:
13160 case X86::BI__builtin_ia32_pblendvb256: {
13162 APValue SourceF, SourceT, SourceC;
13170 ResultElements.reserve(SourceLen);
13172 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13176 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13177 ResultElements.push_back(M.isNegative() ? T : F);
13180 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13182 case X86::BI__builtin_ia32_selectb_128:
13183 case X86::BI__builtin_ia32_selectb_256:
13184 case X86::BI__builtin_ia32_selectb_512:
13185 case X86::BI__builtin_ia32_selectw_128:
13186 case X86::BI__builtin_ia32_selectw_256:
13187 case X86::BI__builtin_ia32_selectw_512:
13188 case X86::BI__builtin_ia32_selectd_128:
13189 case X86::BI__builtin_ia32_selectd_256:
13190 case X86::BI__builtin_ia32_selectd_512:
13191 case X86::BI__builtin_ia32_selectq_128:
13192 case X86::BI__builtin_ia32_selectq_256:
13193 case X86::BI__builtin_ia32_selectq_512:
13194 case X86::BI__builtin_ia32_selectph_128:
13195 case X86::BI__builtin_ia32_selectph_256:
13196 case X86::BI__builtin_ia32_selectph_512:
13197 case X86::BI__builtin_ia32_selectpbf_128:
13198 case X86::BI__builtin_ia32_selectpbf_256:
13199 case X86::BI__builtin_ia32_selectpbf_512:
13200 case X86::BI__builtin_ia32_selectps_128:
13201 case X86::BI__builtin_ia32_selectps_256:
13202 case X86::BI__builtin_ia32_selectps_512:
13203 case X86::BI__builtin_ia32_selectpd_128:
13204 case X86::BI__builtin_ia32_selectpd_256:
13205 case X86::BI__builtin_ia32_selectpd_512: {
13207 APValue SourceMask, SourceLHS, SourceRHS;
13216 ResultElements.reserve(SourceLen);
13218 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13221 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13224 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13227 case X86::BI__builtin_ia32_cvtsd2ss: {
13240 Elements.push_back(ResultVal);
13243 for (
unsigned I = 1; I < NumEltsA; ++I) {
13249 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13250 APValue VecA, VecB, VecSrc, MaskValue;
13258 unsigned Mask = MaskValue.
getInt().getZExtValue();
13266 Elements.push_back(ResultVal);
13272 for (
unsigned I = 1; I < NumEltsA; ++I) {
13278 case X86::BI__builtin_ia32_cvtpd2ps:
13279 case X86::BI__builtin_ia32_cvtpd2ps256:
13280 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13281 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13284 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13285 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13292 unsigned Mask = 0xFFFFFFFF;
13293 bool NeedsMerge =
false;
13298 Mask = MaskValue.
getInt().getZExtValue();
13299 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13300 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13301 if (!((Mask >> I) & 1)) {
13312 unsigned NumEltsResult =
13316 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13317 if (IsMasked && !((Mask >> I) & 1)) {
13325 if (I >= NumEltsInput) {
13326 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13335 Elements.push_back(ResultVal);
13340 case X86::BI__builtin_ia32_shufps:
13341 case X86::BI__builtin_ia32_shufps256:
13342 case X86::BI__builtin_ia32_shufps512: {
13346 [](
unsigned DstIdx,
13347 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13348 constexpr unsigned LaneBits = 128u;
13349 unsigned NumElemPerLane = LaneBits / 32;
13350 unsigned NumSelectableElems = NumElemPerLane / 2;
13351 unsigned BitsPerElem = 2;
13352 unsigned IndexMask = (1u << BitsPerElem) - 1;
13353 unsigned MaskBits = 8;
13354 unsigned Lane = DstIdx / NumElemPerLane;
13355 unsigned ElemInLane = DstIdx % NumElemPerLane;
13356 unsigned LaneOffset = Lane * NumElemPerLane;
13357 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13358 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13359 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13360 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13365 case X86::BI__builtin_ia32_shufpd:
13366 case X86::BI__builtin_ia32_shufpd256:
13367 case X86::BI__builtin_ia32_shufpd512: {
13371 [](
unsigned DstIdx,
13372 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13373 constexpr unsigned LaneBits = 128u;
13374 unsigned NumElemPerLane = LaneBits / 64;
13375 unsigned NumSelectableElems = NumElemPerLane / 2;
13376 unsigned BitsPerElem = 1;
13377 unsigned IndexMask = (1u << BitsPerElem) - 1;
13378 unsigned MaskBits = 8;
13379 unsigned Lane = DstIdx / NumElemPerLane;
13380 unsigned ElemInLane = DstIdx % NumElemPerLane;
13381 unsigned LaneOffset = Lane * NumElemPerLane;
13382 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13383 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13384 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13385 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13390 case X86::BI__builtin_ia32_insertps128: {
13394 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13396 if ((Mask & (1 << DstIdx)) != 0) {
13401 unsigned SrcElem = (Mask >> 6) & 0x3;
13402 unsigned DstElem = (Mask >> 4) & 0x3;
13403 if (DstIdx == DstElem) {
13405 return {1,
static_cast<int>(SrcElem)};
13408 return {0,
static_cast<int>(DstIdx)};
13414 case X86::BI__builtin_ia32_pshufb128:
13415 case X86::BI__builtin_ia32_pshufb256:
13416 case X86::BI__builtin_ia32_pshufb512: {
13420 [](
unsigned DstIdx,
13421 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13422 uint8_t Ctlb =
static_cast<uint8_t
>(ShuffleMask);
13424 return std::make_pair(0, -1);
13426 unsigned LaneBase = (DstIdx / 16) * 16;
13427 unsigned SrcOffset = Ctlb & 0x0F;
13428 unsigned SrcIdx = LaneBase + SrcOffset;
13429 return std::make_pair(0,
static_cast<int>(SrcIdx));
13435 case X86::BI__builtin_ia32_pshuflw:
13436 case X86::BI__builtin_ia32_pshuflw256:
13437 case X86::BI__builtin_ia32_pshuflw512: {
13441 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13442 constexpr unsigned LaneBits = 128u;
13443 constexpr unsigned ElemBits = 16u;
13444 constexpr unsigned LaneElts = LaneBits / ElemBits;
13445 constexpr unsigned HalfSize = 4;
13446 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13447 unsigned LaneIdx = DstIdx % LaneElts;
13448 if (LaneIdx < HalfSize) {
13449 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13450 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13452 return std::make_pair(0,
static_cast<int>(DstIdx));
13458 case X86::BI__builtin_ia32_pshufhw:
13459 case X86::BI__builtin_ia32_pshufhw256:
13460 case X86::BI__builtin_ia32_pshufhw512: {
13464 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13465 constexpr unsigned LaneBits = 128u;
13466 constexpr unsigned ElemBits = 16u;
13467 constexpr unsigned LaneElts = LaneBits / ElemBits;
13468 constexpr unsigned HalfSize = 4;
13469 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13470 unsigned LaneIdx = DstIdx % LaneElts;
13471 if (LaneIdx >= HalfSize) {
13472 unsigned Rel = LaneIdx - HalfSize;
13473 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13474 return std::make_pair(
13475 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13477 return std::make_pair(0,
static_cast<int>(DstIdx));
13483 case X86::BI__builtin_ia32_pshufd:
13484 case X86::BI__builtin_ia32_pshufd256:
13485 case X86::BI__builtin_ia32_pshufd512:
13486 case X86::BI__builtin_ia32_vpermilps:
13487 case X86::BI__builtin_ia32_vpermilps256:
13488 case X86::BI__builtin_ia32_vpermilps512: {
13492 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13493 constexpr unsigned LaneBits = 128u;
13494 constexpr unsigned ElemBits = 32u;
13495 constexpr unsigned LaneElts = LaneBits / ElemBits;
13496 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13497 unsigned LaneIdx = DstIdx % LaneElts;
13498 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13499 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13505 case X86::BI__builtin_ia32_vpermilvarpd:
13506 case X86::BI__builtin_ia32_vpermilvarpd256:
13507 case X86::BI__builtin_ia32_vpermilvarpd512: {
13511 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13512 unsigned NumElemPerLane = 2;
13513 unsigned Lane = DstIdx / NumElemPerLane;
13514 unsigned Offset = Mask & 0b10 ? 1 : 0;
13515 return std::make_pair(
13516 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13522 case X86::BI__builtin_ia32_vpermilpd:
13523 case X86::BI__builtin_ia32_vpermilpd256:
13524 case X86::BI__builtin_ia32_vpermilpd512: {
13527 unsigned NumElemPerLane = 2;
13528 unsigned BitsPerElem = 1;
13529 unsigned MaskBits = 8;
13530 unsigned IndexMask = 0x1;
13531 unsigned Lane = DstIdx / NumElemPerLane;
13532 unsigned LaneOffset = Lane * NumElemPerLane;
13533 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13534 unsigned Index = (Control >> BitIndex) & IndexMask;
13535 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
13541 case X86::BI__builtin_ia32_permdf256:
13542 case X86::BI__builtin_ia32_permdi256: {
13547 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
13548 return std::make_pair(0,
static_cast<int>(Index));
13554 case X86::BI__builtin_ia32_vpermilvarps:
13555 case X86::BI__builtin_ia32_vpermilvarps256:
13556 case X86::BI__builtin_ia32_vpermilvarps512: {
13560 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13561 unsigned NumElemPerLane = 4;
13562 unsigned Lane = DstIdx / NumElemPerLane;
13563 unsigned Offset = Mask & 0b11;
13564 return std::make_pair(
13565 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13571 case X86::BI__builtin_ia32_vpmultishiftqb128:
13572 case X86::BI__builtin_ia32_vpmultishiftqb256:
13573 case X86::BI__builtin_ia32_vpmultishiftqb512: {
13581 unsigned NumBytesInQWord = 8;
13582 unsigned NumBitsInByte = 8;
13584 unsigned NumQWords = NumBytes / NumBytesInQWord;
13586 Result.reserve(NumBytes);
13588 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
13589 APInt BQWord(64, 0);
13590 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13591 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13593 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
13596 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13597 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13601 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
13602 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
13610 case X86::BI__builtin_ia32_phminposuw128: {
13617 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
13619 APInt MinIndex(ElemBitWidth, 0);
13621 for (
unsigned I = 1; I != SourceLen; ++I) {
13623 if (MinVal.ugt(Val)) {
13632 ->isUnsignedIntegerOrEnumerationType();
13635 Result.reserve(SourceLen);
13637 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
13638 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
13644 case X86::BI__builtin_ia32_psraq128:
13645 case X86::BI__builtin_ia32_psraq256:
13646 case X86::BI__builtin_ia32_psraq512:
13647 case X86::BI__builtin_ia32_psrad128:
13648 case X86::BI__builtin_ia32_psrad256:
13649 case X86::BI__builtin_ia32_psrad512:
13650 case X86::BI__builtin_ia32_psraw128:
13651 case X86::BI__builtin_ia32_psraw256:
13652 case X86::BI__builtin_ia32_psraw512: {
13656 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
13657 [](
const APInt &Elt,
unsigned Width) {
13658 return Elt.ashr(Width - 1);
13664 case X86::BI__builtin_ia32_psllq128:
13665 case X86::BI__builtin_ia32_psllq256:
13666 case X86::BI__builtin_ia32_psllq512:
13667 case X86::BI__builtin_ia32_pslld128:
13668 case X86::BI__builtin_ia32_pslld256:
13669 case X86::BI__builtin_ia32_pslld512:
13670 case X86::BI__builtin_ia32_psllw128:
13671 case X86::BI__builtin_ia32_psllw256:
13672 case X86::BI__builtin_ia32_psllw512: {
13676 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
13677 [](
const APInt &Elt,
unsigned Width) {
13678 return APInt::getZero(Width);
13684 case X86::BI__builtin_ia32_psrlq128:
13685 case X86::BI__builtin_ia32_psrlq256:
13686 case X86::BI__builtin_ia32_psrlq512:
13687 case X86::BI__builtin_ia32_psrld128:
13688 case X86::BI__builtin_ia32_psrld256:
13689 case X86::BI__builtin_ia32_psrld512:
13690 case X86::BI__builtin_ia32_psrlw128:
13691 case X86::BI__builtin_ia32_psrlw256:
13692 case X86::BI__builtin_ia32_psrlw512: {
13696 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
13697 [](
const APInt &Elt,
unsigned Width) {
13698 return APInt::getZero(Width);
13704 case X86::BI__builtin_ia32_pternlogd128_mask:
13705 case X86::BI__builtin_ia32_pternlogd256_mask:
13706 case X86::BI__builtin_ia32_pternlogd512_mask:
13707 case X86::BI__builtin_ia32_pternlogq128_mask:
13708 case X86::BI__builtin_ia32_pternlogq256_mask:
13709 case X86::BI__builtin_ia32_pternlogq512_mask: {
13710 APValue AValue, BValue, CValue, ImmValue, UValue;
13718 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13724 ResultElements.reserve(ResultLen);
13726 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13732 unsigned BitWidth = ALane.getBitWidth();
13733 APInt ResLane(BitWidth, 0);
13735 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13736 unsigned ABit = ALane[Bit];
13737 unsigned BBit = BLane[Bit];
13738 unsigned CBit = CLane[Bit];
13740 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13741 ResLane.setBitVal(Bit, Imm[Idx]);
13743 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13745 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
13748 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13750 case X86::BI__builtin_ia32_pternlogd128_maskz:
13751 case X86::BI__builtin_ia32_pternlogd256_maskz:
13752 case X86::BI__builtin_ia32_pternlogd512_maskz:
13753 case X86::BI__builtin_ia32_pternlogq128_maskz:
13754 case X86::BI__builtin_ia32_pternlogq256_maskz:
13755 case X86::BI__builtin_ia32_pternlogq512_maskz: {
13756 APValue AValue, BValue, CValue, ImmValue, UValue;
13764 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13770 ResultElements.reserve(ResultLen);
13772 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13777 unsigned BitWidth = ALane.getBitWidth();
13778 APInt ResLane(BitWidth, 0);
13781 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13782 unsigned ABit = ALane[Bit];
13783 unsigned BBit = BLane[Bit];
13784 unsigned CBit = CLane[Bit];
13786 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13787 ResLane.setBitVal(Bit, Imm[Idx]);
13790 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13792 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13795 case Builtin::BI__builtin_elementwise_clzg:
13796 case Builtin::BI__builtin_elementwise_ctzg: {
13798 std::optional<APValue> Fallback;
13805 Fallback = FallbackTmp;
13808 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13811 ResultElements.reserve(SourceLen);
13813 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13818 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13820 Builtin::BI__builtin_elementwise_ctzg);
13823 ResultElements.push_back(Fallback->getVectorElt(EltNum));
13827 case Builtin::BI__builtin_elementwise_clzg:
13828 ResultElements.push_back(
APValue(
13829 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
13832 case Builtin::BI__builtin_elementwise_ctzg:
13833 ResultElements.push_back(
APValue(
13834 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
13840 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13843 case Builtin::BI__builtin_elementwise_fma: {
13844 APValue SourceX, SourceY, SourceZ;
13852 ResultElements.reserve(SourceLen);
13854 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13859 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
13862 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13865 case clang::X86::BI__builtin_ia32_phaddw128:
13866 case clang::X86::BI__builtin_ia32_phaddw256:
13867 case clang::X86::BI__builtin_ia32_phaddd128:
13868 case clang::X86::BI__builtin_ia32_phaddd256:
13869 case clang::X86::BI__builtin_ia32_phaddsw128:
13870 case clang::X86::BI__builtin_ia32_phaddsw256:
13872 case clang::X86::BI__builtin_ia32_phsubw128:
13873 case clang::X86::BI__builtin_ia32_phsubw256:
13874 case clang::X86::BI__builtin_ia32_phsubd128:
13875 case clang::X86::BI__builtin_ia32_phsubd256:
13876 case clang::X86::BI__builtin_ia32_phsubsw128:
13877 case clang::X86::BI__builtin_ia32_phsubsw256: {
13878 APValue SourceLHS, SourceRHS;
13882 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13886 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
13887 unsigned EltsPerLane = 128 / EltBits;
13889 ResultElements.reserve(NumElts);
13891 for (
unsigned LaneStart = 0; LaneStart != NumElts;
13892 LaneStart += EltsPerLane) {
13893 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13897 case clang::X86::BI__builtin_ia32_phaddw128:
13898 case clang::X86::BI__builtin_ia32_phaddw256:
13899 case clang::X86::BI__builtin_ia32_phaddd128:
13900 case clang::X86::BI__builtin_ia32_phaddd256: {
13901 APSInt Res(LHSA + LHSB, DestUnsigned);
13902 ResultElements.push_back(
APValue(Res));
13905 case clang::X86::BI__builtin_ia32_phaddsw128:
13906 case clang::X86::BI__builtin_ia32_phaddsw256: {
13907 APSInt Res(LHSA.sadd_sat(LHSB));
13908 ResultElements.push_back(
APValue(Res));
13911 case clang::X86::BI__builtin_ia32_phsubw128:
13912 case clang::X86::BI__builtin_ia32_phsubw256:
13913 case clang::X86::BI__builtin_ia32_phsubd128:
13914 case clang::X86::BI__builtin_ia32_phsubd256: {
13915 APSInt Res(LHSA - LHSB, DestUnsigned);
13916 ResultElements.push_back(
APValue(Res));
13919 case clang::X86::BI__builtin_ia32_phsubsw128:
13920 case clang::X86::BI__builtin_ia32_phsubsw256: {
13921 APSInt Res(LHSA.ssub_sat(LHSB));
13922 ResultElements.push_back(
APValue(Res));
13927 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13931 case clang::X86::BI__builtin_ia32_phaddw128:
13932 case clang::X86::BI__builtin_ia32_phaddw256:
13933 case clang::X86::BI__builtin_ia32_phaddd128:
13934 case clang::X86::BI__builtin_ia32_phaddd256: {
13935 APSInt Res(RHSA + RHSB, DestUnsigned);
13936 ResultElements.push_back(
APValue(Res));
13939 case clang::X86::BI__builtin_ia32_phaddsw128:
13940 case clang::X86::BI__builtin_ia32_phaddsw256: {
13941 APSInt Res(RHSA.sadd_sat(RHSB));
13942 ResultElements.push_back(
APValue(Res));
13945 case clang::X86::BI__builtin_ia32_phsubw128:
13946 case clang::X86::BI__builtin_ia32_phsubw256:
13947 case clang::X86::BI__builtin_ia32_phsubd128:
13948 case clang::X86::BI__builtin_ia32_phsubd256: {
13949 APSInt Res(RHSA - RHSB, DestUnsigned);
13950 ResultElements.push_back(
APValue(Res));
13953 case clang::X86::BI__builtin_ia32_phsubsw128:
13954 case clang::X86::BI__builtin_ia32_phsubsw256: {
13955 APSInt Res(RHSA.ssub_sat(RHSB));
13956 ResultElements.push_back(
APValue(Res));
13962 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13964 case clang::X86::BI__builtin_ia32_haddpd:
13965 case clang::X86::BI__builtin_ia32_haddps:
13966 case clang::X86::BI__builtin_ia32_haddps256:
13967 case clang::X86::BI__builtin_ia32_haddpd256:
13968 case clang::X86::BI__builtin_ia32_hsubpd:
13969 case clang::X86::BI__builtin_ia32_hsubps:
13970 case clang::X86::BI__builtin_ia32_hsubps256:
13971 case clang::X86::BI__builtin_ia32_hsubpd256: {
13972 APValue SourceLHS, SourceRHS;
13978 ResultElements.reserve(NumElts);
13980 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13981 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
13982 unsigned NumLanes = NumElts * EltBits / 128;
13983 unsigned NumElemsPerLane = NumElts / NumLanes;
13984 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
13986 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
13987 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13991 case clang::X86::BI__builtin_ia32_haddpd:
13992 case clang::X86::BI__builtin_ia32_haddps:
13993 case clang::X86::BI__builtin_ia32_haddps256:
13994 case clang::X86::BI__builtin_ia32_haddpd256:
13995 LHSA.add(LHSB, RM);
13997 case clang::X86::BI__builtin_ia32_hsubpd:
13998 case clang::X86::BI__builtin_ia32_hsubps:
13999 case clang::X86::BI__builtin_ia32_hsubps256:
14000 case clang::X86::BI__builtin_ia32_hsubpd256:
14001 LHSA.subtract(LHSB, RM);
14004 ResultElements.push_back(
APValue(LHSA));
14006 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14010 case clang::X86::BI__builtin_ia32_haddpd:
14011 case clang::X86::BI__builtin_ia32_haddps:
14012 case clang::X86::BI__builtin_ia32_haddps256:
14013 case clang::X86::BI__builtin_ia32_haddpd256:
14014 RHSA.add(RHSB, RM);
14016 case clang::X86::BI__builtin_ia32_hsubpd:
14017 case clang::X86::BI__builtin_ia32_hsubps:
14018 case clang::X86::BI__builtin_ia32_hsubps256:
14019 case clang::X86::BI__builtin_ia32_hsubpd256:
14020 RHSA.subtract(RHSB, RM);
14023 ResultElements.push_back(
APValue(RHSA));
14026 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14028 case clang::X86::BI__builtin_ia32_addsubpd:
14029 case clang::X86::BI__builtin_ia32_addsubps:
14030 case clang::X86::BI__builtin_ia32_addsubpd256:
14031 case clang::X86::BI__builtin_ia32_addsubps256: {
14034 APValue SourceLHS, SourceRHS;
14040 ResultElements.reserve(NumElems);
14043 for (
unsigned I = 0; I != NumElems; ++I) {
14048 LHS.subtract(RHS, RM);
14053 ResultElements.push_back(
APValue(LHS));
14055 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14057 case clang::X86::BI__builtin_ia32_pclmulqdq128:
14058 case clang::X86::BI__builtin_ia32_pclmulqdq256:
14059 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
14063 APValue SourceLHS, SourceRHS;
14073 bool SelectUpperA = (Imm8 & 0x01) != 0;
14074 bool SelectUpperB = (Imm8 & 0x10) != 0;
14078 ResultElements.reserve(NumElems);
14079 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14083 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
14092 APInt A = SelectUpperA ? A1 : A0;
14093 APInt B = SelectUpperB ? B1 : B0;
14096 APInt A128 = A.zext(128);
14097 APInt B128 = B.zext(128);
14100 APInt Result = llvm::APIntOps::clmul(A128, B128);
14103 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
14104 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
14106 ResultElements.push_back(
APValue(ResultLow));
14107 ResultElements.push_back(
APValue(ResultHigh));
14110 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14112 case Builtin::BI__builtin_elementwise_clmul:
14113 return EvaluateBinOpExpr(llvm::APIntOps::clmul);
14114 case Builtin::BI__builtin_elementwise_fshl:
14115 case Builtin::BI__builtin_elementwise_fshr: {
14116 APValue SourceHi, SourceLo, SourceShift;
14122 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14128 ResultElements.reserve(SourceLen);
14129 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14134 case Builtin::BI__builtin_elementwise_fshl:
14135 ResultElements.push_back(
APValue(
14136 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14138 case Builtin::BI__builtin_elementwise_fshr:
14139 ResultElements.push_back(
APValue(
14140 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14145 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14148 case X86::BI__builtin_ia32_shuf_f32x4_256:
14149 case X86::BI__builtin_ia32_shuf_i32x4_256:
14150 case X86::BI__builtin_ia32_shuf_f64x2_256:
14151 case X86::BI__builtin_ia32_shuf_i64x2_256:
14152 case X86::BI__builtin_ia32_shuf_f32x4:
14153 case X86::BI__builtin_ia32_shuf_i32x4:
14154 case X86::BI__builtin_ia32_shuf_f64x2:
14155 case X86::BI__builtin_ia32_shuf_i64x2: {
14169 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14170 unsigned LaneBits = 128u;
14171 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14172 unsigned NumElemsPerLane = LaneBits / ElemBits;
14176 ResultElements.reserve(DstLen);
14181 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14182 -> std::pair<unsigned, int> {
14184 unsigned BitsPerElem = NumLanes / 2;
14185 unsigned IndexMask = (1u << BitsPerElem) - 1;
14186 unsigned Lane = DstIdx / NumElemsPerLane;
14187 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14188 unsigned BitIdx = BitsPerElem * Lane;
14189 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14190 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14191 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14192 return {SrcIdx, IdxToPick};
14198 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14199 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14200 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14201 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14202 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14203 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14215 bool IsInverse =
false;
14217 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14218 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14219 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14224 unsigned NumBitsInByte = 8;
14225 unsigned NumBytesInQWord = 8;
14226 unsigned NumBitsInQWord = 64;
14228 unsigned NumQWords = NumBytes / NumBytesInQWord;
14230 Result.reserve(NumBytes);
14233 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14235 APInt XQWord(NumBitsInQWord, 0);
14236 APInt AQWord(NumBitsInQWord, 0);
14237 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14238 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14239 APInt XByte =
X.getVectorElt(Idx).getInt();
14241 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14242 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14245 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14247 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14256 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14257 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14258 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14269 Result.reserve(NumBytes);
14271 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14281 case X86::BI__builtin_ia32_insertf32x4_256:
14282 case X86::BI__builtin_ia32_inserti32x4_256:
14283 case X86::BI__builtin_ia32_insertf64x2_256:
14284 case X86::BI__builtin_ia32_inserti64x2_256:
14285 case X86::BI__builtin_ia32_insertf32x4:
14286 case X86::BI__builtin_ia32_inserti32x4:
14287 case X86::BI__builtin_ia32_insertf64x2_512:
14288 case X86::BI__builtin_ia32_inserti64x2_512:
14289 case X86::BI__builtin_ia32_insertf32x8:
14290 case X86::BI__builtin_ia32_inserti32x8:
14291 case X86::BI__builtin_ia32_insertf64x4:
14292 case X86::BI__builtin_ia32_inserti64x4:
14293 case X86::BI__builtin_ia32_vinsertf128_ps256:
14294 case X86::BI__builtin_ia32_vinsertf128_pd256:
14295 case X86::BI__builtin_ia32_vinsertf128_si256:
14296 case X86::BI__builtin_ia32_insert128i256: {
14297 APValue SourceDst, SourceSub;
14309 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14310 unsigned NumLanes = DstLen / SubLen;
14311 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14314 ResultElements.reserve(DstLen);
14316 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14317 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14318 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14320 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14323 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14326 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14327 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14328 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14329 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14330 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14331 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14332 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14333 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14334 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14342 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14343 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
14345 Scalar.setIsUnsigned(ElemUnsigned);
14351 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14354 Elems.reserve(NumElems);
14355 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14356 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14361 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14362 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14363 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14367 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14368 unsigned LaneBase = (DstIdx / 16) * 16;
14369 unsigned LaneIdx = DstIdx % 16;
14370 if (LaneIdx < Shift)
14371 return std::make_pair(0, -1);
14373 return std::make_pair(
14374 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14380 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14381 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14382 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14386 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14387 unsigned LaneBase = (DstIdx / 16) * 16;
14388 unsigned LaneIdx = DstIdx % 16;
14389 if (LaneIdx + Shift < 16)
14390 return std::make_pair(
14391 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14393 return std::make_pair(0, -1);
14399 case X86::BI__builtin_ia32_palignr128:
14400 case X86::BI__builtin_ia32_palignr256:
14401 case X86::BI__builtin_ia32_palignr512: {
14405 unsigned VecIdx = 1;
14408 int Lane = DstIdx / 16;
14409 int Offset = DstIdx % 16;
14412 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14413 if (ShiftedIdx < 16) {
14414 ElemIdx = ShiftedIdx + (Lane * 16);
14415 }
else if (ShiftedIdx < 32) {
14417 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14420 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14425 case X86::BI__builtin_ia32_alignd128:
14426 case X86::BI__builtin_ia32_alignd256:
14427 case X86::BI__builtin_ia32_alignd512:
14428 case X86::BI__builtin_ia32_alignq128:
14429 case X86::BI__builtin_ia32_alignq256:
14430 case X86::BI__builtin_ia32_alignq512: {
14432 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14434 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14435 unsigned Imm =
Shift & 0xFF;
14436 unsigned EffectiveShift = Imm & (NumElems - 1);
14437 unsigned SourcePos = DstIdx + EffectiveShift;
14438 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14439 unsigned ElemIdx = SourcePos & (NumElems - 1);
14441 return std::pair<unsigned, int>{
14442 VecIdx,
static_cast<int>(ElemIdx)};
14447 case X86::BI__builtin_ia32_permvarsi256:
14448 case X86::BI__builtin_ia32_permvarsf256:
14449 case X86::BI__builtin_ia32_permvardf512:
14450 case X86::BI__builtin_ia32_permvardi512:
14451 case X86::BI__builtin_ia32_permvarhi128: {
14454 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14455 int Offset = ShuffleMask & 0x7;
14456 return std::pair<unsigned, int>{0, Offset};
14461 case X86::BI__builtin_ia32_permvarqi128:
14462 case X86::BI__builtin_ia32_permvarhi256:
14463 case X86::BI__builtin_ia32_permvarsi512:
14464 case X86::BI__builtin_ia32_permvarsf512: {
14467 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14468 int Offset = ShuffleMask & 0xF;
14469 return std::pair<unsigned, int>{0, Offset};
14474 case X86::BI__builtin_ia32_permvardi256:
14475 case X86::BI__builtin_ia32_permvardf256: {
14478 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14479 int Offset = ShuffleMask & 0x3;
14480 return std::pair<unsigned, int>{0, Offset};
14485 case X86::BI__builtin_ia32_permvarqi256:
14486 case X86::BI__builtin_ia32_permvarhi512: {
14489 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14490 int Offset = ShuffleMask & 0x1F;
14491 return std::pair<unsigned, int>{0, Offset};
14496 case X86::BI__builtin_ia32_permvarqi512: {
14499 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14500 int Offset = ShuffleMask & 0x3F;
14501 return std::pair<unsigned, int>{0, Offset};
14506 case X86::BI__builtin_ia32_vpermi2varq128:
14507 case X86::BI__builtin_ia32_vpermi2varpd128: {
14510 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14511 int Offset = ShuffleMask & 0x1;
14512 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
14513 return std::pair<unsigned, int>{SrcIdx, Offset};
14518 case X86::BI__builtin_ia32_vpermi2vard128:
14519 case X86::BI__builtin_ia32_vpermi2varps128:
14520 case X86::BI__builtin_ia32_vpermi2varq256:
14521 case X86::BI__builtin_ia32_vpermi2varpd256: {
14524 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14525 int Offset = ShuffleMask & 0x3;
14526 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
14527 return std::pair<unsigned, int>{SrcIdx, Offset};
14532 case X86::BI__builtin_ia32_vpermi2varhi128:
14533 case X86::BI__builtin_ia32_vpermi2vard256:
14534 case X86::BI__builtin_ia32_vpermi2varps256:
14535 case X86::BI__builtin_ia32_vpermi2varq512:
14536 case X86::BI__builtin_ia32_vpermi2varpd512: {
14539 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14540 int Offset = ShuffleMask & 0x7;
14541 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
14542 return std::pair<unsigned, int>{SrcIdx, Offset};
14547 case X86::BI__builtin_ia32_vpermi2varqi128:
14548 case X86::BI__builtin_ia32_vpermi2varhi256:
14549 case X86::BI__builtin_ia32_vpermi2vard512:
14550 case X86::BI__builtin_ia32_vpermi2varps512: {
14553 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14554 int Offset = ShuffleMask & 0xF;
14555 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
14556 return std::pair<unsigned, int>{SrcIdx, Offset};
14561 case X86::BI__builtin_ia32_vpermi2varqi256:
14562 case X86::BI__builtin_ia32_vpermi2varhi512: {
14565 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14566 int Offset = ShuffleMask & 0x1F;
14567 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
14568 return std::pair<unsigned, int>{SrcIdx, Offset};
14573 case X86::BI__builtin_ia32_vpermi2varqi512: {
14576 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14577 int Offset = ShuffleMask & 0x3F;
14578 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
14579 return std::pair<unsigned, int>{SrcIdx, Offset};
14585 case clang::X86::BI__builtin_ia32_minps:
14586 case clang::X86::BI__builtin_ia32_minpd:
14587 case clang::X86::BI__builtin_ia32_minps256:
14588 case clang::X86::BI__builtin_ia32_minpd256:
14589 case clang::X86::BI__builtin_ia32_minps512:
14590 case clang::X86::BI__builtin_ia32_minpd512:
14591 case clang::X86::BI__builtin_ia32_minph128:
14592 case clang::X86::BI__builtin_ia32_minph256:
14593 case clang::X86::BI__builtin_ia32_minph512:
14594 return EvaluateFpBinOpExpr(
14595 [](
const APFloat &A,
const APFloat &B,
14596 std::optional<APSInt>) -> std::optional<APFloat> {
14597 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14598 B.isInfinity() || B.isDenormal())
14599 return std::nullopt;
14600 if (A.isZero() && B.isZero())
14602 return llvm::minimum(A, B);
14605 case clang::X86::BI__builtin_ia32_minss:
14606 case clang::X86::BI__builtin_ia32_minsd:
14607 return EvaluateFpBinOpExpr(
14608 [](
const APFloat &A,
const APFloat &B,
14609 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14614 case clang::X86::BI__builtin_ia32_minsd_round_mask:
14615 case clang::X86::BI__builtin_ia32_minss_round_mask:
14616 case clang::X86::BI__builtin_ia32_minsh_round_mask:
14617 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
14618 case clang::X86::BI__builtin_ia32_maxss_round_mask:
14619 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
14622 clang::X86::BI__builtin_ia32_minsd_round_mask ||
14624 clang::X86::BI__builtin_ia32_minss_round_mask ||
14626 return EvaluateScalarFpRoundMaskBinOp(
14627 [IsMin](
const APFloat &A,
const APFloat &B,
14628 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14633 case clang::X86::BI__builtin_ia32_maxps:
14634 case clang::X86::BI__builtin_ia32_maxpd:
14635 case clang::X86::BI__builtin_ia32_maxps256:
14636 case clang::X86::BI__builtin_ia32_maxpd256:
14637 case clang::X86::BI__builtin_ia32_maxps512:
14638 case clang::X86::BI__builtin_ia32_maxpd512:
14639 case clang::X86::BI__builtin_ia32_maxph128:
14640 case clang::X86::BI__builtin_ia32_maxph256:
14641 case clang::X86::BI__builtin_ia32_maxph512:
14642 return EvaluateFpBinOpExpr(
14643 [](
const APFloat &A,
const APFloat &B,
14644 std::optional<APSInt>) -> std::optional<APFloat> {
14645 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14646 B.isInfinity() || B.isDenormal())
14647 return std::nullopt;
14648 if (A.isZero() && B.isZero())
14650 return llvm::maximum(A, B);
14653 case clang::X86::BI__builtin_ia32_maxss:
14654 case clang::X86::BI__builtin_ia32_maxsd:
14655 return EvaluateFpBinOpExpr(
14656 [](
const APFloat &A,
const APFloat &B,
14657 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14662 case clang::X86::BI__builtin_ia32_vcvtps2ph:
14663 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
14673 unsigned SrcNumElems = SrcVTy->getNumElements();
14675 unsigned DstNumElems = DstVTy->getNumElements();
14676 QualType DstElemTy = DstVTy->getElementType();
14678 const llvm::fltSemantics &HalfSem =
14679 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
14681 int ImmVal = Imm.getZExtValue();
14682 bool UseMXCSR = (ImmVal & 4) != 0;
14683 bool IsFPConstrained =
14686 llvm::RoundingMode RM;
14688 switch (ImmVal & 3) {
14690 RM = llvm::RoundingMode::NearestTiesToEven;
14693 RM = llvm::RoundingMode::TowardNegative;
14696 RM = llvm::RoundingMode::TowardPositive;
14699 RM = llvm::RoundingMode::TowardZero;
14702 llvm_unreachable(
"Invalid immediate rounding mode");
14705 RM = llvm::RoundingMode::NearestTiesToEven;
14709 ResultElements.reserve(DstNumElems);
14711 for (
unsigned I = 0; I < SrcNumElems; ++I) {
14715 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
14717 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
14718 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
14722 APSInt DstInt(SrcVal.bitcastToAPInt(),
14724 ResultElements.push_back(
APValue(DstInt));
14727 if (DstNumElems > SrcNumElems) {
14728 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
14729 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
14734 return Success(ResultElements, E);
14736 case X86::BI__builtin_ia32_vperm2f128_pd256:
14737 case X86::BI__builtin_ia32_vperm2f128_ps256:
14738 case X86::BI__builtin_ia32_vperm2f128_si256:
14739 case X86::BI__builtin_ia32_permti256: {
14740 unsigned NumElements =
14742 unsigned PreservedBitsCnt = NumElements >> 2;
14746 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
14747 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
14748 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
14750 if (ControlBits & 0b1000)
14751 return std::make_pair(0u, -1);
14753 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
14754 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
14755 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
14756 (DstIdx & PreservedBitsMask);
14757 return std::make_pair(SrcVecIdx, SrcIdx);
14765bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
14771 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
14772 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
14778 ResultElements.reserve(SourceLen);
14779 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14784 ResultElements.push_back(std::move(Elt));
14787 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14792 APValue const &VecVal2,
unsigned EltNum,
14794 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
14795 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
14798 int64_t
index = IndexVal.getExtValue();
14805 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
14811 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
14812 llvm_unreachable(
"Out of bounds shuffle index");
14814 if (
index >= TotalElementsInInputVector1)
14821bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
14826 const Expr *Vec1 = E->
getExpr(0);
14830 const Expr *Vec2 = E->
getExpr(1);
14834 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
14840 ResultElements.reserve(TotalElementsInOutputVector);
14841 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
14845 ResultElements.push_back(std::move(Elt));
14848 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14856class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
14863 bool Success(ArrayRef<APValue> M,
const Expr *E) {
14865 assert(M.size() == CMTy->getNumElementsFlattened());
14867 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
14871 assert(M.
isMatrix() &&
"expected matrix");
14876 bool VisitCastExpr(
const CastExpr *E);
14877 bool VisitInitListExpr(
const InitListExpr *E);
14883 "not a matrix prvalue");
14884 return MatrixExprEvaluator(Info,
Result).Visit(E);
14887bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14888 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
14889 unsigned NumRows = MT->getNumRows();
14890 unsigned NumCols = MT->getNumColumns();
14891 unsigned NElts = NumRows * NumCols;
14892 QualType EltTy = MT->getElementType();
14896 case CK_HLSLAggregateSplatCast: {
14911 case CK_HLSLElementwiseCast: {
14924 return Success(ResultEls, E);
14927 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14931bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
14932 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
14933 QualType EltTy = MT->getElementType();
14935 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
14936 "Expected number of elements in initializer list to match the number "
14937 "of matrix elements");
14940 Elements.reserve(MT->getNumElementsFlattened());
14945 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
14946 if (EltTy->isIntegerType()) {
14947 llvm::APSInt IntVal;
14950 Elements.push_back(
APValue(IntVal));
14952 llvm::APFloat FloatVal(0.0);
14955 Elements.push_back(
APValue(FloatVal));
14967 class ArrayExprEvaluator
14968 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
14969 const LValue &
This;
14973 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
14977 assert(
V.isArray() &&
"expected array");
14982 bool ZeroInitialization(
const Expr *E) {
14983 const ConstantArrayType *CAT =
14984 Info.Ctx.getAsConstantArrayType(E->
getType());
14998 if (!
Result.hasArrayFiller())
15002 LValue Subobject =
This;
15003 Subobject.addArray(Info, E, CAT);
15008 bool VisitCallExpr(
const CallExpr *E) {
15009 return handleCallExpr(E,
Result, &This);
15011 bool VisitCastExpr(
const CastExpr *E);
15012 bool VisitInitListExpr(
const InitListExpr *E,
15013 QualType AllocType = QualType());
15014 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
15015 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
15016 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
15017 const LValue &Subobject,
15019 bool VisitStringLiteral(
const StringLiteral *E,
15020 QualType AllocType = QualType()) {
15024 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
15025 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
15026 ArrayRef<Expr *> Args,
15027 const Expr *ArrayFiller,
15028 QualType AllocType = QualType());
15036 "not an array prvalue");
15037 return ArrayExprEvaluator(Info,
This,
Result).Visit(E);
15045 "not an array prvalue");
15046 return ArrayExprEvaluator(Info,
This,
Result)
15047 .VisitInitListExpr(ILE, AllocType);
15056 "not an array prvalue");
15057 return ArrayExprEvaluator(Info,
This,
Result)
15058 .VisitCXXConstructExpr(CCE,
This, &
Result, AllocType);
15067 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
15068 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
15073 if (ILE->hasArrayFiller() &&
15082bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15087 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15088 case CK_HLSLAggregateSplatCast: {
15108 case CK_HLSLElementwiseCast: {
15125bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15126 QualType AllocType) {
15127 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15140 return VisitStringLiteral(SL, AllocType);
15145 "transparent array list initialization is not string literal init?");
15151bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15153 QualType AllocType) {
15154 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15159 unsigned NumEltsToInit = Args.size();
15164 if (NumEltsToInit != NumElts &&
15166 NumEltsToInit = NumElts;
15169 for (
auto *
Init : Args) {
15170 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15171 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15174 if (NumEltsToInit > NumElts)
15175 NumEltsToInit = NumElts;
15179 if (
Result.hasValue() && NumEltsToInit <
Result.getArrayInitializedElts())
15180 NumEltsToInit =
Result.getArrayInitializedElts();
15183 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15184 << NumEltsToInit <<
".\n");
15186 if (!
Result.hasValue()) {
15187 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15188 }
else if (
Result.getArrayInitializedElts() != NumEltsToInit) {
15199 APValue NewResult =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15201 unsigned NumOldElts =
Result.getArrayInitializedElts();
15202 for (
unsigned I = 0; I < NumOldElts; ++I) {
15204 std::move(
Result.getArrayInitializedElt(I));
15207 for (
unsigned I =
Result.getArrayInitializedElts(); I < NumEltsToInit; ++I)
15211 Result = std::move(NewResult);
15214 LValue Subobject =
This;
15215 Subobject.addArray(Info, ExprToVisit, CAT);
15216 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15217 if (
Init->isValueDependent())
15226 Subobject,
Init) ||
15229 if (!Info.noteFailure())
15235 unsigned ArrayIndex = 0;
15238 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
15239 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
15240 if (ArrayIndex >= NumEltsToInit)
15242 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
15243 StringLiteral *SL = EmbedS->getDataStringLiteral();
15244 for (
unsigned I = EmbedS->getStartingElementPos(),
15245 N = EmbedS->getDataElementCount();
15246 I != EmbedS->getStartingElementPos() + N; ++I) {
15252 const FPOptions FPO =
15253 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
15258 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
15263 if (!Eval(
Init, ArrayIndex))
15269 if (!
Result.hasArrayFiller())
15274 assert(ArrayFiller &&
"no array filler for incomplete init list");
15280bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
15283 !
Evaluate(Info.CurrentCall->createTemporary(
15286 ScopeKind::FullExpression, CommonLV),
15293 Result =
APValue(APValue::UninitArray(), Elements, Elements);
15295 LValue Subobject =
This;
15296 Subobject.addArray(Info, E, CAT);
15299 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
15308 FullExpressionRAII Scope(Info);
15314 if (!Info.noteFailure())
15326bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
15327 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
15330bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
15331 const LValue &Subobject,
15334 bool HadZeroInit =
Value->hasValue();
15336 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
15341 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
15344 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
15345 if (FinalSize == 0)
15351 LValue ArrayElt = Subobject;
15352 ArrayElt.addArray(Info, E, CAT);
15358 for (
const unsigned N : {1u, FinalSize}) {
15359 unsigned OldElts =
Value->getArrayInitializedElts();
15364 APValue NewValue(APValue::UninitArray(), N, FinalSize);
15365 for (
unsigned I = 0; I < OldElts; ++I)
15366 NewValue.getArrayInitializedElt(I).swap(
15367 Value->getArrayInitializedElt(I));
15368 Value->swap(NewValue);
15371 for (
unsigned I = OldElts; I < N; ++I)
15372 Value->getArrayInitializedElt(I) = Filler;
15374 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
15377 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15378 for (
unsigned I = OldElts; I < FinalSize; ++I)
15379 Value->getArrayInitializedElt(I) = FirstResult;
15381 for (
unsigned I = OldElts; I < N; ++I) {
15382 if (!VisitCXXConstructExpr(E, ArrayElt,
15383 &
Value->getArrayInitializedElt(I),
15390 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
15391 !Info.keepEvaluatingAfterFailure())
15400 if (!
Type->isRecordType())
15403 return RecordExprEvaluator(Info, Subobject, *
Value)
15404 .VisitCXXConstructExpr(E,
Type);
15407bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15408 const CXXParenListInitExpr *E) {
15410 "Expression result is not a constant array type");
15412 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15425class IntExprEvaluator
15426 :
public ExprEvaluatorBase<IntExprEvaluator> {
15429 IntExprEvaluator(EvalInfo &info,
APValue &result)
15430 : ExprEvaluatorBaseTy(info),
Result(result) {}
15434 "Invalid evaluation result.");
15436 "Invalid evaluation result.");
15437 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15438 "Invalid evaluation result.");
15442 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
15448 "Invalid evaluation result.");
15449 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15450 "Invalid evaluation result.");
15452 Result.getInt().setIsUnsigned(
15456 bool Success(
const llvm::APInt &I,
const Expr *E) {
15462 "Invalid evaluation result.");
15470 bool Success(CharUnits Size,
const Expr *E) {
15477 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
15478 V.allowConstexprUnknown()) {
15485 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
15487 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
15494 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
15497 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
15501 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
15502 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
15503 if (CheckReferencedDecl(E, E->
getDecl()))
15506 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
15508 bool VisitMemberExpr(
const MemberExpr *E) {
15510 VisitIgnoredBaseExpression(E->
getBase());
15514 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
15517 bool VisitCallExpr(
const CallExpr *E);
15518 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
15519 bool VisitBinaryOperator(
const BinaryOperator *E);
15520 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
15521 bool VisitUnaryOperator(
const UnaryOperator *E);
15523 bool VisitCastExpr(
const CastExpr* E);
15524 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
15526 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
15530 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
15534 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
15535 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
15541 return Success(Info.ArrayInitIndex, E);
15545 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
15546 return ZeroInitialization(E);
15549 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
15558 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
15562 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
15566 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
15573 bool VisitUnaryReal(
const UnaryOperator *E);
15574 bool VisitUnaryImag(
const UnaryOperator *E);
15576 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
15577 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
15578 bool VisitSourceLocExpr(
const SourceLocExpr *E);
15579 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
15584class FixedPointExprEvaluator
15585 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
15589 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
15590 : ExprEvaluatorBaseTy(info),
Result(result) {}
15592 bool Success(
const llvm::APInt &I,
const Expr *E) {
15594 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15599 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15603 return Success(
V.getFixedPoint(), E);
15606 bool Success(
const APFixedPoint &
V,
const Expr *E) {
15608 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15609 "Invalid evaluation result.");
15614 bool ZeroInitialization(
const Expr *E) {
15622 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
15626 bool VisitCastExpr(
const CastExpr *E);
15627 bool VisitUnaryOperator(
const UnaryOperator *E);
15628 bool VisitBinaryOperator(
const BinaryOperator *E);
15644 return IntExprEvaluator(Info,
Result).Visit(E);
15652 if (!Val.
isInt()) {
15655 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15662bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
15664 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
15673 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
15688 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
15692 Result = APFixedPoint(Val, FXSema);
15703bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
15705 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
15707 bool SameSign = (ECD->getInitVal().isSigned()
15709 bool SameWidth = (ECD->getInitVal().
getBitWidth()
15710 == Info.Ctx.getIntWidth(E->
getType()));
15711 if (SameSign && SameWidth)
15712 return Success(ECD->getInitVal(), E);
15716 llvm::APSInt Val = ECD->getInitVal();
15718 Val.setIsSigned(!ECD->getInitVal().isSigned());
15720 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
15731 assert(!T->isDependentType() &&
"unexpected dependent type");
15736#define TYPE(ID, BASE)
15737#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
15738#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
15739#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
15740#include "clang/AST/TypeNodes.inc"
15742 case Type::DeducedTemplateSpecialization:
15743 llvm_unreachable(
"unexpected non-canonical or dependent type");
15745 case Type::Builtin:
15747#define BUILTIN_TYPE(ID, SINGLETON_ID)
15748#define SIGNED_TYPE(ID, SINGLETON_ID) \
15749 case BuiltinType::ID: return GCCTypeClass::Integer;
15750#define FLOATING_TYPE(ID, SINGLETON_ID) \
15751 case BuiltinType::ID: return GCCTypeClass::RealFloat;
15752#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
15753 case BuiltinType::ID: break;
15754#include "clang/AST/BuiltinTypes.def"
15755 case BuiltinType::Void:
15758 case BuiltinType::Bool:
15761 case BuiltinType::Char_U:
15762 case BuiltinType::UChar:
15763 case BuiltinType::WChar_U:
15764 case BuiltinType::Char8:
15765 case BuiltinType::Char16:
15766 case BuiltinType::Char32:
15767 case BuiltinType::UShort:
15768 case BuiltinType::UInt:
15769 case BuiltinType::ULong:
15770 case BuiltinType::ULongLong:
15771 case BuiltinType::UInt128:
15774 case BuiltinType::UShortAccum:
15775 case BuiltinType::UAccum:
15776 case BuiltinType::ULongAccum:
15777 case BuiltinType::UShortFract:
15778 case BuiltinType::UFract:
15779 case BuiltinType::ULongFract:
15780 case BuiltinType::SatUShortAccum:
15781 case BuiltinType::SatUAccum:
15782 case BuiltinType::SatULongAccum:
15783 case BuiltinType::SatUShortFract:
15784 case BuiltinType::SatUFract:
15785 case BuiltinType::SatULongFract:
15788 case BuiltinType::NullPtr:
15790 case BuiltinType::ObjCId:
15791 case BuiltinType::ObjCClass:
15792 case BuiltinType::ObjCSel:
15793#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
15794 case BuiltinType::Id:
15795#include "clang/Basic/OpenCLImageTypes.def"
15796#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
15797 case BuiltinType::Id:
15798#include "clang/Basic/OpenCLExtensionTypes.def"
15799 case BuiltinType::OCLSampler:
15800 case BuiltinType::OCLEvent:
15801 case BuiltinType::OCLClkEvent:
15802 case BuiltinType::OCLQueue:
15803 case BuiltinType::OCLReserveID:
15804#define SVE_TYPE(Name, Id, SingletonId) \
15805 case BuiltinType::Id:
15806#include "clang/Basic/AArch64ACLETypes.def"
15807#define PPC_VECTOR_TYPE(Name, Id, Size) \
15808 case BuiltinType::Id:
15809#include "clang/Basic/PPCTypes.def"
15810#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15811#include "clang/Basic/RISCVVTypes.def"
15812#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15813#include "clang/Basic/WebAssemblyReferenceTypes.def"
15814#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
15815#include "clang/Basic/AMDGPUTypes.def"
15816#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15817#include "clang/Basic/HLSLIntangibleTypes.def"
15820 case BuiltinType::Dependent:
15821 llvm_unreachable(
"unexpected dependent type");
15823 llvm_unreachable(
"unexpected placeholder type");
15828 case Type::Pointer:
15829 case Type::ConstantArray:
15830 case Type::VariableArray:
15831 case Type::IncompleteArray:
15832 case Type::FunctionNoProto:
15833 case Type::FunctionProto:
15834 case Type::ArrayParameter:
15837 case Type::MemberPointer:
15842 case Type::Complex:
15855 case Type::ExtVector:
15858 case Type::BlockPointer:
15859 case Type::ConstantMatrix:
15860 case Type::ObjCObject:
15861 case Type::ObjCInterface:
15862 case Type::ObjCObjectPointer:
15864 case Type::HLSLAttributedResource:
15865 case Type::HLSLInlineSpirv:
15866 case Type::OverflowBehavior:
15874 case Type::LValueReference:
15875 case Type::RValueReference:
15876 llvm_unreachable(
"invalid type for expression");
15879 llvm_unreachable(
"unexpected type class");
15904 if (
Base.isNull()) {
15907 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
15926 SpeculativeEvaluationRAII SpeculativeEval(Info);
15931 FoldConstant Fold(Info,
true);
15949 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
15950 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
15951 ArgType->isNullPtrType()) {
15954 Fold.keepDiagnostics();
15963 return V.hasValue();
15974 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
15998 const auto *Cast = dyn_cast<CastExpr>(NoParens);
15999 if (Cast ==
nullptr)
16004 auto CastKind = Cast->getCastKind();
16006 CastKind != CK_AddressSpaceConversion)
16009 const auto *SubExpr = Cast->getSubExpr();
16031 assert(!LVal.Designator.Invalid);
16033 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
16041 auto &
Base = LVal.getLValueBase();
16042 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
16043 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
16044 if (!IsLastOrInvalidFieldDecl(FD))
16046 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
16047 for (
auto *FD : IFD->chain()) {
16056 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
16060 if (BaseType->isIncompleteArrayType())
16066 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
16067 const auto &Entry = LVal.Designator.Entries[I];
16068 if (BaseType->isArrayType()) {
16074 uint64_t Index = Entry.getAsArrayIndex();
16078 }
else if (BaseType->isAnyComplexType()) {
16079 const auto *CT = BaseType->castAs<
ComplexType>();
16080 uint64_t Index = Entry.getAsArrayIndex();
16083 BaseType = CT->getElementType();
16084 }
else if (
auto *FD = getAsField(Entry)) {
16085 if (!IsLastOrInvalidFieldDecl(FD))
16089 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
16101 if (LVal.Designator.Invalid)
16104 if (!LVal.Designator.Entries.empty())
16105 return LVal.Designator.isMostDerivedAnUnsizedArray();
16107 if (!LVal.InvalidBase)
16119 const SubobjectDesignator &
Designator = LVal.Designator;
16131 auto isFlexibleArrayMember = [&] {
16133 FAMKind StrictFlexArraysLevel =
16136 if (
Designator.isMostDerivedAnUnsizedArray())
16139 if (StrictFlexArraysLevel == FAMKind::Default)
16142 if (
Designator.getMostDerivedArraySize() == 0 &&
16143 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
16146 if (
Designator.getMostDerivedArraySize() == 1 &&
16147 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16153 return LVal.InvalidBase &&
16155 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16163 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16164 if (Int.ugt(CharUnitsMax))
16174 if (!T.isNull() && T->isStructureType() &&
16175 T->castAsRecordDecl()->hasFlexibleArrayMember())
16176 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16177 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16189 unsigned Type,
const LValue &LVal,
16208 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
16210 if (
Type == 3 && !DetermineForCompleteObject)
16213 llvm::APInt APEndOffset;
16214 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16218 if (LVal.InvalidBase)
16222 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
16228 const SubobjectDesignator &
Designator = LVal.Designator;
16240 llvm::APInt APEndOffset;
16241 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16253 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
16259 int64_t ElemsRemaining;
16262 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
16263 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
16264 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
16266 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
16269 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
16278static std::optional<uint64_t>
16286 SpeculativeEvaluationRAII SpeculativeEval(Info);
16287 IgnoreSideEffectsRAII Fold(Info);
16294 return std::nullopt;
16295 LVal.setFrom(Info.Ctx, RVal);
16298 return std::nullopt;
16303 if (LVal.getLValueOffset().isNegative())
16308 return std::nullopt;
16312 if (EndOffset <= LVal.getLValueOffset())
16314 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
16317bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16318 if (!IsConstantEvaluatedBuiltinCall(E))
16319 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16336 Info.FFDiag(E->
getArg(0));
16342 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
16343 "Bit widths must be the same");
16350bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
16351 unsigned BuiltinOp) {
16352 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
16354 APValue SourceLHS, SourceRHS;
16362 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
16364 APInt AWide(LaneWidth * SourceLen, 0);
16365 APInt BWide(LaneWidth * SourceLen, 0);
16367 for (
unsigned I = 0; I != SourceLen; ++I) {
16370 if (ElemQT->isIntegerType()) {
16373 }
else if (ElemQT->isFloatingType()) {
16381 AWide.insertBits(ALane, I * LaneWidth);
16382 BWide.insertBits(BLane, I * LaneWidth);
16387 auto HandleMaskBinOp =
16400 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16406 uint64_t CRCVal = CRC.getZExtValue();
16410 static const uint32_t CRC32C_POLY = 0x82F63B78;
16414 for (
unsigned I = 0; I != DataBytes; ++I) {
16415 uint8_t Byte =
static_cast<uint8_t
>((DataVal >> (I * 8)) & 0xFF);
16417 for (
int J = 0; J != 8; ++J) {
16425 switch (BuiltinOp) {
16429 case X86::BI__builtin_ia32_crc32qi:
16430 return HandleCRC32(1);
16431 case X86::BI__builtin_ia32_crc32hi:
16432 return HandleCRC32(2);
16433 case X86::BI__builtin_ia32_crc32si:
16434 return HandleCRC32(4);
16435 case X86::BI__builtin_ia32_crc32di:
16436 return HandleCRC32(8);
16438 case Builtin::BI__builtin_dynamic_object_size:
16439 case Builtin::BI__builtin_object_size: {
16443 assert(
Type <= 3 &&
"unexpected type");
16445 if (std::optional<uint64_t> Size =
16454 switch (Info.EvalMode) {
16455 case EvaluationMode::ConstantExpression:
16456 case EvaluationMode::ConstantFold:
16457 case EvaluationMode::IgnoreSideEffects:
16460 case EvaluationMode::ConstantExpressionUnevaluated:
16465 llvm_unreachable(
"unexpected EvalMode");
16468 case Builtin::BI__builtin_os_log_format_buffer_size: {
16469 analyze_os_log::OSLogBufferLayout Layout;
16474 case Builtin::BI__builtin_is_aligned: {
16482 Ptr.setFrom(Info.Ctx, Src);
16488 assert(Alignment.isPowerOf2());
16501 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
16505 assert(Src.
isInt());
16506 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
16508 case Builtin::BI__builtin_align_up: {
16516 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
16517 Src.
getInt().isUnsigned());
16518 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16519 return Success(AlignedVal, E);
16521 case Builtin::BI__builtin_align_down: {
16530 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16531 return Success(AlignedVal, E);
16534 case Builtin::BI__builtin_bitreverseg:
16535 case Builtin::BI__builtin_bitreverse8:
16536 case Builtin::BI__builtin_bitreverse16:
16537 case Builtin::BI__builtin_bitreverse32:
16538 case Builtin::BI__builtin_bitreverse64:
16539 case Builtin::BI__builtin_elementwise_bitreverse: {
16544 return Success(Val.reverseBits(), E);
16546 case Builtin::BI__builtin_bswapg:
16547 case Builtin::BI__builtin_bswap16:
16548 case Builtin::BI__builtin_bswap32:
16549 case Builtin::BI__builtin_bswap64: {
16553 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
16556 return Success(Val.byteSwap(), E);
16559 case Builtin::BI__builtin_classify_type:
16562 case Builtin::BI__builtin_clrsb:
16563 case Builtin::BI__builtin_clrsbl:
16564 case Builtin::BI__builtin_clrsbll: {
16569 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
16572 case Builtin::BI__builtin_clz:
16573 case Builtin::BI__builtin_clzl:
16574 case Builtin::BI__builtin_clzll:
16575 case Builtin::BI__builtin_clzs:
16576 case Builtin::BI__builtin_clzg:
16577 case Builtin::BI__builtin_elementwise_clzg:
16578 case Builtin::BI__lzcnt16:
16579 case Builtin::BI__lzcnt:
16580 case Builtin::BI__lzcnt64: {
16591 std::optional<APSInt> Fallback;
16592 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
16593 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
16598 Fallback = FallbackTemp;
16603 return Success(*Fallback, E);
16608 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
16609 BuiltinOp != Builtin::BI__lzcnt &&
16610 BuiltinOp != Builtin::BI__lzcnt64;
16612 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
16613 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16617 if (ZeroIsUndefined)
16621 return Success(Val.countl_zero(), E);
16624 case Builtin::BI__builtin_constant_p: {
16625 const Expr *Arg = E->
getArg(0);
16634 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16638 case Builtin::BI__noop:
16642 case Builtin::BI__builtin_is_constant_evaluated: {
16643 const auto *
Callee = Info.CurrentCall->getCallee();
16644 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
16645 (Info.CallStackDepth == 1 ||
16646 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
16647 Callee->getIdentifier() &&
16648 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
16650 if (Info.EvalStatus.Diag)
16651 Info.report((Info.CallStackDepth == 1)
16653 : Info.CurrentCall->getCallRange().getBegin(),
16654 diag::warn_is_constant_evaluated_always_true_constexpr)
16655 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
16656 :
"std::is_constant_evaluated");
16659 return Success(Info.InConstantContext, E);
16662 case Builtin::BI__builtin_is_within_lifetime:
16663 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
16667 case Builtin::BI__builtin_ctz:
16668 case Builtin::BI__builtin_ctzl:
16669 case Builtin::BI__builtin_ctzll:
16670 case Builtin::BI__builtin_ctzs:
16671 case Builtin::BI__builtin_ctzg:
16672 case Builtin::BI__builtin_elementwise_ctzg: {
16683 std::optional<APSInt> Fallback;
16684 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
16685 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
16690 Fallback = FallbackTemp;
16695 return Success(*Fallback, E);
16697 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
16698 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16704 return Success(Val.countr_zero(), E);
16707 case Builtin::BI__builtin_eh_return_data_regno: {
16709 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
16713 case Builtin::BI__builtin_elementwise_abs: {
16718 return Success(Val.abs(), E);
16721 case Builtin::BI__builtin_expect:
16722 case Builtin::BI__builtin_expect_with_probability:
16723 return Visit(E->
getArg(0));
16725 case Builtin::BI__builtin_ptrauth_string_discriminator: {
16732 case Builtin::BI__builtin_infer_alloc_token: {
16738 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
16741 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
16743 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
16744 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
16745 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
16747 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
16748 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
16750 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
16751 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
16754 case Builtin::BI__builtin_ffs:
16755 case Builtin::BI__builtin_ffsl:
16756 case Builtin::BI__builtin_ffsll: {
16761 unsigned N = Val.countr_zero();
16762 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
16765 case Builtin::BI__builtin_fpclassify: {
16770 switch (Val.getCategory()) {
16771 case APFloat::fcNaN: Arg = 0;
break;
16772 case APFloat::fcInfinity: Arg = 1;
break;
16773 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
16774 case APFloat::fcZero: Arg = 4;
break;
16776 return Visit(E->
getArg(Arg));
16779 case Builtin::BI__builtin_isinf_sign: {
16782 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
16785 case Builtin::BI__builtin_isinf: {
16788 Success(Val.isInfinity() ? 1 : 0, E);
16791 case Builtin::BI__builtin_isfinite: {
16794 Success(Val.isFinite() ? 1 : 0, E);
16797 case Builtin::BI__builtin_isnan: {
16800 Success(Val.isNaN() ? 1 : 0, E);
16803 case Builtin::BI__builtin_isnormal: {
16806 Success(Val.isNormal() ? 1 : 0, E);
16809 case Builtin::BI__builtin_issubnormal: {
16812 Success(Val.isDenormal() ? 1 : 0, E);
16815 case Builtin::BI__builtin_iszero: {
16818 Success(Val.isZero() ? 1 : 0, E);
16821 case Builtin::BI__builtin_signbit:
16822 case Builtin::BI__builtin_signbitf:
16823 case Builtin::BI__builtin_signbitl: {
16826 Success(Val.isNegative() ? 1 : 0, E);
16829 case Builtin::BI__builtin_isgreater:
16830 case Builtin::BI__builtin_isgreaterequal:
16831 case Builtin::BI__builtin_isless:
16832 case Builtin::BI__builtin_islessequal:
16833 case Builtin::BI__builtin_islessgreater:
16834 case Builtin::BI__builtin_isunordered: {
16843 switch (BuiltinOp) {
16844 case Builtin::BI__builtin_isgreater:
16846 case Builtin::BI__builtin_isgreaterequal:
16848 case Builtin::BI__builtin_isless:
16850 case Builtin::BI__builtin_islessequal:
16852 case Builtin::BI__builtin_islessgreater: {
16853 APFloat::cmpResult cmp = LHS.compare(RHS);
16854 return cmp == APFloat::cmpResult::cmpLessThan ||
16855 cmp == APFloat::cmpResult::cmpGreaterThan;
16857 case Builtin::BI__builtin_isunordered:
16858 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
16860 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
16861 "point comparison function");
16869 case Builtin::BI__builtin_issignaling: {
16872 Success(Val.isSignaling() ? 1 : 0, E);
16875 case Builtin::BI__builtin_isfpclass: {
16879 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
16882 Success((Val.classify() & Test) ? 1 : 0, E);
16885 case Builtin::BI__builtin_parity:
16886 case Builtin::BI__builtin_parityl:
16887 case Builtin::BI__builtin_parityll: {
16892 return Success(Val.popcount() % 2, E);
16895 case Builtin::BI__builtin_abs:
16896 case Builtin::BI__builtin_labs:
16897 case Builtin::BI__builtin_llabs: {
16901 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
16904 if (Val.isNegative())
16909 case Builtin::BI__builtin_popcount:
16910 case Builtin::BI__builtin_popcountl:
16911 case Builtin::BI__builtin_popcountll:
16912 case Builtin::BI__builtin_popcountg:
16913 case Builtin::BI__builtin_elementwise_popcount:
16914 case Builtin::BI__popcnt16:
16915 case Builtin::BI__popcnt:
16916 case Builtin::BI__popcnt64: {
16927 return Success(Val.popcount(), E);
16930 case Builtin::BI__builtin_rotateleft8:
16931 case Builtin::BI__builtin_rotateleft16:
16932 case Builtin::BI__builtin_rotateleft32:
16933 case Builtin::BI__builtin_rotateleft64:
16934 case Builtin::BI__builtin_rotateright8:
16935 case Builtin::BI__builtin_rotateright16:
16936 case Builtin::BI__builtin_rotateright32:
16937 case Builtin::BI__builtin_rotateright64:
16938 case Builtin::BI__builtin_stdc_rotate_left:
16939 case Builtin::BI__builtin_stdc_rotate_right:
16940 case Builtin::BIstdc_rotate_left_uc:
16941 case Builtin::BIstdc_rotate_left_us:
16942 case Builtin::BIstdc_rotate_left_ui:
16943 case Builtin::BIstdc_rotate_left_ul:
16944 case Builtin::BIstdc_rotate_left_ull:
16945 case Builtin::BIstdc_rotate_right_uc:
16946 case Builtin::BIstdc_rotate_right_us:
16947 case Builtin::BIstdc_rotate_right_ui:
16948 case Builtin::BIstdc_rotate_right_ul:
16949 case Builtin::BIstdc_rotate_right_ull:
16950 case Builtin::BI_rotl8:
16951 case Builtin::BI_rotl16:
16952 case Builtin::BI_rotl:
16953 case Builtin::BI_lrotl:
16954 case Builtin::BI_rotl64:
16955 case Builtin::BI_rotr8:
16956 case Builtin::BI_rotr16:
16957 case Builtin::BI_rotr:
16958 case Builtin::BI_lrotr:
16959 case Builtin::BI_rotr64: {
16967 switch (BuiltinOp) {
16968 case Builtin::BI__builtin_rotateright8:
16969 case Builtin::BI__builtin_rotateright16:
16970 case Builtin::BI__builtin_rotateright32:
16971 case Builtin::BI__builtin_rotateright64:
16972 case Builtin::BI__builtin_stdc_rotate_right:
16973 case Builtin::BIstdc_rotate_right_uc:
16974 case Builtin::BIstdc_rotate_right_us:
16975 case Builtin::BIstdc_rotate_right_ui:
16976 case Builtin::BIstdc_rotate_right_ul:
16977 case Builtin::BIstdc_rotate_right_ull:
16978 case Builtin::BI_rotr8:
16979 case Builtin::BI_rotr16:
16980 case Builtin::BI_rotr:
16981 case Builtin::BI_lrotr:
16982 case Builtin::BI_rotr64:
16991 case Builtin::BIstdc_leading_zeros_uc:
16992 case Builtin::BIstdc_leading_zeros_us:
16993 case Builtin::BIstdc_leading_zeros_ui:
16994 case Builtin::BIstdc_leading_zeros_ul:
16995 case Builtin::BIstdc_leading_zeros_ull:
16996 case Builtin::BIstdc_leading_ones_uc:
16997 case Builtin::BIstdc_leading_ones_us:
16998 case Builtin::BIstdc_leading_ones_ui:
16999 case Builtin::BIstdc_leading_ones_ul:
17000 case Builtin::BIstdc_leading_ones_ull:
17001 case Builtin::BIstdc_trailing_zeros_uc:
17002 case Builtin::BIstdc_trailing_zeros_us:
17003 case Builtin::BIstdc_trailing_zeros_ui:
17004 case Builtin::BIstdc_trailing_zeros_ul:
17005 case Builtin::BIstdc_trailing_zeros_ull:
17006 case Builtin::BIstdc_trailing_ones_uc:
17007 case Builtin::BIstdc_trailing_ones_us:
17008 case Builtin::BIstdc_trailing_ones_ui:
17009 case Builtin::BIstdc_trailing_ones_ul:
17010 case Builtin::BIstdc_trailing_ones_ull:
17011 case Builtin::BIstdc_first_leading_zero_uc:
17012 case Builtin::BIstdc_first_leading_zero_us:
17013 case Builtin::BIstdc_first_leading_zero_ui:
17014 case Builtin::BIstdc_first_leading_zero_ul:
17015 case Builtin::BIstdc_first_leading_zero_ull:
17016 case Builtin::BIstdc_first_leading_one_uc:
17017 case Builtin::BIstdc_first_leading_one_us:
17018 case Builtin::BIstdc_first_leading_one_ui:
17019 case Builtin::BIstdc_first_leading_one_ul:
17020 case Builtin::BIstdc_first_leading_one_ull:
17021 case Builtin::BIstdc_first_trailing_zero_uc:
17022 case Builtin::BIstdc_first_trailing_zero_us:
17023 case Builtin::BIstdc_first_trailing_zero_ui:
17024 case Builtin::BIstdc_first_trailing_zero_ul:
17025 case Builtin::BIstdc_first_trailing_zero_ull:
17026 case Builtin::BIstdc_first_trailing_one_uc:
17027 case Builtin::BIstdc_first_trailing_one_us:
17028 case Builtin::BIstdc_first_trailing_one_ui:
17029 case Builtin::BIstdc_first_trailing_one_ul:
17030 case Builtin::BIstdc_first_trailing_one_ull:
17031 case Builtin::BIstdc_count_zeros_uc:
17032 case Builtin::BIstdc_count_zeros_us:
17033 case Builtin::BIstdc_count_zeros_ui:
17034 case Builtin::BIstdc_count_zeros_ul:
17035 case Builtin::BIstdc_count_zeros_ull:
17036 case Builtin::BIstdc_count_ones_uc:
17037 case Builtin::BIstdc_count_ones_us:
17038 case Builtin::BIstdc_count_ones_ui:
17039 case Builtin::BIstdc_count_ones_ul:
17040 case Builtin::BIstdc_count_ones_ull:
17041 case Builtin::BIstdc_has_single_bit_uc:
17042 case Builtin::BIstdc_has_single_bit_us:
17043 case Builtin::BIstdc_has_single_bit_ui:
17044 case Builtin::BIstdc_has_single_bit_ul:
17045 case Builtin::BIstdc_has_single_bit_ull:
17046 case Builtin::BIstdc_bit_width_uc:
17047 case Builtin::BIstdc_bit_width_us:
17048 case Builtin::BIstdc_bit_width_ui:
17049 case Builtin::BIstdc_bit_width_ul:
17050 case Builtin::BIstdc_bit_width_ull:
17051 case Builtin::BIstdc_bit_floor_uc:
17052 case Builtin::BIstdc_bit_floor_us:
17053 case Builtin::BIstdc_bit_floor_ui:
17054 case Builtin::BIstdc_bit_floor_ul:
17055 case Builtin::BIstdc_bit_floor_ull:
17056 case Builtin::BIstdc_bit_ceil_uc:
17057 case Builtin::BIstdc_bit_ceil_us:
17058 case Builtin::BIstdc_bit_ceil_ui:
17059 case Builtin::BIstdc_bit_ceil_ul:
17060 case Builtin::BIstdc_bit_ceil_ull:
17061 case Builtin::BI__builtin_stdc_leading_zeros:
17062 case Builtin::BI__builtin_stdc_leading_ones:
17063 case Builtin::BI__builtin_stdc_trailing_zeros:
17064 case Builtin::BI__builtin_stdc_trailing_ones:
17065 case Builtin::BI__builtin_stdc_first_leading_zero:
17066 case Builtin::BI__builtin_stdc_first_leading_one:
17067 case Builtin::BI__builtin_stdc_first_trailing_zero:
17068 case Builtin::BI__builtin_stdc_first_trailing_one:
17069 case Builtin::BI__builtin_stdc_count_zeros:
17070 case Builtin::BI__builtin_stdc_count_ones:
17071 case Builtin::BI__builtin_stdc_has_single_bit:
17072 case Builtin::BI__builtin_stdc_bit_width:
17073 case Builtin::BI__builtin_stdc_bit_floor:
17074 case Builtin::BI__builtin_stdc_bit_ceil: {
17079 unsigned BitWidth = Val.getBitWidth();
17080 const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->
getType());
17082 switch (BuiltinOp) {
17083 case Builtin::BIstdc_leading_zeros_uc:
17084 case Builtin::BIstdc_leading_zeros_us:
17085 case Builtin::BIstdc_leading_zeros_ui:
17086 case Builtin::BIstdc_leading_zeros_ul:
17087 case Builtin::BIstdc_leading_zeros_ull:
17088 case Builtin::BI__builtin_stdc_leading_zeros:
17089 return Success(
APInt(ResBitWidth, Val.countl_zero()), E);
17090 case Builtin::BIstdc_leading_ones_uc:
17091 case Builtin::BIstdc_leading_ones_us:
17092 case Builtin::BIstdc_leading_ones_ui:
17093 case Builtin::BIstdc_leading_ones_ul:
17094 case Builtin::BIstdc_leading_ones_ull:
17095 case Builtin::BI__builtin_stdc_leading_ones:
17096 return Success(
APInt(ResBitWidth, Val.countl_one()), E);
17097 case Builtin::BIstdc_trailing_zeros_uc:
17098 case Builtin::BIstdc_trailing_zeros_us:
17099 case Builtin::BIstdc_trailing_zeros_ui:
17100 case Builtin::BIstdc_trailing_zeros_ul:
17101 case Builtin::BIstdc_trailing_zeros_ull:
17102 case Builtin::BI__builtin_stdc_trailing_zeros:
17103 return Success(
APInt(ResBitWidth, Val.countr_zero()), E);
17104 case Builtin::BIstdc_trailing_ones_uc:
17105 case Builtin::BIstdc_trailing_ones_us:
17106 case Builtin::BIstdc_trailing_ones_ui:
17107 case Builtin::BIstdc_trailing_ones_ul:
17108 case Builtin::BIstdc_trailing_ones_ull:
17109 case Builtin::BI__builtin_stdc_trailing_ones:
17110 return Success(
APInt(ResBitWidth, Val.countr_one()), E);
17111 case Builtin::BIstdc_first_leading_zero_uc:
17112 case Builtin::BIstdc_first_leading_zero_us:
17113 case Builtin::BIstdc_first_leading_zero_ui:
17114 case Builtin::BIstdc_first_leading_zero_ul:
17115 case Builtin::BIstdc_first_leading_zero_ull:
17116 case Builtin::BI__builtin_stdc_first_leading_zero:
17118 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
17119 case Builtin::BIstdc_first_leading_one_uc:
17120 case Builtin::BIstdc_first_leading_one_us:
17121 case Builtin::BIstdc_first_leading_one_ui:
17122 case Builtin::BIstdc_first_leading_one_ul:
17123 case Builtin::BIstdc_first_leading_one_ull:
17124 case Builtin::BI__builtin_stdc_first_leading_one:
17126 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
17127 case Builtin::BIstdc_first_trailing_zero_uc:
17128 case Builtin::BIstdc_first_trailing_zero_us:
17129 case Builtin::BIstdc_first_trailing_zero_ui:
17130 case Builtin::BIstdc_first_trailing_zero_ul:
17131 case Builtin::BIstdc_first_trailing_zero_ull:
17132 case Builtin::BI__builtin_stdc_first_trailing_zero:
17134 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
17135 case Builtin::BIstdc_first_trailing_one_uc:
17136 case Builtin::BIstdc_first_trailing_one_us:
17137 case Builtin::BIstdc_first_trailing_one_ui:
17138 case Builtin::BIstdc_first_trailing_one_ul:
17139 case Builtin::BIstdc_first_trailing_one_ull:
17140 case Builtin::BI__builtin_stdc_first_trailing_one:
17142 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
17143 case Builtin::BIstdc_count_zeros_uc:
17144 case Builtin::BIstdc_count_zeros_us:
17145 case Builtin::BIstdc_count_zeros_ui:
17146 case Builtin::BIstdc_count_zeros_ul:
17147 case Builtin::BIstdc_count_zeros_ull:
17148 case Builtin::BI__builtin_stdc_count_zeros: {
17149 APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
17152 case Builtin::BIstdc_count_ones_uc:
17153 case Builtin::BIstdc_count_ones_us:
17154 case Builtin::BIstdc_count_ones_ui:
17155 case Builtin::BIstdc_count_ones_ul:
17156 case Builtin::BIstdc_count_ones_ull:
17157 case Builtin::BI__builtin_stdc_count_ones: {
17158 APInt Cnt(ResBitWidth, Val.popcount());
17161 case Builtin::BIstdc_has_single_bit_uc:
17162 case Builtin::BIstdc_has_single_bit_us:
17163 case Builtin::BIstdc_has_single_bit_ui:
17164 case Builtin::BIstdc_has_single_bit_ul:
17165 case Builtin::BIstdc_has_single_bit_ull:
17166 case Builtin::BI__builtin_stdc_has_single_bit: {
17167 APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
17170 case Builtin::BIstdc_bit_width_uc:
17171 case Builtin::BIstdc_bit_width_us:
17172 case Builtin::BIstdc_bit_width_ui:
17173 case Builtin::BIstdc_bit_width_ul:
17174 case Builtin::BIstdc_bit_width_ull:
17175 case Builtin::BI__builtin_stdc_bit_width:
17176 return Success(
APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
17177 case Builtin::BIstdc_bit_floor_uc:
17178 case Builtin::BIstdc_bit_floor_us:
17179 case Builtin::BIstdc_bit_floor_ui:
17180 case Builtin::BIstdc_bit_floor_ul:
17181 case Builtin::BIstdc_bit_floor_ull:
17182 case Builtin::BI__builtin_stdc_bit_floor: {
17185 unsigned Exp = BitWidth - Val.countl_zero() - 1;
17187 APSInt(APInt::getOneBitSet(BitWidth, Exp),
true), E);
17189 case Builtin::BIstdc_bit_ceil_uc:
17190 case Builtin::BIstdc_bit_ceil_us:
17191 case Builtin::BIstdc_bit_ceil_ui:
17192 case Builtin::BIstdc_bit_ceil_ul:
17193 case Builtin::BIstdc_bit_ceil_ull:
17194 case Builtin::BI__builtin_stdc_bit_ceil: {
17197 APInt ValMinusOne = Val - 1;
17198 unsigned LZ = ValMinusOne.countl_zero();
17202 APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
17206 llvm_unreachable(
"Unknown stdc builtin");
17210 case Builtin::BI__builtin_elementwise_add_sat: {
17216 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
17219 case Builtin::BI__builtin_elementwise_sub_sat: {
17225 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
17228 case Builtin::BI__builtin_elementwise_max: {
17237 case Builtin::BI__builtin_elementwise_min: {
17246 case Builtin::BI__builtin_elementwise_clmul: {
17255 case Builtin::BI__builtin_elementwise_fshl:
17256 case Builtin::BI__builtin_elementwise_fshr: {
17263 switch (BuiltinOp) {
17264 case Builtin::BI__builtin_elementwise_fshl: {
17265 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
17268 case Builtin::BI__builtin_elementwise_fshr: {
17269 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
17273 llvm_unreachable(
"Fully covered switch above");
17275 case Builtin::BIstrlen:
17276 case Builtin::BIwcslen:
17278 if (Info.getLangOpts().CPlusPlus11)
17279 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17281 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17283 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17285 case Builtin::BI__builtin_strlen:
17286 case Builtin::BI__builtin_wcslen: {
17289 if (std::optional<uint64_t> StrLen =
17295 case Builtin::BIstrcmp:
17296 case Builtin::BIwcscmp:
17297 case Builtin::BIstrncmp:
17298 case Builtin::BIwcsncmp:
17299 case Builtin::BImemcmp:
17300 case Builtin::BIbcmp:
17301 case Builtin::BIwmemcmp:
17303 if (Info.getLangOpts().CPlusPlus11)
17304 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17306 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17308 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17310 case Builtin::BI__builtin_strcmp:
17311 case Builtin::BI__builtin_wcscmp:
17312 case Builtin::BI__builtin_strncmp:
17313 case Builtin::BI__builtin_wcsncmp:
17314 case Builtin::BI__builtin_memcmp:
17315 case Builtin::BI__builtin_bcmp:
17316 case Builtin::BI__builtin_wmemcmp: {
17317 LValue String1, String2;
17323 if (BuiltinOp != Builtin::BIstrcmp &&
17324 BuiltinOp != Builtin::BIwcscmp &&
17325 BuiltinOp != Builtin::BI__builtin_strcmp &&
17326 BuiltinOp != Builtin::BI__builtin_wcscmp) {
17330 MaxLength = N.getZExtValue();
17334 if (MaxLength == 0u)
17337 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17338 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17339 String1.Designator.Invalid || String2.Designator.Invalid)
17342 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
17343 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
17345 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
17346 BuiltinOp == Builtin::BIbcmp ||
17347 BuiltinOp == Builtin::BI__builtin_memcmp ||
17348 BuiltinOp == Builtin::BI__builtin_bcmp;
17350 assert(IsRawByte ||
17351 (Info.Ctx.hasSameUnqualifiedType(
17353 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
17360 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
17361 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
17366 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
17369 Char1.
isInt() && Char2.isInt();
17371 const auto &AdvanceElems = [&] {
17377 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
17378 BuiltinOp != Builtin::BIwmemcmp &&
17379 BuiltinOp != Builtin::BI__builtin_memcmp &&
17380 BuiltinOp != Builtin::BI__builtin_bcmp &&
17381 BuiltinOp != Builtin::BI__builtin_wmemcmp);
17382 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
17383 BuiltinOp == Builtin::BIwcsncmp ||
17384 BuiltinOp == Builtin::BIwmemcmp ||
17385 BuiltinOp == Builtin::BI__builtin_wcscmp ||
17386 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
17387 BuiltinOp == Builtin::BI__builtin_wmemcmp;
17389 for (; MaxLength; --MaxLength) {
17391 if (!ReadCurElems(Char1, Char2))
17399 if (StopAtNull && !Char1.
getInt())
17401 assert(!(StopAtNull && !Char2.
getInt()));
17402 if (!AdvanceElems())
17409 case Builtin::BI__atomic_always_lock_free:
17410 case Builtin::BI__atomic_is_lock_free:
17411 case Builtin::BI__c11_atomic_is_lock_free: {
17427 if (
Size.isPowerOfTwo()) {
17429 unsigned InlineWidthBits =
17430 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
17431 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
17432 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
17438 const Expr *PtrArg = E->
getArg(1);
17444 IntResult.isAligned(
Size.getAsAlign()))
17448 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
17451 if (ICE->getCastKind() == CK_BitCast)
17452 PtrArg = ICE->getSubExpr();
17455 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
17458 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
17466 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
17469 case Builtin::BI__builtin_addcb:
17470 case Builtin::BI__builtin_addcs:
17471 case Builtin::BI__builtin_addc:
17472 case Builtin::BI__builtin_addcl:
17473 case Builtin::BI__builtin_addcll:
17474 case Builtin::BI__builtin_subcb:
17475 case Builtin::BI__builtin_subcs:
17476 case Builtin::BI__builtin_subc:
17477 case Builtin::BI__builtin_subcl:
17478 case Builtin::BI__builtin_subcll: {
17479 LValue CarryOutLValue;
17491 bool FirstOverflowed =
false;
17492 bool SecondOverflowed =
false;
17493 switch (BuiltinOp) {
17495 llvm_unreachable(
"Invalid value for BuiltinOp");
17496 case Builtin::BI__builtin_addcb:
17497 case Builtin::BI__builtin_addcs:
17498 case Builtin::BI__builtin_addc:
17499 case Builtin::BI__builtin_addcl:
17500 case Builtin::BI__builtin_addcll:
17502 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
17504 case Builtin::BI__builtin_subcb:
17505 case Builtin::BI__builtin_subcs:
17506 case Builtin::BI__builtin_subc:
17507 case Builtin::BI__builtin_subcl:
17508 case Builtin::BI__builtin_subcll:
17510 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
17516 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
17522 case Builtin::BI__builtin_add_overflow:
17523 case Builtin::BI__builtin_sub_overflow:
17524 case Builtin::BI__builtin_mul_overflow:
17525 case Builtin::BI__builtin_sadd_overflow:
17526 case Builtin::BI__builtin_uadd_overflow:
17527 case Builtin::BI__builtin_uaddl_overflow:
17528 case Builtin::BI__builtin_uaddll_overflow:
17529 case Builtin::BI__builtin_usub_overflow:
17530 case Builtin::BI__builtin_usubl_overflow:
17531 case Builtin::BI__builtin_usubll_overflow:
17532 case Builtin::BI__builtin_umul_overflow:
17533 case Builtin::BI__builtin_umull_overflow:
17534 case Builtin::BI__builtin_umulll_overflow:
17535 case Builtin::BI__builtin_saddl_overflow:
17536 case Builtin::BI__builtin_saddll_overflow:
17537 case Builtin::BI__builtin_ssub_overflow:
17538 case Builtin::BI__builtin_ssubl_overflow:
17539 case Builtin::BI__builtin_ssubll_overflow:
17540 case Builtin::BI__builtin_smul_overflow:
17541 case Builtin::BI__builtin_smull_overflow:
17542 case Builtin::BI__builtin_smulll_overflow: {
17543 LValue ResultLValue;
17553 bool DidOverflow =
false;
17556 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17557 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17558 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17559 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
17561 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
17563 uint64_t LHSSize = LHS.getBitWidth();
17564 uint64_t RHSSize = RHS.getBitWidth();
17565 uint64_t ResultSize = Info.Ctx.getIntWidth(ResultType);
17566 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
17572 if (IsSigned && !AllSigned)
17575 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
17576 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
17581 switch (BuiltinOp) {
17583 llvm_unreachable(
"Invalid value for BuiltinOp");
17584 case Builtin::BI__builtin_add_overflow:
17585 case Builtin::BI__builtin_sadd_overflow:
17586 case Builtin::BI__builtin_saddl_overflow:
17587 case Builtin::BI__builtin_saddll_overflow:
17588 case Builtin::BI__builtin_uadd_overflow:
17589 case Builtin::BI__builtin_uaddl_overflow:
17590 case Builtin::BI__builtin_uaddll_overflow:
17591 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
17592 : LHS.uadd_ov(RHS, DidOverflow);
17594 case Builtin::BI__builtin_sub_overflow:
17595 case Builtin::BI__builtin_ssub_overflow:
17596 case Builtin::BI__builtin_ssubl_overflow:
17597 case Builtin::BI__builtin_ssubll_overflow:
17598 case Builtin::BI__builtin_usub_overflow:
17599 case Builtin::BI__builtin_usubl_overflow:
17600 case Builtin::BI__builtin_usubll_overflow:
17601 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
17602 : LHS.usub_ov(RHS, DidOverflow);
17604 case Builtin::BI__builtin_mul_overflow:
17605 case Builtin::BI__builtin_smul_overflow:
17606 case Builtin::BI__builtin_smull_overflow:
17607 case Builtin::BI__builtin_smulll_overflow:
17608 case Builtin::BI__builtin_umul_overflow:
17609 case Builtin::BI__builtin_umull_overflow:
17610 case Builtin::BI__builtin_umulll_overflow:
17611 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
17612 : LHS.umul_ov(RHS, DidOverflow);
17621 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getIntWidth(ResultType));
17626 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17627 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17628 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17629 if (!APSInt::isSameValue(Temp,
Result))
17630 DidOverflow =
true;
17637 return Success(DidOverflow, E);
17640 case Builtin::BI__builtin_reduce_add:
17641 case Builtin::BI__builtin_reduce_mul:
17642 case Builtin::BI__builtin_reduce_and:
17643 case Builtin::BI__builtin_reduce_or:
17644 case Builtin::BI__builtin_reduce_xor:
17645 case Builtin::BI__builtin_reduce_min:
17646 case Builtin::BI__builtin_reduce_max: {
17653 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
17654 switch (BuiltinOp) {
17657 case Builtin::BI__builtin_reduce_add: {
17660 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
17664 case Builtin::BI__builtin_reduce_mul: {
17667 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
17671 case Builtin::BI__builtin_reduce_and: {
17675 case Builtin::BI__builtin_reduce_or: {
17679 case Builtin::BI__builtin_reduce_xor: {
17683 case Builtin::BI__builtin_reduce_min: {
17687 case Builtin::BI__builtin_reduce_max: {
17697 case clang::X86::BI__builtin_ia32_addcarryx_u32:
17698 case clang::X86::BI__builtin_ia32_addcarryx_u64:
17699 case clang::X86::BI__builtin_ia32_subborrow_u32:
17700 case clang::X86::BI__builtin_ia32_subborrow_u64: {
17701 LValue ResultLValue;
17702 APSInt CarryIn, LHS, RHS;
17710 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
17711 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
17713 unsigned BitWidth = LHS.getBitWidth();
17714 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
17717 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
17718 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
17720 APInt Result = ExResult.extractBits(BitWidth, 0);
17721 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
17729 case clang::X86::BI__builtin_ia32_movmskps:
17730 case clang::X86::BI__builtin_ia32_movmskpd:
17731 case clang::X86::BI__builtin_ia32_pmovmskb128:
17732 case clang::X86::BI__builtin_ia32_pmovmskb256:
17733 case clang::X86::BI__builtin_ia32_movmskps256:
17734 case clang::X86::BI__builtin_ia32_movmskpd256: {
17741 unsigned ResultLen = Info.Ctx.getTypeSize(
17745 for (
unsigned I = 0; I != SourceLen; ++I) {
17747 if (ElemQT->isIntegerType()) {
17749 }
else if (ElemQT->isRealFloatingType()) {
17754 Result.setBitVal(I, Elem.isNegative());
17759 case clang::X86::BI__builtin_ia32_bextr_u32:
17760 case clang::X86::BI__builtin_ia32_bextr_u64:
17761 case clang::X86::BI__builtin_ia32_bextri_u32:
17762 case clang::X86::BI__builtin_ia32_bextri_u64: {
17768 unsigned BitWidth = Val.getBitWidth();
17770 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
17771 Length = Length > BitWidth ? BitWidth : Length;
17774 if (Length == 0 || Shift >= BitWidth)
17778 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
17782 case clang::X86::BI__builtin_ia32_bzhi_si:
17783 case clang::X86::BI__builtin_ia32_bzhi_di: {
17789 unsigned BitWidth = Val.getBitWidth();
17790 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
17791 if (Index < BitWidth)
17792 Val.clearHighBits(BitWidth - Index);
17796 case clang::X86::BI__builtin_ia32_ktestcqi:
17797 case clang::X86::BI__builtin_ia32_ktestchi:
17798 case clang::X86::BI__builtin_ia32_ktestcsi:
17799 case clang::X86::BI__builtin_ia32_ktestcdi: {
17805 return Success((~A & B) == 0, E);
17808 case clang::X86::BI__builtin_ia32_ktestzqi:
17809 case clang::X86::BI__builtin_ia32_ktestzhi:
17810 case clang::X86::BI__builtin_ia32_ktestzsi:
17811 case clang::X86::BI__builtin_ia32_ktestzdi: {
17817 return Success((A & B) == 0, E);
17820 case clang::X86::BI__builtin_ia32_kortestcqi:
17821 case clang::X86::BI__builtin_ia32_kortestchi:
17822 case clang::X86::BI__builtin_ia32_kortestcsi:
17823 case clang::X86::BI__builtin_ia32_kortestcdi: {
17829 return Success(~(A | B) == 0, E);
17832 case clang::X86::BI__builtin_ia32_kortestzqi:
17833 case clang::X86::BI__builtin_ia32_kortestzhi:
17834 case clang::X86::BI__builtin_ia32_kortestzsi:
17835 case clang::X86::BI__builtin_ia32_kortestzdi: {
17841 return Success((A | B) == 0, E);
17844 case clang::X86::BI__builtin_ia32_kunpckhi:
17845 case clang::X86::BI__builtin_ia32_kunpckdi:
17846 case clang::X86::BI__builtin_ia32_kunpcksi: {
17854 unsigned BW = A.getBitWidth();
17855 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
17859 case clang::X86::BI__builtin_ia32_lzcnt_u16:
17860 case clang::X86::BI__builtin_ia32_lzcnt_u32:
17861 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
17865 return Success(Val.countLeadingZeros(), E);
17868 case clang::X86::BI__builtin_ia32_tzcnt_u16:
17869 case clang::X86::BI__builtin_ia32_tzcnt_u32:
17870 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
17874 return Success(Val.countTrailingZeros(), E);
17877 case clang::X86::BI__builtin_ia32_pdep_si:
17878 case clang::X86::BI__builtin_ia32_pdep_di: {
17883 return Success(llvm::APIntOps::expandBits(Val, Msk), E);
17886 case clang::X86::BI__builtin_ia32_pext_si:
17887 case clang::X86::BI__builtin_ia32_pext_di: {
17892 return Success(llvm::APIntOps::compressBits(Val, Msk), E);
17894 case X86::BI__builtin_ia32_ptestz128:
17895 case X86::BI__builtin_ia32_ptestz256:
17896 case X86::BI__builtin_ia32_vtestzps:
17897 case X86::BI__builtin_ia32_vtestzps256:
17898 case X86::BI__builtin_ia32_vtestzpd:
17899 case X86::BI__builtin_ia32_vtestzpd256: {
17901 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
17903 case X86::BI__builtin_ia32_ptestc128:
17904 case X86::BI__builtin_ia32_ptestc256:
17905 case X86::BI__builtin_ia32_vtestcps:
17906 case X86::BI__builtin_ia32_vtestcps256:
17907 case X86::BI__builtin_ia32_vtestcpd:
17908 case X86::BI__builtin_ia32_vtestcpd256: {
17910 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
17912 case X86::BI__builtin_ia32_ptestnzc128:
17913 case X86::BI__builtin_ia32_ptestnzc256:
17914 case X86::BI__builtin_ia32_vtestnzcps:
17915 case X86::BI__builtin_ia32_vtestnzcps256:
17916 case X86::BI__builtin_ia32_vtestnzcpd:
17917 case X86::BI__builtin_ia32_vtestnzcpd256: {
17918 return EvalTestOp([](
const APInt &A,
const APInt &B) {
17919 return ((A & B) != 0) && ((~A & B) != 0);
17922 case X86::BI__builtin_ia32_kandqi:
17923 case X86::BI__builtin_ia32_kandhi:
17924 case X86::BI__builtin_ia32_kandsi:
17925 case X86::BI__builtin_ia32_kanddi: {
17926 return HandleMaskBinOp(
17927 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
17930 case X86::BI__builtin_ia32_kandnqi:
17931 case X86::BI__builtin_ia32_kandnhi:
17932 case X86::BI__builtin_ia32_kandnsi:
17933 case X86::BI__builtin_ia32_kandndi: {
17934 return HandleMaskBinOp(
17935 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
17938 case X86::BI__builtin_ia32_korqi:
17939 case X86::BI__builtin_ia32_korhi:
17940 case X86::BI__builtin_ia32_korsi:
17941 case X86::BI__builtin_ia32_kordi: {
17942 return HandleMaskBinOp(
17943 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
17946 case X86::BI__builtin_ia32_kxnorqi:
17947 case X86::BI__builtin_ia32_kxnorhi:
17948 case X86::BI__builtin_ia32_kxnorsi:
17949 case X86::BI__builtin_ia32_kxnordi: {
17950 return HandleMaskBinOp(
17951 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
17954 case X86::BI__builtin_ia32_kxorqi:
17955 case X86::BI__builtin_ia32_kxorhi:
17956 case X86::BI__builtin_ia32_kxorsi:
17957 case X86::BI__builtin_ia32_kxordi: {
17958 return HandleMaskBinOp(
17959 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
17962 case X86::BI__builtin_ia32_knotqi:
17963 case X86::BI__builtin_ia32_knothi:
17964 case X86::BI__builtin_ia32_knotsi:
17965 case X86::BI__builtin_ia32_knotdi: {
17973 case X86::BI__builtin_ia32_kaddqi:
17974 case X86::BI__builtin_ia32_kaddhi:
17975 case X86::BI__builtin_ia32_kaddsi:
17976 case X86::BI__builtin_ia32_kadddi: {
17977 return HandleMaskBinOp(
17978 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
17981 case X86::BI__builtin_ia32_kmovb:
17982 case X86::BI__builtin_ia32_kmovw:
17983 case X86::BI__builtin_ia32_kmovd:
17984 case X86::BI__builtin_ia32_kmovq: {
17991 case X86::BI__builtin_ia32_kshiftliqi:
17992 case X86::BI__builtin_ia32_kshiftlihi:
17993 case X86::BI__builtin_ia32_kshiftlisi:
17994 case X86::BI__builtin_ia32_kshiftlidi: {
17995 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
17996 unsigned Amt = RHS.getZExtValue() & 0xFF;
17997 if (Amt >= LHS.getBitWidth())
17998 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
17999 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
18003 case X86::BI__builtin_ia32_kshiftriqi:
18004 case X86::BI__builtin_ia32_kshiftrihi:
18005 case X86::BI__builtin_ia32_kshiftrisi:
18006 case X86::BI__builtin_ia32_kshiftridi: {
18007 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18008 unsigned Amt = RHS.getZExtValue() & 0xFF;
18009 if (Amt >= LHS.getBitWidth())
18010 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18011 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
18015 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
18016 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
18017 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
18018 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
18019 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
18020 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
18021 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
18022 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
18023 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
18030 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18034 case clang::X86::BI__builtin_ia32_cvtb2mask128:
18035 case clang::X86::BI__builtin_ia32_cvtb2mask256:
18036 case clang::X86::BI__builtin_ia32_cvtb2mask512:
18037 case clang::X86::BI__builtin_ia32_cvtw2mask128:
18038 case clang::X86::BI__builtin_ia32_cvtw2mask256:
18039 case clang::X86::BI__builtin_ia32_cvtw2mask512:
18040 case clang::X86::BI__builtin_ia32_cvtd2mask128:
18041 case clang::X86::BI__builtin_ia32_cvtd2mask256:
18042 case clang::X86::BI__builtin_ia32_cvtd2mask512:
18043 case clang::X86::BI__builtin_ia32_cvtq2mask128:
18044 case clang::X86::BI__builtin_ia32_cvtq2mask256:
18045 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
18052 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
18053 llvm::APInt Bits(RetWidth, 0);
18055 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
18057 unsigned MSB = A[A.getBitWidth() - 1];
18058 Bits.setBitVal(ElemNum, MSB);
18061 APSInt RetMask(Bits,
true);
18065 case clang::X86::BI__builtin_ia32_cmpb128_mask:
18066 case clang::X86::BI__builtin_ia32_cmpw128_mask:
18067 case clang::X86::BI__builtin_ia32_cmpd128_mask:
18068 case clang::X86::BI__builtin_ia32_cmpq128_mask:
18069 case clang::X86::BI__builtin_ia32_cmpb256_mask:
18070 case clang::X86::BI__builtin_ia32_cmpw256_mask:
18071 case clang::X86::BI__builtin_ia32_cmpd256_mask:
18072 case clang::X86::BI__builtin_ia32_cmpq256_mask:
18073 case clang::X86::BI__builtin_ia32_cmpb512_mask:
18074 case clang::X86::BI__builtin_ia32_cmpw512_mask:
18075 case clang::X86::BI__builtin_ia32_cmpd512_mask:
18076 case clang::X86::BI__builtin_ia32_cmpq512_mask:
18077 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
18078 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
18079 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
18080 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
18081 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
18082 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
18083 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
18084 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
18085 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
18086 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
18087 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
18088 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
18092 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
18093 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
18106 unsigned RetWidth = Mask.getBitWidth();
18108 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18110 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
18115 switch (
Opcode.getExtValue() & 0x7) {
18120 Result = IsUnsigned ? A.ult(B) : A.slt(B);
18123 Result = IsUnsigned ? A.ule(B) : A.sle(B);
18132 Result = IsUnsigned ? A.uge(B) : A.sge(B);
18135 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
18142 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
18147 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
18148 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
18149 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
18162 unsigned NumBytesInQWord = 8;
18163 unsigned NumBitsInByte = 8;
18165 unsigned NumQWords = NumBytes / NumBytesInQWord;
18166 unsigned RetWidth = ZeroMask.getBitWidth();
18167 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18169 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
18170 APInt SourceQWord(64, 0);
18171 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18175 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
18178 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18179 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
18182 if (ZeroMask[SelIdx]) {
18183 RetMask.setBitVal(SelIdx, SourceQWord[M]);
18195 const LValue &LV) {
18198 if (!LV.getLValueBase())
18203 if (!LV.getLValueDesignator().Invalid &&
18204 !LV.getLValueDesignator().isOnePastTheEnd())
18214 if (LV.getLValueDesignator().Invalid)
18220 return LV.getLValueOffset() == Size;
18230class DataRecursiveIntBinOpEvaluator {
18231 struct EvalResult {
18233 bool Failed =
false;
18235 EvalResult() =
default;
18237 void swap(EvalResult &RHS) {
18239 Failed = RHS.Failed;
18240 RHS.Failed =
false;
18246 EvalResult LHSResult;
18247 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
18250 Job(Job &&) =
default;
18252 void startSpeculativeEval(EvalInfo &Info) {
18253 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
18257 SpeculativeEvaluationRAII SpecEvalRAII;
18260 SmallVector<Job, 16> Queue;
18262 IntExprEvaluator &IntEval;
18267 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
18268 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
18274 static bool shouldEnqueue(
const BinaryOperator *E) {
18281 bool Traverse(
const BinaryOperator *E) {
18283 EvalResult PrevResult;
18284 while (!Queue.empty())
18285 process(PrevResult);
18287 if (PrevResult.Failed)
return false;
18289 FinalResult.
swap(PrevResult.Val);
18300 bool Error(
const Expr *E) {
18301 return IntEval.Error(E);
18304 return IntEval.Error(E, D);
18307 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
18308 return Info.CCEDiag(E, D);
18312 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18313 bool &SuppressRHSDiags);
18315 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18318 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
18324 void process(EvalResult &
Result);
18326 void enqueue(
const Expr *E) {
18328 Queue.resize(Queue.size()+1);
18329 Queue.back().E = E;
18330 Queue.back().Kind = Job::AnyExprKind;
18336bool DataRecursiveIntBinOpEvaluator::
18337 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18338 bool &SuppressRHSDiags) {
18341 if (LHSResult.Failed)
18342 return Info.noteSideEffect();
18351 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
18352 Success(LHSAsBool, E, LHSResult.Val);
18356 LHSResult.Failed =
true;
18360 if (!Info.noteSideEffect())
18366 SuppressRHSDiags =
true;
18375 if (LHSResult.Failed && !Info.noteFailure())
18386 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
18388 uint64_t Offset64 = Offset.getQuantity();
18389 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
18391 : Offset64 + Index64);
18394bool DataRecursiveIntBinOpEvaluator::
18395 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18398 if (RHSResult.Failed)
18405 bool lhsResult, rhsResult;
18420 if (rhsResult == (E->
getOpcode() == BO_LOr))
18431 if (LHSResult.Failed || RHSResult.Failed)
18434 const APValue &LHSVal = LHSResult.Val;
18435 const APValue &RHSVal = RHSResult.Val;
18459 if (!LHSExpr || !RHSExpr)
18461 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
18462 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
18463 if (!LHSAddrExpr || !RHSAddrExpr)
18488void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
18489 Job &job = Queue.back();
18491 switch (job.Kind) {
18492 case Job::AnyExprKind: {
18493 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
18494 if (shouldEnqueue(Bop)) {
18495 job.Kind = Job::BinOpKind;
18496 enqueue(Bop->getLHS());
18501 EvaluateExpr(job.E,
Result);
18506 case Job::BinOpKind: {
18508 bool SuppressRHSDiags =
false;
18509 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
18513 if (SuppressRHSDiags)
18514 job.startSpeculativeEval(Info);
18515 job.LHSResult.swap(
Result);
18516 job.Kind = Job::BinOpVisitedLHSKind;
18521 case Job::BinOpVisitedLHSKind: {
18525 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
18531 llvm_unreachable(
"Invalid Job::Kind!");
18535enum class CmpResult {
18544template <
class SuccessCB,
class AfterCB>
18547 SuccessCB &&
Success, AfterCB &&DoAfter) {
18552 "unsupported binary expression evaluation");
18554 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
18568 if (!LHSOK && !Info.noteFailure())
18573 return Success(CmpResult::Less, E);
18575 return Success(CmpResult::Greater, E);
18576 return Success(CmpResult::Equal, E);
18580 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
18581 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
18584 if (!LHSOK && !Info.noteFailure())
18589 return Success(CmpResult::Less, E);
18591 return Success(CmpResult::Greater, E);
18592 return Success(CmpResult::Equal, E);
18596 ComplexValue LHS, RHS;
18605 LHS.makeComplexFloat();
18606 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
18611 if (!LHSOK && !Info.noteFailure())
18617 RHS.makeComplexFloat();
18618 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
18622 if (LHS.isComplexFloat()) {
18623 APFloat::cmpResult CR_r =
18624 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
18625 APFloat::cmpResult CR_i =
18626 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
18627 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
18628 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18630 assert(IsEquality &&
"invalid complex comparison");
18631 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
18632 LHS.getComplexIntImag() == RHS.getComplexIntImag();
18633 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18639 APFloat RHS(0.0), LHS(0.0);
18642 if (!LHSOK && !Info.noteFailure())
18649 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
18650 if (!Info.InConstantContext &&
18651 APFloatCmpResult == APFloat::cmpUnordered &&
18654 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
18657 auto GetCmpRes = [&]() {
18658 switch (APFloatCmpResult) {
18659 case APFloat::cmpEqual:
18660 return CmpResult::Equal;
18661 case APFloat::cmpLessThan:
18662 return CmpResult::Less;
18663 case APFloat::cmpGreaterThan:
18664 return CmpResult::Greater;
18665 case APFloat::cmpUnordered:
18666 return CmpResult::Unordered;
18668 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
18670 return Success(GetCmpRes(), E);
18674 LValue LHSValue, RHSValue;
18677 if (!LHSOK && !Info.noteFailure())
18688 if (Info.checkingPotentialConstantExpression() &&
18689 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
18691 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
18692 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
18693 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
18694 Info.FFDiag(E, DiagID)
18701 return DiagComparison(
18702 diag::note_constexpr_pointer_comparison_unspecified);
18708 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
18709 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
18710 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
18724 return DiagComparison(diag::note_constexpr_literal_comparison);
18726 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
18731 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
18735 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
18737 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18739 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
18741 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18747 return DiagComparison(
18748 diag::note_constexpr_pointer_comparison_zero_sized);
18749 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
18750 return DiagComparison(
18751 diag::note_constexpr_pointer_comparison_unspecified);
18753 return Success(CmpResult::Unequal, E);
18756 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
18757 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
18759 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
18760 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
18770 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
18771 bool WasArrayIndex;
18774 :
getType(LHSValue.Base).getNonReferenceType(),
18775 LHSDesignator, RHSDesignator, WasArrayIndex);
18782 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
18783 Mismatch < RHSDesignator.Entries.size()) {
18784 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
18785 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
18787 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
18789 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18790 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
18793 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18794 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
18799 diag::note_constexpr_pointer_comparison_differing_access)
18807 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
18810 assert(PtrSize <= 64 &&
"Unexpected pointer width");
18811 uint64_t Mask = ~0ULL >> (64 - PtrSize);
18812 CompareLHS &= Mask;
18813 CompareRHS &= Mask;
18818 if (!LHSValue.Base.
isNull() && IsRelational) {
18822 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
18823 uint64_t OffsetLimit = Size.getQuantity();
18824 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
18828 if (CompareLHS < CompareRHS)
18829 return Success(CmpResult::Less, E);
18830 if (CompareLHS > CompareRHS)
18831 return Success(CmpResult::Greater, E);
18832 return Success(CmpResult::Equal, E);
18836 assert(IsEquality &&
"unexpected member pointer operation");
18839 MemberPtr LHSValue, RHSValue;
18842 if (!LHSOK && !Info.noteFailure())
18850 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
18851 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18852 << LHSValue.getDecl();
18855 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
18856 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18857 << RHSValue.getDecl();
18864 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
18865 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
18866 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18871 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
18872 if (MD->isVirtual())
18873 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18874 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
18875 if (MD->isVirtual())
18876 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18882 bool Equal = LHSValue == RHSValue;
18883 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18888 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
18896 return Success(CmpResult::Equal, E);
18902bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
18906 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18909 case CmpResult::Unequal:
18910 llvm_unreachable(
"should never produce Unequal for three-way comparison");
18911 case CmpResult::Less:
18912 CCR = ComparisonCategoryResult::Less;
18914 case CmpResult::Equal:
18915 CCR = ComparisonCategoryResult::Equal;
18917 case CmpResult::Greater:
18918 CCR = ComparisonCategoryResult::Greater;
18920 case CmpResult::Unordered:
18921 CCR = ComparisonCategoryResult::Unordered;
18926 const ComparisonCategoryInfo &CmpInfo =
18927 Info.Ctx.CompCategories.getInfoForType(E->
getType());
18935 ConstantExprKind::Normal);
18938 return ExprEvaluatorBaseTy::VisitBinCmp(E);
18942bool RecordExprEvaluator::VisitCXXParenListInitExpr(
18943 const CXXParenListInitExpr *E) {
18944 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
18947bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18952 if (!Info.noteFailure())
18956 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
18957 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
18961 "DataRecursiveIntBinOpEvaluator should have handled integral types");
18966 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18967 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
18968 "should only produce Unequal for equality comparisons");
18969 bool IsEqual = CR == CmpResult::Equal,
18970 IsLess = CR == CmpResult::Less,
18971 IsGreater = CR == CmpResult::Greater;
18975 llvm_unreachable(
"unsupported binary operator");
18978 return Success(IsEqual == (Op == BO_EQ), E);
18982 return Success(IsGreater, E);
18984 return Success(IsEqual || IsLess, E);
18986 return Success(IsEqual || IsGreater, E);
18990 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18999 LValue LHSValue, RHSValue;
19002 if (!LHSOK && !Info.noteFailure())
19011 if (Info.checkingPotentialConstantExpression() &&
19012 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19015 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
19016 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
19018 auto DiagArith = [&](
unsigned DiagID) {
19019 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19020 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19021 Info.FFDiag(E, DiagID) << LHS << RHS;
19022 if (LHSExpr && LHSExpr == RHSExpr)
19024 diag::note_constexpr_repeated_literal_eval)
19029 if (!LHSExpr || !RHSExpr)
19030 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
19033 return DiagArith(diag::note_constexpr_literal_arith);
19035 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19036 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19037 if (!LHSAddrExpr || !RHSAddrExpr)
19045 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19046 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19048 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19049 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19055 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
19058 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
19063 CharUnits ElementSize;
19070 if (ElementSize.
isZero()) {
19071 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
19088 APSInt TrueResult = (LHS - RHS) / ElemSize;
19091 if (
Result.extend(65) != TrueResult &&
19097 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19102bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
19103 const UnaryExprOrTypeTraitExpr *E) {
19105 case UETT_PreferredAlignOf:
19106 case UETT_AlignOf: {
19115 case UETT_PtrAuthTypeDiscriminator: {
19121 case UETT_VecStep: {
19125 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
19137 case UETT_DataSizeOf:
19138 case UETT_SizeOf: {
19142 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
19153 case UETT_OpenMPRequiredSimdAlign:
19156 Info.Ctx.toCharUnitsFromBits(
19160 case UETT_VectorElements: {
19164 if (
const auto *VT = Ty->
getAs<VectorType>())
19168 if (Info.InConstantContext)
19169 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
19174 case UETT_CountOf: {
19180 if (
const auto *CAT =
19190 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
19192 if (VAT->getElementType()->isArrayType()) {
19195 if (!VAT->getSizeExpr()) {
19200 std::optional<APSInt> Res =
19201 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
19206 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
19207 Res->getZExtValue()};
19219 llvm_unreachable(
"unknown expr/type trait");
19222bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
19223 Info.Ctx.recordOffsetOfEvaluation(OOE);
19229 for (
unsigned i = 0; i != n; ++i) {
19237 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
19241 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
19242 Result += IdxResult.getSExtValue() * ElementSize;
19247 FieldDecl *MemberDecl = ON.
getField();
19252 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19254 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
19261 llvm_unreachable(
"dependent __builtin_offsetof");
19264 CXXBaseSpecifier *BaseSpec = ON.
getBase();
19273 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19276 CurrentType = BaseSpec->
getType();
19290bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19310 if (Info.checkingForUndefinedBehavior())
19311 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19312 diag::warn_integer_constant_overflow)
19340bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19342 QualType DestType = E->
getType();
19343 QualType SrcType = SubExpr->
getType();
19346 case CK_BaseToDerived:
19347 case CK_DerivedToBase:
19348 case CK_UncheckedDerivedToBase:
19351 case CK_ArrayToPointerDecay:
19352 case CK_FunctionToPointerDecay:
19353 case CK_NullToPointer:
19354 case CK_NullToMemberPointer:
19355 case CK_BaseToDerivedMemberPointer:
19356 case CK_DerivedToBaseMemberPointer:
19357 case CK_ReinterpretMemberPointer:
19358 case CK_ConstructorConversion:
19359 case CK_IntegralToPointer:
19361 case CK_VectorSplat:
19362 case CK_IntegralToFloating:
19363 case CK_FloatingCast:
19364 case CK_CPointerToObjCPointerCast:
19365 case CK_BlockPointerToObjCPointerCast:
19366 case CK_AnyPointerToBlockPointerCast:
19367 case CK_ObjCObjectLValueCast:
19368 case CK_FloatingRealToComplex:
19369 case CK_FloatingComplexToReal:
19370 case CK_FloatingComplexCast:
19371 case CK_FloatingComplexToIntegralComplex:
19372 case CK_IntegralRealToComplex:
19373 case CK_IntegralComplexCast:
19374 case CK_IntegralComplexToFloatingComplex:
19375 case CK_BuiltinFnToFnPtr:
19376 case CK_ZeroToOCLOpaqueType:
19377 case CK_NonAtomicToAtomic:
19378 case CK_AddressSpaceConversion:
19379 case CK_IntToOCLSampler:
19380 case CK_FloatingToFixedPoint:
19381 case CK_FixedPointToFloating:
19382 case CK_FixedPointCast:
19383 case CK_IntegralToFixedPoint:
19384 case CK_MatrixCast:
19385 case CK_HLSLAggregateSplatCast:
19386 llvm_unreachable(
"invalid cast kind for integral value");
19390 case CK_LValueBitCast:
19391 case CK_ARCProduceObject:
19392 case CK_ARCConsumeObject:
19393 case CK_ARCReclaimReturnedObject:
19394 case CK_ARCExtendBlockObject:
19395 case CK_CopyAndAutoreleaseBlockObject:
19398 case CK_UserDefinedConversion:
19399 case CK_LValueToRValue:
19400 case CK_AtomicToNonAtomic:
19402 case CK_LValueToRValueBitCast:
19403 case CK_HLSLArrayRValue:
19404 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19406 case CK_MemberPointerToBoolean:
19407 case CK_PointerToBoolean:
19408 case CK_IntegralToBoolean:
19409 case CK_FloatingToBoolean:
19410 case CK_BooleanToSignedIntegral:
19411 case CK_FloatingComplexToBoolean:
19412 case CK_IntegralComplexToBoolean: {
19417 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
19419 return Success(IntResult, E);
19422 case CK_FixedPointToIntegral: {
19423 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
19427 llvm::APSInt
Result = Src.convertToInt(
19428 Info.Ctx.getIntWidth(DestType),
19435 case CK_FixedPointToBoolean: {
19438 if (!
Evaluate(Val, Info, SubExpr))
19443 case CK_IntegralCast: {
19444 if (!Visit(SubExpr))
19454 if (
Result.isAddrLabelDiff()) {
19455 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
19456 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
19459 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
19462 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
19474 if (!ED->isFixed()) {
19478 ED->getValueRange(
Max,
Min);
19481 if (ED->getNumNegativeBits() &&
19482 (
Max.slt(
Result.getInt().getSExtValue()) ||
19483 Min.sgt(
Result.getInt().getSExtValue())))
19484 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19485 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
19486 <<
Max.getSExtValue() << ED;
19487 else if (!ED->getNumNegativeBits() &&
19488 Max.ult(
Result.getInt().getZExtValue()))
19489 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19490 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
19491 <<
Max.getZExtValue() << ED;
19499 case CK_PointerToIntegral: {
19500 CCEDiag(E, diag::note_constexpr_invalid_cast)
19501 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
19508 if (LV.getLValueBase()) {
19513 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
19516 LV.Designator.setInvalid();
19524 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
19525 llvm_unreachable(
"Can't cast this!");
19530 case CK_IntegralComplexToReal: {
19534 return Success(
C.getComplexIntReal(), E);
19537 case CK_FloatingToIntegral: {
19547 case CK_HLSLVectorTruncation: {
19553 case CK_HLSLMatrixTruncation: {
19559 case CK_HLSLElementwiseCast: {
19572 return Success(ResultVal, E);
19576 llvm_unreachable(
"unknown cast resulting in integral value");
19579bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
19584 if (!LV.isComplexInt())
19586 return Success(LV.getComplexIntReal(), E);
19592bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
19597 if (!LV.isComplexInt())
19599 return Success(LV.getComplexIntImag(), E);
19606bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
19610bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
19614bool IntExprEvaluator::VisitConceptSpecializationExpr(
19615 const ConceptSpecializationExpr *E) {
19619bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
19623bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19633 if (!
Result.isFixedPoint())
19636 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
19650bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19652 QualType DestType = E->
getType();
19654 "Expected destination type to be a fixed point type");
19655 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
19658 case CK_FixedPointCast: {
19659 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
19663 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
19665 if (Info.checkingForUndefinedBehavior())
19666 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19667 diag::warn_fixedpoint_constant_overflow)
19674 case CK_IntegralToFixedPoint: {
19680 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
19681 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
19684 if (Info.checkingForUndefinedBehavior())
19685 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19686 diag::warn_fixedpoint_constant_overflow)
19687 << IntResult.toString() << E->
getType();
19692 return Success(IntResult, E);
19694 case CK_FloatingToFixedPoint: {
19700 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
19701 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
19704 if (Info.checkingForUndefinedBehavior())
19705 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19706 diag::warn_fixedpoint_constant_overflow)
19715 case CK_LValueToRValue:
19716 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19722bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19724 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19726 const Expr *LHS = E->
getLHS();
19727 const Expr *RHS = E->
getRHS();
19729 Info.Ctx.getFixedPointSemantics(E->
getType());
19731 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
19734 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
19738 bool OpOverflow =
false, ConversionOverflow =
false;
19739 APFixedPoint
Result(LHSFX.getSemantics());
19742 Result = LHSFX.add(RHSFX, &OpOverflow)
19743 .convert(ResultFXSema, &ConversionOverflow);
19747 Result = LHSFX.sub(RHSFX, &OpOverflow)
19748 .convert(ResultFXSema, &ConversionOverflow);
19752 Result = LHSFX.mul(RHSFX, &OpOverflow)
19753 .convert(ResultFXSema, &ConversionOverflow);
19757 if (RHSFX.getValue() == 0) {
19758 Info.FFDiag(E, diag::note_expr_divide_by_zero);
19761 Result = LHSFX.div(RHSFX, &OpOverflow)
19762 .convert(ResultFXSema, &ConversionOverflow);
19768 llvm::APSInt RHSVal = RHSFX.getValue();
19771 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
19772 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
19776 if (RHSVal.isNegative())
19777 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
19778 else if (Amt != RHSVal)
19779 Info.CCEDiag(E, diag::note_constexpr_large_shift)
19780 << RHSVal << E->
getType() << ShiftBW;
19783 Result = LHSFX.shl(Amt, &OpOverflow);
19785 Result = LHSFX.shr(Amt, &OpOverflow);
19791 if (OpOverflow || ConversionOverflow) {
19792 if (Info.checkingForUndefinedBehavior())
19793 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19794 diag::warn_fixedpoint_constant_overflow)
19807class FloatExprEvaluator
19808 :
public ExprEvaluatorBase<FloatExprEvaluator> {
19811 FloatExprEvaluator(EvalInfo &info, APFloat &result)
19812 : ExprEvaluatorBaseTy(info),
Result(result) {}
19819 bool ZeroInitialization(
const Expr *E) {
19820 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
19824 bool VisitCallExpr(
const CallExpr *E);
19826 bool VisitUnaryOperator(
const UnaryOperator *E);
19827 bool VisitBinaryOperator(
const BinaryOperator *E);
19828 bool VisitFloatingLiteral(
const FloatingLiteral *E);
19829 bool VisitCastExpr(
const CastExpr *E);
19831 bool VisitUnaryReal(
const UnaryOperator *E);
19832 bool VisitUnaryImag(
const UnaryOperator *E);
19841 return FloatExprEvaluator(Info,
Result).Visit(E);
19848 llvm::APFloat &
Result) {
19850 if (!S)
return false;
19852 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
19858 fill = llvm::APInt(32, 0);
19859 else if (S->
getString().getAsInteger(0, fill))
19862 if (Context.getTargetInfo().isNan2008()) {
19864 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19866 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19874 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19876 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19882bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
19883 if (!IsConstantEvaluatedBuiltinCall(E))
19884 return ExprEvaluatorBaseTy::VisitCallExpr(E);
19890 case Builtin::BI__builtin_huge_val:
19891 case Builtin::BI__builtin_huge_valf:
19892 case Builtin::BI__builtin_huge_vall:
19893 case Builtin::BI__builtin_huge_valf16:
19894 case Builtin::BI__builtin_huge_valf128:
19895 case Builtin::BI__builtin_inf:
19896 case Builtin::BI__builtin_inff:
19897 case Builtin::BI__builtin_infl:
19898 case Builtin::BI__builtin_inff16:
19899 case Builtin::BI__builtin_inff128: {
19900 const llvm::fltSemantics &Sem =
19901 Info.Ctx.getFloatTypeSemantics(E->
getType());
19902 Result = llvm::APFloat::getInf(Sem);
19906 case Builtin::BI__builtin_nans:
19907 case Builtin::BI__builtin_nansf:
19908 case Builtin::BI__builtin_nansl:
19909 case Builtin::BI__builtin_nansf16:
19910 case Builtin::BI__builtin_nansf128:
19916 case Builtin::BI__builtin_nan:
19917 case Builtin::BI__builtin_nanf:
19918 case Builtin::BI__builtin_nanl:
19919 case Builtin::BI__builtin_nanf16:
19920 case Builtin::BI__builtin_nanf128:
19928 case Builtin::BI__builtin_elementwise_abs:
19929 case Builtin::BI__builtin_fabs:
19930 case Builtin::BI__builtin_fabsf:
19931 case Builtin::BI__builtin_fabsl:
19932 case Builtin::BI__builtin_fabsf128:
19941 if (
Result.isNegative())
19945 case Builtin::BI__arithmetic_fence:
19952 case Builtin::BI__builtin_copysign:
19953 case Builtin::BI__builtin_copysignf:
19954 case Builtin::BI__builtin_copysignl:
19955 case Builtin::BI__builtin_copysignf128: {
19964 case Builtin::BI__builtin_fmax:
19965 case Builtin::BI__builtin_fmaxf:
19966 case Builtin::BI__builtin_fmaxl:
19967 case Builtin::BI__builtin_fmaxf16:
19968 case Builtin::BI__builtin_fmaxf128: {
19977 case Builtin::BI__builtin_fmin:
19978 case Builtin::BI__builtin_fminf:
19979 case Builtin::BI__builtin_fminl:
19980 case Builtin::BI__builtin_fminf16:
19981 case Builtin::BI__builtin_fminf128: {
19990 case Builtin::BI__builtin_fmaximum_num:
19991 case Builtin::BI__builtin_fmaximum_numf:
19992 case Builtin::BI__builtin_fmaximum_numl:
19993 case Builtin::BI__builtin_fmaximum_numf16:
19994 case Builtin::BI__builtin_fmaximum_numf128: {
20003 case Builtin::BI__builtin_fminimum_num:
20004 case Builtin::BI__builtin_fminimum_numf:
20005 case Builtin::BI__builtin_fminimum_numl:
20006 case Builtin::BI__builtin_fminimum_numf16:
20007 case Builtin::BI__builtin_fminimum_numf128: {
20016 case Builtin::BI__builtin_elementwise_fma: {
20021 APFloat SourceY(0.), SourceZ(0.);
20027 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
20031 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
20038 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
20044bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20056bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20066 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
20067 Result = llvm::APFloat::getZero(Sem);
20071bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20073 default:
return Error(E);
20087bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20089 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20093 if (!LHSOK && !Info.noteFailure())
20099bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
20104bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20109 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20111 case CK_HLSLAggregateSplatCast:
20112 llvm_unreachable(
"invalid cast kind for floating value");
20114 case CK_IntegralToFloating: {
20117 Info.Ctx.getLangOpts());
20123 case CK_FixedPointToFloating: {
20124 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20128 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20132 case CK_FloatingCast: {
20133 if (!Visit(SubExpr))
20139 case CK_FloatingComplexToReal: {
20143 Result =
V.getComplexFloatReal();
20146 case CK_HLSLVectorTruncation: {
20152 case CK_HLSLMatrixTruncation: {
20158 case CK_HLSLElementwiseCast: {
20173 return Success(ResultVal, E);
20183class ComplexExprEvaluator
20184 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
20188 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
20196 bool ZeroInitialization(
const Expr *E);
20202 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
20203 bool VisitCastExpr(
const CastExpr *E);
20204 bool VisitBinaryOperator(
const BinaryOperator *E);
20205 bool VisitUnaryOperator(
const UnaryOperator *E);
20206 bool VisitInitListExpr(
const InitListExpr *E);
20207 bool VisitCallExpr(
const CallExpr *E);
20215 return ComplexExprEvaluator(Info,
Result).Visit(E);
20218bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
20219 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
20221 Result.makeComplexFloat();
20222 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
20226 Result.makeComplexInt();
20227 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
20234bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
20238 Result.makeComplexFloat();
20247 "Unexpected imaginary literal.");
20249 Result.makeComplexInt();
20254 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
20259bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20263 case CK_BaseToDerived:
20264 case CK_DerivedToBase:
20265 case CK_UncheckedDerivedToBase:
20268 case CK_ArrayToPointerDecay:
20269 case CK_FunctionToPointerDecay:
20270 case CK_NullToPointer:
20271 case CK_NullToMemberPointer:
20272 case CK_BaseToDerivedMemberPointer:
20273 case CK_DerivedToBaseMemberPointer:
20274 case CK_MemberPointerToBoolean:
20275 case CK_ReinterpretMemberPointer:
20276 case CK_ConstructorConversion:
20277 case CK_IntegralToPointer:
20278 case CK_PointerToIntegral:
20279 case CK_PointerToBoolean:
20281 case CK_VectorSplat:
20282 case CK_IntegralCast:
20283 case CK_BooleanToSignedIntegral:
20284 case CK_IntegralToBoolean:
20285 case CK_IntegralToFloating:
20286 case CK_FloatingToIntegral:
20287 case CK_FloatingToBoolean:
20288 case CK_FloatingCast:
20289 case CK_CPointerToObjCPointerCast:
20290 case CK_BlockPointerToObjCPointerCast:
20291 case CK_AnyPointerToBlockPointerCast:
20292 case CK_ObjCObjectLValueCast:
20293 case CK_FloatingComplexToReal:
20294 case CK_FloatingComplexToBoolean:
20295 case CK_IntegralComplexToReal:
20296 case CK_IntegralComplexToBoolean:
20297 case CK_ARCProduceObject:
20298 case CK_ARCConsumeObject:
20299 case CK_ARCReclaimReturnedObject:
20300 case CK_ARCExtendBlockObject:
20301 case CK_CopyAndAutoreleaseBlockObject:
20302 case CK_BuiltinFnToFnPtr:
20303 case CK_ZeroToOCLOpaqueType:
20304 case CK_NonAtomicToAtomic:
20305 case CK_AddressSpaceConversion:
20306 case CK_IntToOCLSampler:
20307 case CK_FloatingToFixedPoint:
20308 case CK_FixedPointToFloating:
20309 case CK_FixedPointCast:
20310 case CK_FixedPointToBoolean:
20311 case CK_FixedPointToIntegral:
20312 case CK_IntegralToFixedPoint:
20313 case CK_MatrixCast:
20314 case CK_HLSLVectorTruncation:
20315 case CK_HLSLMatrixTruncation:
20316 case CK_HLSLElementwiseCast:
20317 case CK_HLSLAggregateSplatCast:
20318 llvm_unreachable(
"invalid cast kind for complex value");
20320 case CK_LValueToRValue:
20321 case CK_AtomicToNonAtomic:
20323 case CK_LValueToRValueBitCast:
20324 case CK_HLSLArrayRValue:
20325 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20328 case CK_LValueBitCast:
20329 case CK_UserDefinedConversion:
20332 case CK_FloatingRealToComplex: {
20337 Result.makeComplexFloat();
20342 case CK_FloatingComplexCast: {
20346 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20354 case CK_FloatingComplexToIntegralComplex: {
20358 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20361 Result.makeComplexInt();
20368 case CK_IntegralRealToComplex: {
20373 Result.makeComplexInt();
20374 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
20378 case CK_IntegralComplexCast: {
20382 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20391 case CK_IntegralComplexToFloatingComplex: {
20396 Info.Ctx.getLangOpts());
20397 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20400 Result.makeComplexFloat();
20402 To,
Result.FloatReal) &&
20408 llvm_unreachable(
"unknown cast resulting in complex value");
20413 const uint8_t GFInv[256] = {
20414 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
20415 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
20416 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
20417 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
20418 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
20419 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
20420 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
20421 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
20422 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
20423 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
20424 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
20425 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
20426 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
20427 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
20428 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
20429 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
20430 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
20431 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
20432 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
20433 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
20434 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
20435 0xcd, 0x1a, 0x41, 0x1c};
20437 return GFInv[Byte];
20442 unsigned NumBitsInByte = 8;
20444 uint8_t RetByte = 0;
20445 for (uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20447 AQword.lshr((7 -
static_cast<int32_t
>(BitIdx)) * NumBitsInByte)
20454 Product = AByte & XByte;
20456 uint8_t Parity = 0;
20459 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
20460 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
20463 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
20464 RetByte |= (Temp ^ Parity) << BitIdx;
20473 uint16_t TWord = 0;
20474 unsigned NumBitsInByte = 8;
20475 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20476 if ((BByte >> BitIdx) & 0x1) {
20477 TWord = TWord ^ (AByte << BitIdx);
20485 for (int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
20486 if ((TWord >> BitIdx) & 0x1) {
20487 TWord = TWord ^ (0x11B << (BitIdx - 8));
20490 return (TWord & 0xFF);
20494 APFloat &ResR, APFloat &ResI) {
20500 APFloat AC = A *
C;
20501 APFloat BD = B * D;
20502 APFloat AD = A * D;
20503 APFloat BC = B *
C;
20506 if (ResR.isNaN() && ResI.isNaN()) {
20507 bool Recalc =
false;
20508 if (A.isInfinity() || B.isInfinity()) {
20509 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20511 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20514 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20516 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20519 if (
C.isInfinity() || D.isInfinity()) {
20520 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20522 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20525 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20527 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20530 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
20531 BC.isInfinity())) {
20533 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20535 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20537 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20539 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20543 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
20544 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
20550 APFloat &ResR, APFloat &ResI) {
20557 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
20558 if (MaxCD.isFinite()) {
20559 DenomLogB =
ilogb(MaxCD);
20560 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
20561 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
20563 APFloat Denom =
C *
C + D * D;
20565 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20567 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20568 if (ResR.isNaN() && ResI.isNaN()) {
20569 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
20570 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
20571 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
20572 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
20574 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20576 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20578 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
20579 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
20580 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
20581 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20583 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20585 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
20586 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
20593 APSInt NormAmt = Amount;
20594 unsigned BitWidth =
Value.getBitWidth();
20595 unsigned AmtBitWidth = NormAmt.getBitWidth();
20596 if (BitWidth == 1) {
20598 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
20599 }
else if (BitWidth == 2) {
20604 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
20607 if (AmtBitWidth > BitWidth) {
20608 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
20610 Divisor = llvm::APInt(BitWidth, BitWidth);
20611 if (AmtBitWidth < BitWidth) {
20612 NormAmt = NormAmt.extend(BitWidth);
20617 if (NormAmt.isSigned()) {
20618 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
20619 if (NormAmt.isNegative()) {
20620 APSInt SignedDivisor(Divisor,
false);
20621 NormAmt += SignedDivisor;
20624 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
20631bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20633 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20637 bool LHSReal =
false, RHSReal =
false;
20645 Result.makeComplexFloat();
20649 LHSOK = Visit(E->
getLHS());
20651 if (!LHSOK && !Info.noteFailure())
20657 APFloat &Real = RHS.FloatReal;
20660 RHS.makeComplexFloat();
20661 RHS.FloatImag =
APFloat(Real.getSemantics());
20665 assert(!(LHSReal && RHSReal) &&
20666 "Cannot have both operands of a complex operation be real.");
20668 default:
return Error(E);
20670 if (
Result.isComplexFloat()) {
20671 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
20672 APFloat::rmNearestTiesToEven);
20674 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20676 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
20677 APFloat::rmNearestTiesToEven);
20679 Result.getComplexIntReal() += RHS.getComplexIntReal();
20680 Result.getComplexIntImag() += RHS.getComplexIntImag();
20684 if (
Result.isComplexFloat()) {
20685 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
20686 APFloat::rmNearestTiesToEven);
20688 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20689 Result.getComplexFloatImag().changeSign();
20690 }
else if (!RHSReal) {
20691 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
20692 APFloat::rmNearestTiesToEven);
20695 Result.getComplexIntReal() -= RHS.getComplexIntReal();
20696 Result.getComplexIntImag() -= RHS.getComplexIntImag();
20700 if (
Result.isComplexFloat()) {
20705 ComplexValue LHS =
Result;
20706 APFloat &A = LHS.getComplexFloatReal();
20707 APFloat &B = LHS.getComplexFloatImag();
20708 APFloat &
C = RHS.getComplexFloatReal();
20709 APFloat &D = RHS.getComplexFloatImag();
20713 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
20721 }
else if (RHSReal) {
20733 ComplexValue LHS =
Result;
20734 Result.getComplexIntReal() =
20735 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
20736 LHS.getComplexIntImag() * RHS.getComplexIntImag());
20737 Result.getComplexIntImag() =
20738 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
20739 LHS.getComplexIntImag() * RHS.getComplexIntReal());
20743 if (
Result.isComplexFloat()) {
20748 ComplexValue LHS =
Result;
20749 APFloat &A = LHS.getComplexFloatReal();
20750 APFloat &B = LHS.getComplexFloatImag();
20751 APFloat &
C = RHS.getComplexFloatReal();
20752 APFloat &D = RHS.getComplexFloatImag();
20766 B = APFloat::getZero(A.getSemantics());
20771 ComplexValue LHS =
Result;
20772 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
20773 RHS.getComplexIntImag() * RHS.getComplexIntImag();
20775 return Error(E, diag::note_expr_divide_by_zero);
20777 Result.getComplexIntReal() =
20778 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
20779 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
20780 Result.getComplexIntImag() =
20781 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
20782 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
20790bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20804 if (
Result.isComplexFloat()) {
20805 Result.getComplexFloatReal().changeSign();
20806 Result.getComplexFloatImag().changeSign();
20809 Result.getComplexIntReal() = -
Result.getComplexIntReal();
20810 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20814 if (
Result.isComplexFloat())
20815 Result.getComplexFloatImag().changeSign();
20817 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20822bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
20825 Result.makeComplexFloat();
20831 Result.makeComplexInt();
20839 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
20842bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20843 if (!IsConstantEvaluatedBuiltinCall(E))
20844 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20847 case Builtin::BI__builtin_complex:
20848 Result.makeComplexFloat();
20866class AtomicExprEvaluator :
20867 public ExprEvaluatorBase<AtomicExprEvaluator> {
20868 const LValue *
This;
20871 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
20879 bool ZeroInitialization(
const Expr *E) {
20880 ImplicitValueInitExpr VIE(
20888 bool VisitCastExpr(
const CastExpr *E) {
20891 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20892 case CK_NullToPointer:
20894 return ZeroInitialization(E);
20895 case CK_NonAtomicToAtomic:
20907 return AtomicExprEvaluator(Info,
This,
Result).Visit(E);
20916class VoidExprEvaluator
20917 :
public ExprEvaluatorBase<VoidExprEvaluator> {
20919 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
20923 bool ZeroInitialization(
const Expr *E) {
return true; }
20925 bool VisitCastExpr(
const CastExpr *E) {
20928 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20935 bool VisitCallExpr(
const CallExpr *E) {
20936 if (!IsConstantEvaluatedBuiltinCall(E))
20937 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20940 case Builtin::BI__assume:
20941 case Builtin::BI__builtin_assume:
20945 case Builtin::BI__builtin_operator_delete:
20953 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
20957bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
20959 if (Info.SpeculativeEvaluationDepth)
20963 if (!OperatorDelete
20964 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
20965 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
20975 if (
Pointer.Designator.Invalid)
20979 if (
Pointer.isNullPointer()) {
20983 if (!Info.getLangOpts().CPlusPlus20)
20984 Info.CCEDiag(E, diag::note_constexpr_new);
20992 QualType AllocType =
Pointer.Base.getDynamicAllocType();
20998 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
21007 if (VirtualDelete &&
21009 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21010 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21017 (*Alloc)->Value, AllocType))
21020 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
21025 Info.FFDiag(E, diag::note_constexpr_double_delete);
21035 return VoidExprEvaluator(Info).Visit(E);
21047 if (E->
isGLValue() || T->isFunctionType()) {
21052 }
else if (T->isVectorType()) {
21055 }
else if (T->isConstantMatrixType()) {
21058 }
else if (T->isIntegralOrEnumerationType()) {
21059 if (!IntExprEvaluator(Info,
Result).Visit(E))
21061 }
else if (T->hasPointerRepresentation()) {
21066 }
else if (T->isRealFloatingType()) {
21067 llvm::APFloat F(0.0);
21071 }
else if (T->isAnyComplexType()) {
21076 }
else if (T->isFixedPointType()) {
21077 if (!FixedPointExprEvaluator(Info,
Result).Visit(E))
return false;
21078 }
else if (T->isMemberPointerType()) {
21084 }
else if (T->isArrayType()) {
21087 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
21091 }
else if (T->isRecordType()) {
21094 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
21098 }
else if (T->isVoidType()) {
21099 if (!Info.getLangOpts().CPlusPlus11)
21100 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
21104 }
else if (T->isAtomicType()) {
21109 E, Unqual, ScopeKind::FullExpression, LV);
21117 }
else if (Info.getLangOpts().CPlusPlus11) {
21118 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
21121 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
21132 const Expr *E,
bool AllowNonLiteralTypes) {
21148 if (T->isArrayType())
21150 else if (T->isRecordType())
21152 else if (T->isAtomicType()) {
21174 if (Info.EnableNewConstInterp) {
21175 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E,
Result))
21178 ConstantExprKind::Normal);
21187 LV.setFrom(Info.Ctx,
Result);
21194 ConstantExprKind::Normal) &&
21202 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
21204 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
21209 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
21215 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
21221 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
21227 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
21228 if (CE->hasAPValueResult()) {
21229 APValue APV = CE->getAPValueResult();
21231 Result = std::move(APV);
21307 bool InConstantContext)
const {
21309 "Expression evaluator can't be called on a dependent expression.");
21310 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
21312 Info.InConstantContext = InConstantContext;
21313 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
21317 bool InConstantContext)
const {
21319 "Expression evaluator can't be called on a dependent expression.");
21320 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
21328 bool InConstantContext)
const {
21330 "Expression evaluator can't be called on a dependent expression.");
21331 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
21333 Info.InConstantContext = InConstantContext;
21334 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
21339 bool InConstantContext)
const {
21341 "Expression evaluator can't be called on a dependent expression.");
21342 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
21344 Info.InConstantContext = InConstantContext;
21345 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
21350 bool InConstantContext)
const {
21352 "Expression evaluator can't be called on a dependent expression.");
21354 if (!
getType()->isRealFloatingType())
21357 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
21369 bool InConstantContext)
const {
21371 "Expression evaluator can't be called on a dependent expression.");
21373 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
21375 Info.InConstantContext = InConstantContext;
21379 if (Info.EnableNewConstInterp) {
21380 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val,
21381 ConstantExprKind::Normal))
21384 LV.setFrom(Ctx,
Result.Val);
21387 ConstantExprKind::Normal, CheckedTemps);
21390 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
21391 Result.HasSideEffects ||
21394 ConstantExprKind::Normal, CheckedTemps))
21397 LV.moveInto(
Result.Val);
21404 bool IsConstantDestruction) {
21405 EvalInfo Info(Ctx, EStatus,
21408 Info.setEvaluatingDecl(
Base, DestroyedValue,
21409 EvalInfo::EvaluatingDeclKind::Dtor);
21410 Info.InConstantContext = IsConstantDestruction;
21419 if (!Info.discardCleanups())
21420 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21428 "Expression evaluator can't be called on a dependent expression.");
21434 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
21436 EvalInfo Info(Ctx,
Result, EM);
21437 Info.InConstantContext =
true;
21439 if (Info.EnableNewConstInterp) {
21440 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val, Kind))
21443 getStorageType(Ctx,
this),
Result.Val, Kind);
21448 if (Kind == ConstantExprKind::ClassTemplateArgument)
21464 FullExpressionRAII
Scope(Info);
21469 if (!Info.discardCleanups())
21470 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21480 if (Kind == ConstantExprKind::ClassTemplateArgument &&
21483 Result.HasSideEffects)) {
21495 bool IsConstantInitialization)
const {
21497 "Expression evaluator can't be called on a dependent expression.");
21498 assert(VD &&
"Need a valid VarDecl");
21500 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
21502 llvm::raw_string_ostream OS(Name);
21508 EStatus.
Diag = &Notes;
21510 EvalInfo Info(Ctx, EStatus,
21511 (IsConstantInitialization &&
21515 Info.setEvaluatingDecl(VD,
Value);
21516 Info.InConstantContext = IsConstantInitialization;
21521 if (Info.EnableNewConstInterp) {
21523 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
21527 ConstantExprKind::Normal);
21542 FullExpressionRAII
Scope(Info);
21545 EStatus.HasSideEffects)
21551 Info.performLifetimeExtension();
21553 if (!Info.discardCleanups())
21554 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21558 ConstantExprKind::Normal) &&
21565 EStatus.
Diag = &Notes;
21582 EvalInfo Info(Ctx, EStatus,
21585 Info.setEvaluatingDecl(
this, DestroyedValue,
21586 EvalInfo::EvaluatingDeclKind::Dtor);
21587 Info.InConstantContext = IsConstantDestruction;
21589 std::move(DestroyedValue)))
21596 getLocation(), EStatus, IsConstantDestruction) ||
21608 "Expression evaluator can't be called on a dependent expression.");
21617 "Expression evaluator can't be called on a dependent expression.");
21619 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
21622 Info.InConstantContext =
true;
21626 assert(
Result &&
"Could not evaluate expression");
21627 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
21629 return EVResult.Val.getInt();
21635 "Expression evaluator can't be called on a dependent expression.");
21637 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
21639 EVResult.Diag =
Diag;
21641 Info.InConstantContext =
true;
21642 Info.CheckingForUndefinedBehavior =
true;
21646 assert(
Result &&
"Could not evaluate expression");
21647 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
21649 return EVResult.Val.getInt();
21654 "Expression evaluator can't be called on a dependent expression.");
21656 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
21661 Info.CheckingForUndefinedBehavior =
true;
21667 assert(
Val.isLValue());
21693 IK_ICEIfUnevaluated,
21709static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
21716 Info.InConstantContext =
true;
21725 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
21730#define ABSTRACT_STMT(Node)
21731#define STMT(Node, Base) case Expr::Node##Class:
21732#define EXPR(Node, Base)
21733#include "clang/AST/StmtNodes.inc"
21734 case Expr::PredefinedExprClass:
21735 case Expr::FloatingLiteralClass:
21736 case Expr::ImaginaryLiteralClass:
21737 case Expr::StringLiteralClass:
21738 case Expr::ArraySubscriptExprClass:
21739 case Expr::MatrixSingleSubscriptExprClass:
21740 case Expr::MatrixSubscriptExprClass:
21741 case Expr::ArraySectionExprClass:
21742 case Expr::OMPArrayShapingExprClass:
21743 case Expr::OMPIteratorExprClass:
21744 case Expr::CompoundAssignOperatorClass:
21745 case Expr::CompoundLiteralExprClass:
21746 case Expr::ExtVectorElementExprClass:
21747 case Expr::MatrixElementExprClass:
21748 case Expr::DesignatedInitExprClass:
21749 case Expr::ArrayInitLoopExprClass:
21750 case Expr::ArrayInitIndexExprClass:
21751 case Expr::NoInitExprClass:
21752 case Expr::DesignatedInitUpdateExprClass:
21753 case Expr::ImplicitValueInitExprClass:
21754 case Expr::ParenListExprClass:
21755 case Expr::VAArgExprClass:
21756 case Expr::AddrLabelExprClass:
21757 case Expr::StmtExprClass:
21758 case Expr::CXXMemberCallExprClass:
21759 case Expr::CUDAKernelCallExprClass:
21760 case Expr::CXXAddrspaceCastExprClass:
21761 case Expr::CXXDynamicCastExprClass:
21762 case Expr::CXXTypeidExprClass:
21763 case Expr::CXXUuidofExprClass:
21764 case Expr::MSPropertyRefExprClass:
21765 case Expr::MSPropertySubscriptExprClass:
21766 case Expr::CXXNullPtrLiteralExprClass:
21767 case Expr::UserDefinedLiteralClass:
21768 case Expr::CXXThisExprClass:
21769 case Expr::CXXThrowExprClass:
21770 case Expr::CXXNewExprClass:
21771 case Expr::CXXDeleteExprClass:
21772 case Expr::CXXPseudoDestructorExprClass:
21773 case Expr::UnresolvedLookupExprClass:
21774 case Expr::RecoveryExprClass:
21775 case Expr::DependentScopeDeclRefExprClass:
21776 case Expr::CXXConstructExprClass:
21777 case Expr::CXXInheritedCtorInitExprClass:
21778 case Expr::CXXStdInitializerListExprClass:
21779 case Expr::CXXBindTemporaryExprClass:
21780 case Expr::ExprWithCleanupsClass:
21781 case Expr::CXXTemporaryObjectExprClass:
21782 case Expr::CXXUnresolvedConstructExprClass:
21783 case Expr::CXXDependentScopeMemberExprClass:
21784 case Expr::UnresolvedMemberExprClass:
21785 case Expr::ObjCStringLiteralClass:
21786 case Expr::ObjCBoxedExprClass:
21787 case Expr::ObjCArrayLiteralClass:
21788 case Expr::ObjCDictionaryLiteralClass:
21789 case Expr::ObjCEncodeExprClass:
21790 case Expr::ObjCMessageExprClass:
21791 case Expr::ObjCSelectorExprClass:
21792 case Expr::ObjCProtocolExprClass:
21793 case Expr::ObjCIvarRefExprClass:
21794 case Expr::ObjCPropertyRefExprClass:
21795 case Expr::ObjCSubscriptRefExprClass:
21796 case Expr::ObjCIsaExprClass:
21797 case Expr::ObjCAvailabilityCheckExprClass:
21798 case Expr::ShuffleVectorExprClass:
21799 case Expr::ConvertVectorExprClass:
21800 case Expr::BlockExprClass:
21802 case Expr::OpaqueValueExprClass:
21803 case Expr::PackExpansionExprClass:
21804 case Expr::SubstNonTypeTemplateParmPackExprClass:
21805 case Expr::FunctionParmPackExprClass:
21806 case Expr::AsTypeExprClass:
21807 case Expr::ObjCIndirectCopyRestoreExprClass:
21808 case Expr::MaterializeTemporaryExprClass:
21809 case Expr::PseudoObjectExprClass:
21810 case Expr::AtomicExprClass:
21811 case Expr::LambdaExprClass:
21812 case Expr::CXXFoldExprClass:
21813 case Expr::CoawaitExprClass:
21814 case Expr::DependentCoawaitExprClass:
21815 case Expr::CoyieldExprClass:
21816 case Expr::SYCLUniqueStableNameExprClass:
21817 case Expr::CXXParenListInitExprClass:
21818 case Expr::HLSLOutArgExprClass:
21821 case Expr::MemberExprClass: {
21824 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
21827 ME = M->getBase()->IgnoreParenImpCasts();
21829 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
21831 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
21839 case Expr::InitListExprClass: {
21850 case Expr::SizeOfPackExprClass:
21851 case Expr::GNUNullExprClass:
21852 case Expr::SourceLocExprClass:
21853 case Expr::EmbedExprClass:
21854 case Expr::OpenACCAsteriskSizeExprClass:
21857 case Expr::PackIndexingExprClass:
21860 case Expr::SubstNonTypeTemplateParmExprClass:
21864 case Expr::ConstantExprClass:
21867 case Expr::ParenExprClass:
21869 case Expr::GenericSelectionExprClass:
21871 case Expr::IntegerLiteralClass:
21872 case Expr::FixedPointLiteralClass:
21873 case Expr::CharacterLiteralClass:
21874 case Expr::ObjCBoolLiteralExprClass:
21875 case Expr::CXXBoolLiteralExprClass:
21876 case Expr::CXXScalarValueInitExprClass:
21877 case Expr::TypeTraitExprClass:
21878 case Expr::ConceptSpecializationExprClass:
21879 case Expr::RequiresExprClass:
21880 case Expr::ArrayTypeTraitExprClass:
21881 case Expr::ExpressionTraitExprClass:
21882 case Expr::CXXNoexceptExprClass:
21883 case Expr::CXXReflectExprClass:
21885 case Expr::CallExprClass:
21886 case Expr::CXXOperatorCallExprClass: {
21895 case Expr::CXXRewrittenBinaryOperatorClass:
21898 case Expr::DeclRefExprClass: {
21912 const VarDecl *VD = dyn_cast<VarDecl>(D);
21919 case Expr::UnaryOperatorClass: {
21942 llvm_unreachable(
"invalid unary operator class");
21944 case Expr::OffsetOfExprClass: {
21953 case Expr::UnaryExprOrTypeTraitExprClass: {
21955 if ((Exp->
getKind() == UETT_SizeOf) &&
21958 if (Exp->
getKind() == UETT_CountOf) {
21965 if (VAT->getElementType()->isArrayType())
21977 case Expr::BinaryOperatorClass: {
22022 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
22025 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22026 if (REval.isSigned() && REval.isAllOnes()) {
22028 if (LEval.isMinSignedValue())
22029 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22037 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
22038 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22044 return Worst(LHSResult, RHSResult);
22050 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
22060 return Worst(LHSResult, RHSResult);
22063 llvm_unreachable(
"invalid binary operator kind");
22065 case Expr::ImplicitCastExprClass:
22066 case Expr::CStyleCastExprClass:
22067 case Expr::CXXFunctionalCastExprClass:
22068 case Expr::CXXStaticCastExprClass:
22069 case Expr::CXXReinterpretCastExprClass:
22070 case Expr::CXXConstCastExprClass:
22071 case Expr::ObjCBridgedCastExprClass: {
22078 APSInt IgnoredVal(DestWidth, !DestSigned);
22083 if (FL->getValue().convertToInteger(IgnoredVal,
22084 llvm::APFloat::rmTowardZero,
22085 &Ignored) & APFloat::opInvalidOp)
22091 case CK_LValueToRValue:
22092 case CK_AtomicToNonAtomic:
22093 case CK_NonAtomicToAtomic:
22095 case CK_IntegralToBoolean:
22096 case CK_IntegralCast:
22102 case Expr::BinaryConditionalOperatorClass: {
22105 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
22107 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
22108 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
22109 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
22111 return FalseResult;
22113 case Expr::ConditionalOperatorClass: {
22121 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
22124 if (CondResult.Kind == IK_NotICE)
22130 if (TrueResult.Kind == IK_NotICE)
22132 if (FalseResult.Kind == IK_NotICE)
22133 return FalseResult;
22134 if (CondResult.Kind == IK_ICEIfUnevaluated)
22136 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
22142 return FalseResult;
22145 case Expr::CXXDefaultArgExprClass:
22147 case Expr::CXXDefaultInitExprClass:
22149 case Expr::ChooseExprClass: {
22152 case Expr::BuiltinBitCastExprClass: {
22153 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
22159 llvm_unreachable(
"Invalid StmtClass!");
22165 llvm::APSInt *
Value) {
22182 "Expression evaluator can't be called on a dependent expression.");
22184 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
22190 if (D.Kind != IK_ICE)
22195std::optional<llvm::APSInt>
22199 return std::nullopt;
22206 return std::nullopt;
22210 return std::nullopt;
22219 Info.InConstantContext =
true;
22222 llvm_unreachable(
"ICE cannot be evaluated!");
22229 "Expression evaluator can't be called on a dependent expression.");
22231 return CheckICE(
this, Ctx).Kind == IK_ICE;
22236 "Expression evaluator can't be called on a dependent expression.");
22246 *
Result = std::move(Scratch);
22253 Status.Diag = &Diags;
22260 Info.discardCleanups() && !Status.HasSideEffects;
22262 return IsConstExpr && Diags.empty();
22270 "Expression evaluator can't be called on a dependent expression.");
22272 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
22274 llvm::raw_string_ostream OS(Name);
22282 Info.InConstantContext =
true;
22285 const LValue *ThisPtr =
nullptr;
22288 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
22289 assert(MD &&
"Don't provide `this` for non-methods.");
22290 assert(MD->isImplicitObjectMemberFunction() &&
22291 "Don't provide `this` for methods without an implicit object.");
22293 if (!
This->isValueDependent() &&
22295 !Info.EvalStatus.HasSideEffects)
22296 ThisPtr = &ThisVal;
22300 Info.EvalStatus.HasSideEffects =
false;
22303 CallRef
Call = Info.CurrentCall->createCall(Callee);
22306 unsigned Idx = I - Args.begin();
22307 if (Idx >= Callee->getNumParams())
22309 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
22310 if ((*I)->isValueDependent() ||
22312 Info.EvalStatus.HasSideEffects) {
22314 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
22320 Info.EvalStatus.HasSideEffects =
false;
22325 Info.discardCleanups();
22326 Info.EvalStatus.HasSideEffects =
false;
22329 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
22332 FullExpressionRAII
Scope(Info);
22334 !Info.EvalStatus.HasSideEffects;
22346 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
22348 llvm::raw_string_ostream OS(Name);
22355 Status.
Diag = &Diags;
22359 Info.InConstantContext =
true;
22360 Info.CheckingPotentialConstantExpression =
true;
22363 if (Info.EnableNewConstInterp) {
22364 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
22365 return Diags.empty();
22376 This.set({&VIE, Info.CurrentCall->Index});
22384 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
22390 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
22394 return Diags.empty();
22402 "Expression evaluator can't be called on a dependent expression.");
22405 Status.
Diag = &Diags;
22409 Info.InConstantContext =
true;
22410 Info.CheckingPotentialConstantExpression =
true;
22412 if (Info.EnableNewConstInterp) {
22413 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info, E, FD);
22414 return Diags.empty();
22419 nullptr, CallRef());
22423 return Diags.empty();
22427 unsigned Type)
const {
22428 if (!
getType()->isPointerType())
22429 return std::nullopt;
22433 if (Info.EnableNewConstInterp)
22434 return Info.Ctx.getInterpContext().tryEvaluateObjectSize(Info,
this,
Type);
22438static std::optional<uint64_t>
22440 std::string *StringResult) {
22442 return std::nullopt;
22447 return std::nullopt;
22452 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
22453 String.getLValueBase().dyn_cast<
const Expr *>())) {
22456 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
22459 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
22460 Str = Str.substr(Off);
22462 StringRef::size_type Pos = Str.find(0);
22463 if (Pos != StringRef::npos)
22464 Str = Str.substr(0, Pos);
22467 *StringResult = Str;
22475 for (uint64_t Strlen = 0; ; ++Strlen) {
22479 return std::nullopt;
22482 else if (StringResult)
22483 StringResult->push_back(Char.
getInt().getExtValue());
22485 return std::nullopt;
22492 std::string StringResult;
22494 if (Info.EnableNewConstInterp) {
22495 if (!Info.Ctx.getInterpContext().evaluateString(Info,
this, StringResult))
22496 return std::nullopt;
22497 return StringResult;
22501 return StringResult;
22502 return std::nullopt;
22505template <
typename T>
22507 const Expr *SizeExpression,
22508 const Expr *PtrExpression,
22512 Info.InConstantContext =
true;
22514 if (Info.EnableNewConstInterp)
22515 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
22519 FullExpressionRAII
Scope(Info);
22524 uint64_t Size = SizeValue.getZExtValue();
22527 if constexpr (std::is_same_v<APValue, T>)
22530 if (Size <
Result.max_size())
22537 for (uint64_t I = 0; I < Size; ++I) {
22543 if constexpr (std::is_same_v<APValue, T>) {
22544 Result.getArrayInitializedElt(I) = std::move(Char);
22548 assert(
C.getBitWidth() <= 8 &&
22549 "string element not representable in char");
22551 Result.push_back(
static_cast<char>(
C.getExtValue()));
22562 const Expr *SizeExpression,
22566 PtrExpression, Ctx, Status);
22570 const Expr *SizeExpression,
22574 PtrExpression, Ctx, Status);
22581 if (Info.EnableNewConstInterp)
22582 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this);
22587struct IsWithinLifetimeHandler {
22590 using result_type = std::optional<bool>;
22591 std::optional<bool> failed() {
return std::nullopt; }
22592 template <
typename T>
22593 std::optional<bool> found(T &Subobj,
QualType SubobjType,
22597 template <
typename T>
22598 std::optional<bool> found(T &Subobj, QualType SubobjType) {
22603std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
22604 const CallExpr *E) {
22605 EvalInfo &Info = IEE.Info;
22610 if (!Info.InConstantContext)
22611 return std::nullopt;
22613 const Expr *Arg = E->
getArg(0);
22615 return std::nullopt;
22618 return std::nullopt;
22620 if (Val.allowConstexprUnknown())
22624 bool CalledFromStd =
false;
22625 const auto *
Callee = Info.CurrentCall->getCallee();
22626 if (Callee &&
Callee->isInStdNamespace()) {
22627 const IdentifierInfo *Identifier =
Callee->getIdentifier();
22628 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
22630 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
22632 diag::err_invalid_is_within_lifetime)
22633 << (CalledFromStd ?
"std::is_within_lifetime"
22634 :
"__builtin_is_within_lifetime")
22636 return std::nullopt;
22646 if (Val.isNullPointer() || Val.getLValueBase().isNull())
22648 QualType T = Val.getLValueBase().getType();
22650 "Pointers to functions should have been typed as function pointers "
22651 "which would have been rejected earlier");
22654 if (Val.getLValueDesignator().isOnePastTheEnd())
22656 assert(Val.getLValueDesignator().isValidSubobject() &&
22657 "Unchecked case for valid subobject");
22661 CompleteObject CO =
22665 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
22670 IsWithinLifetimeHandler handler{Info};
22671 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.
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)
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)
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 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 CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps)
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 HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
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)
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result)
Perform zero-initialization on an object of non-union class type. C++11 [dcl.init]p5: To zero-initial...
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.
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 handleDefaultInitValue(QualType T, APValue &Result)
Get the value to use for a default-initialized object of type T.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
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 IsOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
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 std::optional< uint64_t > tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info)
Tries to evaluate the __builtin_object_size for E. If successful, returns true and stores the result ...
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 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 isModification(AccessKinds AK)
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 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 bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value)
Evaluate an expression as a C++11 integral constant expression.
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 checkFloatingPointResult(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given evaluation result is allowed for constant evaluation.
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 EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
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....
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 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 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 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 bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
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 isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
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 HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T)
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 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.
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
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)
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
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
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.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
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
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
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.
base_class_iterator bases_end()
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_iterator bases_begin()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
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.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
isPowerOfTwo - 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
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - 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 isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
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.
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 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...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
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< 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...
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl< PartialDiagnosticAt > &Notes, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
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, void *&InsertPos)
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...
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.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
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.
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.
unsigned getLength() const
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() 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()
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
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
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 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.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
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.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
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.
bool evaluateDestruction(State &Parent, const VarDecl *VD, APValue Value)
Evaluates the destruction of a variable.
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 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.
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
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)
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
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
@ 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)
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
static ObjectUnderConstruction getTombstoneKey()
DenseMapInfo< APValue::LValueBase > Base
static ObjectUnderConstruction getEmptyKey()
static unsigned getHashValue(const ObjectUnderConstruction &Object)
static bool isEqual(const ObjectUnderConstruction &LHS, const ObjectUnderConstruction &RHS)