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>;
739 static bool isEqual(
const ObjectUnderConstruction &LHS,
740 const ObjectUnderConstruction &RHS) {
754 const Expr *AllocExpr =
nullptr;
765 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
766 return NE->isArray() ? ArrayNew : New;
772 struct DynAllocOrder {
773 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
795 CallStackFrame *CurrentCall;
798 unsigned CallStackDepth;
801 unsigned NextCallIndex;
810 bool EnableNewConstInterp;
814 CallStackFrame BottomFrame;
818 llvm::SmallVector<Cleanup, 16> CleanupStack;
822 APValue::LValueBase EvaluatingDecl;
824 enum class EvaluatingDeclKind {
831 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
840 SmallVector<const Stmt *> BreakContinueStack;
843 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
844 ObjectsUnderConstruction;
849 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
852 unsigned NumHeapAllocs = 0;
854 struct EvaluatingConstructorRAII {
856 ObjectUnderConstruction Object;
858 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
860 : EI(EI), Object(Object) {
862 EI.ObjectsUnderConstruction
863 .insert({Object, HasBases ? ConstructionPhase::Bases
864 : ConstructionPhase::AfterBases})
867 void finishedConstructingBases() {
868 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
870 void finishedConstructingFields() {
871 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
873 ~EvaluatingConstructorRAII() {
874 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
878 struct EvaluatingDestructorRAII {
880 ObjectUnderConstruction Object;
882 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
883 : EI(EI), Object(Object) {
884 DidInsert = EI.ObjectsUnderConstruction
885 .insert({Object, ConstructionPhase::Destroying})
888 void startedDestroyingBases() {
889 EI.ObjectsUnderConstruction[Object] =
890 ConstructionPhase::DestroyingBases;
892 ~EvaluatingDestructorRAII() {
894 EI.ObjectsUnderConstruction.erase(Object);
899 isEvaluatingCtorDtor(APValue::LValueBase Base,
900 ArrayRef<APValue::LValuePathEntry> Path) {
901 return ObjectsUnderConstruction.lookup({
Base, Path});
906 unsigned SpeculativeEvaluationDepth = 0;
912 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
913 : State(const_cast<ASTContext &>(
C), S), CurrentCall(
nullptr),
914 CallStackDepth(0), NextCallIndex(1),
915 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
916 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
917 BottomFrame(*this, SourceLocation(),
nullptr,
920 EvaluatingDecl((const ValueDecl *)
nullptr),
929 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
930 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
931 EvaluatingDecl =
Base;
932 IsEvaluatingDecl = EDK;
933 EvaluatingDeclValue = &
Value;
936 bool CheckCallLimit(SourceLocation Loc) {
939 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
941 if (NextCallIndex == 0) {
943 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
946 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
948 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
949 << getLangOpts().ConstexprCallDepth;
954 uint64_t ElemCount,
bool Diag) {
960 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
962 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
971 uint64_t Limit = getLangOpts().ConstexprStepLimit;
972 if (Limit != 0 && ElemCount > Limit) {
974 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
975 << ElemCount << Limit;
981 std::pair<CallStackFrame *, unsigned>
982 getCallFrameAndDepth(
unsigned CallIndex) {
983 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
986 unsigned Depth = CallStackDepth;
987 CallStackFrame *Frame = CurrentCall;
988 while (Frame->Index > CallIndex) {
989 Frame = Frame->Caller;
992 if (Frame->Index == CallIndex)
993 return {Frame, Depth};
997 bool nextStep(
const Stmt *S) {
998 if (getLangOpts().ConstexprStepLimit == 0)
1002 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1009 APValue *createHeapAlloc(
const Expr *E, QualType T, LValue &LV);
1011 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1012 std::optional<DynAlloc *>
Result;
1013 auto It = HeapAllocs.find(DA);
1014 if (It != HeapAllocs.end())
1020 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1021 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1022 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1027 struct StdAllocatorCaller {
1028 unsigned FrameIndex;
1031 explicit operator bool()
const {
return FrameIndex != 0; };
1034 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1035 for (
const CallStackFrame *
Call = CurrentCall;
Call->Caller !=
nullptr;
1037 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1040 const IdentifierInfo *FnII = MD->getIdentifier();
1041 if (!FnII || !FnII->
isStr(FnName))
1045 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1049 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1050 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1051 if (CTSD->isInStdNamespace() && ClassII &&
1052 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1054 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1060 void performLifetimeExtension() {
1062 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1063 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1070 bool discardCleanups() {
1071 for (Cleanup &
C : CleanupStack) {
1072 if (
C.hasSideEffect() && !noteSideEffect()) {
1073 CleanupStack.clear();
1077 CleanupStack.clear();
1082 const interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1084 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1085 bool stepsLeft()
const override {
return StepsLeft > 0; }
1098 [[nodiscard]]
bool noteFailure() {
1106 bool KeepGoing = keepEvaluatingAfterFailure();
1107 EvalStatus.HasSideEffects |= KeepGoing;
1111 class ArrayInitLoopIndex {
1116 ArrayInitLoopIndex(EvalInfo &Info)
1117 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1118 Info.ArrayInitIndex = 0;
1120 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1122 operator uint64_t&() {
return Info.ArrayInitIndex; }
1127 struct FoldConstant {
1130 bool HadNoPriorDiags;
1133 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1136 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1137 Info.EvalStatus.
Diag->empty() &&
1138 !Info.EvalStatus.HasSideEffects),
1139 OldMode(Info.EvalMode) {
1141 Info.EvalMode = EvaluationMode::ConstantFold;
1143 void keepDiagnostics() { Enabled =
false; }
1145 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1146 !Info.EvalStatus.HasSideEffects) {
1147 Info.EvalStatus.Diag->clear();
1148 Info.EvalStatus.DiagEmitted =
false;
1150 Info.EvalMode = OldMode;
1156 struct IgnoreSideEffectsRAII {
1159 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1160 : Info(Info), OldMode(Info.EvalMode) {
1161 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1164 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1169 class SpeculativeEvaluationRAII {
1170 EvalInfo *Info =
nullptr;
1171 Expr::EvalStatus OldStatus;
1172 unsigned OldSpeculativeEvaluationDepth = 0;
1174 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1176 OldStatus =
Other.OldStatus;
1177 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1178 Other.Info =
nullptr;
1181 void maybeRestoreState() {
1185 Info->EvalStatus = OldStatus;
1186 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1190 SpeculativeEvaluationRAII() =
default;
1192 SpeculativeEvaluationRAII(
1193 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1194 : Info(&Info), OldStatus(Info.EvalStatus),
1195 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1196 Info.EvalStatus.Diag = NewDiag;
1197 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1200 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1201 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1202 moveFromAndCancel(std::move(
Other));
1205 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1206 maybeRestoreState();
1207 moveFromAndCancel(std::move(
Other));
1211 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1216 template<ScopeKind Kind>
1219 unsigned OldStackSize;
1221 ScopeRAII(EvalInfo &Info)
1222 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1225 Info.CurrentCall->pushTempVersion();
1227 bool destroy(
bool RunDestructors =
true) {
1228 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1229 OldStackSize = std::numeric_limits<unsigned>::max();
1233 if (OldStackSize != std::numeric_limits<unsigned>::max())
1237 Info.CurrentCall->popTempVersion();
1240 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1241 unsigned OldStackSize) {
1242 assert(OldStackSize <= Info.CleanupStack.size() &&
1243 "running cleanups out of order?");
1248 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1249 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1250 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1258 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1259 if (Kind != ScopeKind::Block)
1261 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1262 return C.isDestroyedAtEndOf(Kind);
1264 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1268 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1269 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1270 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1273bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1277 if (isOnePastTheEnd()) {
1278 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1289void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1291 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1296void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1301 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1302 Info.CCEDiag(E, diag::note_constexpr_array_index)
1304 <<
static_cast<unsigned>(getMostDerivedArraySize());
1306 Info.CCEDiag(E, diag::note_constexpr_array_index)
1311CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1312 const FunctionDecl *Callee,
const LValue *This,
1313 const Expr *CallExpr, CallRef Call)
1315 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1316 Index(Info.NextCallIndex++) {
1317 Info.CurrentCall =
this;
1318 ++Info.CallStackDepth;
1321CallStackFrame::~CallStackFrame() {
1322 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1323 --Info.CallStackDepth;
1324 Info.CurrentCall = Caller;
1349 llvm_unreachable(
"unknown access kind");
1386 llvm_unreachable(
"unknown access kind");
1390 struct ComplexValue {
1398 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1400 void makeComplexFloat() { IsInt =
false; }
1401 bool isComplexFloat()
const {
return !IsInt; }
1402 APFloat &getComplexFloatReal() {
return FloatReal; }
1403 APFloat &getComplexFloatImag() {
return FloatImag; }
1405 void makeComplexInt() { IsInt =
true; }
1406 bool isComplexInt()
const {
return IsInt; }
1407 APSInt &getComplexIntReal() {
return IntReal; }
1408 APSInt &getComplexIntImag() {
return IntImag; }
1410 void moveInto(
APValue &v)
const {
1411 if (isComplexFloat())
1412 v =
APValue(FloatReal, FloatImag);
1414 v =
APValue(IntReal, IntImag);
1416 void setFrom(
const APValue &v) {
1431 APValue::LValueBase
Base;
1433 SubobjectDesignator Designator;
1435 bool InvalidBase : 1;
1437 bool AllowConstexprUnknown =
false;
1439 const APValue::LValueBase getLValueBase()
const {
return Base; }
1440 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1441 CharUnits &getLValueOffset() {
return Offset; }
1442 const CharUnits &getLValueOffset()
const {
return Offset; }
1443 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1444 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1445 bool isNullPointer()
const {
return IsNullPtr;}
1447 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1448 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1451 if (Designator.Invalid)
1452 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1454 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1455 V =
APValue(Base, Offset, Designator.Entries,
1456 Designator.IsOnePastTheEnd, IsNullPtr);
1458 if (AllowConstexprUnknown)
1459 V.setConstexprUnknown();
1461 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1462 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1463 Base =
V.getLValueBase();
1464 Offset =
V.getLValueOffset();
1465 InvalidBase =
false;
1466 Designator = SubobjectDesignator(Ctx,
V);
1467 IsNullPtr =
V.isNullPointer();
1468 AllowConstexprUnknown =
V.allowConstexprUnknown();
1471 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1475 const auto *E = B.
get<
const Expr *>();
1477 "Unexpected type of invalid base");
1483 InvalidBase = BInvalid;
1484 Designator = SubobjectDesignator(
getType(B));
1486 AllowConstexprUnknown =
false;
1489 void setNull(ASTContext &Ctx, QualType PointerTy) {
1490 Base = (
const ValueDecl *)
nullptr;
1493 InvalidBase =
false;
1496 AllowConstexprUnknown =
false;
1499 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1503 std::string
toString(ASTContext &Ctx, QualType T)
const {
1505 moveInto(Printable);
1512 template <
typename GenDiagType>
1513 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1514 if (Designator.Invalid)
1518 Designator.setInvalid();
1525 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1527 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1528 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1532 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1534 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1535 if (AK == AccessKinds::AK_Dereference)
1536 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1538 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1546 Designator.checkSubobject(Info, E, CSK);
1549 void addDecl(EvalInfo &Info,
const Expr *E,
1550 const Decl *D,
bool Virtual =
false) {
1552 Designator.addDeclUnchecked(D,
Virtual);
1554 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1555 if (!Designator.Entries.empty()) {
1556 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1557 Designator.setInvalid();
1561 assert(
getType(Base).getNonReferenceType()->isPointerType() ||
1562 getType(Base).getNonReferenceType()->isArrayType());
1563 Designator.FirstEntryIsAnUnsizedArray =
true;
1564 Designator.addUnsizedArrayUnchecked(ElemTy);
1567 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1569 Designator.addArrayUnchecked(CAT);
1571 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1573 Designator.addComplexUnchecked(EltTy, Imag);
1575 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1576 uint64_t Size, uint64_t Idx) {
1578 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1580 void clearIsNullPointer() {
1583 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1584 const APSInt &Index, CharUnits ElementSize) {
1595 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1599 Designator.adjustIndex(Info, E, Index, *
this);
1600 clearIsNullPointer();
1602 void adjustOffset(CharUnits N) {
1605 clearIsNullPointer();
1611 explicit MemberPtr(
const ValueDecl *Decl)
1612 : DeclAndIsDerivedMember(
Decl,
false) {}
1616 const ValueDecl *getDecl()
const {
1617 return DeclAndIsDerivedMember.getPointer();
1620 bool isDerivedMember()
const {
1621 return DeclAndIsDerivedMember.getInt();
1624 const CXXRecordDecl *getContainingRecord()
const {
1626 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1630 V =
APValue(getDecl(), isDerivedMember(), Path);
1633 assert(
V.isMemberPointer());
1634 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1635 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1637 llvm::append_range(Path,
V.getMemberPointerPath());
1643 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1646 SmallVector<const CXXRecordDecl*, 4> Path;
1650 bool castBack(
const CXXRecordDecl *
Class) {
1651 assert(!Path.empty());
1652 const CXXRecordDecl *Expected;
1653 if (Path.size() >= 2)
1654 Expected = Path[Path.size() - 2];
1656 Expected = getContainingRecord();
1670 bool castToDerived(
const CXXRecordDecl *Derived) {
1673 if (!isDerivedMember()) {
1674 Path.push_back(Derived);
1677 if (!castBack(Derived))
1680 DeclAndIsDerivedMember.setInt(
false);
1688 DeclAndIsDerivedMember.setInt(
true);
1689 if (isDerivedMember()) {
1690 Path.push_back(Base);
1693 return castBack(Base);
1698 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1699 if (!LHS.getDecl() || !RHS.getDecl())
1700 return !LHS.getDecl() && !RHS.getDecl();
1701 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1703 return LHS.Path == RHS.Path;
1707void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1711 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1712 if (isMostDerivedAnUnsizedArray()) {
1713 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1718 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1726 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1728 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1731 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1732 if (!Info.checkingPotentialConstantExpression() ||
1733 !LV.AllowConstexprUnknown) {
1736 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1737 (llvm::APInt &)N += ArrayIndex;
1738 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1739 diagnosePointerArithmetic(Info, E, N);
1745 ArrayIndex += TruncatedN;
1746 assert(ArrayIndex <= ArraySize &&
1747 "bounds check succeeded for out-of-bounds index");
1750 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1752 IsOnePastTheEnd = (ArrayIndex != 0);
1757 const LValue &This,
const Expr *E,
1758 bool AllowNonLiteralTypes =
false);
1760 bool InvalidBaseOK =
false);
1762 bool InvalidBaseOK =
false);
1770static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1775static std::optional<uint64_t>
1777 std::string *StringResult =
nullptr);
1794 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1795 Int = Int.extend(Int.getBitWidth() + 1);
1796 Int.setIsSigned(
true);
1801template<
typename KeyT>
1802APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType T,
1803 ScopeKind Scope, LValue &LV) {
1804 unsigned Version = getTempVersion();
1805 APValue::LValueBase
Base(Key, Index, Version);
1807 return createLocal(Base, Key, T, Scope);
1811APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1813 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1814 APValue::LValueBase
Base(PVD, Index, Args.Version);
1819 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1822APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1823 QualType T, ScopeKind Scope) {
1824 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1825 unsigned Version =
Base.getVersion();
1827 assert(
Result.isAbsent() &&
"local created multiple times");
1833 if (Index <= Info.SpeculativeEvaluationDepth) {
1835 Info.noteSideEffect();
1837 Info.CleanupStack.push_back(Cleanup(&
Result, Base, T, Scope));
1842APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType T, LValue &LV) {
1844 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1848 DynamicAllocLValue DA(NumHeapAllocs++);
1850 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1851 std::forward_as_tuple(DA), std::tuple<>());
1852 assert(
Result.second &&
"reused a heap alloc index?");
1853 Result.first->second.AllocExpr = E;
1854 return &
Result.first->second.Value;
1858void CallStackFrame::describe(raw_ostream &Out)
const {
1859 bool IsMemberCall =
false;
1860 bool ExplicitInstanceParam =
false;
1861 clang::PrintingPolicy PrintingPolicy = Info.Ctx.getPrintingPolicy();
1864 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1866 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1870 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1873 if (This && IsMemberCall) {
1874 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1875 const Expr *
Object = MCE->getImplicitObjectArgument();
1876 Object->printPretty(Out,
nullptr, PrintingPolicy,
1878 if (
Object->getType()->isPointerType())
1882 }
else if (
const auto *OCE =
1883 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1884 OCE->getArg(0)->printPretty(Out,
nullptr, PrintingPolicy,
1889 This->moveInto(Val);
1892 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
1895 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1901 llvm::ListSeparator
Comma;
1902 for (
const ParmVarDecl *Param :
1903 Callee->parameters().slice(ExplicitInstanceParam)) {
1905 const APValue *
V = Info.getParamSlot(Arguments, Param);
1907 V->printPretty(Out, Info.Ctx, Param->getType());
1923 return Info.noteSideEffect();
1930 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1931 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
1932 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
1933 Builtin == Builtin::BI__builtin_function_start);
1937 const auto *BaseExpr =
1938 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
1953 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1954 return VD->hasGlobalStorage();
1970 case Expr::CompoundLiteralExprClass: {
1974 case Expr::MaterializeTemporaryExprClass:
1979 case Expr::StringLiteralClass:
1980 case Expr::PredefinedExprClass:
1981 case Expr::ObjCStringLiteralClass:
1982 case Expr::ObjCEncodeExprClass:
1984 case Expr::ObjCBoxedExprClass:
1985 case Expr::ObjCArrayLiteralClass:
1986 case Expr::ObjCDictionaryLiteralClass:
1988 case Expr::CallExprClass:
1991 case Expr::AddrLabelExprClass:
1995 case Expr::BlockExprClass:
1999 case Expr::SourceLocExprClass:
2001 case Expr::ImplicitValueInitExprClass:
2026 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2031 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2032 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2040 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2041 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2042 Lit = PE->getFunctionName();
2047 AsString.
Bytes = Lit->getBytes();
2048 AsString.
CharWidth = Lit->getCharByteWidth();
2068 const LValue &RHS) {
2077 CharUnits Offset = RHS.Offset - LHS.Offset;
2078 if (Offset.isNegative()) {
2079 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2081 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2083 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2085 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2088 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2089 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2090 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2091 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2096 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2097 if (Shorter.size() + NullByte >= Longer.size())
2099 if (Longer[Shorter.size() + NullByte])
2105 return Shorter == Longer.take_front(Shorter.size());
2115 if (isa_and_nonnull<VarDecl>(
Decl)) {
2125 if (!A.getLValueBase())
2126 return !B.getLValueBase();
2127 if (!B.getLValueBase())
2130 if (A.getLValueBase().getOpaqueValue() !=
2131 B.getLValueBase().getOpaqueValue())
2134 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2135 A.getLValueVersion() == B.getLValueVersion();
2139 assert(
Base &&
"no location for a null lvalue");
2145 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2147 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2148 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2149 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2150 Idx < F->Callee->getNumParams()) {
2151 VD = F->Callee->getParamDecl(Idx);
2158 Info.Note(VD->
getLocation(), diag::note_declared_at);
2160 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2163 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2164 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2165 diag::note_constexpr_dynamic_alloc_here);
2198 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2206 if (isTemplateArgument(Kind)) {
2207 int InvalidBaseKind = -1;
2210 InvalidBaseKind = 0;
2211 else if (isa_and_nonnull<StringLiteral>(BaseE))
2212 InvalidBaseKind = 1;
2213 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2214 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2215 InvalidBaseKind = 2;
2216 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2217 InvalidBaseKind = 3;
2218 Ident = PE->getIdentKindName();
2221 if (InvalidBaseKind != -1) {
2222 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2223 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2229 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2230 FD && FD->isImmediateFunction()) {
2231 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2233 Info.Note(FD->getLocation(), diag::note_declared_at);
2241 if (Info.getLangOpts().CPlusPlus11) {
2242 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2243 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2245 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2246 if (VarD && VarD->isConstexpr()) {
2252 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2264 assert((Info.checkingPotentialConstantExpression() ||
2265 LVal.getLValueCallIndex() == 0) &&
2266 "have call index for global lvalue");
2268 if (LVal.allowConstexprUnknown()) {
2270 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2279 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2280 << IsReferenceType << !
Designator.Entries.empty();
2286 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2288 if (Var->getTLSKind())
2296 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>() &&
2297 !Var->isStaticLocal())
2302 if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
2303 Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
2304 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2305 !Var->hasAttr<CUDAConstantAttr>() &&
2306 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2307 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2308 Var->hasAttr<HIPManagedAttr>())
2312 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2323 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2324 FD->hasAttr<DLLImportAttr>())
2328 }
else if (
const auto *MTE =
2329 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2330 if (CheckedTemps.insert(MTE).second) {
2333 Info.FFDiag(MTE->getExprLoc(),
2334 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2339 APValue *
V = MTE->getOrCreateValue(
false);
2340 assert(
V &&
"evasluation result refers to uninitialised temporary");
2342 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2343 nullptr, CheckedTemps))
2350 if (!IsReferenceType)
2362 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2363 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2378 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2381 if (FD->isImmediateFunction()) {
2382 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2383 Info.Note(FD->getLocation(), diag::note_declared_at);
2386 return isForManglingOnly(Kind) || FD->isVirtual() ||
2387 !FD->hasAttr<DLLImportAttr>();
2393 const LValue *
This =
nullptr) {
2395 if (Info.getLangOpts().CPlusPlus23)
2414 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2418 if (Info.getLangOpts().CPlusPlus11)
2419 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2422 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2433 if (SubobjectDecl) {
2434 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2435 << 1 << SubobjectDecl;
2437 diag::note_constexpr_subobject_declared_here);
2439 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2448 Type = AT->getValueType();
2453 if (
Value.isArray()) {
2455 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2457 Value.getArrayInitializedElt(I), Kind,
2458 SubobjectDecl, CheckedTemps))
2461 if (!
Value.hasArrayFiller())
2464 Value.getArrayFiller(), Kind, SubobjectDecl,
2467 if (
Value.isUnion() &&
Value.getUnionField()) {
2470 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2472 if (
Value.isStruct()) {
2474 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2475 unsigned BaseIndex = 0;
2477 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2480 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2481 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2491 for (
const auto *I : RD->fields()) {
2492 if (I->isUnnamedBitField())
2496 Value.getStructField(I->getFieldIndex()), Kind,
2502 if (
Value.isLValue() &&
2505 LVal.setFrom(Info.Ctx,
Value);
2510 if (
Value.isMemberPointer() &&
2531 nullptr, CheckedTemps);
2541 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2547 if (!Info.HeapAllocs.empty()) {
2551 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2552 diag::note_constexpr_memory_leak)
2553 <<
unsigned(Info.HeapAllocs.size() - 1);
2561 if (!
Value.getLValueBase()) {
2614 llvm_unreachable(
"unknown APValue kind");
2620 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2629 const T &SrcValue,
QualType DestType) {
2630 Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType;
2631 if (
const auto *OBT = DestType->
getAs<OverflowBehaviorType>();
2632 OBT && OBT->isTrapKind()) {
2635 return Info.noteUndefinedBehavior();
2641 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2647 if (
Value.convertToInteger(
Result, llvm::APFloat::rmTowardZero, &ignored)
2648 & APFloat::opInvalidOp)
2659 llvm::RoundingMode RM =
2661 if (RM == llvm::RoundingMode::Dynamic)
2662 RM = llvm::RoundingMode::NearestTiesToEven;
2668 APFloat::opStatus St) {
2671 if (Info.InConstantContext)
2675 if ((St & APFloat::opInexact) &&
2679 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2683 if ((St != APFloat::opOK) &&
2686 FPO.getAllowFEnvAccess())) {
2687 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2691 if ((St & APFloat::opStatus::opInvalidOp) &&
2712 "HandleFloatToFloatCast has been checked with only CastExpr, "
2713 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2714 "the new expression or address the root cause of this usage.");
2716 APFloat::opStatus St;
2719 St =
Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2726 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2740 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2742 APFloat::opStatus St =
Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2748 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2750 if (!
Value.isInt()) {
2754 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2760 unsigned OldBitWidth = Int.getBitWidth();
2762 if (NewBitWidth < OldBitWidth)
2763 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2770template<
typename Operation>
2773 unsigned BitWidth, Operation Op,
2775 if (LHS.isUnsigned()) {
2780 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2783 if (Info.checkingForUndefinedBehavior())
2784 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2785 diag::warn_integer_constant_overflow)
2798 bool HandleOverflowResult =
true;
2805 std::multiplies<APSInt>(),
Result);
2808 std::plus<APSInt>(),
Result);
2811 std::minus<APSInt>(),
Result);
2812 case BO_And:
Result = LHS & RHS;
return true;
2813 case BO_Xor:
Result = LHS ^ RHS;
return true;
2814 case BO_Or:
Result = LHS | RHS;
return true;
2818 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2824 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2825 LHS.isMinSignedValue())
2827 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2828 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2829 return HandleOverflowResult;
2831 if (Info.getLangOpts().OpenCL)
2833 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2834 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2836 else if (RHS.isSigned() && RHS.isNegative()) {
2839 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2840 if (!Info.noteUndefinedBehavior())
2848 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2850 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2851 << RHS << E->
getType() << LHS.getBitWidth();
2852 if (!Info.noteUndefinedBehavior())
2854 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2859 if (LHS.isNegative()) {
2860 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2861 if (!Info.noteUndefinedBehavior())
2863 }
else if (LHS.countl_zero() < SA) {
2864 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2865 if (!Info.noteUndefinedBehavior())
2873 if (Info.getLangOpts().OpenCL)
2875 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2876 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2878 else if (RHS.isSigned() && RHS.isNegative()) {
2881 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2882 if (!Info.noteUndefinedBehavior())
2890 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2892 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2893 << RHS << E->
getType() << LHS.getBitWidth();
2894 if (!Info.noteUndefinedBehavior())
2902 case BO_LT:
Result = LHS < RHS;
return true;
2903 case BO_GT:
Result = LHS > RHS;
return true;
2904 case BO_LE:
Result = LHS <= RHS;
return true;
2905 case BO_GE:
Result = LHS >= RHS;
return true;
2906 case BO_EQ:
Result = LHS == RHS;
return true;
2907 case BO_NE:
Result = LHS != RHS;
return true;
2909 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2916 const APFloat &RHS) {
2918 APFloat::opStatus St;
2924 St = LHS.multiply(RHS, RM);
2927 St = LHS.add(RHS, RM);
2930 St = LHS.subtract(RHS, RM);
2936 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2937 St = LHS.divide(RHS, RM);
2946 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2947 return Info.noteUndefinedBehavior();
2955 const APInt &RHSValue, APInt &
Result) {
2956 bool LHS = (LHSValue != 0);
2957 bool RHS = (RHSValue != 0);
2959 if (Opcode == BO_LAnd)
2967 const APFloat &RHSValue, APInt &
Result) {
2968 bool LHS = !LHSValue.isZero();
2969 bool RHS = !RHSValue.isZero();
2971 if (Opcode == BO_LAnd)
2990template <
typename APTy>
2993 const APTy &RHSValue, APInt &
Result) {
2996 llvm_unreachable(
"unsupported binary operator");
2998 Result = (LHSValue == RHSValue);
3001 Result = (LHSValue != RHSValue);
3004 Result = (LHSValue < RHSValue);
3007 Result = (LHSValue > RHSValue);
3010 Result = (LHSValue <= RHSValue);
3013 Result = (LHSValue >= RHSValue);
3042 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3043 "Operation not supported on vector types");
3047 QualType EltTy = VT->getElementType();
3054 "A vector result that isn't a vector OR uncalculated LValue");
3060 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3064 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3069 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3079 RHSElt.
getInt(), EltResult);
3085 ResultElements.emplace_back(EltResult);
3090 "Mismatched LHS/RHS/Result Type");
3091 APFloat LHSFloat = LHSElt.
getFloat();
3099 ResultElements.emplace_back(LHSFloat);
3103 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3111 unsigned TruncatedElements) {
3112 SubobjectDesignator &D =
Result.Designator;
3115 if (TruncatedElements == D.Entries.size())
3117 assert(TruncatedElements >= D.MostDerivedPathLength &&
3118 "not casting to a derived class");
3124 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3128 if (isVirtualBaseClass(D.Entries[I]))
3134 D.Entries.resize(TruncatedElements);
3144 RL = &Info.Ctx.getASTRecordLayout(Derived);
3147 Obj.addDecl(Info, E,
Base,
false);
3148 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3157 if (!
Base->isVirtual())
3160 SubobjectDesignator &D = Obj.Designator;
3175 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3176 Obj.addDecl(Info, E, BaseDecl,
true);
3185 PathI != PathE; ++PathI) {
3189 Type = (*PathI)->getType();
3201 llvm_unreachable(
"Class must be derived from the passed in base class!");
3216 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3220 LVal.addDecl(Info, E, FD);
3221 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3229 for (
const auto *
C : IFD->
chain())
3263 Size = Info.Ctx.getTypeSizeInChars(
Type);
3265 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3282 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3288 int64_t Adjustment) {
3290 APSInt::get(Adjustment));
3305 LVal.Offset += SizeOfComponent;
3307 LVal.addComplex(Info, E, EltTy, Imag);
3313 uint64_t Size, uint64_t Idx) {
3318 LVal.Offset += SizeOfElement * Idx;
3320 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3334 const VarDecl *VD, CallStackFrame *Frame,
3338 bool AllowConstexprUnknown =
3343 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3355 if (!AllowConstexprUnknown || IsLocalVariable) {
3356 if (!Info.checkingPotentialConstantExpression())
3357 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3367 Result = Frame->getTemporary(VD, Version);
3369 return CheckUninitReference(
true);
3378 "missing value for local variable");
3379 if (Info.checkingPotentialConstantExpression())
3383 "A variable in a frame should either be a local or a parameter");
3389 if (Info.EvaluatingDecl ==
Base) {
3390 Result = Info.EvaluatingDeclValue;
3391 return CheckUninitReference(
false);
3399 if (AllowConstexprUnknown) {
3406 if (!Info.checkingPotentialConstantExpression() ||
3407 !Info.CurrentCall->Callee ||
3409 if (Info.getLangOpts().CPlusPlus11) {
3410 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3431 if (!
Init && !AllowConstexprUnknown) {
3434 if (!Info.checkingPotentialConstantExpression()) {
3435 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3446 if (
Init &&
Init->isValueDependent()) {
3453 if (!Info.checkingPotentialConstantExpression()) {
3454 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3455 ? diag::note_constexpr_ltor_non_constexpr
3456 : diag::note_constexpr_ltor_non_integral, 1)
3470 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3486 !AllowConstexprUnknown) ||
3487 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3490 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3500 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3507 if (!
Result && !AllowConstexprUnknown)
3510 return CheckUninitReference(
false);
3520 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3521 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3525 llvm_unreachable(
"base class missing from derived class's bases list");
3532 "SourceLocExpr should have already been converted to a StringLiteral");
3535 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3537 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3538 assert(Index <= Str.size() &&
"Index too large");
3539 return APSInt::getUnsigned(Str.c_str()[Index]);
3542 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3543 Lit = PE->getFunctionName();
3546 Info.Ctx.getAsConstantArrayType(S->
getType());
3547 assert(CAT &&
"string literal isn't an array");
3549 assert(CharType->
isIntegerType() &&
"unexpected character type");
3552 if (Index < S->getLength())
3565 AllocType.isNull() ? S->
getType() : AllocType);
3566 assert(CAT &&
"string literal isn't an array");
3568 assert(CharType->
isIntegerType() &&
"unexpected character type");
3575 if (
Result.hasArrayFiller())
3577 for (
unsigned I = 0, N =
Result.getArrayInitializedElts(); I != N; ++I) {
3585 unsigned Size =
Array.getArraySize();
3586 assert(Index < Size);
3589 unsigned OldElts =
Array.getArrayInitializedElts();
3590 unsigned NewElts = std::max(Index+1, OldElts * 2);
3591 NewElts = std::min(Size, std::max(NewElts, 8u));
3595 for (
unsigned I = 0; I != OldElts; ++I)
3597 for (
unsigned I = OldElts; I != NewElts; ++I)
3601 Array.swap(NewValue);
3608 Vec =
APValue(Elts.data(), Elts.size());
3618 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3629 for (
auto *Field : RD->
fields())
3630 if (!Field->isUnnamedBitField() &&
3634 for (
auto &BaseSpec : RD->
bases())
3645 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3652 for (
auto *Field : RD->
fields()) {
3657 if (Field->isMutable() &&
3659 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3660 Info.Note(Field->getLocation(), diag::note_declared_at);
3668 for (
auto &BaseSpec : RD->
bases())
3678 bool MutableSubobject =
false) {
3683 switch (Info.IsEvaluatingDecl) {
3684 case EvalInfo::EvaluatingDeclKind::None:
3687 case EvalInfo::EvaluatingDeclKind::Ctor:
3689 if (Info.EvaluatingDecl ==
Base)
3694 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3695 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3696 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3699 case EvalInfo::EvaluatingDeclKind::Dtor:
3704 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3710 return T.isConstQualified() || T->isReferenceType();
3713 llvm_unreachable(
"unknown evaluating decl kind");
3718 return Info.CheckArraySize(
3738 uint64_t IntResult = BoolResult;
3741 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3742 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3747 Info.Ctx.getIntTypeForBitwidth(64,
false),
3750 Result = std::move(Result2);
3758 DestTy,
Result.getFloat());
3764 uint64_t IntResult = BoolResult;
3783 uint64_t IntResult = BoolResult;
3790 DestTy,
Result.getInt());
3794 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3807 {&
Result, ResultType, 0}};
3810 while (!WorkList.empty() && ElI < Elements.size()) {
3811 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3827 APSInt &Int = Res->getInt();
3828 unsigned OldBitWidth = Int.getBitWidth();
3829 unsigned NewBitWidth = BitWidth;
3830 if (NewBitWidth < OldBitWidth)
3831 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3840 for (
unsigned I = 0; I < NumEl; ++I) {
3846 *Res =
APValue(Vals.data(), NumEl);
3855 for (int64_t I = Size - 1; I > -1; --I)
3856 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3862 unsigned NumBases = 0;
3863 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3864 NumBases = CXXRD->getNumBases();
3871 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3872 if (CXXRD->getNumBases() > 0) {
3873 assert(CXXRD->getNumBases() == 1);
3875 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3882 if (FD->isUnnamedBitField())
3884 if (FD->isBitField()) {
3885 FDBW = FD->getBitWidthValue();
3888 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3889 FD->getType(), FDBW);
3892 std::reverse(ReverseList.begin(), ReverseList.end());
3893 llvm::append_range(WorkList, ReverseList);
3896 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3909 assert((Elements.size() == SrcTypes.size()) &&
3910 (Elements.size() == DestTypes.size()));
3912 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
3913 APValue Original = Elements[I];
3917 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
3928 while (!WorkList.empty()) {
3951 for (uint64_t I = 0; I < ArrSize; ++I) {
3952 WorkList.push_back(ElTy);
3960 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3961 if (CXXRD->getNumBases() > 0) {
3962 assert(CXXRD->getNumBases() == 1);
3964 WorkList.push_back(BS.
getType());
3970 if (FD->isUnnamedBitField())
3972 WorkList.push_back(FD->getType());
3989 "Not a valid HLSLAggregateSplatCast.");
4009 unsigned Populated = 0;
4010 while (!WorkList.empty() && Populated < Size) {
4011 auto [Work,
Type] = WorkList.pop_back_val();
4013 if (Work.isFloat() || Work.isInt()) {
4014 Elements.push_back(Work);
4015 Types.push_back(
Type);
4019 if (Work.isVector()) {
4022 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4024 Elements.push_back(Work.getVectorElt(I));
4025 Types.push_back(ElTy);
4030 if (Work.isMatrix()) {
4033 QualType ElTy = MT->getElementType();
4035 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4037 for (
unsigned Col = 0;
4038 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4039 Elements.push_back(Work.getMatrixElt(Row, Col));
4040 Types.push_back(ElTy);
4046 if (Work.isArray()) {
4050 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4051 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4056 if (Work.isStruct()) {
4064 if (FD->isUnnamedBitField())
4066 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4070 std::reverse(ReverseList.begin(), ReverseList.end());
4071 llvm::append_range(WorkList, ReverseList);
4074 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4075 if (CXXRD->getNumBases() > 0) {
4076 assert(CXXRD->getNumBases() == 1);
4081 if (!
Base.isStruct())
4089 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4098struct CompleteObject {
4100 APValue::LValueBase
Base;
4110 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4121 if (!Info.getLangOpts().CPlusPlus14 &&
4122 AK != AccessKinds::AK_IsWithinLifetime)
4127 explicit operator bool()
const {
return !
Type.isNull(); }
4132 bool IsMutable =
false) {
4146template <
typename Sub
objectHandler>
4147static typename SubobjectHandler::result_type
4149 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4152 return handler.failed();
4153 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4154 if (Info.getLangOpts().CPlusPlus11)
4155 Info.FFDiag(E, Sub.isOnePastTheEnd()
4156 ? diag::note_constexpr_access_past_end
4157 : diag::note_constexpr_access_unsized_array)
4158 << handler.AccessKind;
4161 return handler.failed();
4167 const FieldDecl *VolatileField =
nullptr;
4170 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4181 if (!Info.checkingPotentialConstantExpression()) {
4182 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4187 return handler.failed();
4195 Info.isEvaluatingCtorDtor(
4196 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4197 ConstructionPhase::None) {
4198 ObjType = Info.Ctx.getCanonicalType(ObjType);
4207 if (Info.getLangOpts().CPlusPlus) {
4211 if (VolatileField) {
4214 Decl = VolatileField;
4217 Loc = VD->getLocation();
4224 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4225 << handler.AccessKind << DiagKind <<
Decl;
4226 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4228 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4230 return handler.failed();
4238 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4240 return handler.failed();
4244 if (!handler.found(*O, ObjType, Obj.Base))
4256 LastField =
nullptr;
4259 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4261 "vla in literal type?");
4262 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4263 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4264 CAT && CAT->
getSize().ule(Index)) {
4267 if (Info.getLangOpts().CPlusPlus11)
4268 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4269 << handler.AccessKind;
4272 return handler.failed();
4279 else if (!
isRead(handler.AccessKind)) {
4280 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4282 return handler.failed();
4290 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4292 if (Info.getLangOpts().CPlusPlus11)
4293 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4294 << handler.AccessKind;
4297 return handler.failed();
4303 assert(I == N - 1 &&
"extracting subobject of scalar?");
4313 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4314 unsigned NumElements = VT->getNumElements();
4315 if (Index == NumElements) {
4316 if (Info.getLangOpts().CPlusPlus11)
4317 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4318 << handler.AccessKind;
4321 return handler.failed();
4324 if (Index > NumElements) {
4325 Info.CCEDiag(E, diag::note_constexpr_array_index)
4326 << Index << 0 << NumElements;
4327 return handler.failed();
4330 ObjType = VT->getElementType();
4331 assert(I == N - 1 &&
"extracting subobject of scalar?");
4334 if (
isRead(handler.AccessKind)) {
4336 return handler.failed();
4340 assert(O->
isVector() &&
"unexpected object during vector element access");
4341 return handler.found(O->
getVectorElt(Index), ObjType, Obj.Base);
4342 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4343 if (Field->isMutable() &&
4344 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4345 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4346 << handler.AccessKind << Field;
4347 Info.Note(Field->getLocation(), diag::note_declared_at);
4348 return handler.failed();
4357 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4368 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4369 << handler.AccessKind << Field << !UnionField << UnionField;
4370 return handler.failed();
4379 if (Field->getType().isVolatileQualified())
4380 VolatileField = Field;
4393struct ExtractSubobjectHandler {
4399 typedef bool result_type;
4400 bool failed() {
return false; }
4401 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4411 bool found(APFloat &
Value, QualType SubobjType) {
4420 const CompleteObject &Obj,
4424 ExtractSubobjectHandler Handler = {Info, E,
Result, AK};
4429struct ModifySubobjectHandler {
4434 typedef bool result_type;
4437 bool checkConst(QualType QT) {
4440 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4446 bool failed() {
return false; }
4447 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4448 if (!checkConst(SubobjType))
4451 Subobj.
swap(NewVal);
4455 if (!checkConst(SubobjType))
4457 if (!NewVal.
isInt()) {
4465 bool found(APFloat &
Value, QualType SubobjType) {
4466 if (!checkConst(SubobjType))
4474const AccessKinds ModifySubobjectHandler::AccessKind;
4478 const CompleteObject &Obj,
4479 const SubobjectDesignator &Sub,
4481 ModifySubobjectHandler Handler = { Info, NewVal, E };
4488 const SubobjectDesignator &A,
4489 const SubobjectDesignator &B,
4490 bool &WasArrayIndex) {
4491 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4492 for (; I != N; ++I) {
4496 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4497 WasArrayIndex =
true;
4505 if (A.Entries[I].getAsBaseOrMember() !=
4506 B.Entries[I].getAsBaseOrMember()) {
4507 WasArrayIndex =
false;
4510 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4512 ObjType = FD->getType();
4518 WasArrayIndex =
false;
4525 const SubobjectDesignator &A,
4526 const SubobjectDesignator &B) {
4527 if (A.Entries.size() != B.Entries.size())
4530 bool IsArray = A.MostDerivedIsArrayElement;
4531 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4540 return CommonLength >= A.Entries.size() - IsArray;
4547 if (LVal.InvalidBase) {
4549 return CompleteObject();
4554 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4556 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4557 return CompleteObject();
4560 CallStackFrame *Frame =
nullptr;
4562 if (LVal.getLValueCallIndex()) {
4563 std::tie(Frame, Depth) =
4564 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4566 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4569 return CompleteObject();
4580 if (Info.getLangOpts().CPlusPlus)
4581 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4585 return CompleteObject();
4592 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4596 BaseVal = Info.EvaluatingDeclValue;
4599 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4602 Info.FFDiag(E, diag::note_constexpr_modify_global);
4603 return CompleteObject();
4607 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4609 return CompleteObject();
4611 return CompleteObject(LVal.Base, &
V, GD->getType());
4615 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4617 Info.FFDiag(E, diag::note_constexpr_modify_global);
4618 return CompleteObject();
4620 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4625 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4627 Info.FFDiag(E, diag::note_constexpr_modify_global);
4628 return CompleteObject();
4630 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4641 const VarDecl *VD = dyn_cast<VarDecl>(D);
4648 return CompleteObject();
4651 bool IsConstant = BaseType.isConstant(Info.Ctx);
4652 bool ConstexprVar =
false;
4653 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4665 }
else if (Info.getLangOpts().CPlusPlus14 &&
4672 Info.FFDiag(E, diag::note_constexpr_modify_global);
4673 return CompleteObject();
4676 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4678 return CompleteObject();
4679 }
else if (BaseType->isIntegralOrEnumerationType()) {
4682 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4683 if (Info.getLangOpts().CPlusPlus) {
4684 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4685 Info.Note(VD->
getLocation(), diag::note_declared_at);
4689 return CompleteObject();
4691 }
else if (!IsAccess) {
4692 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4693 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4694 Info.checkingPotentialConstantExpression() &&
4695 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4697 }
else if (IsConstant) {
4701 if (Info.getLangOpts().CPlusPlus) {
4702 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4703 ? diag::note_constexpr_ltor_non_constexpr
4704 : diag::note_constexpr_ltor_non_integral, 1)
4706 Info.Note(VD->
getLocation(), diag::note_declared_at);
4712 if (Info.getLangOpts().CPlusPlus) {
4713 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4714 ? diag::note_constexpr_ltor_non_constexpr
4715 : diag::note_constexpr_ltor_non_integral, 1)
4717 Info.Note(VD->
getLocation(), diag::note_declared_at);
4721 return CompleteObject();
4730 return CompleteObject();
4735 if (!Info.checkingPotentialConstantExpression()) {
4736 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4738 Info.Note(VD->getLocation(), diag::note_declared_at);
4740 return CompleteObject();
4743 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4745 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4746 return CompleteObject();
4748 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4758 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4759 assert(MTE->getStorageDuration() ==
SD_Static &&
4760 "should have a frame for a non-global materialized temporary");
4787 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4790 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4791 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4792 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4793 return CompleteObject();
4796 BaseVal = MTE->getOrCreateValue(
false);
4797 assert(BaseVal &&
"got reference to unevaluated temporary");
4799 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4815 !CLETy.isConstant(Info.Ctx)) {
4817 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4818 return CompleteObject();
4821 BaseVal = &CLE->getStaticValue();
4824 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4827 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4830 Info.Ctx.getLValueReferenceType(LValType));
4832 return CompleteObject();
4836 assert(BaseVal &&
"missing value for temporary");
4847 unsigned VisibleDepth = Depth;
4848 if (llvm::isa_and_nonnull<ParmVarDecl>(
4851 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4852 Info.EvalStatus.HasSideEffects) ||
4853 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4854 return CompleteObject();
4856 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4875 const LValue &LVal,
APValue &RVal,
4876 bool WantObjectRepresentation =
false) {
4877 if (LVal.Designator.Invalid)
4886 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4890 assert(LVal.Designator.Entries.size() <= 1 &&
4891 "Can only read characters from string literals");
4892 if (LVal.Designator.Entries.empty()) {
4899 if (LVal.Designator.isOnePastTheEnd()) {
4900 if (Info.getLangOpts().CPlusPlus11)
4901 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4906 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4913 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4927 LVal.setFrom(Info.Ctx, Val);
4943 if (LVal.Designator.Invalid)
4946 if (!Info.getLangOpts().CPlusPlus14) {
4956struct CompoundAssignSubobjectHandler {
4958 const CompoundAssignOperator *E;
4959 QualType PromotedLHSType;
4965 typedef bool result_type;
4967 bool checkConst(QualType QT) {
4970 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4976 bool failed() {
return false; }
4977 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4980 return found(Subobj.
getInt(), SubobjType);
4982 return found(Subobj.
getFloat(), SubobjType);
4989 return foundPointer(Subobj, SubobjType);
4991 return foundVector(Subobj, SubobjType);
4993 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5005 bool foundVector(
APValue &
Value, QualType SubobjType) {
5006 if (!checkConst(SubobjType))
5017 if (!checkConst(SubobjType))
5036 Info.Ctx.getLangOpts());
5039 PromotedLHSType, FValue) &&
5048 bool found(APFloat &
Value, QualType SubobjType) {
5049 return checkConst(SubobjType) &&
5055 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5056 if (!checkConst(SubobjType))
5059 QualType PointeeType;
5060 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5064 (Opcode != BO_Add && Opcode != BO_Sub)) {
5070 if (Opcode == BO_Sub)
5074 LVal.setFrom(Info.Ctx, Subobj);
5077 LVal.moveInto(Subobj);
5083const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5088 const LValue &LVal,
QualType LValType,
5092 if (LVal.Designator.Invalid)
5095 if (!Info.getLangOpts().CPlusPlus14) {
5101 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5103 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5107struct IncDecSubobjectHandler {
5109 const UnaryOperator *E;
5113 typedef bool result_type;
5115 bool checkConst(QualType QT) {
5118 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5124 bool failed() {
return false; }
5125 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5135 return found(Subobj.
getInt(), SubobjType);
5137 return found(Subobj.
getFloat(), SubobjType);
5140 SubobjType->
castAs<ComplexType>()->getElementType()
5144 SubobjType->
castAs<ComplexType>()->getElementType()
5147 return foundPointer(Subobj, SubobjType);
5155 if (!checkConst(SubobjType))
5177 bool WasNegative =
Value.isNegative();
5191 unsigned BitWidth =
Value.getBitWidth();
5192 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5193 ActualValue.setBit(BitWidth);
5199 bool found(APFloat &
Value, QualType SubobjType) {
5200 if (!checkConst(SubobjType))
5207 APFloat::opStatus St;
5209 St =
Value.add(One, RM);
5211 St =
Value.subtract(One, RM);
5214 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5215 if (!checkConst(SubobjType))
5218 QualType PointeeType;
5219 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5227 LVal.setFrom(Info.Ctx, Subobj);
5231 LVal.moveInto(Subobj);
5240 if (LVal.Designator.Invalid)
5243 if (!Info.getLangOpts().CPlusPlus14) {
5251 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5257 if (
Object->getType()->isPointerType() &&
Object->isPRValue())
5263 if (
Object->getType()->isLiteralType(Info.Ctx))
5266 if (
Object->getType()->isRecordType() &&
Object->isPRValue())
5269 Info.FFDiag(
Object, diag::note_constexpr_nonliteral) <<
Object->getType();
5288 bool IncludeMember =
true) {
5295 if (!MemPtr.getDecl()) {
5301 if (MemPtr.isDerivedMember()) {
5308 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5309 LV.Designator.Entries.size()) {
5313 unsigned PathLengthToMember =
5314 LV.Designator.Entries.size() - MemPtr.Path.size();
5315 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5317 LV.Designator.Entries[PathLengthToMember + I]);
5334 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5335 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5337 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5345 PathLengthToMember))
5347 }
else if (!MemPtr.Path.empty()) {
5349 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5350 MemPtr.Path.size() + IncludeMember);
5356 assert(RD &&
"member pointer access on non-class-type expression");
5358 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5366 MemPtr.getContainingRecord()))
5371 if (IncludeMember) {
5372 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5376 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5380 llvm_unreachable(
"can't construct reference to bound member function");
5384 return MemPtr.getDecl();
5390 bool IncludeMember =
true) {
5394 if (Info.noteFailure()) {
5402 BO->
getRHS(), IncludeMember);
5409 SubobjectDesignator &D =
Result.Designator;
5417 auto InvalidCast = [&]() {
5418 if (!Info.checkingPotentialConstantExpression() ||
5419 !
Result.AllowConstexprUnknown) {
5420 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5421 << D.MostDerivedType << TargetQT;
5427 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5428 return InvalidCast();
5432 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5435 if (NewEntriesSize == D.MostDerivedPathLength)
5438 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5440 return InvalidCast();
5455 if (
auto *RD = T->getAsCXXRecordDecl()) {
5456 if (RD->isInvalidDecl()) {
5460 if (RD->isUnion()) {
5469 End = RD->bases_end();
5470 I != End; ++I, ++Index)
5474 for (
const auto *I : RD->fields()) {
5475 if (I->isUnnamedBitField())
5478 I->getType(),
Result.getStructField(I->getFieldIndex()));
5484 dyn_cast_or_null<ConstantArrayType>(T->getAsArrayTypeUnsafe())) {
5486 if (
Result.hasArrayFiller())
5498enum EvalStmtResult {
5527 if (!
Result.Designator.Invalid &&
Result.Designator.isOnePastTheEnd()) {
5545 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5546 ScopeKind::Block,
Result);
5551 return Info.noteSideEffect();
5572 const DecompositionDecl *DD);
5575 bool EvaluateConditionDecl =
false) {
5577 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5581 EvaluateConditionDecl && DD)
5591 if (
auto *VD = BD->getHoldingVar())
5599 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5608 if (Info.noteSideEffect())
5610 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5611 "reach invalid code path.");
5618 if (
Cond->isValueDependent())
5620 FullExpressionRAII
Scope(Info);
5627 return Scope.destroy();
5640struct TempVersionRAII {
5641 CallStackFrame &Frame;
5643 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5644 Frame.pushTempVersion();
5647 ~TempVersionRAII() {
5648 Frame.popTempVersion();
5656 const SwitchCase *SC =
nullptr);
5662 const Stmt *LoopOrSwitch,
5664 EvalStmtResult &ESR) {
5668 if (!IsSwitch && ESR == ESR_Succeeded) {
5673 if (ESR != ESR_Break && ESR != ESR_Continue)
5677 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5678 const Stmt *StackTop = Info.BreakContinueStack.back();
5679 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5680 Info.BreakContinueStack.pop_back();
5681 if (ESR == ESR_Break)
5682 ESR = ESR_Succeeded;
5687 for (BlockScopeRAII *S : Scopes) {
5688 if (!S->destroy()) {
5700 BlockScopeRAII
Scope(Info);
5703 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5712 BlockScopeRAII
Scope(Info);
5719 if (ESR != ESR_Succeeded) {
5720 if (ESR != ESR_Failed && !
Scope.destroy())
5726 FullExpressionRAII CondScope(Info);
5741 if (!CondScope.destroy())
5762 if (LHSValue <=
Value &&
Value <= RHSValue) {
5769 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5773 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5780 llvm_unreachable(
"Should have been converted to Succeeded");
5786 case ESR_CaseNotFound:
5789 Info.FFDiag(
Found->getBeginLoc(),
5790 diag::note_constexpr_stmt_expr_unsupported);
5793 llvm_unreachable(
"Invalid EvalStmtResult!");
5803 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5813 if (!Info.nextStep(S))
5820 case Stmt::CompoundStmtClass:
5824 case Stmt::LabelStmtClass:
5825 case Stmt::AttributedStmtClass:
5826 case Stmt::DoStmtClass:
5829 case Stmt::CaseStmtClass:
5830 case Stmt::DefaultStmtClass:
5835 case Stmt::IfStmtClass: {
5842 BlockScopeRAII
Scope(Info);
5848 if (ESR != ESR_CaseNotFound) {
5849 assert(ESR != ESR_Succeeded);
5860 if (ESR == ESR_Failed)
5862 if (ESR != ESR_CaseNotFound)
5863 return Scope.destroy() ? ESR : ESR_Failed;
5865 return ESR_CaseNotFound;
5868 if (ESR == ESR_Failed)
5870 if (ESR != ESR_CaseNotFound)
5871 return Scope.destroy() ? ESR : ESR_Failed;
5872 return ESR_CaseNotFound;
5875 case Stmt::WhileStmtClass: {
5876 EvalStmtResult ESR =
5880 if (ESR != ESR_Continue)
5885 case Stmt::ForStmtClass: {
5887 BlockScopeRAII
Scope(Info);
5893 if (ESR != ESR_CaseNotFound) {
5894 assert(ESR != ESR_Succeeded);
5899 EvalStmtResult ESR =
5903 if (ESR != ESR_Continue)
5905 if (
const auto *Inc = FS->
getInc()) {
5906 if (Inc->isValueDependent()) {
5910 FullExpressionRAII IncScope(Info);
5918 case Stmt::DeclStmtClass: {
5922 for (
const auto *D : DS->
decls()) {
5923 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5926 if (VD->hasLocalStorage() && !VD->getInit())
5934 return ESR_CaseNotFound;
5938 return ESR_CaseNotFound;
5944 if (
const Expr *E = dyn_cast<Expr>(S)) {
5953 FullExpressionRAII
Scope(Info);
5957 return ESR_Succeeded;
5963 case Stmt::NullStmtClass:
5964 return ESR_Succeeded;
5966 case Stmt::DeclStmtClass: {
5968 for (
const auto *D : DS->
decls()) {
5969 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
5973 FullExpressionRAII
Scope(Info);
5975 !Info.noteFailure())
5977 if (!
Scope.destroy())
5980 return ESR_Succeeded;
5983 case Stmt::ReturnStmtClass: {
5985 FullExpressionRAII
Scope(Info);
5996 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5999 case Stmt::CompoundStmtClass: {
6000 BlockScopeRAII
Scope(Info);
6003 for (
const auto *BI : CS->
body()) {
6005 if (ESR == ESR_Succeeded)
6007 else if (ESR != ESR_CaseNotFound) {
6008 if (ESR != ESR_Failed && !
Scope.destroy())
6014 return ESR_CaseNotFound;
6015 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6018 case Stmt::IfStmtClass: {
6022 BlockScopeRAII
Scope(Info);
6025 if (ESR != ESR_Succeeded) {
6026 if (ESR != ESR_Failed && !
Scope.destroy())
6036 if (!Info.InConstantContext)
6044 if (ESR != ESR_Succeeded) {
6045 if (ESR != ESR_Failed && !
Scope.destroy())
6050 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6053 case Stmt::WhileStmtClass: {
6056 BlockScopeRAII
Scope(Info);
6068 if (ESR != ESR_Continue) {
6069 if (ESR != ESR_Failed && !
Scope.destroy())
6073 if (!
Scope.destroy())
6076 return ESR_Succeeded;
6079 case Stmt::DoStmtClass: {
6086 if (ESR != ESR_Continue)
6095 FullExpressionRAII CondScope(Info);
6097 !CondScope.destroy())
6100 return ESR_Succeeded;
6103 case Stmt::ForStmtClass: {
6105 BlockScopeRAII ForScope(Info);
6108 if (ESR != ESR_Succeeded) {
6109 if (ESR != ESR_Failed && !ForScope.destroy())
6115 BlockScopeRAII IterScope(Info);
6116 bool Continue =
true;
6122 if (!IterScope.destroy())
6130 if (ESR != ESR_Continue) {
6131 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6136 if (
const auto *Inc = FS->
getInc()) {
6137 if (Inc->isValueDependent()) {
6141 FullExpressionRAII IncScope(Info);
6147 if (!IterScope.destroy())
6150 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6153 case Stmt::CXXForRangeStmtClass: {
6155 BlockScopeRAII
Scope(Info);
6160 if (ESR != ESR_Succeeded) {
6161 if (ESR != ESR_Failed && !
Scope.destroy())
6169 if (ESR != ESR_Succeeded) {
6170 if (ESR != ESR_Failed && !
Scope.destroy())
6182 if (ESR != ESR_Succeeded) {
6183 if (ESR != ESR_Failed && !
Scope.destroy())
6188 if (ESR != ESR_Succeeded) {
6189 if (ESR != ESR_Failed && !
Scope.destroy())
6202 bool Continue =
true;
6203 FullExpressionRAII CondExpr(Info);
6211 BlockScopeRAII InnerScope(Info);
6213 if (ESR != ESR_Succeeded) {
6214 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6223 if (ESR != ESR_Continue) {
6224 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6237 if (!InnerScope.destroy())
6241 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6244 case Stmt::SwitchStmtClass:
6247 case Stmt::ContinueStmtClass:
6248 case Stmt::BreakStmtClass: {
6250 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6254 case Stmt::LabelStmtClass:
6257 case Stmt::AttributedStmtClass: {
6259 const auto *SS = AS->getSubStmt();
6260 MSConstexprContextRAII ConstexprContext(
6264 auto LO = Info.Ctx.getLangOpts();
6265 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6266 for (
auto *
Attr : AS->getAttrs()) {
6267 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6271 auto *Assumption = AA->getAssumption();
6272 if (Assumption->isValueDependent())
6275 if (Assumption->HasSideEffects(Info.Ctx))
6282 Info.CCEDiag(Assumption->getExprLoc(),
6283 diag::note_constexpr_assumption_failed);
6292 case Stmt::CaseStmtClass:
6293 case Stmt::DefaultStmtClass:
6295 case Stmt::CXXTryStmtClass:
6307 bool IsValueInitialization) {
6314 if (!CD->
isConstexpr() && !IsValueInitialization) {
6315 if (Info.getLangOpts().CPlusPlus11) {
6318 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6320 Info.Note(CD->
getLocation(), diag::note_declared_at);
6322 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6336 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6344 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6353 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6356 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6362 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6372 StringRef Name = DiagDecl->
getName();
6374 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6376 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6381 if (Info.getLangOpts().CPlusPlus11) {
6384 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6385 if (CD && CD->isInheritingConstructor()) {
6386 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6387 if (!Inherited->isConstexpr())
6388 DiagDecl = CD = Inherited;
6394 if (CD && CD->isInheritingConstructor())
6395 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6396 << CD->getInheritedConstructor().getConstructor()->getParent();
6398 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6400 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6402 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6408struct CheckDynamicTypeHandler {
6410 typedef bool result_type;
6411 bool failed() {
return false; }
6412 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6415 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6416 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6424 if (
This.Designator.Invalid)
6436 if (
This.Designator.isOnePastTheEnd() ||
6437 This.Designator.isMostDerivedAnUnsizedArray()) {
6438 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6439 ? diag::note_constexpr_access_past_end
6440 : diag::note_constexpr_access_unsized_array)
6443 }
else if (Polymorphic) {
6446 if (!Info.checkingPotentialConstantExpression() ||
6447 !
This.AllowConstexprUnknown) {
6451 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6452 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6460 CheckDynamicTypeHandler Handler{AK};
6483 unsigned PathLength) {
6484 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6485 Designator.Entries.size() &&
"invalid path length");
6486 return (PathLength ==
Designator.MostDerivedPathLength)
6487 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6488 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6501 return std::nullopt;
6503 if (
This.Designator.Invalid)
6504 return std::nullopt;
6513 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6514 if (!Class || Class->getNumVBases()) {
6516 return std::nullopt;
6524 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6525 PathLength <= Path.size(); ++PathLength) {
6526 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6527 Path.slice(0, PathLength))) {
6528 case ConstructionPhase::Bases:
6529 case ConstructionPhase::DestroyingBases:
6534 case ConstructionPhase::None:
6535 case ConstructionPhase::AfterBases:
6536 case ConstructionPhase::AfterFields:
6537 case ConstructionPhase::Destroying:
6549 return std::nullopt;
6567 unsigned PathLength = DynType->PathLength;
6568 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6571 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6581 if (Callee->isPureVirtual()) {
6582 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6583 Info.Note(Callee->getLocation(), diag::note_declared_at);
6589 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6590 Found->getReturnType())) {
6591 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6592 for (
unsigned CovariantPathLength = PathLength + 1;
6593 CovariantPathLength !=
This.Designator.Entries.size();
6594 ++CovariantPathLength) {
6598 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6599 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6600 Next->getReturnType(), CovariantAdjustmentPath.back()))
6601 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6603 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6604 CovariantAdjustmentPath.back()))
6605 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6621 assert(
Result.isLValue() &&
6622 "unexpected kind of APValue for covariant return");
6623 if (
Result.isNullPointer())
6627 LVal.setFrom(Info.Ctx,
Result);
6629 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6630 for (
unsigned I = 1; I != Path.size(); ++I) {
6631 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6632 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6633 if (OldClass != NewClass &&
6636 OldClass = NewClass;
6648 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6650 return BaseSpec.getAccessSpecifier() ==
AS_public;
6652 llvm_unreachable(
"Base is not a direct base of Derived");
6662 SubobjectDesignator &D = Ptr.Designator;
6668 if (Ptr.isNullPointer() && !E->
isGLValue())
6674 std::optional<DynamicType> DynType =
6686 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6694 Ptr.setNull(Info.Ctx, E->
getType());
6701 DynType->Type->isDerivedFrom(
C)))
6703 else if (!Paths || Paths->begin() == Paths->end())
6705 else if (Paths->isAmbiguous(CQT))
6708 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6711 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6712 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6713 << Info.Ctx.getCanonicalTagType(DynType->Type)
6721 for (
int PathLength = Ptr.Designator.Entries.size();
6722 PathLength >= (
int)DynType->PathLength; --PathLength) {
6727 if (PathLength > (
int)DynType->PathLength &&
6730 return RuntimeCheckFailed(
nullptr);
6737 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6750 return RuntimeCheckFailed(&Paths);
6754struct StartLifetimeOfUnionMemberHandler {
6756 const Expr *LHSExpr;
6757 const FieldDecl *
Field;
6759 bool Failed =
false;
6762 typedef bool result_type;
6763 bool failed() {
return Failed; }
6764 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6779 }
else if (DuringInit) {
6783 Info.FFDiag(LHSExpr,
6784 diag::note_constexpr_union_member_change_during_init);
6793 llvm_unreachable(
"wrong value kind for union object");
6795 bool found(APFloat &
Value, QualType SubobjType) {
6796 llvm_unreachable(
"wrong value kind for union object");
6801const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6808 const Expr *LHSExpr,
6809 const LValue &LHS) {
6810 if (LHS.InvalidBase || LHS.Designator.Invalid)
6816 unsigned PathLength = LHS.Designator.Entries.size();
6817 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6819 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6820 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6823 if (!FD || FD->getType()->isReferenceType())
6827 if (FD->getParent()->isUnion()) {
6832 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6833 if (!RD || RD->hasTrivialDefaultConstructor())
6834 UnionPathLengths.push_back({PathLength - 1, FD});
6840 LHS.Designator.Entries[PathLength]
6841 .getAsBaseOrMember().getPointer()));
6845 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6847 auto *
Base = ASE->getBase()->IgnoreImplicit();
6848 if (!
Base->getType()->isArrayType())
6854 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6857 if (ICE->getCastKind() == CK_NoOp)
6859 if (ICE->getCastKind() != CK_DerivedToBase &&
6860 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6864 if (Elt->isVirtual()) {
6873 LHS.Designator.Entries[PathLength]
6874 .getAsBaseOrMember().getPointer()));
6884 if (UnionPathLengths.empty())
6889 CompleteObject Obj =
6893 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6894 llvm::reverse(UnionPathLengths)) {
6896 SubobjectDesignator D = LHS.Designator;
6897 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6899 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6900 ConstructionPhase::AfterBases;
6901 StartLifetimeOfUnionMemberHandler StartLifetime{
6902 Info, LHSExpr, LengthAndField.second, DuringInit};
6911 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6912 APValue **EvaluatedArg =
nullptr) {
6919 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6920 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6921 ScopeKind::Call, LV);
6927 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6928 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6941 bool RightToLeft =
false,
6942 LValue *ObjectArg =
nullptr) {
6944 llvm::SmallBitVector ForbiddenNullArgs;
6945 if (Callee->hasAttr<NonNullAttr>()) {
6946 ForbiddenNullArgs.resize(Args.size());
6947 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6948 if (!
Attr->args_size()) {
6949 ForbiddenNullArgs.set();
6952 for (
auto Idx :
Attr->args()) {
6953 unsigned ASTIdx = Idx.getASTIndex();
6954 if (ASTIdx >= Args.size())
6956 ForbiddenNullArgs[ASTIdx] =
true;
6960 for (
unsigned I = 0; I < Args.size(); I++) {
6961 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6963 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6964 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6969 if (!Info.noteFailure())
6974 ObjectArg->setFrom(Info.Ctx, *That);
6983 bool CopyObjectRepresentation) {
6985 CallStackFrame *Frame = Info.CurrentCall;
6986 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6994 RefLValue.setFrom(Info.Ctx, *RefValue);
6997 CopyObjectRepresentation);
7003 const LValue *ObjectArg,
const Expr *E,
7005 const Stmt *Body, EvalInfo &Info,
7007 if (!Info.CheckCallLimit(CallLoc))
7036 ObjectArg->moveInto(
Result);
7045 if (!Info.checkingPotentialConstantExpression())
7047 Frame.LambdaThisCaptureField);
7050 StmtResult Ret = {
Result, ResultSlot};
7052 if (ESR == ESR_Succeeded) {
7053 if (Callee->getReturnType()->isVoidType())
7055 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7057 return ESR == ESR_Returned;
7066 if (!Info.CheckCallLimit(CallLoc))
7071 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7075 EvalInfo::EvaluatingConstructorRAII EvalObj(
7077 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7084 StmtResult Ret = {RetVal,
nullptr};
7089 if ((*I)->getInit()->isValueDependent()) {
7093 FullExpressionRAII InitScope(Info);
7095 !InitScope.destroy())
7118 if (!
Result.hasValue()) {
7131 BlockScopeRAII LifetimeExtendedScope(Info);
7134 unsigned BasesSeen = 0;
7139 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7144 assert(Indirect &&
"fields out of order?");
7150 assert(FieldIt != RD->
field_end() &&
"missing field?");
7151 if (!FieldIt->isUnnamedBitField())
7154 Result.getStructField(FieldIt->getFieldIndex()));
7159 LValue Subobject =
This;
7160 LValue SubobjectParent =
This;
7165 if (I->isBaseInitializer()) {
7166 QualType BaseType(I->getBaseClass(), 0);
7170 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
7171 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
7172 "base class initializers not in expected order");
7176 BaseType->getAsCXXRecordDecl(), &Layout))
7179 }
else if ((FD = I->getMember())) {
7186 SkipToField(FD,
false);
7192 auto IndirectFieldChain = IFD->chain();
7193 for (
auto *
C : IndirectFieldChain) {
7202 (
Value->isUnion() &&
7215 if (
C == IndirectFieldChain.back())
7216 SubobjectParent = Subobject;
7222 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7223 SkipToField(FD,
true);
7228 llvm_unreachable(
"unknown base initializer kind");
7235 if (
Init->isValueDependent()) {
7239 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7241 FullExpressionRAII InitScope(Info);
7247 if (!Info.noteFailure())
7256 if (!Info.noteFailure())
7264 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
7265 EvalObj.finishedConstructingBases();
7270 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7271 if (!FieldIt->isUnnamedBitField())
7274 Result.getStructField(FieldIt->getFieldIndex()));
7278 EvalObj.finishedConstructingFields();
7282 LifetimeExtendedScope.destroy();
7289 CallScopeRAII CallScope(Info);
7295 CallScope.destroy();
7305 if (
Value.isAbsent() && !T->isNullPtrType()) {
7307 This.moveInto(Printable);
7309 diag::note_constexpr_destroy_out_of_lifetime)
7310 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(T));
7326 LValue ElemLV =
This;
7327 ElemLV.addArray(Info, &LocE, CAT);
7334 if (Size && Size >
Value.getArrayInitializedElts())
7339 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7340 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7353 if (T.isDestructedType()) {
7355 diag::note_constexpr_unsupported_destruction)
7365 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7390 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7399 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7404 EvalInfo::EvaluatingDestructorRAII EvalObj(
7406 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7407 if (!EvalObj.DidInsert) {
7414 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7421 StmtResult Ret = {RetVal,
nullptr};
7434 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7435 if (FD->isUnnamedBitField())
7438 LValue Subobject =
This;
7442 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7449 EvalObj.startedDestroyingBases();
7456 LValue Subobject =
This;
7458 BaseType->getAsCXXRecordDecl(), &Layout))
7461 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7466 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7474struct DestroyObjectHandler {
7480 typedef bool result_type;
7481 bool failed() {
return false; }
7482 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
7487 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7490 bool found(APFloat &
Value, QualType SubobjType) {
7491 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7512 if (Info.EvalStatus.HasSideEffects)
7523 if (Info.checkingPotentialConstantExpression() ||
7524 Info.SpeculativeEvaluationDepth)
7528 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7530 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7531 ? diag::note_constexpr_new_untyped
7532 : diag::note_constexpr_new);
7536 QualType ElemType = Caller.ElemType;
7539 diag::note_constexpr_new_not_complete_object_type)
7547 bool IsNothrow =
false;
7548 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7556 APInt Size, Remainder;
7557 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7558 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7559 if (Remainder != 0) {
7561 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7562 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7566 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7567 Size.getZExtValue(), !IsNothrow)) {
7575 QualType AllocType = Info.Ctx.getConstantArrayType(
7577 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType,
Result);
7586 return DD->isVirtual();
7593 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7604 DynAlloc::Kind DeallocKind) {
7605 auto PointerAsString = [&] {
7606 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7611 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7612 << PointerAsString();
7615 return std::nullopt;
7618 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7620 Info.FFDiag(E, diag::note_constexpr_double_delete);
7621 return std::nullopt;
7624 if (DeallocKind != (*Alloc)->getKind()) {
7626 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7627 << DeallocKind << (*Alloc)->getKind() << AllocType;
7629 return std::nullopt;
7632 bool Subobject =
false;
7633 if (DeallocKind == DynAlloc::New) {
7634 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7635 Pointer.Designator.isOnePastTheEnd();
7637 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7638 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7641 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7642 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7643 return std::nullopt;
7651 if (Info.checkingPotentialConstantExpression() ||
7652 Info.SpeculativeEvaluationDepth)
7656 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7664 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7667 if (
Pointer.Designator.Invalid)
7672 if (
Pointer.isNullPointer()) {
7673 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7689class BitCastBuffer {
7695 SmallVector<std::optional<unsigned char>, 32> Bytes;
7697 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7698 "Need at least 8 bit unsigned char");
7700 bool TargetIsLittleEndian;
7703 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7704 : Bytes(Width.getQuantity()),
7705 TargetIsLittleEndian(TargetIsLittleEndian) {}
7707 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7708 SmallVectorImpl<unsigned char> &Output)
const {
7709 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7712 if (!Bytes[I.getQuantity()])
7714 Output.push_back(*Bytes[I.getQuantity()]);
7716 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7717 std::reverse(Output.begin(), Output.end());
7721 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7722 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7723 std::reverse(Input.begin(), Input.end());
7726 for (
unsigned char Byte : Input) {
7727 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7733 size_t size() {
return Bytes.size(); }
7738class APValueToBufferConverter {
7740 BitCastBuffer Buffer;
7743 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7746 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7749 bool visit(
const APValue &Val, QualType Ty) {
7754 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7755 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7768 return visitInt(Val.
getInt(), Ty, Offset);
7770 return visitFloat(Val.
getFloat(), Ty, Offset);
7772 return visitArray(Val, Ty, Offset);
7774 return visitRecord(Val, Ty, Offset);
7776 return visitVector(Val, Ty, Offset);
7780 return visitComplex(Val, Ty, Offset);
7790 diag::note_constexpr_bit_cast_unsupported_type)
7795 llvm_unreachable(
"Unhandled APValue::ValueKind");
7798 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7800 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
7803 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7804 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7805 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7810 if (!
Base.isStruct())
7813 if (!visitRecord(Base, BS.
getType(),
7820 unsigned FieldIdx = 0;
7821 for (FieldDecl *FD : RD->
fields()) {
7822 if (FD->isBitField()) {
7824 diag::note_constexpr_bit_cast_unsupported_bitfield);
7830 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7831 "only bit-fields can have sub-char alignment");
7832 CharUnits FieldOffset =
7833 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7834 QualType FieldTy = FD->getType();
7843 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7849 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
7853 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7855 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7862 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7863 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7871 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7872 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7874 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7879 Offset + (0 * EltSizeChars)))
7882 Offset + (1 * EltSizeChars)))
7886 Offset + (0 * EltSizeChars)))
7889 Offset + (1 * EltSizeChars)))
7896 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7897 const VectorType *VTy = Ty->
castAs<VectorType>();
7910 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7912 llvm::APInt Res = llvm::APInt::getZero(NElts);
7913 for (
unsigned I = 0; I < NElts; ++I) {
7915 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7916 "bool vector element must be 1-bit unsigned integer!");
7918 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7921 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7922 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7923 Buffer.writeObject(Offset, Bytes);
7927 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7928 for (
unsigned I = 0; I < NElts; ++I) {
7929 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7937 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
7938 APSInt AdjustedVal = Val;
7939 unsigned Width = AdjustedVal.getBitWidth();
7941 Width = Info.Ctx.getTypeSize(Ty);
7942 AdjustedVal = AdjustedVal.extend(Width);
7945 SmallVector<uint8_t, 8> Bytes(Width / 8);
7946 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7947 Buffer.writeObject(Offset, Bytes);
7951 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
7952 APSInt AsInt(Val.bitcastToAPInt());
7953 return visitInt(AsInt, Ty, Offset);
7957 static std::optional<BitCastBuffer>
7959 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
7960 APValueToBufferConverter Converter(Info, DstSize, BCE);
7962 return std::nullopt;
7963 return Converter.Buffer;
7968class BufferToAPValueConverter {
7970 const BitCastBuffer &Buffer;
7973 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7975 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7980 std::nullopt_t unsupportedType(QualType Ty) {
7982 diag::note_constexpr_bit_cast_unsupported_type)
7984 return std::nullopt;
7987 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
7989 diag::note_constexpr_bit_cast_unrepresentable_value)
7991 return std::nullopt;
7994 std::optional<APValue> visit(
const BuiltinType *T, CharUnits Offset,
7995 const EnumType *EnumSugar =
nullptr) {
7997 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(T, 0));
7998 return APValue((Expr *)
nullptr,
8000 APValue::NoLValuePath{},
true);
8003 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(T);
8009 const llvm::fltSemantics &Semantics =
8010 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8011 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8012 assert(NumBits % 8 == 0);
8018 SmallVector<uint8_t, 8> Bytes;
8019 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8022 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8026 if (!IsStdByte && !IsUChar) {
8027 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar : T, 0);
8029 diag::note_constexpr_bit_cast_indet_dest)
8030 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8031 return std::nullopt;
8037 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8038 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8043 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(T, 0));
8044 if (IntWidth != Val.getBitWidth()) {
8045 APSInt Truncated = Val.trunc(IntWidth);
8046 if (Truncated.extend(Val.getBitWidth()) != Val)
8047 return unrepresentableValue(QualType(T, 0), Val);
8055 const llvm::fltSemantics &Semantics =
8056 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8060 return unsupportedType(QualType(T, 0));
8063 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8064 const RecordDecl *RD = RTy->getAsRecordDecl();
8066 return std::nullopt;
8067 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8069 unsigned NumBases = 0;
8070 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8071 NumBases = CXXRD->getNumBases();
8076 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8077 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8078 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8081 std::optional<APValue> SubObj = visitType(
8084 return std::nullopt;
8085 ResultVal.getStructBase(I) = *SubObj;
8090 unsigned FieldIdx = 0;
8091 for (FieldDecl *FD : RD->
fields()) {
8094 if (FD->isBitField()) {
8096 diag::note_constexpr_bit_cast_unsupported_bitfield);
8097 return std::nullopt;
8101 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8103 CharUnits FieldOffset =
8106 QualType FieldTy = FD->getType();
8107 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8109 return std::nullopt;
8110 ResultVal.getStructField(FieldIdx) = *SubObj;
8117 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8118 QualType RepresentationType =
8119 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8120 assert(!RepresentationType.
isNull() &&
8121 "enum forward decl should be caught by Sema");
8122 const auto *AsBuiltin =
8126 return visit(AsBuiltin, Offset, Ty);
8129 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8131 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8133 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8134 for (
size_t I = 0; I !=
Size; ++I) {
8135 std::optional<APValue> ElementValue =
8138 return std::nullopt;
8139 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8145 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8147 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8150 std::optional<APValue> Values[2];
8151 for (
unsigned I = 0; I != 2; ++I) {
8152 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8154 return std::nullopt;
8158 return APValue(Values[0]->getInt(), Values[1]->getInt());
8159 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8162 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8168 SmallVector<APValue, 4> Elts;
8169 Elts.reserve(NElts);
8179 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8181 SmallVector<uint8_t, 8> Bytes;
8182 Bytes.reserve(NElts / 8);
8184 return std::nullopt;
8186 APSInt SValInt(NElts,
true);
8187 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8189 for (
unsigned I = 0; I < NElts; ++I) {
8191 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8198 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8199 for (
unsigned I = 0; I < NElts; ++I) {
8200 std::optional<APValue> EltValue =
8201 visitType(EltTy, Offset + I * EltSizeChars);
8203 return std::nullopt;
8204 Elts.push_back(std::move(*EltValue));
8208 return APValue(Elts.data(), Elts.size());
8211 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8212 return unsupportedType(QualType(Ty, 0));
8215 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8219#define TYPE(Class, Base) \
8221 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8222#define ABSTRACT_TYPE(Class, Base)
8223#define NON_CANONICAL_TYPE(Class, Base) \
8225 llvm_unreachable("non-canonical type should be impossible!");
8226#define DEPENDENT_TYPE(Class, Base) \
8229 "dependent types aren't supported in the constant evaluator!");
8230#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8232 llvm_unreachable("either dependent or not canonical!");
8233#include "clang/AST/TypeNodes.inc"
8235 llvm_unreachable(
"Unhandled Type::TypeClass");
8240 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8242 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8247static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8248 QualType Ty, EvalInfo *Info,
8249 const ASTContext &Ctx,
8250 bool CheckingDest) {
8253 auto diag = [&](
int Reason) {
8255 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8256 << CheckingDest << (Reason == 4) << Reason;
8259 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8261 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8262 << NoteTy << Construct << Ty;
8276 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8277 for (CXXBaseSpecifier &BS : CXXRD->bases())
8278 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8282 for (FieldDecl *FD :
Record->fields()) {
8283 if (FD->getType()->isReferenceType())
8285 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8287 return note(0, FD->getType(), FD->getBeginLoc());
8293 Info, Ctx, CheckingDest))
8296 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8308 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8309 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8319 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8328static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8329 const ASTContext &Ctx,
8331 bool DestOK = checkBitCastConstexprEligibilityType(
8333 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8339static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8342 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8343 "no host or target supports non 8-bit chars");
8345 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8349 std::optional<BitCastBuffer> Buffer =
8350 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8355 std::optional<APValue> MaybeDestValue =
8356 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8357 if (!MaybeDestValue)
8360 DestValue = std::move(*MaybeDestValue);
8364static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8367 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8368 "no host or target supports non 8-bit chars");
8370 "LValueToRValueBitcast requires an lvalue operand!");
8372 LValue SourceLValue;
8374 SourceLValue.setFrom(Info.Ctx, SourceValue);
8377 SourceRValue,
true))
8380 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8383template <
class Derived>
8384class ExprEvaluatorBase
8385 :
public ConstStmtVisitor<Derived, bool> {
8387 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8388 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8389 return getDerived().Success(
V, E);
8391 bool DerivedZeroInitialization(
const Expr *E) {
8392 return getDerived().ZeroInitialization(E);
8398 template<
typename ConditionalOperator>
8399 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8400 assert(Info.checkingPotentialConstantExpression());
8403 SmallVector<PartialDiagnosticAt, 8>
Diag;
8405 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8412 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8414 Info.EvalStatus.DiagEmitted =
false;
8420 Error(E, diag::note_constexpr_conditional_never_const);
8424 template<
typename ConditionalOperator>
8425 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8428 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8429 CheckPotentialConstantConditional(E);
8432 if (Info.noteFailure()) {
8440 return StmtVisitorTy::Visit(EvalExpr);
8445 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8446 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8448 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8449 return Info.CCEDiag(E, D);
8452 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8454 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8456 return BuiltinOp != 0 &&
8457 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8461 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8463 EvalInfo &getEvalInfo() {
return Info; }
8471 bool Error(
const Expr *E) {
8472 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8475 bool VisitStmt(
const Stmt *) {
8476 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8478 bool VisitExpr(
const Expr *E) {
8482 bool VisitEmbedExpr(
const EmbedExpr *E) {
8483 const auto It = E->
begin();
8484 return StmtVisitorTy::Visit(*It);
8487 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8490 bool VisitConstantExpr(
const ConstantExpr *E) {
8494 return StmtVisitorTy::Visit(E->
getSubExpr());
8497 bool VisitParenExpr(
const ParenExpr *E)
8498 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8499 bool VisitUnaryExtension(
const UnaryOperator *E)
8500 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8501 bool VisitUnaryPlus(
const UnaryOperator *E)
8502 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8503 bool VisitChooseExpr(
const ChooseExpr *E)
8505 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8507 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8509 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8510 TempVersionRAII RAII(*Info.CurrentCall);
8511 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8512 return StmtVisitorTy::Visit(E->
getExpr());
8514 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8515 TempVersionRAII RAII(*Info.CurrentCall);
8519 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8520 return StmtVisitorTy::Visit(E->
getExpr());
8523 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8524 FullExpressionRAII Scope(Info);
8525 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8530 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8531 return StmtVisitorTy::Visit(E->
getSubExpr());
8534 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8535 CCEDiag(E, diag::note_constexpr_invalid_cast)
8536 << diag::ConstexprInvalidCastKind::Reinterpret;
8537 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8539 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8540 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8541 CCEDiag(E, diag::note_constexpr_invalid_cast)
8542 << diag::ConstexprInvalidCastKind::Dynamic;
8543 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8545 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8546 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8549 bool VisitBinaryOperator(
const BinaryOperator *E) {
8555 VisitIgnoredValue(E->
getLHS());
8556 return StmtVisitorTy::Visit(E->
getRHS());
8566 return DerivedSuccess(
Result, E);
8571 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8575 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8579 if (!
Evaluate(Info.CurrentCall->createTemporary(
8582 ScopeKind::FullExpression, CommonLV),
8586 return HandleConditionalOperator(E);
8589 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8590 bool IsBcpCall =
false;
8595 if (
const CallExpr *CallCE =
8597 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8604 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8607 FoldConstant Fold(Info, IsBcpCall);
8608 if (!HandleConditionalOperator(E)) {
8609 Fold.keepDiagnostics();
8616 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8617 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8619 return DerivedSuccess(*
Value, E);
8625 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8628 return StmtVisitorTy::Visit(Source);
8631 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8632 for (
const Expr *SemE : E->
semantics()) {
8633 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8642 if (OVE->isUnique())
8646 if (!
Evaluate(Info.CurrentCall->createTemporary(
8647 OVE, getStorageType(Info.Ctx, OVE),
8648 ScopeKind::FullExpression, LV),
8649 Info, OVE->getSourceExpr()))
8652 if (!StmtVisitorTy::Visit(SemE))
8662 bool VisitCallExpr(
const CallExpr *E) {
8664 if (!handleCallExpr(E,
Result,
nullptr))
8666 return DerivedSuccess(
Result, E);
8670 const LValue *ResultSlot) {
8671 CallScopeRAII CallScope(Info);
8674 QualType CalleeType =
Callee->getType();
8676 const FunctionDecl *FD =
nullptr;
8677 LValue *
This =
nullptr, ObjectArg;
8679 bool HasQualifier =
false;
8685 const CXXMethodDecl *
Member =
nullptr;
8686 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8690 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8692 return Error(Callee);
8694 HasQualifier = ME->hasQualifier();
8695 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8697 const ValueDecl *D =
8701 Member = dyn_cast<CXXMethodDecl>(D);
8703 return Error(Callee);
8705 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8706 if (!Info.getLangOpts().CPlusPlus20)
8707 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8711 return Error(Callee);
8718 if (!CalleeLV.getLValueOffset().isZero())
8719 return Error(Callee);
8720 if (CalleeLV.isNullPointer()) {
8721 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8722 <<
const_cast<Expr *
>(
Callee);
8725 FD = dyn_cast_or_null<FunctionDecl>(
8726 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8728 return Error(Callee);
8731 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8738 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8739 if (OCE && OCE->isAssignmentOp()) {
8740 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8741 Call = Info.CurrentCall->createCall(FD);
8742 bool HasThis =
false;
8743 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8744 HasThis = MD->isImplicitObjectMemberFunction();
8752 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8772 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8773 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8777 Args = Args.slice(1);
8783 const CXXRecordDecl *ClosureClass = MD->
getParent();
8785 ClosureClass->
captures().empty() &&
8786 "Number of captures must be zero for conversion to function-ptr");
8788 const CXXMethodDecl *LambdaCallOp =
8797 "A generic lambda's static-invoker function must be a "
8798 "template specialization");
8800 FunctionTemplateDecl *CallOpTemplate =
8802 void *InsertPos =
nullptr;
8803 FunctionDecl *CorrespondingCallOpSpecialization =
8805 assert(CorrespondingCallOpSpecialization &&
8806 "We must always have a function call operator specialization "
8807 "that corresponds to our static invoker specialization");
8809 FD = CorrespondingCallOpSpecialization;
8818 return CallScope.destroy();
8828 Call = Info.CurrentCall->createCall(FD);
8834 SmallVector<QualType, 4> CovariantAdjustmentPath;
8836 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8837 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8840 CovariantAdjustmentPath);
8843 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8853 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8854 assert(This &&
"no 'this' pointer for destructor call");
8856 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
8857 CallScope.destroy();
8874 if (!CovariantAdjustmentPath.empty() &&
8876 CovariantAdjustmentPath))
8879 return CallScope.destroy();
8882 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8885 bool VisitInitListExpr(
const InitListExpr *E) {
8887 return DerivedZeroInitialization(E);
8889 return StmtVisitorTy::Visit(E->
getInit(0));
8892 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8893 return DerivedZeroInitialization(E);
8895 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8896 return DerivedZeroInitialization(E);
8898 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8899 return DerivedZeroInitialization(E);
8903 bool VisitMemberExpr(
const MemberExpr *E) {
8904 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8905 "missing temporary materialization conversion");
8906 assert(!E->
isArrow() &&
"missing call to bound member function?");
8914 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8915 if (!FD)
return Error(E);
8919 "record / field mismatch");
8924 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8925 SubobjectDesignator Designator(BaseTy);
8926 Designator.addDeclUnchecked(FD);
8930 DerivedSuccess(
Result, E);
8933 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
8939 SmallVector<uint32_t, 4> Indices;
8941 if (Indices.size() == 1) {
8943 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
8946 SmallVector<APValue, 4> Elts;
8947 for (
unsigned I = 0; I < Indices.size(); ++I) {
8950 APValue VecResult(Elts.data(), Indices.size());
8951 return DerivedSuccess(VecResult, E);
8958 bool VisitCastExpr(
const CastExpr *E) {
8963 case CK_AtomicToNonAtomic: {
8970 return DerivedSuccess(AtomicVal, E);
8974 case CK_UserDefinedConversion:
8975 return StmtVisitorTy::Visit(E->
getSubExpr());
8977 case CK_HLSLArrayRValue: {
8983 return DerivedSuccess(Val, E);
8994 return DerivedSuccess(RVal, E);
8996 case CK_LValueToRValue: {
9005 return DerivedSuccess(RVal, E);
9007 case CK_LValueToRValueBitCast: {
9008 APValue DestValue, SourceValue;
9011 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9013 return DerivedSuccess(DestValue, E);
9016 case CK_AddressSpaceConversion: {
9020 return DerivedSuccess(
Value, E);
9027 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9028 return VisitUnaryPostIncDec(UO);
9030 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9031 return VisitUnaryPostIncDec(UO);
9033 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9034 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9044 return DerivedSuccess(RVal, UO);
9047 bool VisitStmtExpr(
const StmtExpr *E) {
9050 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9057 BlockScopeRAII Scope(Info);
9062 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9064 Info.FFDiag((*BI)->getBeginLoc(),
9065 diag::note_constexpr_stmt_expr_unsupported);
9068 return this->Visit(FinalExpr) && Scope.destroy();
9074 if (ESR != ESR_Succeeded) {
9078 if (ESR != ESR_Failed)
9079 Info.FFDiag((*BI)->getBeginLoc(),
9080 diag::note_constexpr_stmt_expr_unsupported);
9085 llvm_unreachable(
"Return from function from the loop above.");
9088 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9093 void VisitIgnoredValue(
const Expr *E) {
9098 void VisitIgnoredBaseExpression(
const Expr *E) {
9101 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9103 VisitIgnoredValue(E);
9113template<
class Derived>
9114class LValueExprEvaluatorBase
9115 :
public ExprEvaluatorBase<Derived> {
9119 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9120 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9122 bool Success(APValue::LValueBase B) {
9127 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9132 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9134 InvalidBaseOK(InvalidBaseOK) {}
9137 Result.setFrom(this->Info.Ctx,
V);
9141 bool VisitMemberExpr(
const MemberExpr *E) {
9153 EvalOK = this->Visit(E->
getBase());
9164 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9167 "record / field mismatch");
9171 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9175 return this->
Error(E);
9187 bool VisitBinaryOperator(
const BinaryOperator *E) {
9190 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9198 bool VisitCastExpr(
const CastExpr *E) {
9201 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9203 case CK_DerivedToBase:
9204 case CK_UncheckedDerivedToBase:
9251class LValueExprEvaluator
9252 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9254 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9255 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9257 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9258 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9260 bool VisitCallExpr(
const CallExpr *E);
9261 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9262 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9263 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9264 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9265 bool VisitMemberExpr(
const MemberExpr *E);
9266 bool VisitStringLiteral(
const StringLiteral *E) {
9268 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9270 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9271 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9272 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9273 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9274 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9275 bool VisitUnaryDeref(
const UnaryOperator *E);
9276 bool VisitUnaryReal(
const UnaryOperator *E);
9277 bool VisitUnaryImag(
const UnaryOperator *E);
9278 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9279 return VisitUnaryPreIncDec(UO);
9281 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9282 return VisitUnaryPreIncDec(UO);
9284 bool VisitBinAssign(
const BinaryOperator *BO);
9285 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9287 bool VisitCastExpr(
const CastExpr *E) {
9290 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9292 case CK_LValueBitCast:
9293 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9294 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9295 << Info.Ctx.getLangOpts().CPlusPlus;
9298 Result.Designator.setInvalid();
9301 case CK_BaseToDerived:
9318 bool LValueToRValueConversion) {
9322 assert(Info.CurrentCall->This ==
nullptr &&
9323 "This should not be set for a static call operator");
9331 if (
Self->getType()->isReferenceType()) {
9332 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9334 Result.setFrom(Info.Ctx, *RefValue);
9336 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9337 CallStackFrame *Frame =
9338 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9340 unsigned Version = Info.CurrentCall->Arguments.Version;
9341 Result.set({VD, Frame->Index, Version});
9344 Result = *Info.CurrentCall->This;
9354 if (LValueToRValueConversion) {
9358 Result.setFrom(Info.Ctx, RVal);
9369 bool InvalidBaseOK) {
9373 return LValueExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
9376bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9377 const ValueDecl *D = E->
getDecl();
9389 if (Info.checkingPotentialConstantExpression())
9392 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9399 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9400 UnnamedGlobalConstantDecl>(D))
9402 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9403 return VisitVarDecl(E, VD);
9404 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9405 return Visit(BD->getBinding());
9409bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9410 CallStackFrame *Frame =
nullptr;
9411 unsigned Version = 0;
9419 CallStackFrame *CurrFrame = Info.CurrentCall;
9424 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9425 if (CurrFrame->Arguments) {
9426 VD = CurrFrame->Arguments.getOrigParam(PVD);
9428 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9429 Version = CurrFrame->Arguments.Version;
9433 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9440 Result.set({VD, Frame->Index, Version});
9446 if (!Info.getLangOpts().CPlusPlus11) {
9447 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9449 Info.Note(VD->
getLocation(), diag::note_declared_at);
9458 Result.AllowConstexprUnknown =
true;
9465bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9466 if (!IsConstantEvaluatedBuiltinCall(E))
9467 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9472 case Builtin::BIas_const:
9473 case Builtin::BIforward:
9474 case Builtin::BIforward_like:
9475 case Builtin::BImove:
9476 case Builtin::BImove_if_noexcept:
9478 return Visit(E->
getArg(0));
9482 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9485bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9486 const MaterializeTemporaryExpr *E) {
9494 for (
const Expr *E : CommaLHSs)
9503 if (Info.EvalMode == EvaluationMode::ConstantFold)
9510 Value = &Info.CurrentCall->createTemporary(
9526 for (
unsigned I = Adjustments.size(); I != 0; ) {
9528 switch (Adjustments[I].Kind) {
9533 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9539 Type = Adjustments[I].Field->getType();
9544 Adjustments[I].Ptr.RHS))
9546 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9555LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9556 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9557 "lvalue compound literal in c++?");
9569 assert(!Info.getLangOpts().CPlusPlus);
9571 ScopeKind::Block,
Result);
9583bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9584 TypeInfoLValue TypeInfo;
9592 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9593 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9601 std::optional<DynamicType> DynType =
9606 TypeInfo = TypeInfoLValue(
9607 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9613bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9617bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9619 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9620 VisitIgnoredBaseExpression(E->
getBase());
9621 return VisitVarDecl(E, VD);
9625 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9626 if (MD->isStatic()) {
9627 VisitIgnoredBaseExpression(E->
getBase());
9633 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9636bool LValueExprEvaluator::VisitExtVectorElementExpr(
9637 const ExtVectorElementExpr *E) {
9642 if (!Info.noteFailure())
9650 if (Indices.size() > 1)
9654 Result.setFrom(Info.Ctx, Val);
9658 const auto *VT = BaseType->
castAs<VectorType>();
9660 VT->getNumElements(), Indices[0]);
9666bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9676 if (!Info.noteFailure())
9682 if (!Info.noteFailure())
9688 Result.setFrom(Info.Ctx, Val);
9690 VT->getNumElements(), Index.getZExtValue());
9698 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9699 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9701 if (!Info.noteFailure())
9711bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9722 Info.noteUndefinedBehavior();
9725bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9734bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9736 "lvalue __imag__ on scalar?");
9743bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9744 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9755bool LValueExprEvaluator::VisitCompoundAssignOperator(
9756 const CompoundAssignOperator *CAO) {
9757 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9765 if (!Info.noteFailure())
9780bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9781 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9789 if (!Info.noteFailure())
9797 if (Info.getLangOpts().CPlusPlus20 &&
9814 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9815 "Can't get the size of a non alloc_size function");
9816 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9818 std::optional<llvm::APInt> Size =
9819 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9823 Result = std::move(*Size);
9842 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9847 if (!
Init ||
Init->getType().isNull())
9850 const Expr *E =
Init->IgnoreParens();
9851 if (!tryUnwrapAllocSizeCall(E))
9859 Result.addUnsizedArray(Info, E, Pointee);
9864class PointerExprEvaluator
9865 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9874 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9878 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9882 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9885 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9887 InvalidBaseOK(InvalidBaseOK) {}
9893 bool ZeroInitialization(
const Expr *E) {
9898 bool VisitBinaryOperator(
const BinaryOperator *E);
9899 bool VisitCastExpr(
const CastExpr* E);
9900 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9901 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9903 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9906 if (Info.noteFailure())
9910 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
9913 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
9916 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9918 bool VisitCallExpr(
const CallExpr *E);
9919 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9920 bool VisitBlockExpr(
const BlockExpr *E) {
9925 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9926 auto DiagnoseInvalidUseOfThis = [&] {
9927 if (Info.getLangOpts().CPlusPlus11)
9928 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9934 if (Info.checkingPotentialConstantExpression())
9937 bool IsExplicitLambda =
9939 if (!IsExplicitLambda) {
9940 if (!Info.CurrentCall->This) {
9941 DiagnoseInvalidUseOfThis();
9945 Result = *Info.CurrentCall->This;
9953 if (!Info.CurrentCall->LambdaThisCaptureField) {
9954 if (IsExplicitLambda && !Info.CurrentCall->This) {
9955 DiagnoseInvalidUseOfThis();
9964 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9970 bool VisitCXXNewExpr(
const CXXNewExpr *E);
9972 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
9973 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
9975 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
9976 Result.setFrom(Info.Ctx, LValResult);
9980 bool VisitEmbedExpr(
const EmbedExpr *E) {
9981 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9985 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
9988 QualType CharTy = Info.Ctx.CharTy.withConst();
9989 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9990 ResultStr.size() + 1);
9991 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9992 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9995 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
9998 evaluateLValue(SL,
Result);
10008 bool InvalidBaseOK) {
10011 return PointerExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
10014bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10017 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10019 const Expr *PExp = E->
getLHS();
10020 const Expr *IExp = E->
getRHS();
10022 std::swap(PExp, IExp);
10024 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10025 if (!EvalPtrOK && !Info.noteFailure())
10028 llvm::APSInt Offset;
10039bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10047 if (!Info.getLangOpts().CPlusPlus) {
10049 if (
const auto *Deref = dyn_cast<UnaryOperator>(Sub);
10050 Deref && Deref->getOpcode() == UO_Deref)
10051 return evaluatePointer(Deref->getSubExpr(),
Result);
10061 if (!FnII || !FnII->
isStr(
"current"))
10064 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10072bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10079 case CK_CPointerToObjCPointerCast:
10080 case CK_BlockPointerToObjCPointerCast:
10081 case CK_AnyPointerToBlockPointerCast:
10082 case CK_AddressSpaceConversion:
10083 if (!Visit(SubExpr))
10089 CCEDiag(E, diag::note_constexpr_invalid_cast)
10090 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10091 << Info.Ctx.getLangOpts().CPlusPlus;
10092 Result.Designator.setInvalid();
10100 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10102 bool VoidPtrCastMaybeOK =
10105 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10114 if (VoidPtrCastMaybeOK &&
10115 (Info.getStdAllocatorCaller(
"allocate") ||
10117 Info.getLangOpts().CPlusPlus26)) {
10121 Info.getLangOpts().CPlusPlus) {
10122 if (HasValidResult)
10123 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10124 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10125 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10128 CCEDiag(E, diag::note_constexpr_invalid_cast)
10129 << diag::ConstexprInvalidCastKind::CastFrom
10132 CCEDiag(E, diag::note_constexpr_invalid_cast)
10133 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10134 << Info.Ctx.getLangOpts().CPlusPlus;
10135 Result.Designator.setInvalid();
10139 ZeroInitialization(E);
10142 case CK_DerivedToBase:
10143 case CK_UncheckedDerivedToBase:
10155 case CK_BaseToDerived:
10167 case CK_NullToPointer:
10169 return ZeroInitialization(E);
10171 case CK_IntegralToPointer: {
10172 CCEDiag(E, diag::note_constexpr_invalid_cast)
10173 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10174 << Info.Ctx.getLangOpts().CPlusPlus;
10180 if (
Value.isInt()) {
10181 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10182 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10183 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10186 Result.Base = (Expr *)
nullptr;
10187 Result.InvalidBase =
false;
10189 Result.Designator.setInvalid();
10190 Result.IsNullPtr =
false;
10198 if (!
Value.isLValue())
10207 case CK_ArrayToPointerDecay: {
10209 if (!evaluateLValue(SubExpr,
Result))
10213 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10218 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10219 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10220 Result.addArray(Info, E, CAT);
10222 Result.addUnsizedArray(Info, E, AT->getElementType());
10226 case CK_FunctionToPointerDecay:
10227 return evaluateLValue(SubExpr,
Result);
10229 case CK_LValueToRValue: {
10238 return InvalidBaseOK &&
10244 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10252 T = T.getNonReferenceType();
10254 if (T.getQualifiers().hasUnaligned())
10257 const bool AlignOfReturnsPreferred =
10263 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10266 else if (ExprKind == UETT_AlignOf)
10269 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10282 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10286 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10295 return Info.Ctx.getDeclAlign(VD);
10296 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10304 EvalInfo &Info,
APSInt &Alignment) {
10307 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10308 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10311 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10312 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10313 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10314 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10315 << MaxValue << ForType << Alignment;
10321 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10322 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10323 "Alignment should not be changed by ext/trunc");
10324 Alignment = ExtAlignment;
10325 assert(Alignment.getBitWidth() == SrcWidth);
10330bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10331 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10339 Result.addUnsizedArray(Info, E, PointeeTy);
10343bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10344 if (!IsConstantEvaluatedBuiltinCall(E))
10345 return visitNonBuiltinCallExpr(E);
10352 return T->isCharType() || T->isChar8Type();
10355bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10356 unsigned BuiltinOp) {
10360 switch (BuiltinOp) {
10361 case Builtin::BIaddressof:
10362 case Builtin::BI__addressof:
10363 case Builtin::BI__builtin_addressof:
10365 case Builtin::BI__builtin_assume_aligned: {
10372 LValue OffsetResult(
Result);
10384 int64_t AdditionalOffset = -Offset.getZExtValue();
10389 if (OffsetResult.Base) {
10392 if (BaseAlignment < Align) {
10393 Result.Designator.setInvalid();
10394 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10401 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10402 Result.Designator.setInvalid();
10406 diag::note_constexpr_baa_insufficient_alignment)
10409 diag::note_constexpr_baa_value_insufficient_alignment))
10410 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10416 case Builtin::BI__builtin_align_up:
10417 case Builtin::BI__builtin_align_down: {
10437 assert(Alignment.getBitWidth() <= 64 &&
10438 "Cannot handle > 64-bit address-space");
10439 uint64_t Alignment64 = Alignment.getZExtValue();
10441 BuiltinOp == Builtin::BI__builtin_align_down
10442 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10443 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10449 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10453 case Builtin::BI__builtin_operator_new:
10455 case Builtin::BI__builtin_launder:
10457 case Builtin::BIstrchr:
10458 case Builtin::BIwcschr:
10459 case Builtin::BImemchr:
10460 case Builtin::BIwmemchr:
10461 if (Info.getLangOpts().CPlusPlus11)
10462 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10464 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10466 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10468 case Builtin::BI__builtin_strchr:
10469 case Builtin::BI__builtin_wcschr:
10470 case Builtin::BI__builtin_memchr:
10471 case Builtin::BI__builtin_char_memchr:
10472 case Builtin::BI__builtin_wmemchr: {
10473 if (!Visit(E->
getArg(0)))
10479 if (BuiltinOp != Builtin::BIstrchr &&
10480 BuiltinOp != Builtin::BIwcschr &&
10481 BuiltinOp != Builtin::BI__builtin_strchr &&
10482 BuiltinOp != Builtin::BI__builtin_wcschr) {
10486 MaxLength = N.getZExtValue();
10489 if (MaxLength == 0u)
10490 return ZeroInitialization(E);
10491 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10492 Result.Designator.Invalid)
10494 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10495 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10496 BuiltinOp == Builtin::BI__builtin_memchr;
10497 assert(IsRawByte ||
10498 Info.Ctx.hasSameUnqualifiedType(
10502 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10508 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10509 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10515 bool StopAtNull =
false;
10516 switch (BuiltinOp) {
10517 case Builtin::BIstrchr:
10518 case Builtin::BI__builtin_strchr:
10525 return ZeroInitialization(E);
10528 case Builtin::BImemchr:
10529 case Builtin::BI__builtin_memchr:
10530 case Builtin::BI__builtin_char_memchr:
10534 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10537 case Builtin::BIwcschr:
10538 case Builtin::BI__builtin_wcschr:
10541 case Builtin::BIwmemchr:
10542 case Builtin::BI__builtin_wmemchr:
10544 DesiredVal = Desired.getZExtValue();
10548 for (; MaxLength; --MaxLength) {
10553 if (Char.
getInt().getZExtValue() == DesiredVal)
10555 if (StopAtNull && !Char.
getInt())
10561 return ZeroInitialization(E);
10564 case Builtin::BImemcpy:
10565 case Builtin::BImemmove:
10566 case Builtin::BIwmemcpy:
10567 case Builtin::BIwmemmove:
10568 if (Info.getLangOpts().CPlusPlus11)
10569 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10571 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10573 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10575 case Builtin::BI__builtin_memcpy:
10576 case Builtin::BI__builtin_memmove:
10577 case Builtin::BI__builtin_wmemcpy:
10578 case Builtin::BI__builtin_wmemmove: {
10579 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10580 BuiltinOp == Builtin::BIwmemmove ||
10581 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10582 BuiltinOp == Builtin::BI__builtin_wmemmove;
10583 bool Move = BuiltinOp == Builtin::BImemmove ||
10584 BuiltinOp == Builtin::BIwmemmove ||
10585 BuiltinOp == Builtin::BI__builtin_memmove ||
10586 BuiltinOp == Builtin::BI__builtin_wmemmove;
10589 if (!Visit(E->
getArg(0)))
10600 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10610 if (!Src.Base || !Dest.Base) {
10612 (!Src.Base ? Src : Dest).moveInto(Val);
10613 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10614 <<
Move << WChar << !!Src.Base
10618 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10624 QualType T = Dest.Designator.getType(Info.Ctx);
10625 QualType SrcT = Src.Designator.getType(Info.Ctx);
10626 if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) {
10628 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT << T;
10632 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move << T;
10636 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move << T;
10641 uint64_t TSize = Info.Ctx.getTypeSizeInChars(T).getQuantity();
10646 llvm::APInt OrigN = N;
10647 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10649 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10650 <<
Move << WChar << 0 << T <<
toString(OrigN, 10,
false)
10651 << (unsigned)TSize;
10659 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10660 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10661 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10662 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10663 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) << T
10667 uint64_t NElems = N.getZExtValue();
10673 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10674 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10675 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10678 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10686 }
else if (!Move && SrcOffset >= DestOffset &&
10687 SrcOffset - DestOffset < NBytes) {
10689 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10718 QualType AllocType);
10721 const CXXConstructExpr *CCE,
10722 QualType AllocType);
10724bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10725 if (!Info.getLangOpts().CPlusPlus20)
10726 Info.CCEDiag(E, diag::note_constexpr_new);
10729 if (Info.SpeculativeEvaluationDepth)
10734 QualType TargetType = AllocType;
10736 bool IsNothrow =
false;
10737 bool IsPlacement =
false;
10755 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10756 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10757 (Info.CurrentCall->CanEvalMSConstexpr &&
10758 OperatorNew->hasAttr<MSConstexprAttr>())) {
10761 if (
Result.Designator.Invalid)
10764 IsPlacement =
true;
10766 Info.FFDiag(E, diag::note_constexpr_new_placement)
10771 Info.FFDiag(E, diag::note_constexpr_new_placement)
10774 }
else if (!OperatorNew
10775 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10776 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10782 const InitListExpr *ResizedArrayILE =
nullptr;
10783 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10784 bool ValueInit =
false;
10786 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10787 const Expr *Stripped = *ArraySize;
10788 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10789 Stripped = ICE->getSubExpr())
10790 if (ICE->getCastKind() != CK_NoOp &&
10791 ICE->getCastKind() != CK_IntegralCast)
10804 return ZeroInitialization(E);
10806 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10807 <<
ArrayBound << (*ArraySize)->getSourceRange();
10813 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10818 return ZeroInitialization(E);
10830 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10831 ResizedArrayCCE = CCE;
10833 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10834 assert(CAT &&
"unexpected type for array initializer");
10838 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10839 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10840 if (InitBound.ugt(AllocBound)) {
10842 return ZeroInitialization(E);
10844 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10845 <<
toString(AllocBound, 10,
false)
10847 << (*ArraySize)->getSourceRange();
10853 if (InitBound != AllocBound)
10857 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
10858 ArraySizeModifier::Normal, 0);
10861 "array allocation with non-array new");
10867 struct FindObjectHandler {
10870 QualType AllocType;
10874 typedef bool result_type;
10875 bool failed() {
return false; }
10876 bool checkConst(QualType QT) {
10878 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10883 bool found(
APValue &Subobj, QualType SubobjType,
10884 APValue::LValueBase Base) {
10885 if (!checkConst(SubobjType))
10889 unsigned SubobjectSize = 1;
10890 unsigned AllocSize = 1;
10891 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10893 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10895 if (SubobjectSize < AllocSize ||
10896 !Info.Ctx.hasSimilarType(Info.Ctx.getBaseElementType(SubobjType),
10897 Info.Ctx.getBaseElementType(AllocType))) {
10898 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10899 << SubobjType << AllocType;
10906 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10909 bool found(APFloat &
Value, QualType SubobjType) {
10910 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10913 } Handler = {Info, E, AllocType, AK,
nullptr};
10919 Val = Handler.Value;
10928 Val = Info.createHeapAlloc(E, AllocType,
Result);
10934 ImplicitValueInitExpr VIE(AllocType);
10937 }
else if (ResizedArrayILE) {
10941 }
else if (ResizedArrayCCE) {
10964class MemberPointerExprEvaluator
10965 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10968 bool Success(
const ValueDecl *D) {
10974 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
10981 bool ZeroInitialization(
const Expr *E) {
10982 return Success((
const ValueDecl*)
nullptr);
10985 bool VisitCastExpr(
const CastExpr *E);
10986 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10994 return MemberPointerExprEvaluator(Info,
Result).Visit(E);
10997bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11000 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11002 case CK_NullToMemberPointer:
11004 return ZeroInitialization(E);
11006 case CK_BaseToDerivedMemberPointer: {
11014 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11016 PathI != PathE; ++PathI) {
11017 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11018 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11019 if (!
Result.castToDerived(Derived))
11023 ->
castAs<MemberPointerType>()
11024 ->getMostRecentCXXRecordDecl()))
11029 case CK_DerivedToBaseMemberPointer:
11033 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11034 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11035 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11036 if (!
Result.castToBase(Base))
11043bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11054 class RecordExprEvaluator
11055 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11056 const LValue &
This;
11060 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11067 bool ZeroInitialization(
const Expr *E) {
11068 return ZeroInitialization(E, E->
getType());
11070 bool ZeroInitialization(
const Expr *E, QualType T);
11072 bool VisitCallExpr(
const CallExpr *E) {
11073 return handleCallExpr(E,
Result, &This);
11075 bool VisitCastExpr(
const CastExpr *E);
11076 bool VisitInitListExpr(
const InitListExpr *E);
11077 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11078 return VisitCXXConstructExpr(E, E->
getType());
11081 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11082 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType T);
11083 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11084 bool VisitBinCmp(
const BinaryOperator *E);
11085 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11086 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11087 ArrayRef<Expr *> Args);
11088 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
11102 assert(!RD->
isUnion() &&
"Expected non-union class type");
11111 unsigned Index = 0;
11113 End = CD->
bases_end(); I != End; ++I, ++Index) {
11115 LValue Subobject =
This;
11119 Result.getStructBase(Index)))
11124 for (
const auto *I : RD->
fields()) {
11126 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11129 LValue Subobject =
This;
11135 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11142bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType T) {
11149 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11156 LValue Subobject =
This;
11160 ImplicitValueInitExpr VIE(I->getType());
11165 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11172bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11175 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11177 case CK_ConstructorConversion:
11180 case CK_DerivedToBase:
11181 case CK_UncheckedDerivedToBase: {
11192 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11193 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11194 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11201 case CK_HLSLAggregateSplatCast: {
11221 case CK_HLSLElementwiseCast: {
11239 LValue Subobject =
This;
11246 if (
Field->isBitField()) {
11256bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11259 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11262bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11266 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11267 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11269 EvalInfo::EvaluatingConstructorRAII EvalObj(
11271 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11272 CXXRD && CXXRD->getNumBases());
11275 const FieldDecl *
Field;
11276 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11277 Field = ILE->getInitializedFieldInUnion();
11278 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11279 Field = PLIE->getInitializedFieldInUnion();
11282 "Expression is neither an init list nor a C++ paren list");
11294 ImplicitValueInitExpr VIE(
Field->getType());
11295 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11297 LValue Subobject =
This;
11302 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11306 if (
Field->isBitField())
11316 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11318 unsigned ElementNo = 0;
11322 if (CXXRD && CXXRD->getNumBases()) {
11323 for (
const auto &Base : CXXRD->bases()) {
11324 assert(ElementNo < Args.size() &&
"missing init for base class");
11325 const Expr *
Init = Args[ElementNo];
11327 LValue Subobject =
This;
11333 if (!Info.noteFailure())
11340 EvalObj.finishedConstructingBases();
11344 for (
const auto *Field : RD->
fields()) {
11347 if (
Field->isUnnamedBitField())
11350 LValue Subobject =
This;
11352 bool HaveInit = ElementNo < Args.size();
11357 Subobject, Field, &Layout))
11362 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11363 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11370 if (
Field->getType()->isIncompleteArrayType()) {
11371 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11375 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11382 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11386 if (
Field->getType()->isReferenceType()) {
11390 if (!Info.noteFailure())
11395 (
Field->isBitField() &&
11397 if (!Info.noteFailure())
11403 EvalObj.finishedConstructingFields();
11408bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11418 return ZeroInitialization(E, T);
11436 const Expr *SrcObj = E->
getArg(0);
11438 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11439 if (
const MaterializeTemporaryExpr *ME =
11440 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11441 return Visit(ME->getSubExpr());
11444 if (ZeroInit && !ZeroInitialization(E, T))
11453bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11454 const CXXInheritedCtorInitExpr *E) {
11455 if (!Info.CurrentCall) {
11456 assert(Info.checkingPotentialConstantExpression());
11475bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11476 const CXXStdInitializerListExpr *E) {
11477 const ConstantArrayType *ArrayType =
11484 assert(ArrayType &&
"unexpected type for array initializer");
11487 Array.addArray(Info, E, ArrayType);
11495 assert(Field !=
Record->field_end() &&
11496 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11498 "Expected std::initializer_list first field to be const E *");
11500 assert(Field !=
Record->field_end() &&
11501 "Expected std::initializer_list to have two fields");
11503 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11508 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11510 "Expected std::initializer_list second field to be const E *");
11518 assert(++Field ==
Record->field_end() &&
11519 "Expected std::initializer_list to only have two fields");
11524bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11529 const size_t NumFields = ClosureClass->
getNumFields();
11533 "The number of lambda capture initializers should equal the number of "
11534 "fields within the closure type");
11541 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11542 for (
const auto *Field : ClosureClass->
fields()) {
11545 Expr *
const CurFieldInit = *CaptureInitIt++;
11552 LValue Subobject =
This;
11559 if (!Info.keepEvaluatingAfterFailure())
11567bool RecordExprEvaluator::VisitDesignatedInitUpdateExpr(
11568 const DesignatedInitUpdateExpr *E) {
11578 "can't evaluate expression as a record rvalue");
11579 return RecordExprEvaluator(Info,
This,
Result).Visit(E);
11590class TemporaryExprEvaluator
11591 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11593 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11594 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11597 bool VisitConstructExpr(
const Expr *E) {
11603 bool VisitCastExpr(
const CastExpr *E) {
11606 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11608 case CK_ConstructorConversion:
11612 bool VisitInitListExpr(
const InitListExpr *E) {
11613 return VisitConstructExpr(E);
11615 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11616 return VisitConstructExpr(E);
11618 bool VisitCallExpr(
const CallExpr *E) {
11619 return VisitConstructExpr(E);
11621 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11622 return VisitConstructExpr(E);
11625 return VisitConstructExpr(E);
11634 return TemporaryExprEvaluator(Info,
Result).Visit(E);
11642 class VectorExprEvaluator
11643 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11650 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11651 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11657 assert(
V.isVector());
11661 bool ZeroInitialization(
const Expr *E);
11663 bool VisitUnaryReal(
const UnaryOperator *E)
11665 bool VisitCastExpr(
const CastExpr* E);
11666 bool VisitInitListExpr(
const InitListExpr *E);
11667 bool VisitUnaryImag(
const UnaryOperator *E);
11668 bool VisitBinaryOperator(
const BinaryOperator *E);
11669 bool VisitUnaryOperator(
const UnaryOperator *E);
11670 bool VisitCallExpr(
const CallExpr *E);
11671 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11672 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11681 "not a vector prvalue");
11682 return VectorExprEvaluator(Info,
Result).Visit(E);
11686 assert(Val.
isVector() &&
"expected vector APValue");
11690 llvm::APInt
Result(NumElts, 0);
11692 for (
unsigned I = 0; I < NumElts; ++I) {
11694 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11696 if (Elt.
getInt().getBoolValue())
11703bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11704 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11708 QualType SETy = SE->
getType();
11711 case CK_VectorSplat: {
11717 Val =
APValue(std::move(IntResult));
11722 Val =
APValue(std::move(FloatResult));
11739 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11740 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11741 << Info.Ctx.getLangOpts().CPlusPlus;
11745 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11750 case CK_HLSLVectorTruncation: {
11755 for (
unsigned I = 0; I < NElts; I++)
11759 case CK_HLSLMatrixTruncation: {
11765 for (
unsigned Row = 0;
11767 for (
unsigned Col = 0;
11772 case CK_HLSLAggregateSplatCast: {
11789 case CK_HLSLElementwiseCast: {
11802 return Success(ResultEls, E);
11804 case CK_IntegralToFloating:
11805 case CK_FloatingToIntegral:
11806 case CK_IntegralCast:
11807 case CK_FloatingCast:
11808 case CK_FloatingToBoolean:
11809 case CK_IntegralToBoolean: {
11811 assert(SETy->
isVectorType() &&
"expected vector source type");
11817 QualType SrcEltTy = SETy->
castAs<VectorType>()->getElementType();
11822 for (
unsigned I = 0; I < NElts; ++I) {
11827 return Success(ResultEls, E);
11830 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11835VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11852 unsigned CountInits = 0, CountElts = 0;
11853 while (CountElts < NumElements) {
11855 if (CountInits < NumInits
11861 for (
unsigned j = 0; j < vlen; j++)
11865 llvm::APSInt sInt(32);
11866 if (CountInits < NumInits) {
11870 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11871 Elements.push_back(
APValue(sInt));
11874 llvm::APFloat f(0.0);
11875 if (CountInits < NumInits) {
11879 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11880 Elements.push_back(
APValue(f));
11889VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
11893 if (EltTy->isIntegerType())
11894 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
11897 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
11903bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11905 return ZeroInitialization(E);
11908bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11910 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11911 "Operation not supported on vector types");
11913 if (Op == BO_Comma)
11914 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11916 Expr *LHS = E->
getLHS();
11917 Expr *RHS = E->
getRHS();
11920 "Must both be vector types");
11923 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
11927 "All operands must be the same size.");
11931 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11932 if (!LHSOK && !Info.noteFailure())
11934 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11956 "Vector can only be int or float type");
11964 "Vector operator ~ can only be int");
11965 Elt.
getInt().flipAllBits();
11975 "Vector can only be int or float type");
11981 EltResult.setAllBits();
11983 EltResult.clearAllBits();
11989 return std::nullopt;
11993bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11999 const QualType ResultEltTy = VD->getElementType();
12003 if (!
Evaluate(SubExprValue, Info, SubExpr))
12016 "Vector length doesn't match type?");
12019 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
12021 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12024 ResultElements.push_back(*Elt);
12026 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12037 DestTy,
Result.getFloat());
12053 DestTy,
Result.getInt());
12057 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12058 << SourceTy << DestTy;
12063 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12072 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12073 "pack builtin LHSVecLen must equal to RHSVecLen");
12076 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12082 const unsigned SrcPerLane = 128 / SrcBits;
12083 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12086 Out.reserve(LHSVecLen + RHSVecLen);
12088 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12089 unsigned base = Lane * SrcPerLane;
12090 for (
unsigned I = 0; I != SrcPerLane; ++I)
12093 for (
unsigned I = 0; I != SrcPerLane; ++I)
12104 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12111 unsigned ShuffleMask = 0;
12113 bool IsVectorMask =
false;
12114 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12116 if (IsSingleOperand) {
12119 IsVectorMask =
true;
12128 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12138 IsVectorMask =
true;
12147 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12158 ResultElements.reserve(NumElts);
12160 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12161 if (IsVectorMask) {
12162 ShuffleMask =
static_cast<unsigned>(
12163 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12165 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12171 ResultElements.push_back(
12172 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12178 ResultElements.push_back(
APValue());
12181 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12186 Out =
APValue(ResultElements.data(), ResultElements.size());
12192 if (OrigVal.isInfinity()) {
12193 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12196 if (OrigVal.isNaN()) {
12197 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12201 APFloat Val = OrigVal;
12202 bool LosesInfo =
false;
12203 APFloat::opStatus Status = Val.convert(
12204 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12206 if (LosesInfo || Val.isDenormal()) {
12207 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12211 if (Status != APFloat::opOK) {
12212 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12221 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12222 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12229 assert(
Call->getNumArgs() == 2);
12233 Call->getArg(1)->getType()->isVectorType());
12236 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12237 unsigned DestLen = Source.getVectorLength();
12240 unsigned NumBitsInQWord = 64;
12241 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12243 Result.reserve(DestLen);
12245 uint64_t CountLQWord = 0;
12246 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12248 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12251 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12252 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12253 if (CountLQWord < DestEltWidth) {
12255 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12258 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12266 std::optional<APSInt> RoundingMode,
12268 APSInt DefaultMode(APInt(32, 4),
true);
12269 if (RoundingMode.value_or(DefaultMode) != 4)
12270 return std::nullopt;
12271 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12272 B.isInfinity() || B.isDenormal())
12273 return std::nullopt;
12274 if (A.isZero() && B.isZero())
12276 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12279bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12280 if (!IsConstantEvaluatedBuiltinCall(E))
12281 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12283 auto EvaluateBinOpExpr =
12285 APValue SourceLHS, SourceRHS;
12291 QualType DestEltTy = DestTy->getElementType();
12292 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12295 ResultElements.reserve(SourceLen);
12297 if (SourceRHS.
isInt()) {
12299 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12301 ResultElements.push_back(
12305 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12308 ResultElements.push_back(
12315 auto EvaluateFpBinOpExpr =
12316 [&](llvm::function_ref<std::optional<APFloat>(
12317 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12319 bool IsScalar =
false) {
12329 std::optional<APSInt> RoundingMode;
12334 RoundingMode = Imm;
12339 ResultElements.reserve(NumElems);
12341 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12342 if (IsScalar && EltNum > 0) {
12348 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12356 auto EvaluateScalarFpRoundMaskBinOp =
12357 [&](llvm::function_ref<std::optional<APFloat>(
12358 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12362 APSInt MaskVal, Rounding;
12373 ResultElements.reserve(NumElems);
12375 if (MaskVal.getZExtValue() & 1) {
12378 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12386 for (
unsigned I = 1; I < NumElems; ++I)
12392 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12400 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12404 for (
unsigned I = 1; I < Len; ++I)
12406 APValue V(Res.data(), Res.size());
12413 case Builtin::BI__builtin_elementwise_popcount:
12414 case Builtin::BI__builtin_elementwise_bitreverse: {
12419 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12422 ResultElements.reserve(SourceLen);
12424 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12427 case Builtin::BI__builtin_elementwise_popcount:
12428 ResultElements.push_back(
APValue(
12429 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
12432 case Builtin::BI__builtin_elementwise_bitreverse:
12433 ResultElements.push_back(
12440 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12442 case Builtin::BI__builtin_elementwise_abs: {
12447 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12450 ResultElements.reserve(SourceLen);
12452 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12457 CurrentEle.getInt().
abs(),
12458 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12459 ResultElements.push_back(Val);
12462 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12465 case Builtin::BI__builtin_elementwise_add_sat:
12466 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12467 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12470 case Builtin::BI__builtin_elementwise_sub_sat:
12471 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12472 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12475 case X86::BI__builtin_ia32_extract128i256:
12476 case X86::BI__builtin_ia32_vextractf128_pd256:
12477 case X86::BI__builtin_ia32_vextractf128_ps256:
12478 case X86::BI__builtin_ia32_vextractf128_si256: {
12479 APValue SourceVec, SourceImm;
12488 unsigned RetLen = RetVT->getNumElements();
12489 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12492 ResultElements.reserve(RetLen);
12494 for (
unsigned I = 0; I < RetLen; I++)
12495 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12500 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12501 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12502 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12503 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12504 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12505 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12506 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12507 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12508 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12509 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12510 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12511 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12517 QualType VecTy = E->
getType();
12518 const VectorType *VT = VecTy->
castAs<VectorType>();
12521 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
12524 for (
unsigned I = 0; I != VectorLen; ++I) {
12525 bool BitSet = Mask[I];
12526 APSInt ElemVal(ElemWidth,
false);
12528 ElemVal.setAllBits();
12530 Elems.push_back(
APValue(ElemVal));
12535 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12536 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12537 case X86::BI__builtin_ia32_extracti32x4_mask:
12538 case X86::BI__builtin_ia32_extractf32x4_mask:
12539 case X86::BI__builtin_ia32_extracti32x8_mask:
12540 case X86::BI__builtin_ia32_extractf32x8_mask:
12541 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12542 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12543 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12544 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12545 case X86::BI__builtin_ia32_extracti64x4_mask:
12546 case X86::BI__builtin_ia32_extractf64x4_mask: {
12557 unsigned RetLen = RetVT->getNumElements();
12562 unsigned Lanes = SrcLen / RetLen;
12563 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12564 unsigned Base = Lane * RetLen;
12567 ResultElements.reserve(RetLen);
12568 for (
unsigned I = 0; I < RetLen; ++I) {
12570 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12574 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12577 case clang::X86::BI__builtin_ia32_pavgb128:
12578 case clang::X86::BI__builtin_ia32_pavgw128:
12579 case clang::X86::BI__builtin_ia32_pavgb256:
12580 case clang::X86::BI__builtin_ia32_pavgw256:
12581 case clang::X86::BI__builtin_ia32_pavgb512:
12582 case clang::X86::BI__builtin_ia32_pavgw512:
12583 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12585 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12586 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12587 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12588 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12589 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12590 .extractBits(16, 1);
12593 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12594 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12595 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12596 case clang::X86::BI__builtin_ia32_pmaddwd128:
12597 case clang::X86::BI__builtin_ia32_pmaddwd256:
12598 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12599 APValue SourceLHS, SourceRHS;
12605 QualType DestEltTy = DestTy->getElementType();
12607 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12609 ResultElements.reserve(SourceLen / 2);
12611 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12616 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12619 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12620 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12621 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12622 ResultElements.push_back(
APValue(
12623 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
12624 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
12627 case clang::X86::BI__builtin_ia32_pmaddwd128:
12628 case clang::X86::BI__builtin_ia32_pmaddwd256:
12629 case clang::X86::BI__builtin_ia32_pmaddwd512:
12630 ResultElements.push_back(
12631 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
12632 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
12638 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12641 case clang::X86::BI__builtin_ia32_dbpsadbw128:
12642 case clang::X86::BI__builtin_ia32_dbpsadbw256:
12643 case clang::X86::BI__builtin_ia32_dbpsadbw512: {
12644 APValue SourceA, SourceB, SourceImm;
12651 constexpr unsigned LaneSize = 16;
12652 unsigned Imm = SourceImm.
getInt().getZExtValue();
12655 QualType DestEltTy = DestTy->getElementType();
12656 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12658 ResultElements.reserve(SourceLen / 2);
12664 for (
unsigned I = 0; I < SourceLen; I += LaneSize) {
12665 for (
unsigned J = 0; J < 4; ++J) {
12666 unsigned Part = (Imm >> (2 * J)) & 3;
12667 for (
unsigned K = 0; K < 4; ++K) {
12668 Shuffled[I + 4 * J + K] =
static_cast<uint8_t>(
12669 SourceB.
getVectorElt(I + 4 * Part + K).getInt().getZExtValue());
12677 unsigned Size = SourceLen / 2;
12678 for (
unsigned I = 0; I <
Size; I += 4) {
12679 unsigned Sad[4] = {0, 0, 0, 0};
12680 for (
unsigned J = 0; J < 4; ++J) {
12682 SourceA.
getVectorElt(2 * I + J).getInt().getZExtValue());
12684 SourceA.
getVectorElt(2 * I + J + 4).getInt().getZExtValue());
12685 uint8_t B0 = Shuffled[2 * I + J];
12686 uint8_t B1 = Shuffled[2 * I + J + 1];
12687 uint8_t B2 = Shuffled[2 * I + J + 2];
12688 uint8_t B3 = Shuffled[2 * I + J + 3];
12689 Sad[0] += (A1 > B0) ? (A1 - B0) : (B0 - A1);
12690 Sad[1] += (A1 > B1) ? (A1 - B1) : (B1 - A1);
12691 Sad[2] += (A2 > B2) ? (A2 - B2) : (B2 - A2);
12692 Sad[3] += (A2 > B3) ? (A2 - B3) : (B3 - A2);
12694 for (
unsigned R = 0;
R < 4; ++
R)
12695 ResultElements.push_back(
12699 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12702 case clang::X86::BI__builtin_ia32_pmulhuw128:
12703 case clang::X86::BI__builtin_ia32_pmulhuw256:
12704 case clang::X86::BI__builtin_ia32_pmulhuw512:
12705 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
12707 case clang::X86::BI__builtin_ia32_pmulhw128:
12708 case clang::X86::BI__builtin_ia32_pmulhw256:
12709 case clang::X86::BI__builtin_ia32_pmulhw512:
12710 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
12712 case clang::X86::BI__builtin_ia32_psllv2di:
12713 case clang::X86::BI__builtin_ia32_psllv4di:
12714 case clang::X86::BI__builtin_ia32_psllv4si:
12715 case clang::X86::BI__builtin_ia32_psllv8di:
12716 case clang::X86::BI__builtin_ia32_psllv8hi:
12717 case clang::X86::BI__builtin_ia32_psllv8si:
12718 case clang::X86::BI__builtin_ia32_psllv16hi:
12719 case clang::X86::BI__builtin_ia32_psllv16si:
12720 case clang::X86::BI__builtin_ia32_psllv32hi:
12721 case clang::X86::BI__builtin_ia32_psllwi128:
12722 case clang::X86::BI__builtin_ia32_pslldi128:
12723 case clang::X86::BI__builtin_ia32_psllqi128:
12724 case clang::X86::BI__builtin_ia32_psllwi256:
12725 case clang::X86::BI__builtin_ia32_pslldi256:
12726 case clang::X86::BI__builtin_ia32_psllqi256:
12727 case clang::X86::BI__builtin_ia32_psllwi512:
12728 case clang::X86::BI__builtin_ia32_pslldi512:
12729 case clang::X86::BI__builtin_ia32_psllqi512:
12730 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12731 if (RHS.uge(LHS.getBitWidth())) {
12732 return APInt::getZero(LHS.getBitWidth());
12734 return LHS.shl(RHS.getZExtValue());
12737 case clang::X86::BI__builtin_ia32_psrav4si:
12738 case clang::X86::BI__builtin_ia32_psrav8di:
12739 case clang::X86::BI__builtin_ia32_psrav8hi:
12740 case clang::X86::BI__builtin_ia32_psrav8si:
12741 case clang::X86::BI__builtin_ia32_psrav16hi:
12742 case clang::X86::BI__builtin_ia32_psrav16si:
12743 case clang::X86::BI__builtin_ia32_psrav32hi:
12744 case clang::X86::BI__builtin_ia32_psravq128:
12745 case clang::X86::BI__builtin_ia32_psravq256:
12746 case clang::X86::BI__builtin_ia32_psrawi128:
12747 case clang::X86::BI__builtin_ia32_psradi128:
12748 case clang::X86::BI__builtin_ia32_psraqi128:
12749 case clang::X86::BI__builtin_ia32_psrawi256:
12750 case clang::X86::BI__builtin_ia32_psradi256:
12751 case clang::X86::BI__builtin_ia32_psraqi256:
12752 case clang::X86::BI__builtin_ia32_psrawi512:
12753 case clang::X86::BI__builtin_ia32_psradi512:
12754 case clang::X86::BI__builtin_ia32_psraqi512:
12755 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12756 if (RHS.uge(LHS.getBitWidth())) {
12757 return LHS.ashr(LHS.getBitWidth() - 1);
12759 return LHS.ashr(RHS.getZExtValue());
12762 case clang::X86::BI__builtin_ia32_psrlv2di:
12763 case clang::X86::BI__builtin_ia32_psrlv4di:
12764 case clang::X86::BI__builtin_ia32_psrlv4si:
12765 case clang::X86::BI__builtin_ia32_psrlv8di:
12766 case clang::X86::BI__builtin_ia32_psrlv8hi:
12767 case clang::X86::BI__builtin_ia32_psrlv8si:
12768 case clang::X86::BI__builtin_ia32_psrlv16hi:
12769 case clang::X86::BI__builtin_ia32_psrlv16si:
12770 case clang::X86::BI__builtin_ia32_psrlv32hi:
12771 case clang::X86::BI__builtin_ia32_psrlwi128:
12772 case clang::X86::BI__builtin_ia32_psrldi128:
12773 case clang::X86::BI__builtin_ia32_psrlqi128:
12774 case clang::X86::BI__builtin_ia32_psrlwi256:
12775 case clang::X86::BI__builtin_ia32_psrldi256:
12776 case clang::X86::BI__builtin_ia32_psrlqi256:
12777 case clang::X86::BI__builtin_ia32_psrlwi512:
12778 case clang::X86::BI__builtin_ia32_psrldi512:
12779 case clang::X86::BI__builtin_ia32_psrlqi512:
12780 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12781 if (RHS.uge(LHS.getBitWidth())) {
12782 return APInt::getZero(LHS.getBitWidth());
12784 return LHS.lshr(RHS.getZExtValue());
12786 case X86::BI__builtin_ia32_packsswb128:
12787 case X86::BI__builtin_ia32_packsswb256:
12788 case X86::BI__builtin_ia32_packsswb512:
12789 case X86::BI__builtin_ia32_packssdw128:
12790 case X86::BI__builtin_ia32_packssdw256:
12791 case X86::BI__builtin_ia32_packssdw512:
12793 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
12795 case X86::BI__builtin_ia32_packusdw128:
12796 case X86::BI__builtin_ia32_packusdw256:
12797 case X86::BI__builtin_ia32_packusdw512:
12798 case X86::BI__builtin_ia32_packuswb128:
12799 case X86::BI__builtin_ia32_packuswb256:
12800 case X86::BI__builtin_ia32_packuswb512:
12802 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
12804 case clang::X86::BI__builtin_ia32_selectss_128:
12805 return EvalSelectScalar(4);
12806 case clang::X86::BI__builtin_ia32_selectsd_128:
12807 return EvalSelectScalar(2);
12808 case clang::X86::BI__builtin_ia32_selectsh_128:
12809 case clang::X86::BI__builtin_ia32_selectsbf_128:
12810 return EvalSelectScalar(8);
12811 case clang::X86::BI__builtin_ia32_pmuldq128:
12812 case clang::X86::BI__builtin_ia32_pmuldq256:
12813 case clang::X86::BI__builtin_ia32_pmuldq512:
12814 case clang::X86::BI__builtin_ia32_pmuludq128:
12815 case clang::X86::BI__builtin_ia32_pmuludq256:
12816 case clang::X86::BI__builtin_ia32_pmuludq512: {
12817 APValue SourceLHS, SourceRHS;
12824 ResultElements.reserve(SourceLen / 2);
12826 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12831 case clang::X86::BI__builtin_ia32_pmuludq128:
12832 case clang::X86::BI__builtin_ia32_pmuludq256:
12833 case clang::X86::BI__builtin_ia32_pmuludq512:
12834 ResultElements.push_back(
12835 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
12837 case clang::X86::BI__builtin_ia32_pmuldq128:
12838 case clang::X86::BI__builtin_ia32_pmuldq256:
12839 case clang::X86::BI__builtin_ia32_pmuldq512:
12840 ResultElements.push_back(
12841 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
12846 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12849 case X86::BI__builtin_ia32_vpmadd52luq128:
12850 case X86::BI__builtin_ia32_vpmadd52luq256:
12851 case X86::BI__builtin_ia32_vpmadd52luq512: {
12860 ResultElements.reserve(ALen);
12862 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12865 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12866 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
12867 ResultElements.push_back(
APValue(ResElt));
12870 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12872 case X86::BI__builtin_ia32_vpmadd52huq128:
12873 case X86::BI__builtin_ia32_vpmadd52huq256:
12874 case X86::BI__builtin_ia32_vpmadd52huq512: {
12883 ResultElements.reserve(ALen);
12885 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12888 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12889 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
12890 ResultElements.push_back(
APValue(ResElt));
12893 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12896 case clang::X86::BI__builtin_ia32_vprotbi:
12897 case clang::X86::BI__builtin_ia32_vprotdi:
12898 case clang::X86::BI__builtin_ia32_vprotqi:
12899 case clang::X86::BI__builtin_ia32_vprotwi:
12900 case clang::X86::BI__builtin_ia32_prold128:
12901 case clang::X86::BI__builtin_ia32_prold256:
12902 case clang::X86::BI__builtin_ia32_prold512:
12903 case clang::X86::BI__builtin_ia32_prolq128:
12904 case clang::X86::BI__builtin_ia32_prolq256:
12905 case clang::X86::BI__builtin_ia32_prolq512:
12906 return EvaluateBinOpExpr(
12907 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
12909 case clang::X86::BI__builtin_ia32_prord128:
12910 case clang::X86::BI__builtin_ia32_prord256:
12911 case clang::X86::BI__builtin_ia32_prord512:
12912 case clang::X86::BI__builtin_ia32_prorq128:
12913 case clang::X86::BI__builtin_ia32_prorq256:
12914 case clang::X86::BI__builtin_ia32_prorq512:
12915 return EvaluateBinOpExpr(
12916 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
12918 case Builtin::BI__builtin_elementwise_max:
12919 case Builtin::BI__builtin_elementwise_min: {
12920 APValue SourceLHS, SourceRHS;
12925 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12932 ResultElements.reserve(SourceLen);
12934 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12938 case Builtin::BI__builtin_elementwise_max:
12939 ResultElements.push_back(
12943 case Builtin::BI__builtin_elementwise_min:
12944 ResultElements.push_back(
12951 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12953 case X86::BI__builtin_ia32_vpshldd128:
12954 case X86::BI__builtin_ia32_vpshldd256:
12955 case X86::BI__builtin_ia32_vpshldd512:
12956 case X86::BI__builtin_ia32_vpshldq128:
12957 case X86::BI__builtin_ia32_vpshldq256:
12958 case X86::BI__builtin_ia32_vpshldq512:
12959 case X86::BI__builtin_ia32_vpshldw128:
12960 case X86::BI__builtin_ia32_vpshldw256:
12961 case X86::BI__builtin_ia32_vpshldw512: {
12962 APValue SourceHi, SourceLo, SourceAmt;
12968 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12971 ResultElements.reserve(SourceLen);
12974 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12977 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
12978 ResultElements.push_back(
12982 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12984 case X86::BI__builtin_ia32_vpshrdd128:
12985 case X86::BI__builtin_ia32_vpshrdd256:
12986 case X86::BI__builtin_ia32_vpshrdd512:
12987 case X86::BI__builtin_ia32_vpshrdq128:
12988 case X86::BI__builtin_ia32_vpshrdq256:
12989 case X86::BI__builtin_ia32_vpshrdq512:
12990 case X86::BI__builtin_ia32_vpshrdw128:
12991 case X86::BI__builtin_ia32_vpshrdw256:
12992 case X86::BI__builtin_ia32_vpshrdw512: {
12994 APValue SourceHi, SourceLo, SourceAmt;
13000 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13003 ResultElements.reserve(SourceLen);
13006 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13009 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
13010 ResultElements.push_back(
13014 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13016 case X86::BI__builtin_ia32_compressdf128_mask:
13017 case X86::BI__builtin_ia32_compressdf256_mask:
13018 case X86::BI__builtin_ia32_compressdf512_mask:
13019 case X86::BI__builtin_ia32_compressdi128_mask:
13020 case X86::BI__builtin_ia32_compressdi256_mask:
13021 case X86::BI__builtin_ia32_compressdi512_mask:
13022 case X86::BI__builtin_ia32_compresshi128_mask:
13023 case X86::BI__builtin_ia32_compresshi256_mask:
13024 case X86::BI__builtin_ia32_compresshi512_mask:
13025 case X86::BI__builtin_ia32_compressqi128_mask:
13026 case X86::BI__builtin_ia32_compressqi256_mask:
13027 case X86::BI__builtin_ia32_compressqi512_mask:
13028 case X86::BI__builtin_ia32_compresssf128_mask:
13029 case X86::BI__builtin_ia32_compresssf256_mask:
13030 case X86::BI__builtin_ia32_compresssf512_mask:
13031 case X86::BI__builtin_ia32_compresssi128_mask:
13032 case X86::BI__builtin_ia32_compresssi256_mask:
13033 case X86::BI__builtin_ia32_compresssi512_mask: {
13044 ResultElements.reserve(NumElts);
13046 for (
unsigned I = 0; I != NumElts; ++I) {
13050 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
13054 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13056 case X86::BI__builtin_ia32_expanddf128_mask:
13057 case X86::BI__builtin_ia32_expanddf256_mask:
13058 case X86::BI__builtin_ia32_expanddf512_mask:
13059 case X86::BI__builtin_ia32_expanddi128_mask:
13060 case X86::BI__builtin_ia32_expanddi256_mask:
13061 case X86::BI__builtin_ia32_expanddi512_mask:
13062 case X86::BI__builtin_ia32_expandhi128_mask:
13063 case X86::BI__builtin_ia32_expandhi256_mask:
13064 case X86::BI__builtin_ia32_expandhi512_mask:
13065 case X86::BI__builtin_ia32_expandqi128_mask:
13066 case X86::BI__builtin_ia32_expandqi256_mask:
13067 case X86::BI__builtin_ia32_expandqi512_mask:
13068 case X86::BI__builtin_ia32_expandsf128_mask:
13069 case X86::BI__builtin_ia32_expandsf256_mask:
13070 case X86::BI__builtin_ia32_expandsf512_mask:
13071 case X86::BI__builtin_ia32_expandsi128_mask:
13072 case X86::BI__builtin_ia32_expandsi256_mask:
13073 case X86::BI__builtin_ia32_expandsi512_mask: {
13084 ResultElements.reserve(NumElts);
13086 unsigned SourceIdx = 0;
13087 for (
unsigned I = 0; I != NumElts; ++I) {
13089 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
13093 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13095 case X86::BI__builtin_ia32_vpconflictsi_128:
13096 case X86::BI__builtin_ia32_vpconflictsi_256:
13097 case X86::BI__builtin_ia32_vpconflictsi_512:
13098 case X86::BI__builtin_ia32_vpconflictdi_128:
13099 case X86::BI__builtin_ia32_vpconflictdi_256:
13100 case X86::BI__builtin_ia32_vpconflictdi_512: {
13108 ResultElements.reserve(SourceLen);
13111 bool DestUnsigned =
13112 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
13114 for (
unsigned I = 0; I != SourceLen; ++I) {
13117 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
13118 for (
unsigned J = 0; J != I; ++J) {
13120 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
13122 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
13124 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13126 case X86::BI__builtin_ia32_blendpd:
13127 case X86::BI__builtin_ia32_blendpd256:
13128 case X86::BI__builtin_ia32_blendps:
13129 case X86::BI__builtin_ia32_blendps256:
13130 case X86::BI__builtin_ia32_pblendw128:
13131 case X86::BI__builtin_ia32_pblendw256:
13132 case X86::BI__builtin_ia32_pblendd128:
13133 case X86::BI__builtin_ia32_pblendd256: {
13134 APValue SourceF, SourceT, SourceC;
13143 ResultElements.reserve(SourceLen);
13144 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13147 ResultElements.push_back(
C[EltNum % 8] ? T : F);
13150 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13153 case X86::BI__builtin_ia32_psignb128:
13154 case X86::BI__builtin_ia32_psignb256:
13155 case X86::BI__builtin_ia32_psignw128:
13156 case X86::BI__builtin_ia32_psignw256:
13157 case X86::BI__builtin_ia32_psignd128:
13158 case X86::BI__builtin_ia32_psignd256:
13159 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13160 if (BElem.isZero())
13161 return APInt::getZero(AElem.getBitWidth());
13162 if (BElem.isNegative())
13167 case X86::BI__builtin_ia32_blendvpd:
13168 case X86::BI__builtin_ia32_blendvpd256:
13169 case X86::BI__builtin_ia32_blendvps:
13170 case X86::BI__builtin_ia32_blendvps256:
13171 case X86::BI__builtin_ia32_pblendvb128:
13172 case X86::BI__builtin_ia32_pblendvb256: {
13174 APValue SourceF, SourceT, SourceC;
13182 ResultElements.reserve(SourceLen);
13184 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13188 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13189 ResultElements.push_back(M.isNegative() ? T : F);
13192 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13194 case X86::BI__builtin_ia32_selectb_128:
13195 case X86::BI__builtin_ia32_selectb_256:
13196 case X86::BI__builtin_ia32_selectb_512:
13197 case X86::BI__builtin_ia32_selectw_128:
13198 case X86::BI__builtin_ia32_selectw_256:
13199 case X86::BI__builtin_ia32_selectw_512:
13200 case X86::BI__builtin_ia32_selectd_128:
13201 case X86::BI__builtin_ia32_selectd_256:
13202 case X86::BI__builtin_ia32_selectd_512:
13203 case X86::BI__builtin_ia32_selectq_128:
13204 case X86::BI__builtin_ia32_selectq_256:
13205 case X86::BI__builtin_ia32_selectq_512:
13206 case X86::BI__builtin_ia32_selectph_128:
13207 case X86::BI__builtin_ia32_selectph_256:
13208 case X86::BI__builtin_ia32_selectph_512:
13209 case X86::BI__builtin_ia32_selectpbf_128:
13210 case X86::BI__builtin_ia32_selectpbf_256:
13211 case X86::BI__builtin_ia32_selectpbf_512:
13212 case X86::BI__builtin_ia32_selectps_128:
13213 case X86::BI__builtin_ia32_selectps_256:
13214 case X86::BI__builtin_ia32_selectps_512:
13215 case X86::BI__builtin_ia32_selectpd_128:
13216 case X86::BI__builtin_ia32_selectpd_256:
13217 case X86::BI__builtin_ia32_selectpd_512: {
13219 APValue SourceMask, SourceLHS, SourceRHS;
13228 ResultElements.reserve(SourceLen);
13230 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13233 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13236 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13239 case X86::BI__builtin_ia32_cvtsd2ss: {
13252 Elements.push_back(ResultVal);
13255 for (
unsigned I = 1; I < NumEltsA; ++I) {
13261 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13262 APValue VecA, VecB, VecSrc, MaskValue;
13270 unsigned Mask = MaskValue.
getInt().getZExtValue();
13278 Elements.push_back(ResultVal);
13284 for (
unsigned I = 1; I < NumEltsA; ++I) {
13290 case X86::BI__builtin_ia32_cvtpd2ps:
13291 case X86::BI__builtin_ia32_cvtpd2ps256:
13292 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13293 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13296 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13297 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13304 unsigned Mask = 0xFFFFFFFF;
13305 bool NeedsMerge =
false;
13310 Mask = MaskValue.
getInt().getZExtValue();
13311 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13312 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13313 if (!((Mask >> I) & 1)) {
13324 unsigned NumEltsResult =
13328 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13329 if (IsMasked && !((Mask >> I) & 1)) {
13337 if (I >= NumEltsInput) {
13338 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13347 Elements.push_back(ResultVal);
13352 case X86::BI__builtin_ia32_shufps:
13353 case X86::BI__builtin_ia32_shufps256:
13354 case X86::BI__builtin_ia32_shufps512: {
13358 [](
unsigned DstIdx,
13359 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13360 constexpr unsigned LaneBits = 128u;
13361 unsigned NumElemPerLane = LaneBits / 32;
13362 unsigned NumSelectableElems = NumElemPerLane / 2;
13363 unsigned BitsPerElem = 2;
13364 unsigned IndexMask = (1u << BitsPerElem) - 1;
13365 unsigned MaskBits = 8;
13366 unsigned Lane = DstIdx / NumElemPerLane;
13367 unsigned ElemInLane = DstIdx % NumElemPerLane;
13368 unsigned LaneOffset = Lane * NumElemPerLane;
13369 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13370 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13371 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13372 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13377 case X86::BI__builtin_ia32_shufpd:
13378 case X86::BI__builtin_ia32_shufpd256:
13379 case X86::BI__builtin_ia32_shufpd512: {
13383 [](
unsigned DstIdx,
13384 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13385 constexpr unsigned LaneBits = 128u;
13386 unsigned NumElemPerLane = LaneBits / 64;
13387 unsigned NumSelectableElems = NumElemPerLane / 2;
13388 unsigned BitsPerElem = 1;
13389 unsigned IndexMask = (1u << BitsPerElem) - 1;
13390 unsigned MaskBits = 8;
13391 unsigned Lane = DstIdx / NumElemPerLane;
13392 unsigned ElemInLane = DstIdx % NumElemPerLane;
13393 unsigned LaneOffset = Lane * NumElemPerLane;
13394 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13395 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13396 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13397 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13402 case X86::BI__builtin_ia32_insertps128: {
13406 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13408 if ((Mask & (1 << DstIdx)) != 0) {
13413 unsigned SrcElem = (Mask >> 6) & 0x3;
13414 unsigned DstElem = (Mask >> 4) & 0x3;
13415 if (DstIdx == DstElem) {
13417 return {1,
static_cast<int>(SrcElem)};
13420 return {0,
static_cast<int>(DstIdx)};
13426 case X86::BI__builtin_ia32_pshufb128:
13427 case X86::BI__builtin_ia32_pshufb256:
13428 case X86::BI__builtin_ia32_pshufb512: {
13432 [](
unsigned DstIdx,
13433 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13436 return std::make_pair(0, -1);
13438 unsigned LaneBase = (DstIdx / 16) * 16;
13439 unsigned SrcOffset = Ctlb & 0x0F;
13440 unsigned SrcIdx = LaneBase + SrcOffset;
13441 return std::make_pair(0,
static_cast<int>(SrcIdx));
13447 case X86::BI__builtin_ia32_pshuflw:
13448 case X86::BI__builtin_ia32_pshuflw256:
13449 case X86::BI__builtin_ia32_pshuflw512: {
13453 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13454 constexpr unsigned LaneBits = 128u;
13455 constexpr unsigned ElemBits = 16u;
13456 constexpr unsigned LaneElts = LaneBits / ElemBits;
13457 constexpr unsigned HalfSize = 4;
13458 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13459 unsigned LaneIdx = DstIdx % LaneElts;
13460 if (LaneIdx < HalfSize) {
13461 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13462 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13464 return std::make_pair(0,
static_cast<int>(DstIdx));
13470 case X86::BI__builtin_ia32_pshufhw:
13471 case X86::BI__builtin_ia32_pshufhw256:
13472 case X86::BI__builtin_ia32_pshufhw512: {
13476 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13477 constexpr unsigned LaneBits = 128u;
13478 constexpr unsigned ElemBits = 16u;
13479 constexpr unsigned LaneElts = LaneBits / ElemBits;
13480 constexpr unsigned HalfSize = 4;
13481 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13482 unsigned LaneIdx = DstIdx % LaneElts;
13483 if (LaneIdx >= HalfSize) {
13484 unsigned Rel = LaneIdx - HalfSize;
13485 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13486 return std::make_pair(
13487 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13489 return std::make_pair(0,
static_cast<int>(DstIdx));
13495 case X86::BI__builtin_ia32_pshufd:
13496 case X86::BI__builtin_ia32_pshufd256:
13497 case X86::BI__builtin_ia32_pshufd512:
13498 case X86::BI__builtin_ia32_vpermilps:
13499 case X86::BI__builtin_ia32_vpermilps256:
13500 case X86::BI__builtin_ia32_vpermilps512: {
13504 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13505 constexpr unsigned LaneBits = 128u;
13506 constexpr unsigned ElemBits = 32u;
13507 constexpr unsigned LaneElts = LaneBits / ElemBits;
13508 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13509 unsigned LaneIdx = DstIdx % LaneElts;
13510 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13511 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13517 case X86::BI__builtin_ia32_vpermilvarpd:
13518 case X86::BI__builtin_ia32_vpermilvarpd256:
13519 case X86::BI__builtin_ia32_vpermilvarpd512: {
13523 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13524 unsigned NumElemPerLane = 2;
13525 unsigned Lane = DstIdx / NumElemPerLane;
13526 unsigned Offset = Mask & 0b10 ? 1 : 0;
13527 return std::make_pair(
13528 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13534 case X86::BI__builtin_ia32_vpermilpd:
13535 case X86::BI__builtin_ia32_vpermilpd256:
13536 case X86::BI__builtin_ia32_vpermilpd512: {
13539 unsigned NumElemPerLane = 2;
13540 unsigned BitsPerElem = 1;
13541 unsigned MaskBits = 8;
13542 unsigned IndexMask = 0x1;
13543 unsigned Lane = DstIdx / NumElemPerLane;
13544 unsigned LaneOffset = Lane * NumElemPerLane;
13545 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13546 unsigned Index = (Control >> BitIndex) & IndexMask;
13547 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
13553 case X86::BI__builtin_ia32_permdf256:
13554 case X86::BI__builtin_ia32_permdi256: {
13559 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
13560 return std::make_pair(0,
static_cast<int>(Index));
13566 case X86::BI__builtin_ia32_vpermilvarps:
13567 case X86::BI__builtin_ia32_vpermilvarps256:
13568 case X86::BI__builtin_ia32_vpermilvarps512: {
13572 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13573 unsigned NumElemPerLane = 4;
13574 unsigned Lane = DstIdx / NumElemPerLane;
13575 unsigned Offset = Mask & 0b11;
13576 return std::make_pair(
13577 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13583 case X86::BI__builtin_ia32_vpmultishiftqb128:
13584 case X86::BI__builtin_ia32_vpmultishiftqb256:
13585 case X86::BI__builtin_ia32_vpmultishiftqb512: {
13593 unsigned NumBytesInQWord = 8;
13594 unsigned NumBitsInByte = 8;
13596 unsigned NumQWords = NumBytes / NumBytesInQWord;
13598 Result.reserve(NumBytes);
13600 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
13601 APInt BQWord(64, 0);
13602 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13603 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13605 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
13608 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13609 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13613 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
13614 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
13622 case X86::BI__builtin_ia32_phminposuw128: {
13629 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
13631 APInt MinIndex(ElemBitWidth, 0);
13633 for (
unsigned I = 1; I != SourceLen; ++I) {
13635 if (MinVal.ugt(Val)) {
13644 ->isUnsignedIntegerOrEnumerationType();
13647 Result.reserve(SourceLen);
13649 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
13650 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
13656 case X86::BI__builtin_ia32_psraq128:
13657 case X86::BI__builtin_ia32_psraq256:
13658 case X86::BI__builtin_ia32_psraq512:
13659 case X86::BI__builtin_ia32_psrad128:
13660 case X86::BI__builtin_ia32_psrad256:
13661 case X86::BI__builtin_ia32_psrad512:
13662 case X86::BI__builtin_ia32_psraw128:
13663 case X86::BI__builtin_ia32_psraw256:
13664 case X86::BI__builtin_ia32_psraw512: {
13668 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
13669 [](
const APInt &Elt,
unsigned Width) {
13670 return Elt.ashr(Width - 1);
13676 case X86::BI__builtin_ia32_psllq128:
13677 case X86::BI__builtin_ia32_psllq256:
13678 case X86::BI__builtin_ia32_psllq512:
13679 case X86::BI__builtin_ia32_pslld128:
13680 case X86::BI__builtin_ia32_pslld256:
13681 case X86::BI__builtin_ia32_pslld512:
13682 case X86::BI__builtin_ia32_psllw128:
13683 case X86::BI__builtin_ia32_psllw256:
13684 case X86::BI__builtin_ia32_psllw512: {
13688 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
13689 [](
const APInt &Elt,
unsigned Width) {
13690 return APInt::getZero(Width);
13696 case X86::BI__builtin_ia32_psrlq128:
13697 case X86::BI__builtin_ia32_psrlq256:
13698 case X86::BI__builtin_ia32_psrlq512:
13699 case X86::BI__builtin_ia32_psrld128:
13700 case X86::BI__builtin_ia32_psrld256:
13701 case X86::BI__builtin_ia32_psrld512:
13702 case X86::BI__builtin_ia32_psrlw128:
13703 case X86::BI__builtin_ia32_psrlw256:
13704 case X86::BI__builtin_ia32_psrlw512: {
13708 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
13709 [](
const APInt &Elt,
unsigned Width) {
13710 return APInt::getZero(Width);
13716 case X86::BI__builtin_ia32_pternlogd128_mask:
13717 case X86::BI__builtin_ia32_pternlogd256_mask:
13718 case X86::BI__builtin_ia32_pternlogd512_mask:
13719 case X86::BI__builtin_ia32_pternlogq128_mask:
13720 case X86::BI__builtin_ia32_pternlogq256_mask:
13721 case X86::BI__builtin_ia32_pternlogq512_mask: {
13722 APValue AValue, BValue, CValue, ImmValue, UValue;
13730 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13736 ResultElements.reserve(ResultLen);
13738 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13744 unsigned BitWidth = ALane.getBitWidth();
13745 APInt ResLane(BitWidth, 0);
13747 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13748 unsigned ABit = ALane[Bit];
13749 unsigned BBit = BLane[Bit];
13750 unsigned CBit = CLane[Bit];
13752 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13753 ResLane.setBitVal(Bit, Imm[Idx]);
13755 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13757 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
13760 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13762 case X86::BI__builtin_ia32_pternlogd128_maskz:
13763 case X86::BI__builtin_ia32_pternlogd256_maskz:
13764 case X86::BI__builtin_ia32_pternlogd512_maskz:
13765 case X86::BI__builtin_ia32_pternlogq128_maskz:
13766 case X86::BI__builtin_ia32_pternlogq256_maskz:
13767 case X86::BI__builtin_ia32_pternlogq512_maskz: {
13768 APValue AValue, BValue, CValue, ImmValue, UValue;
13776 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13782 ResultElements.reserve(ResultLen);
13784 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13789 unsigned BitWidth = ALane.getBitWidth();
13790 APInt ResLane(BitWidth, 0);
13793 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13794 unsigned ABit = ALane[Bit];
13795 unsigned BBit = BLane[Bit];
13796 unsigned CBit = CLane[Bit];
13798 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13799 ResLane.setBitVal(Bit, Imm[Idx]);
13802 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13804 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13807 case Builtin::BI__builtin_elementwise_clzg:
13808 case Builtin::BI__builtin_elementwise_ctzg: {
13810 std::optional<APValue> Fallback;
13817 Fallback = FallbackTmp;
13820 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13823 ResultElements.reserve(SourceLen);
13825 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13830 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13832 Builtin::BI__builtin_elementwise_ctzg);
13835 ResultElements.push_back(Fallback->getVectorElt(EltNum));
13839 case Builtin::BI__builtin_elementwise_clzg:
13840 ResultElements.push_back(
APValue(
13841 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
13844 case Builtin::BI__builtin_elementwise_ctzg:
13845 ResultElements.push_back(
APValue(
13846 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
13852 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13855 case Builtin::BI__builtin_elementwise_fma: {
13856 APValue SourceX, SourceY, SourceZ;
13864 ResultElements.reserve(SourceLen);
13866 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13871 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
13874 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13877 case clang::X86::BI__builtin_ia32_phaddw128:
13878 case clang::X86::BI__builtin_ia32_phaddw256:
13879 case clang::X86::BI__builtin_ia32_phaddd128:
13880 case clang::X86::BI__builtin_ia32_phaddd256:
13881 case clang::X86::BI__builtin_ia32_phaddsw128:
13882 case clang::X86::BI__builtin_ia32_phaddsw256:
13884 case clang::X86::BI__builtin_ia32_phsubw128:
13885 case clang::X86::BI__builtin_ia32_phsubw256:
13886 case clang::X86::BI__builtin_ia32_phsubd128:
13887 case clang::X86::BI__builtin_ia32_phsubd256:
13888 case clang::X86::BI__builtin_ia32_phsubsw128:
13889 case clang::X86::BI__builtin_ia32_phsubsw256: {
13890 APValue SourceLHS, SourceRHS;
13894 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13898 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
13899 unsigned EltsPerLane = 128 / EltBits;
13901 ResultElements.reserve(NumElts);
13903 for (
unsigned LaneStart = 0; LaneStart != NumElts;
13904 LaneStart += EltsPerLane) {
13905 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13909 case clang::X86::BI__builtin_ia32_phaddw128:
13910 case clang::X86::BI__builtin_ia32_phaddw256:
13911 case clang::X86::BI__builtin_ia32_phaddd128:
13912 case clang::X86::BI__builtin_ia32_phaddd256: {
13913 APSInt Res(LHSA + LHSB, DestUnsigned);
13914 ResultElements.push_back(
APValue(Res));
13917 case clang::X86::BI__builtin_ia32_phaddsw128:
13918 case clang::X86::BI__builtin_ia32_phaddsw256: {
13919 APSInt Res(LHSA.sadd_sat(LHSB));
13920 ResultElements.push_back(
APValue(Res));
13923 case clang::X86::BI__builtin_ia32_phsubw128:
13924 case clang::X86::BI__builtin_ia32_phsubw256:
13925 case clang::X86::BI__builtin_ia32_phsubd128:
13926 case clang::X86::BI__builtin_ia32_phsubd256: {
13927 APSInt Res(LHSA - LHSB, DestUnsigned);
13928 ResultElements.push_back(
APValue(Res));
13931 case clang::X86::BI__builtin_ia32_phsubsw128:
13932 case clang::X86::BI__builtin_ia32_phsubsw256: {
13933 APSInt Res(LHSA.ssub_sat(LHSB));
13934 ResultElements.push_back(
APValue(Res));
13939 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13943 case clang::X86::BI__builtin_ia32_phaddw128:
13944 case clang::X86::BI__builtin_ia32_phaddw256:
13945 case clang::X86::BI__builtin_ia32_phaddd128:
13946 case clang::X86::BI__builtin_ia32_phaddd256: {
13947 APSInt Res(RHSA + RHSB, DestUnsigned);
13948 ResultElements.push_back(
APValue(Res));
13951 case clang::X86::BI__builtin_ia32_phaddsw128:
13952 case clang::X86::BI__builtin_ia32_phaddsw256: {
13953 APSInt Res(RHSA.sadd_sat(RHSB));
13954 ResultElements.push_back(
APValue(Res));
13957 case clang::X86::BI__builtin_ia32_phsubw128:
13958 case clang::X86::BI__builtin_ia32_phsubw256:
13959 case clang::X86::BI__builtin_ia32_phsubd128:
13960 case clang::X86::BI__builtin_ia32_phsubd256: {
13961 APSInt Res(RHSA - RHSB, DestUnsigned);
13962 ResultElements.push_back(
APValue(Res));
13965 case clang::X86::BI__builtin_ia32_phsubsw128:
13966 case clang::X86::BI__builtin_ia32_phsubsw256: {
13967 APSInt Res(RHSA.ssub_sat(RHSB));
13968 ResultElements.push_back(
APValue(Res));
13974 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13976 case clang::X86::BI__builtin_ia32_haddpd:
13977 case clang::X86::BI__builtin_ia32_haddps:
13978 case clang::X86::BI__builtin_ia32_haddps256:
13979 case clang::X86::BI__builtin_ia32_haddpd256:
13980 case clang::X86::BI__builtin_ia32_hsubpd:
13981 case clang::X86::BI__builtin_ia32_hsubps:
13982 case clang::X86::BI__builtin_ia32_hsubps256:
13983 case clang::X86::BI__builtin_ia32_hsubpd256: {
13984 APValue SourceLHS, SourceRHS;
13990 ResultElements.reserve(NumElts);
13992 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13993 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
13994 unsigned NumLanes = NumElts * EltBits / 128;
13995 unsigned NumElemsPerLane = NumElts / NumLanes;
13996 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
13998 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
13999 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14003 case clang::X86::BI__builtin_ia32_haddpd:
14004 case clang::X86::BI__builtin_ia32_haddps:
14005 case clang::X86::BI__builtin_ia32_haddps256:
14006 case clang::X86::BI__builtin_ia32_haddpd256:
14007 LHSA.add(LHSB, RM);
14009 case clang::X86::BI__builtin_ia32_hsubpd:
14010 case clang::X86::BI__builtin_ia32_hsubps:
14011 case clang::X86::BI__builtin_ia32_hsubps256:
14012 case clang::X86::BI__builtin_ia32_hsubpd256:
14013 LHSA.subtract(LHSB, RM);
14016 ResultElements.push_back(
APValue(LHSA));
14018 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14022 case clang::X86::BI__builtin_ia32_haddpd:
14023 case clang::X86::BI__builtin_ia32_haddps:
14024 case clang::X86::BI__builtin_ia32_haddps256:
14025 case clang::X86::BI__builtin_ia32_haddpd256:
14026 RHSA.add(RHSB, RM);
14028 case clang::X86::BI__builtin_ia32_hsubpd:
14029 case clang::X86::BI__builtin_ia32_hsubps:
14030 case clang::X86::BI__builtin_ia32_hsubps256:
14031 case clang::X86::BI__builtin_ia32_hsubpd256:
14032 RHSA.subtract(RHSB, RM);
14035 ResultElements.push_back(
APValue(RHSA));
14038 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14040 case clang::X86::BI__builtin_ia32_addsubpd:
14041 case clang::X86::BI__builtin_ia32_addsubps:
14042 case clang::X86::BI__builtin_ia32_addsubpd256:
14043 case clang::X86::BI__builtin_ia32_addsubps256: {
14046 APValue SourceLHS, SourceRHS;
14052 ResultElements.reserve(NumElems);
14055 for (
unsigned I = 0; I != NumElems; ++I) {
14060 LHS.subtract(RHS, RM);
14065 ResultElements.push_back(
APValue(LHS));
14067 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14069 case clang::X86::BI__builtin_ia32_pclmulqdq128:
14070 case clang::X86::BI__builtin_ia32_pclmulqdq256:
14071 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
14075 APValue SourceLHS, SourceRHS;
14085 bool SelectUpperA = (Imm8 & 0x01) != 0;
14086 bool SelectUpperB = (Imm8 & 0x10) != 0;
14090 ResultElements.reserve(NumElems);
14091 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14095 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
14104 APInt A = SelectUpperA ? A1 : A0;
14105 APInt B = SelectUpperB ? B1 : B0;
14108 APInt A128 = A.zext(128);
14109 APInt B128 = B.zext(128);
14112 APInt Result = llvm::APIntOps::clmul(A128, B128);
14115 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
14116 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
14118 ResultElements.push_back(
APValue(ResultLow));
14119 ResultElements.push_back(
APValue(ResultHigh));
14122 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14124 case Builtin::BI__builtin_elementwise_clmul:
14125 return EvaluateBinOpExpr(llvm::APIntOps::clmul);
14126 case Builtin::BI__builtin_elementwise_pext:
14127 return EvaluateBinOpExpr(llvm::APIntOps::compressBits);
14128 case Builtin::BI__builtin_elementwise_pdep:
14129 return EvaluateBinOpExpr(llvm::APIntOps::expandBits);
14130 case Builtin::BI__builtin_elementwise_fshl:
14131 case Builtin::BI__builtin_elementwise_fshr: {
14132 APValue SourceHi, SourceLo, SourceShift;
14138 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14144 ResultElements.reserve(SourceLen);
14145 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14150 case Builtin::BI__builtin_elementwise_fshl:
14151 ResultElements.push_back(
APValue(
14152 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14154 case Builtin::BI__builtin_elementwise_fshr:
14155 ResultElements.push_back(
APValue(
14156 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14161 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14164 case X86::BI__builtin_ia32_shuf_f32x4_256:
14165 case X86::BI__builtin_ia32_shuf_i32x4_256:
14166 case X86::BI__builtin_ia32_shuf_f64x2_256:
14167 case X86::BI__builtin_ia32_shuf_i64x2_256:
14168 case X86::BI__builtin_ia32_shuf_f32x4:
14169 case X86::BI__builtin_ia32_shuf_i32x4:
14170 case X86::BI__builtin_ia32_shuf_f64x2:
14171 case X86::BI__builtin_ia32_shuf_i64x2: {
14185 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14186 unsigned LaneBits = 128u;
14187 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14188 unsigned NumElemsPerLane = LaneBits / ElemBits;
14192 ResultElements.reserve(DstLen);
14197 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14198 -> std::pair<unsigned, int> {
14200 unsigned BitsPerElem = NumLanes / 2;
14201 unsigned IndexMask = (1u << BitsPerElem) - 1;
14202 unsigned Lane = DstIdx / NumElemsPerLane;
14203 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14204 unsigned BitIdx = BitsPerElem * Lane;
14205 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14206 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14207 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14208 return {SrcIdx, IdxToPick};
14214 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14215 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14216 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14217 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14218 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14219 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14231 bool IsInverse =
false;
14233 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14234 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14235 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14240 unsigned NumBitsInByte = 8;
14241 unsigned NumBytesInQWord = 8;
14242 unsigned NumBitsInQWord = 64;
14244 unsigned NumQWords = NumBytes / NumBytesInQWord;
14246 Result.reserve(NumBytes);
14249 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14251 APInt XQWord(NumBitsInQWord, 0);
14252 APInt AQWord(NumBitsInQWord, 0);
14253 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14254 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14255 APInt XByte =
X.getVectorElt(Idx).getInt();
14257 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14258 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14261 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14263 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14272 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14273 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14274 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14285 Result.reserve(NumBytes);
14287 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14297 case X86::BI__builtin_ia32_insertf32x4_256:
14298 case X86::BI__builtin_ia32_inserti32x4_256:
14299 case X86::BI__builtin_ia32_insertf64x2_256:
14300 case X86::BI__builtin_ia32_inserti64x2_256:
14301 case X86::BI__builtin_ia32_insertf32x4:
14302 case X86::BI__builtin_ia32_inserti32x4:
14303 case X86::BI__builtin_ia32_insertf64x2_512:
14304 case X86::BI__builtin_ia32_inserti64x2_512:
14305 case X86::BI__builtin_ia32_insertf32x8:
14306 case X86::BI__builtin_ia32_inserti32x8:
14307 case X86::BI__builtin_ia32_insertf64x4:
14308 case X86::BI__builtin_ia32_inserti64x4:
14309 case X86::BI__builtin_ia32_vinsertf128_ps256:
14310 case X86::BI__builtin_ia32_vinsertf128_pd256:
14311 case X86::BI__builtin_ia32_vinsertf128_si256:
14312 case X86::BI__builtin_ia32_insert128i256: {
14313 APValue SourceDst, SourceSub;
14325 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14326 unsigned NumLanes = DstLen / SubLen;
14327 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14330 ResultElements.reserve(DstLen);
14332 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14333 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14334 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14336 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14339 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14342 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14343 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14344 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14345 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14346 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14347 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14348 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14349 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14350 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14358 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14359 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
14361 Scalar.setIsUnsigned(ElemUnsigned);
14367 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14370 Elems.reserve(NumElems);
14371 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14372 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14377 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14378 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14379 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14383 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14384 unsigned LaneBase = (DstIdx / 16) * 16;
14385 unsigned LaneIdx = DstIdx % 16;
14386 if (LaneIdx < Shift)
14387 return std::make_pair(0, -1);
14389 return std::make_pair(
14390 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14396 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14397 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14398 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14402 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14403 unsigned LaneBase = (DstIdx / 16) * 16;
14404 unsigned LaneIdx = DstIdx % 16;
14405 if (LaneIdx + Shift < 16)
14406 return std::make_pair(
14407 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14409 return std::make_pair(0, -1);
14415 case X86::BI__builtin_ia32_palignr128:
14416 case X86::BI__builtin_ia32_palignr256:
14417 case X86::BI__builtin_ia32_palignr512: {
14421 unsigned VecIdx = 1;
14424 int Lane = DstIdx / 16;
14425 int Offset = DstIdx % 16;
14428 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14429 if (ShiftedIdx < 16) {
14430 ElemIdx = ShiftedIdx + (Lane * 16);
14431 }
else if (ShiftedIdx < 32) {
14433 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14436 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14441 case X86::BI__builtin_ia32_alignd128:
14442 case X86::BI__builtin_ia32_alignd256:
14443 case X86::BI__builtin_ia32_alignd512:
14444 case X86::BI__builtin_ia32_alignq128:
14445 case X86::BI__builtin_ia32_alignq256:
14446 case X86::BI__builtin_ia32_alignq512: {
14448 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14450 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14451 unsigned Imm =
Shift & 0xFF;
14452 unsigned EffectiveShift = Imm & (NumElems - 1);
14453 unsigned SourcePos = DstIdx + EffectiveShift;
14454 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14455 unsigned ElemIdx = SourcePos & (NumElems - 1);
14457 return std::pair<unsigned, int>{
14458 VecIdx,
static_cast<int>(ElemIdx)};
14463 case X86::BI__builtin_ia32_permvarsi256:
14464 case X86::BI__builtin_ia32_permvarsf256:
14465 case X86::BI__builtin_ia32_permvardf512:
14466 case X86::BI__builtin_ia32_permvardi512:
14467 case X86::BI__builtin_ia32_permvarhi128: {
14470 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14471 int Offset = ShuffleMask & 0x7;
14472 return std::pair<unsigned, int>{0, Offset};
14477 case X86::BI__builtin_ia32_permvarqi128:
14478 case X86::BI__builtin_ia32_permvarhi256:
14479 case X86::BI__builtin_ia32_permvarsi512:
14480 case X86::BI__builtin_ia32_permvarsf512: {
14483 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14484 int Offset = ShuffleMask & 0xF;
14485 return std::pair<unsigned, int>{0, Offset};
14490 case X86::BI__builtin_ia32_permvardi256:
14491 case X86::BI__builtin_ia32_permvardf256: {
14494 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14495 int Offset = ShuffleMask & 0x3;
14496 return std::pair<unsigned, int>{0, Offset};
14501 case X86::BI__builtin_ia32_permvarqi256:
14502 case X86::BI__builtin_ia32_permvarhi512: {
14505 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14506 int Offset = ShuffleMask & 0x1F;
14507 return std::pair<unsigned, int>{0, Offset};
14512 case X86::BI__builtin_ia32_permvarqi512: {
14515 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14516 int Offset = ShuffleMask & 0x3F;
14517 return std::pair<unsigned, int>{0, Offset};
14522 case X86::BI__builtin_ia32_vpermi2varq128:
14523 case X86::BI__builtin_ia32_vpermi2varpd128: {
14526 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14527 int Offset = ShuffleMask & 0x1;
14528 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
14529 return std::pair<unsigned, int>{SrcIdx, Offset};
14534 case X86::BI__builtin_ia32_vpermi2vard128:
14535 case X86::BI__builtin_ia32_vpermi2varps128:
14536 case X86::BI__builtin_ia32_vpermi2varq256:
14537 case X86::BI__builtin_ia32_vpermi2varpd256: {
14540 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14541 int Offset = ShuffleMask & 0x3;
14542 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
14543 return std::pair<unsigned, int>{SrcIdx, Offset};
14548 case X86::BI__builtin_ia32_vpermi2varhi128:
14549 case X86::BI__builtin_ia32_vpermi2vard256:
14550 case X86::BI__builtin_ia32_vpermi2varps256:
14551 case X86::BI__builtin_ia32_vpermi2varq512:
14552 case X86::BI__builtin_ia32_vpermi2varpd512: {
14555 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14556 int Offset = ShuffleMask & 0x7;
14557 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
14558 return std::pair<unsigned, int>{SrcIdx, Offset};
14563 case X86::BI__builtin_ia32_vpermi2varqi128:
14564 case X86::BI__builtin_ia32_vpermi2varhi256:
14565 case X86::BI__builtin_ia32_vpermi2vard512:
14566 case X86::BI__builtin_ia32_vpermi2varps512: {
14569 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14570 int Offset = ShuffleMask & 0xF;
14571 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
14572 return std::pair<unsigned, int>{SrcIdx, Offset};
14577 case X86::BI__builtin_ia32_vpermi2varqi256:
14578 case X86::BI__builtin_ia32_vpermi2varhi512: {
14581 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14582 int Offset = ShuffleMask & 0x1F;
14583 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
14584 return std::pair<unsigned, int>{SrcIdx, Offset};
14589 case X86::BI__builtin_ia32_vpermi2varqi512: {
14592 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14593 int Offset = ShuffleMask & 0x3F;
14594 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
14595 return std::pair<unsigned, int>{SrcIdx, Offset};
14601 case clang::X86::BI__builtin_ia32_minps:
14602 case clang::X86::BI__builtin_ia32_minpd:
14603 case clang::X86::BI__builtin_ia32_minps256:
14604 case clang::X86::BI__builtin_ia32_minpd256:
14605 case clang::X86::BI__builtin_ia32_minps512:
14606 case clang::X86::BI__builtin_ia32_minpd512:
14607 case clang::X86::BI__builtin_ia32_minph128:
14608 case clang::X86::BI__builtin_ia32_minph256:
14609 case clang::X86::BI__builtin_ia32_minph512:
14610 return EvaluateFpBinOpExpr(
14611 [](
const APFloat &A,
const APFloat &B,
14612 std::optional<APSInt>) -> std::optional<APFloat> {
14613 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14614 B.isInfinity() || B.isDenormal())
14615 return std::nullopt;
14616 if (A.isZero() && B.isZero())
14618 return llvm::minimum(A, B);
14621 case clang::X86::BI__builtin_ia32_minss:
14622 case clang::X86::BI__builtin_ia32_minsd:
14623 return EvaluateFpBinOpExpr(
14624 [](
const APFloat &A,
const APFloat &B,
14625 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14630 case clang::X86::BI__builtin_ia32_minsd_round_mask:
14631 case clang::X86::BI__builtin_ia32_minss_round_mask:
14632 case clang::X86::BI__builtin_ia32_minsh_round_mask:
14633 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
14634 case clang::X86::BI__builtin_ia32_maxss_round_mask:
14635 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
14638 clang::X86::BI__builtin_ia32_minsd_round_mask ||
14640 clang::X86::BI__builtin_ia32_minss_round_mask ||
14642 return EvaluateScalarFpRoundMaskBinOp(
14643 [IsMin](
const APFloat &A,
const APFloat &B,
14644 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14649 case clang::X86::BI__builtin_ia32_maxps:
14650 case clang::X86::BI__builtin_ia32_maxpd:
14651 case clang::X86::BI__builtin_ia32_maxps256:
14652 case clang::X86::BI__builtin_ia32_maxpd256:
14653 case clang::X86::BI__builtin_ia32_maxps512:
14654 case clang::X86::BI__builtin_ia32_maxpd512:
14655 case clang::X86::BI__builtin_ia32_maxph128:
14656 case clang::X86::BI__builtin_ia32_maxph256:
14657 case clang::X86::BI__builtin_ia32_maxph512:
14658 return EvaluateFpBinOpExpr(
14659 [](
const APFloat &A,
const APFloat &B,
14660 std::optional<APSInt>) -> std::optional<APFloat> {
14661 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14662 B.isInfinity() || B.isDenormal())
14663 return std::nullopt;
14664 if (A.isZero() && B.isZero())
14666 return llvm::maximum(A, B);
14669 case clang::X86::BI__builtin_ia32_maxss:
14670 case clang::X86::BI__builtin_ia32_maxsd:
14671 return EvaluateFpBinOpExpr(
14672 [](
const APFloat &A,
const APFloat &B,
14673 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14678 case clang::X86::BI__builtin_ia32_vcvtps2ph:
14679 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
14689 unsigned SrcNumElems = SrcVTy->getNumElements();
14691 unsigned DstNumElems = DstVTy->getNumElements();
14692 QualType DstElemTy = DstVTy->getElementType();
14694 const llvm::fltSemantics &HalfSem =
14695 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
14697 int ImmVal = Imm.getZExtValue();
14698 bool UseMXCSR = (ImmVal & 4) != 0;
14699 bool IsFPConstrained =
14702 llvm::RoundingMode RM;
14704 switch (ImmVal & 3) {
14706 RM = llvm::RoundingMode::NearestTiesToEven;
14709 RM = llvm::RoundingMode::TowardNegative;
14712 RM = llvm::RoundingMode::TowardPositive;
14715 RM = llvm::RoundingMode::TowardZero;
14718 llvm_unreachable(
"Invalid immediate rounding mode");
14721 RM = llvm::RoundingMode::NearestTiesToEven;
14725 ResultElements.reserve(DstNumElems);
14727 for (
unsigned I = 0; I < SrcNumElems; ++I) {
14731 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
14733 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
14734 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
14738 APSInt DstInt(SrcVal.bitcastToAPInt(),
14740 ResultElements.push_back(
APValue(DstInt));
14743 if (DstNumElems > SrcNumElems) {
14744 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
14745 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
14750 return Success(ResultElements, E);
14752 case X86::BI__builtin_ia32_vperm2f128_pd256:
14753 case X86::BI__builtin_ia32_vperm2f128_ps256:
14754 case X86::BI__builtin_ia32_vperm2f128_si256:
14755 case X86::BI__builtin_ia32_permti256: {
14756 unsigned NumElements =
14758 unsigned PreservedBitsCnt = NumElements >> 2;
14762 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
14763 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
14764 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
14766 if (ControlBits & 0b1000)
14767 return std::make_pair(0u, -1);
14769 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
14770 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
14771 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
14772 (DstIdx & PreservedBitsMask);
14773 return std::make_pair(SrcVecIdx, SrcIdx);
14781bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
14787 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
14788 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
14794 ResultElements.reserve(SourceLen);
14795 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14800 ResultElements.push_back(std::move(Elt));
14803 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14808 APValue const &VecVal2,
unsigned EltNum,
14810 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
14811 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
14814 int64_t
index = IndexVal.getExtValue();
14821 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
14827 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
14828 llvm_unreachable(
"Out of bounds shuffle index");
14830 if (
index >= TotalElementsInInputVector1)
14837bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
14842 const Expr *Vec1 = E->
getExpr(0);
14846 const Expr *Vec2 = E->
getExpr(1);
14850 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
14856 ResultElements.reserve(TotalElementsInOutputVector);
14857 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
14861 ResultElements.push_back(std::move(Elt));
14864 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14872class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
14879 bool Success(ArrayRef<APValue> M,
const Expr *E) {
14881 assert(M.size() == CMTy->getNumElementsFlattened());
14883 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
14887 assert(M.
isMatrix() &&
"expected matrix");
14892 bool VisitCastExpr(
const CastExpr *E);
14893 bool VisitInitListExpr(
const InitListExpr *E);
14899 "not a matrix prvalue");
14900 return MatrixExprEvaluator(Info,
Result).Visit(E);
14903bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14904 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
14905 unsigned NumRows = MT->getNumRows();
14906 unsigned NumCols = MT->getNumColumns();
14907 unsigned NElts = NumRows * NumCols;
14908 QualType EltTy = MT->getElementType();
14912 case CK_HLSLAggregateSplatCast: {
14927 case CK_HLSLElementwiseCast: {
14940 return Success(ResultEls, E);
14943 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14947bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
14948 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
14949 QualType EltTy = MT->getElementType();
14951 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
14952 "Expected number of elements in initializer list to match the number "
14953 "of matrix elements");
14956 Elements.reserve(MT->getNumElementsFlattened());
14961 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
14962 if (EltTy->isIntegerType()) {
14963 llvm::APSInt IntVal;
14966 Elements.push_back(
APValue(IntVal));
14968 llvm::APFloat FloatVal(0.0);
14971 Elements.push_back(
APValue(FloatVal));
14983 class ArrayExprEvaluator
14984 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
14985 const LValue &
This;
14989 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
14993 assert(
V.isArray() &&
"expected array");
14998 bool ZeroInitialization(
const Expr *E) {
14999 const ConstantArrayType *CAT =
15000 Info.Ctx.getAsConstantArrayType(E->
getType());
15014 if (!
Result.hasArrayFiller())
15018 LValue Subobject =
This;
15019 Subobject.addArray(Info, E, CAT);
15024 bool VisitCallExpr(
const CallExpr *E) {
15025 return handleCallExpr(E,
Result, &This);
15027 bool VisitCastExpr(
const CastExpr *E);
15028 bool VisitInitListExpr(
const InitListExpr *E,
15029 QualType AllocType = QualType());
15030 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
15031 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
15032 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
15033 const LValue &Subobject,
15035 bool VisitStringLiteral(
const StringLiteral *E,
15036 QualType AllocType = QualType()) {
15040 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
15041 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
15042 ArrayRef<Expr *> Args,
15043 const Expr *ArrayFiller,
15044 QualType AllocType = QualType());
15045 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
15053 "not an array prvalue");
15054 return ArrayExprEvaluator(Info,
This,
Result).Visit(E);
15062 "not an array prvalue");
15063 return ArrayExprEvaluator(Info,
This,
Result)
15064 .VisitInitListExpr(ILE, AllocType);
15073 "not an array prvalue");
15074 return ArrayExprEvaluator(Info,
This,
Result)
15075 .VisitCXXConstructExpr(CCE,
This, &
Result, AllocType);
15084 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
15085 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
15090 if (ILE->hasArrayFiller() &&
15099bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15104 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15105 case CK_HLSLAggregateSplatCast: {
15125 case CK_HLSLElementwiseCast: {
15142bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15143 QualType AllocType) {
15144 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15157 return VisitStringLiteral(SL, AllocType);
15162 "transparent array list initialization is not string literal init?");
15168bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15170 QualType AllocType) {
15171 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15176 unsigned NumEltsToInit = Args.size();
15181 if (NumEltsToInit != NumElts &&
15183 NumEltsToInit = NumElts;
15186 for (
auto *
Init : Args) {
15187 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15188 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15191 if (NumEltsToInit > NumElts)
15192 NumEltsToInit = NumElts;
15196 if (
Result.hasValue() && NumEltsToInit <
Result.getArrayInitializedElts())
15197 NumEltsToInit =
Result.getArrayInitializedElts();
15200 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15201 << NumEltsToInit <<
".\n");
15203 if (!
Result.hasValue()) {
15204 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15205 }
else if (
Result.getArrayInitializedElts() != NumEltsToInit) {
15216 APValue NewResult =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15218 unsigned NumOldElts =
Result.getArrayInitializedElts();
15219 for (
unsigned I = 0; I < NumOldElts; ++I) {
15221 std::move(
Result.getArrayInitializedElt(I));
15224 for (
unsigned I =
Result.getArrayInitializedElts(); I < NumEltsToInit; ++I)
15228 Result = std::move(NewResult);
15231 LValue Subobject =
This;
15232 Subobject.addArray(Info, ExprToVisit, CAT);
15233 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15234 if (
Init->isValueDependent())
15243 Subobject,
Init) ||
15246 if (!Info.noteFailure())
15252 unsigned ArrayIndex = 0;
15255 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
15256 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
15257 if (ArrayIndex >= NumEltsToInit)
15259 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
15260 StringLiteral *SL = EmbedS->getDataStringLiteral();
15261 for (
unsigned I = EmbedS->getStartingElementPos(),
15262 N = EmbedS->getDataElementCount();
15263 I != EmbedS->getStartingElementPos() + N; ++I) {
15269 const FPOptions FPO =
15270 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
15275 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
15280 if (!Eval(
Init, ArrayIndex))
15286 if (!
Result.hasArrayFiller())
15291 assert(ArrayFiller &&
"no array filler for incomplete init list");
15297bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
15300 !
Evaluate(Info.CurrentCall->createTemporary(
15303 ScopeKind::FullExpression, CommonLV),
15310 Result =
APValue(APValue::UninitArray(), Elements, Elements);
15312 LValue Subobject =
This;
15313 Subobject.addArray(Info, E, CAT);
15316 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
15325 FullExpressionRAII Scope(Info);
15331 if (!Info.noteFailure())
15343bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
15344 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
15347bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
15348 const LValue &Subobject,
15351 bool HadZeroInit =
Value->hasValue();
15353 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
15358 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
15361 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
15362 if (FinalSize == 0)
15368 LValue ArrayElt = Subobject;
15369 ArrayElt.addArray(Info, E, CAT);
15375 for (
const unsigned N : {1u, FinalSize}) {
15376 unsigned OldElts =
Value->getArrayInitializedElts();
15381 APValue NewValue(APValue::UninitArray(), N, FinalSize);
15382 for (
unsigned I = 0; I < OldElts; ++I)
15383 NewValue.getArrayInitializedElt(I).swap(
15384 Value->getArrayInitializedElt(I));
15385 Value->swap(NewValue);
15388 for (
unsigned I = OldElts; I < N; ++I)
15389 Value->getArrayInitializedElt(I) = Filler;
15391 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
15394 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15395 for (
unsigned I = OldElts; I < FinalSize; ++I)
15396 Value->getArrayInitializedElt(I) = FirstResult;
15398 for (
unsigned I = OldElts; I < N; ++I) {
15399 if (!VisitCXXConstructExpr(E, ArrayElt,
15400 &
Value->getArrayInitializedElt(I),
15407 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
15408 !Info.keepEvaluatingAfterFailure())
15417 if (!
Type->isRecordType())
15420 return RecordExprEvaluator(Info, Subobject, *
Value)
15421 .VisitCXXConstructExpr(E,
Type);
15424bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15425 const CXXParenListInitExpr *E) {
15427 "Expression result is not a constant array type");
15429 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15433bool ArrayExprEvaluator::VisitDesignatedInitUpdateExpr(
15434 const DesignatedInitUpdateExpr *E) {
15449class IntExprEvaluator
15450 :
public ExprEvaluatorBase<IntExprEvaluator> {
15453 IntExprEvaluator(EvalInfo &info,
APValue &result)
15454 : ExprEvaluatorBaseTy(info),
Result(result) {}
15458 "Invalid evaluation result.");
15460 "Invalid evaluation result.");
15461 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15462 "Invalid evaluation result.");
15466 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
15472 "Invalid evaluation result.");
15473 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15474 "Invalid evaluation result.");
15476 Result.getInt().setIsUnsigned(
15480 bool Success(
const llvm::APInt &I,
const Expr *E) {
15486 "Invalid evaluation result.");
15494 bool Success(CharUnits Size,
const Expr *E) {
15501 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
15502 V.allowConstexprUnknown()) {
15509 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
15511 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
15518 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
15521 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
15525 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
15526 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
15527 if (CheckReferencedDecl(E, E->
getDecl()))
15530 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
15532 bool VisitMemberExpr(
const MemberExpr *E) {
15534 VisitIgnoredBaseExpression(E->
getBase());
15538 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
15541 bool VisitCallExpr(
const CallExpr *E);
15542 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
15543 bool VisitBinaryOperator(
const BinaryOperator *E);
15544 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
15545 bool VisitUnaryOperator(
const UnaryOperator *E);
15547 bool VisitCastExpr(
const CastExpr* E);
15548 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
15550 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
15554 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
15558 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
15559 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
15565 return Success(Info.ArrayInitIndex, E);
15569 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
15570 return ZeroInitialization(E);
15573 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
15582 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
15586 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
15590 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
15597 bool VisitUnaryReal(
const UnaryOperator *E);
15598 bool VisitUnaryImag(
const UnaryOperator *E);
15600 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
15601 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
15602 bool VisitSourceLocExpr(
const SourceLocExpr *E);
15603 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
15608class FixedPointExprEvaluator
15609 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
15613 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
15614 : ExprEvaluatorBaseTy(info),
Result(result) {}
15616 bool Success(
const llvm::APInt &I,
const Expr *E) {
15618 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15623 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15627 return Success(
V.getFixedPoint(), E);
15630 bool Success(
const APFixedPoint &
V,
const Expr *E) {
15632 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15633 "Invalid evaluation result.");
15638 bool ZeroInitialization(
const Expr *E) {
15646 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
15650 bool VisitCastExpr(
const CastExpr *E);
15651 bool VisitUnaryOperator(
const UnaryOperator *E);
15652 bool VisitBinaryOperator(
const BinaryOperator *E);
15668 return IntExprEvaluator(Info,
Result).Visit(E);
15676 if (!Val.
isInt()) {
15679 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15686bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
15688 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
15697 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
15712 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
15716 Result = APFixedPoint(Val, FXSema);
15727bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
15729 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
15731 bool SameSign = (ECD->getInitVal().isSigned()
15733 bool SameWidth = (ECD->getInitVal().
getBitWidth()
15734 == Info.Ctx.getIntWidth(E->
getType()));
15735 if (SameSign && SameWidth)
15736 return Success(ECD->getInitVal(), E);
15740 llvm::APSInt Val = ECD->getInitVal();
15742 Val.setIsSigned(!ECD->getInitVal().isSigned());
15744 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
15755 assert(!T->isDependentType() &&
"unexpected dependent type");
15760#define TYPE(ID, BASE)
15761#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
15762#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
15763#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
15764#include "clang/AST/TypeNodes.inc"
15766 case Type::DeducedTemplateSpecialization:
15767 llvm_unreachable(
"unexpected non-canonical or dependent type");
15769 case Type::Builtin:
15771#define BUILTIN_TYPE(ID, SINGLETON_ID)
15772#define SIGNED_TYPE(ID, SINGLETON_ID) \
15773 case BuiltinType::ID: return GCCTypeClass::Integer;
15774#define FLOATING_TYPE(ID, SINGLETON_ID) \
15775 case BuiltinType::ID: return GCCTypeClass::RealFloat;
15776#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
15777 case BuiltinType::ID: break;
15778#include "clang/AST/BuiltinTypes.def"
15779 case BuiltinType::Void:
15782 case BuiltinType::Bool:
15785 case BuiltinType::Char_U:
15786 case BuiltinType::UChar:
15787 case BuiltinType::WChar_U:
15788 case BuiltinType::Char8:
15789 case BuiltinType::Char16:
15790 case BuiltinType::Char32:
15791 case BuiltinType::UShort:
15792 case BuiltinType::UInt:
15793 case BuiltinType::ULong:
15794 case BuiltinType::ULongLong:
15795 case BuiltinType::UInt128:
15798 case BuiltinType::UShortAccum:
15799 case BuiltinType::UAccum:
15800 case BuiltinType::ULongAccum:
15801 case BuiltinType::UShortFract:
15802 case BuiltinType::UFract:
15803 case BuiltinType::ULongFract:
15804 case BuiltinType::SatUShortAccum:
15805 case BuiltinType::SatUAccum:
15806 case BuiltinType::SatULongAccum:
15807 case BuiltinType::SatUShortFract:
15808 case BuiltinType::SatUFract:
15809 case BuiltinType::SatULongFract:
15812 case BuiltinType::NullPtr:
15814 case BuiltinType::ObjCId:
15815 case BuiltinType::ObjCClass:
15816 case BuiltinType::ObjCSel:
15817#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
15818 case BuiltinType::Id:
15819#include "clang/Basic/OpenCLImageTypes.def"
15820#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
15821 case BuiltinType::Id:
15822#include "clang/Basic/OpenCLExtensionTypes.def"
15823 case BuiltinType::OCLSampler:
15824 case BuiltinType::OCLEvent:
15825 case BuiltinType::OCLClkEvent:
15826 case BuiltinType::OCLQueue:
15827 case BuiltinType::OCLReserveID:
15828#define SVE_TYPE(Name, Id, SingletonId) \
15829 case BuiltinType::Id:
15830#include "clang/Basic/AArch64ACLETypes.def"
15831#define PPC_VECTOR_TYPE(Name, Id, Size) \
15832 case BuiltinType::Id:
15833#include "clang/Basic/PPCTypes.def"
15834#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15835#include "clang/Basic/RISCVVTypes.def"
15836#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15837#include "clang/Basic/WebAssemblyReferenceTypes.def"
15838#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
15839#include "clang/Basic/AMDGPUTypes.def"
15840#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15841#include "clang/Basic/HLSLIntangibleTypes.def"
15844 case BuiltinType::Dependent:
15845 llvm_unreachable(
"unexpected dependent type");
15847 llvm_unreachable(
"unexpected placeholder type");
15852 case Type::Pointer:
15853 case Type::ConstantArray:
15854 case Type::VariableArray:
15855 case Type::IncompleteArray:
15856 case Type::FunctionNoProto:
15857 case Type::FunctionProto:
15858 case Type::ArrayParameter:
15861 case Type::MemberPointer:
15866 case Type::Complex:
15879 case Type::ExtVector:
15882 case Type::BlockPointer:
15883 case Type::ConstantMatrix:
15884 case Type::ObjCObject:
15885 case Type::ObjCInterface:
15886 case Type::ObjCObjectPointer:
15888 case Type::HLSLAttributedResource:
15889 case Type::HLSLInlineSpirv:
15890 case Type::OverflowBehavior:
15898 case Type::LValueReference:
15899 case Type::RValueReference:
15900 llvm_unreachable(
"invalid type for expression");
15903 llvm_unreachable(
"unexpected type class");
15928 if (
Base.isNull()) {
15931 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
15950 SpeculativeEvaluationRAII SpeculativeEval(Info);
15955 FoldConstant Fold(Info,
true);
15973 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
15974 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
15975 ArgType->isNullPtrType()) {
15978 Fold.keepDiagnostics();
15987 return V.hasValue();
15998 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
16022 const auto *Cast = dyn_cast<CastExpr>(NoParens);
16023 if (Cast ==
nullptr)
16028 auto CastKind = Cast->getCastKind();
16030 CastKind != CK_AddressSpaceConversion)
16033 const auto *SubExpr = Cast->getSubExpr();
16055 assert(!LVal.Designator.Invalid);
16057 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
16065 auto &
Base = LVal.getLValueBase();
16066 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
16067 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
16068 if (!IsLastOrInvalidFieldDecl(FD))
16070 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
16071 for (
auto *FD : IFD->chain()) {
16080 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
16084 if (BaseType->isIncompleteArrayType())
16090 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
16091 const auto &Entry = LVal.Designator.Entries[I];
16092 if (BaseType->isArrayType()) {
16098 uint64_t Index = Entry.getAsArrayIndex();
16102 }
else if (BaseType->isAnyComplexType()) {
16103 const auto *CT = BaseType->castAs<
ComplexType>();
16104 uint64_t Index = Entry.getAsArrayIndex();
16107 BaseType = CT->getElementType();
16108 }
else if (
auto *FD = getAsField(Entry)) {
16109 if (!IsLastOrInvalidFieldDecl(FD))
16113 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
16125 if (LVal.Designator.Invalid)
16128 if (!LVal.Designator.Entries.empty())
16129 return LVal.Designator.isMostDerivedAnUnsizedArray();
16131 if (!LVal.InvalidBase)
16143 const SubobjectDesignator &
Designator = LVal.Designator;
16155 auto isFlexibleArrayMember = [&] {
16157 FAMKind StrictFlexArraysLevel =
16160 if (
Designator.isMostDerivedAnUnsizedArray())
16163 if (StrictFlexArraysLevel == FAMKind::Default)
16166 if (
Designator.getMostDerivedArraySize() == 0 &&
16167 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
16170 if (
Designator.getMostDerivedArraySize() == 1 &&
16171 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16177 return LVal.InvalidBase &&
16179 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16187 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16188 if (Int.ugt(CharUnitsMax))
16198 if (!T.isNull() && T->isStructureType() &&
16199 T->castAsRecordDecl()->hasFlexibleArrayMember())
16200 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16201 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16213 unsigned Type,
const LValue &LVal,
16232 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
16234 if (
Type == 3 && !DetermineForCompleteObject)
16237 llvm::APInt APEndOffset;
16238 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16242 if (LVal.InvalidBase)
16246 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
16252 const SubobjectDesignator &
Designator = LVal.Designator;
16264 llvm::APInt APEndOffset;
16265 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16277 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
16283 int64_t ElemsRemaining;
16286 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
16287 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
16288 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
16290 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
16293 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
16307static std::optional<uint64_t>
16309 bool IsDynamic =
false) {
16316 SpeculativeEvaluationRAII SpeculativeEval(Info);
16317 IgnoreSideEffectsRAII Fold(Info);
16324 return std::nullopt;
16325 LVal.setFrom(Info.Ctx, RVal);
16328 return std::nullopt;
16333 if (LVal.getLValueOffset().isNegative())
16348 const auto *FD = ME ? dyn_cast<FieldDecl>(ME->getMemberDecl()) :
nullptr;
16350 return std::nullopt;
16355 return std::nullopt;
16359 if (EndOffset <= LVal.getLValueOffset())
16361 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
16364bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16365 if (!IsConstantEvaluatedBuiltinCall(E))
16366 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16383 Info.FFDiag(E->
getArg(0));
16389 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
16390 "Bit widths must be the same");
16397bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
16398 unsigned BuiltinOp) {
16399 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
16401 APValue SourceLHS, SourceRHS;
16409 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
16411 APInt AWide(LaneWidth * SourceLen, 0);
16412 APInt BWide(LaneWidth * SourceLen, 0);
16414 for (
unsigned I = 0; I != SourceLen; ++I) {
16417 if (ElemQT->isIntegerType()) {
16420 }
else if (ElemQT->isFloatingType()) {
16428 AWide.insertBits(ALane, I * LaneWidth);
16429 BWide.insertBits(BLane, I * LaneWidth);
16434 auto HandleMaskBinOp =
16447 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16453 uint64_t CRCVal = CRC.getZExtValue();
16457 static const uint32_t CRC32C_POLY = 0x82F63B78;
16461 for (
unsigned I = 0; I != DataBytes; ++I) {
16462 uint8_t Byte =
static_cast<uint8_t>((DataVal >> (I * 8)) & 0xFF);
16464 for (
int J = 0; J != 8; ++J) {
16472 switch (BuiltinOp) {
16476 case X86::BI__builtin_ia32_crc32qi:
16477 return HandleCRC32(1);
16478 case X86::BI__builtin_ia32_crc32hi:
16479 return HandleCRC32(2);
16480 case X86::BI__builtin_ia32_crc32si:
16481 return HandleCRC32(4);
16482 case X86::BI__builtin_ia32_crc32di:
16483 return HandleCRC32(8);
16485 case Builtin::BI__builtin_dynamic_object_size:
16486 case Builtin::BI__builtin_object_size: {
16490 assert(
Type <= 3 &&
"unexpected type");
16492 bool IsDynamic = BuiltinOp == Builtin::BI__builtin_dynamic_object_size;
16493 if (std::optional<uint64_t> Size =
16502 switch (Info.EvalMode) {
16503 case EvaluationMode::ConstantExpression:
16504 case EvaluationMode::ConstantFold:
16505 case EvaluationMode::IgnoreSideEffects:
16508 case EvaluationMode::ConstantExpressionUnevaluated:
16513 llvm_unreachable(
"unexpected EvalMode");
16516 case Builtin::BI__builtin_os_log_format_buffer_size: {
16517 analyze_os_log::OSLogBufferLayout Layout;
16522 case Builtin::BI__builtin_is_aligned: {
16530 Ptr.setFrom(Info.Ctx, Src);
16536 assert(Alignment.isPowerOf2());
16549 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
16553 assert(Src.
isInt());
16554 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
16556 case Builtin::BI__builtin_align_up: {
16564 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
16565 Src.
getInt().isUnsigned());
16566 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16567 return Success(AlignedVal, E);
16569 case Builtin::BI__builtin_align_down: {
16578 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16579 return Success(AlignedVal, E);
16582 case Builtin::BI__builtin_bitreverseg:
16583 case Builtin::BI__builtin_bitreverse8:
16584 case Builtin::BI__builtin_bitreverse16:
16585 case Builtin::BI__builtin_bitreverse32:
16586 case Builtin::BI__builtin_bitreverse64:
16587 case Builtin::BI__builtin_elementwise_bitreverse: {
16592 return Success(Val.reverseBits(), E);
16594 case Builtin::BI__builtin_bswapg:
16595 case Builtin::BI__builtin_bswap16:
16596 case Builtin::BI__builtin_bswap32:
16597 case Builtin::BI__builtin_bswap64:
16598 case Builtin::BIstdc_memreverse8u8:
16599 case Builtin::BIstdc_memreverse8u16:
16600 case Builtin::BIstdc_memreverse8u32:
16601 case Builtin::BIstdc_memreverse8u64: {
16605 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
16608 return Success(Val.byteSwap(), E);
16611 case Builtin::BI__builtin_classify_type:
16614 case Builtin::BI__builtin_clrsb:
16615 case Builtin::BI__builtin_clrsbl:
16616 case Builtin::BI__builtin_clrsbll: {
16621 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
16624 case Builtin::BI__builtin_clz:
16625 case Builtin::BI__builtin_clzl:
16626 case Builtin::BI__builtin_clzll:
16627 case Builtin::BI__builtin_clzs:
16628 case Builtin::BI__builtin_clzg:
16629 case Builtin::BI__builtin_elementwise_clzg:
16630 case Builtin::BI__lzcnt16:
16631 case Builtin::BI__lzcnt:
16632 case Builtin::BI__lzcnt64: {
16643 std::optional<APSInt> Fallback;
16644 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
16645 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
16650 Fallback = FallbackTemp;
16655 return Success(*Fallback, E);
16660 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
16661 BuiltinOp != Builtin::BI__lzcnt &&
16662 BuiltinOp != Builtin::BI__lzcnt64;
16664 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
16665 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16669 if (ZeroIsUndefined)
16673 return Success(Val.countl_zero(), E);
16676 case Builtin::BI__builtin_constant_p: {
16677 const Expr *Arg = E->
getArg(0);
16686 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16690 case Builtin::BI__noop:
16694 case Builtin::BI__builtin_is_constant_evaluated: {
16695 const auto *
Callee = Info.CurrentCall->getCallee();
16696 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
16697 (Info.CallStackDepth == 1 ||
16698 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
16699 Callee->getIdentifier() &&
16700 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
16702 if (Info.EvalStatus.Diag)
16703 Info.report((Info.CallStackDepth == 1)
16705 : Info.CurrentCall->getCallRange().getBegin(),
16706 diag::warn_is_constant_evaluated_always_true_constexpr)
16707 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
16708 :
"std::is_constant_evaluated");
16711 return Success(Info.InConstantContext, E);
16714 case Builtin::BI__builtin_is_within_lifetime:
16715 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
16719 case Builtin::BI__builtin_ctz:
16720 case Builtin::BI__builtin_ctzl:
16721 case Builtin::BI__builtin_ctzll:
16722 case Builtin::BI__builtin_ctzs:
16723 case Builtin::BI__builtin_ctzg:
16724 case Builtin::BI__builtin_elementwise_ctzg: {
16735 std::optional<APSInt> Fallback;
16736 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
16737 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
16742 Fallback = FallbackTemp;
16747 return Success(*Fallback, E);
16749 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
16750 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16756 return Success(Val.countr_zero(), E);
16759 case Builtin::BI__builtin_eh_return_data_regno: {
16761 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
16765 case Builtin::BI__builtin_elementwise_abs: {
16770 return Success(Val.abs(), E);
16773 case Builtin::BI__builtin_expect:
16774 case Builtin::BI__builtin_expect_with_probability:
16775 return Visit(E->
getArg(0));
16777 case Builtin::BI__builtin_ptrauth_string_discriminator: {
16784 case Builtin::BI__builtin_infer_alloc_token: {
16790 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
16793 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
16795 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
16796 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
16797 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
16799 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
16800 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
16802 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
16803 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
16806 case Builtin::BI__builtin_ffs:
16807 case Builtin::BI__builtin_ffsl:
16808 case Builtin::BI__builtin_ffsll: {
16813 unsigned N = Val.countr_zero();
16814 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
16817 case Builtin::BI__builtin_fpclassify: {
16822 switch (Val.getCategory()) {
16823 case APFloat::fcNaN: Arg = 0;
break;
16824 case APFloat::fcInfinity: Arg = 1;
break;
16825 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
16826 case APFloat::fcZero: Arg = 4;
break;
16828 return Visit(E->
getArg(Arg));
16831 case Builtin::BI__builtin_isinf_sign: {
16834 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
16837 case Builtin::BI__builtin_isinf: {
16840 Success(Val.isInfinity() ? 1 : 0, E);
16843 case Builtin::BI__builtin_isfinite: {
16846 Success(Val.isFinite() ? 1 : 0, E);
16849 case Builtin::BI__builtin_isnan: {
16852 Success(Val.isNaN() ? 1 : 0, E);
16855 case Builtin::BI__builtin_isnormal: {
16858 Success(Val.isNormal() ? 1 : 0, E);
16861 case Builtin::BI__builtin_issubnormal: {
16864 Success(Val.isDenormal() ? 1 : 0, E);
16867 case Builtin::BI__builtin_iszero: {
16870 Success(Val.isZero() ? 1 : 0, E);
16873 case Builtin::BI__builtin_signbit:
16874 case Builtin::BI__builtin_signbitf:
16875 case Builtin::BI__builtin_signbitl: {
16878 Success(Val.isNegative() ? 1 : 0, E);
16881 case Builtin::BI__builtin_isgreater:
16882 case Builtin::BI__builtin_isgreaterequal:
16883 case Builtin::BI__builtin_isless:
16884 case Builtin::BI__builtin_islessequal:
16885 case Builtin::BI__builtin_islessgreater:
16886 case Builtin::BI__builtin_isunordered: {
16895 switch (BuiltinOp) {
16896 case Builtin::BI__builtin_isgreater:
16898 case Builtin::BI__builtin_isgreaterequal:
16900 case Builtin::BI__builtin_isless:
16902 case Builtin::BI__builtin_islessequal:
16904 case Builtin::BI__builtin_islessgreater: {
16905 APFloat::cmpResult cmp = LHS.compare(RHS);
16906 return cmp == APFloat::cmpResult::cmpLessThan ||
16907 cmp == APFloat::cmpResult::cmpGreaterThan;
16909 case Builtin::BI__builtin_isunordered:
16910 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
16912 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
16913 "point comparison function");
16921 case Builtin::BI__builtin_issignaling: {
16924 Success(Val.isSignaling() ? 1 : 0, E);
16927 case Builtin::BI__builtin_isfpclass: {
16931 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
16934 Success((Val.classify() & Test) ? 1 : 0, E);
16937 case Builtin::BI__builtin_parity:
16938 case Builtin::BI__builtin_parityl:
16939 case Builtin::BI__builtin_parityll: {
16944 return Success(Val.popcount() % 2, E);
16947 case Builtin::BI__builtin_abs:
16948 case Builtin::BI__builtin_labs:
16949 case Builtin::BI__builtin_llabs: {
16953 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
16956 if (Val.isNegative())
16961 case Builtin::BI__builtin_popcount:
16962 case Builtin::BI__builtin_popcountl:
16963 case Builtin::BI__builtin_popcountll:
16964 case Builtin::BI__builtin_popcountg:
16965 case Builtin::BI__builtin_elementwise_popcount:
16966 case Builtin::BI__popcnt16:
16967 case Builtin::BI__popcnt:
16968 case Builtin::BI__popcnt64: {
16979 return Success(Val.popcount(), E);
16982 case Builtin::BI__builtin_rotateleft8:
16983 case Builtin::BI__builtin_rotateleft16:
16984 case Builtin::BI__builtin_rotateleft32:
16985 case Builtin::BI__builtin_rotateleft64:
16986 case Builtin::BI__builtin_rotateright8:
16987 case Builtin::BI__builtin_rotateright16:
16988 case Builtin::BI__builtin_rotateright32:
16989 case Builtin::BI__builtin_rotateright64:
16990 case Builtin::BI__builtin_stdc_rotate_left:
16991 case Builtin::BI__builtin_stdc_rotate_right:
16992 case Builtin::BIstdc_rotate_left_uc:
16993 case Builtin::BIstdc_rotate_left_us:
16994 case Builtin::BIstdc_rotate_left_ui:
16995 case Builtin::BIstdc_rotate_left_ul:
16996 case Builtin::BIstdc_rotate_left_ull:
16997 case Builtin::BIstdc_rotate_right_uc:
16998 case Builtin::BIstdc_rotate_right_us:
16999 case Builtin::BIstdc_rotate_right_ui:
17000 case Builtin::BIstdc_rotate_right_ul:
17001 case Builtin::BIstdc_rotate_right_ull:
17002 case Builtin::BI_rotl8:
17003 case Builtin::BI_rotl16:
17004 case Builtin::BI_rotl:
17005 case Builtin::BI_lrotl:
17006 case Builtin::BI_rotl64:
17007 case Builtin::BI_rotr8:
17008 case Builtin::BI_rotr16:
17009 case Builtin::BI_rotr:
17010 case Builtin::BI_lrotr:
17011 case Builtin::BI_rotr64: {
17019 switch (BuiltinOp) {
17020 case Builtin::BI__builtin_rotateright8:
17021 case Builtin::BI__builtin_rotateright16:
17022 case Builtin::BI__builtin_rotateright32:
17023 case Builtin::BI__builtin_rotateright64:
17024 case Builtin::BI__builtin_stdc_rotate_right:
17025 case Builtin::BIstdc_rotate_right_uc:
17026 case Builtin::BIstdc_rotate_right_us:
17027 case Builtin::BIstdc_rotate_right_ui:
17028 case Builtin::BIstdc_rotate_right_ul:
17029 case Builtin::BIstdc_rotate_right_ull:
17030 case Builtin::BI_rotr8:
17031 case Builtin::BI_rotr16:
17032 case Builtin::BI_rotr:
17033 case Builtin::BI_lrotr:
17034 case Builtin::BI_rotr64:
17043 case Builtin::BIstdc_leading_zeros_uc:
17044 case Builtin::BIstdc_leading_zeros_us:
17045 case Builtin::BIstdc_leading_zeros_ui:
17046 case Builtin::BIstdc_leading_zeros_ul:
17047 case Builtin::BIstdc_leading_zeros_ull:
17048 case Builtin::BIstdc_leading_ones_uc:
17049 case Builtin::BIstdc_leading_ones_us:
17050 case Builtin::BIstdc_leading_ones_ui:
17051 case Builtin::BIstdc_leading_ones_ul:
17052 case Builtin::BIstdc_leading_ones_ull:
17053 case Builtin::BIstdc_trailing_zeros_uc:
17054 case Builtin::BIstdc_trailing_zeros_us:
17055 case Builtin::BIstdc_trailing_zeros_ui:
17056 case Builtin::BIstdc_trailing_zeros_ul:
17057 case Builtin::BIstdc_trailing_zeros_ull:
17058 case Builtin::BIstdc_trailing_ones_uc:
17059 case Builtin::BIstdc_trailing_ones_us:
17060 case Builtin::BIstdc_trailing_ones_ui:
17061 case Builtin::BIstdc_trailing_ones_ul:
17062 case Builtin::BIstdc_trailing_ones_ull:
17063 case Builtin::BIstdc_first_leading_zero_uc:
17064 case Builtin::BIstdc_first_leading_zero_us:
17065 case Builtin::BIstdc_first_leading_zero_ui:
17066 case Builtin::BIstdc_first_leading_zero_ul:
17067 case Builtin::BIstdc_first_leading_zero_ull:
17068 case Builtin::BIstdc_first_leading_one_uc:
17069 case Builtin::BIstdc_first_leading_one_us:
17070 case Builtin::BIstdc_first_leading_one_ui:
17071 case Builtin::BIstdc_first_leading_one_ul:
17072 case Builtin::BIstdc_first_leading_one_ull:
17073 case Builtin::BIstdc_first_trailing_zero_uc:
17074 case Builtin::BIstdc_first_trailing_zero_us:
17075 case Builtin::BIstdc_first_trailing_zero_ui:
17076 case Builtin::BIstdc_first_trailing_zero_ul:
17077 case Builtin::BIstdc_first_trailing_zero_ull:
17078 case Builtin::BIstdc_first_trailing_one_uc:
17079 case Builtin::BIstdc_first_trailing_one_us:
17080 case Builtin::BIstdc_first_trailing_one_ui:
17081 case Builtin::BIstdc_first_trailing_one_ul:
17082 case Builtin::BIstdc_first_trailing_one_ull:
17083 case Builtin::BIstdc_count_zeros_uc:
17084 case Builtin::BIstdc_count_zeros_us:
17085 case Builtin::BIstdc_count_zeros_ui:
17086 case Builtin::BIstdc_count_zeros_ul:
17087 case Builtin::BIstdc_count_zeros_ull:
17088 case Builtin::BIstdc_count_ones_uc:
17089 case Builtin::BIstdc_count_ones_us:
17090 case Builtin::BIstdc_count_ones_ui:
17091 case Builtin::BIstdc_count_ones_ul:
17092 case Builtin::BIstdc_count_ones_ull:
17093 case Builtin::BIstdc_has_single_bit_uc:
17094 case Builtin::BIstdc_has_single_bit_us:
17095 case Builtin::BIstdc_has_single_bit_ui:
17096 case Builtin::BIstdc_has_single_bit_ul:
17097 case Builtin::BIstdc_has_single_bit_ull:
17098 case Builtin::BIstdc_bit_width_uc:
17099 case Builtin::BIstdc_bit_width_us:
17100 case Builtin::BIstdc_bit_width_ui:
17101 case Builtin::BIstdc_bit_width_ul:
17102 case Builtin::BIstdc_bit_width_ull:
17103 case Builtin::BIstdc_bit_floor_uc:
17104 case Builtin::BIstdc_bit_floor_us:
17105 case Builtin::BIstdc_bit_floor_ui:
17106 case Builtin::BIstdc_bit_floor_ul:
17107 case Builtin::BIstdc_bit_floor_ull:
17108 case Builtin::BIstdc_bit_ceil_uc:
17109 case Builtin::BIstdc_bit_ceil_us:
17110 case Builtin::BIstdc_bit_ceil_ui:
17111 case Builtin::BIstdc_bit_ceil_ul:
17112 case Builtin::BIstdc_bit_ceil_ull:
17113 case Builtin::BI__builtin_stdc_leading_zeros:
17114 case Builtin::BI__builtin_stdc_leading_ones:
17115 case Builtin::BI__builtin_stdc_trailing_zeros:
17116 case Builtin::BI__builtin_stdc_trailing_ones:
17117 case Builtin::BI__builtin_stdc_first_leading_zero:
17118 case Builtin::BI__builtin_stdc_first_leading_one:
17119 case Builtin::BI__builtin_stdc_first_trailing_zero:
17120 case Builtin::BI__builtin_stdc_first_trailing_one:
17121 case Builtin::BI__builtin_stdc_count_zeros:
17122 case Builtin::BI__builtin_stdc_count_ones:
17123 case Builtin::BI__builtin_stdc_has_single_bit:
17124 case Builtin::BI__builtin_stdc_bit_width:
17125 case Builtin::BI__builtin_stdc_bit_floor:
17126 case Builtin::BI__builtin_stdc_bit_ceil: {
17131 unsigned BitWidth = Val.getBitWidth();
17132 const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->
getType());
17134 switch (BuiltinOp) {
17135 case Builtin::BIstdc_leading_zeros_uc:
17136 case Builtin::BIstdc_leading_zeros_us:
17137 case Builtin::BIstdc_leading_zeros_ui:
17138 case Builtin::BIstdc_leading_zeros_ul:
17139 case Builtin::BIstdc_leading_zeros_ull:
17140 case Builtin::BI__builtin_stdc_leading_zeros:
17141 return Success(
APInt(ResBitWidth, Val.countl_zero()), E);
17142 case Builtin::BIstdc_leading_ones_uc:
17143 case Builtin::BIstdc_leading_ones_us:
17144 case Builtin::BIstdc_leading_ones_ui:
17145 case Builtin::BIstdc_leading_ones_ul:
17146 case Builtin::BIstdc_leading_ones_ull:
17147 case Builtin::BI__builtin_stdc_leading_ones:
17148 return Success(
APInt(ResBitWidth, Val.countl_one()), E);
17149 case Builtin::BIstdc_trailing_zeros_uc:
17150 case Builtin::BIstdc_trailing_zeros_us:
17151 case Builtin::BIstdc_trailing_zeros_ui:
17152 case Builtin::BIstdc_trailing_zeros_ul:
17153 case Builtin::BIstdc_trailing_zeros_ull:
17154 case Builtin::BI__builtin_stdc_trailing_zeros:
17155 return Success(
APInt(ResBitWidth, Val.countr_zero()), E);
17156 case Builtin::BIstdc_trailing_ones_uc:
17157 case Builtin::BIstdc_trailing_ones_us:
17158 case Builtin::BIstdc_trailing_ones_ui:
17159 case Builtin::BIstdc_trailing_ones_ul:
17160 case Builtin::BIstdc_trailing_ones_ull:
17161 case Builtin::BI__builtin_stdc_trailing_ones:
17162 return Success(
APInt(ResBitWidth, Val.countr_one()), E);
17163 case Builtin::BIstdc_first_leading_zero_uc:
17164 case Builtin::BIstdc_first_leading_zero_us:
17165 case Builtin::BIstdc_first_leading_zero_ui:
17166 case Builtin::BIstdc_first_leading_zero_ul:
17167 case Builtin::BIstdc_first_leading_zero_ull:
17168 case Builtin::BI__builtin_stdc_first_leading_zero:
17170 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
17171 case Builtin::BIstdc_first_leading_one_uc:
17172 case Builtin::BIstdc_first_leading_one_us:
17173 case Builtin::BIstdc_first_leading_one_ui:
17174 case Builtin::BIstdc_first_leading_one_ul:
17175 case Builtin::BIstdc_first_leading_one_ull:
17176 case Builtin::BI__builtin_stdc_first_leading_one:
17178 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
17179 case Builtin::BIstdc_first_trailing_zero_uc:
17180 case Builtin::BIstdc_first_trailing_zero_us:
17181 case Builtin::BIstdc_first_trailing_zero_ui:
17182 case Builtin::BIstdc_first_trailing_zero_ul:
17183 case Builtin::BIstdc_first_trailing_zero_ull:
17184 case Builtin::BI__builtin_stdc_first_trailing_zero:
17186 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
17187 case Builtin::BIstdc_first_trailing_one_uc:
17188 case Builtin::BIstdc_first_trailing_one_us:
17189 case Builtin::BIstdc_first_trailing_one_ui:
17190 case Builtin::BIstdc_first_trailing_one_ul:
17191 case Builtin::BIstdc_first_trailing_one_ull:
17192 case Builtin::BI__builtin_stdc_first_trailing_one:
17194 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
17195 case Builtin::BIstdc_count_zeros_uc:
17196 case Builtin::BIstdc_count_zeros_us:
17197 case Builtin::BIstdc_count_zeros_ui:
17198 case Builtin::BIstdc_count_zeros_ul:
17199 case Builtin::BIstdc_count_zeros_ull:
17200 case Builtin::BI__builtin_stdc_count_zeros: {
17201 APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
17204 case Builtin::BIstdc_count_ones_uc:
17205 case Builtin::BIstdc_count_ones_us:
17206 case Builtin::BIstdc_count_ones_ui:
17207 case Builtin::BIstdc_count_ones_ul:
17208 case Builtin::BIstdc_count_ones_ull:
17209 case Builtin::BI__builtin_stdc_count_ones: {
17210 APInt Cnt(ResBitWidth, Val.popcount());
17213 case Builtin::BIstdc_has_single_bit_uc:
17214 case Builtin::BIstdc_has_single_bit_us:
17215 case Builtin::BIstdc_has_single_bit_ui:
17216 case Builtin::BIstdc_has_single_bit_ul:
17217 case Builtin::BIstdc_has_single_bit_ull:
17218 case Builtin::BI__builtin_stdc_has_single_bit: {
17219 APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
17222 case Builtin::BIstdc_bit_width_uc:
17223 case Builtin::BIstdc_bit_width_us:
17224 case Builtin::BIstdc_bit_width_ui:
17225 case Builtin::BIstdc_bit_width_ul:
17226 case Builtin::BIstdc_bit_width_ull:
17227 case Builtin::BI__builtin_stdc_bit_width:
17228 return Success(
APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
17229 case Builtin::BIstdc_bit_floor_uc:
17230 case Builtin::BIstdc_bit_floor_us:
17231 case Builtin::BIstdc_bit_floor_ui:
17232 case Builtin::BIstdc_bit_floor_ul:
17233 case Builtin::BIstdc_bit_floor_ull:
17234 case Builtin::BI__builtin_stdc_bit_floor: {
17237 unsigned Exp = BitWidth - Val.countl_zero() - 1;
17239 APSInt(APInt::getOneBitSet(BitWidth, Exp),
true), E);
17241 case Builtin::BIstdc_bit_ceil_uc:
17242 case Builtin::BIstdc_bit_ceil_us:
17243 case Builtin::BIstdc_bit_ceil_ui:
17244 case Builtin::BIstdc_bit_ceil_ul:
17245 case Builtin::BIstdc_bit_ceil_ull:
17246 case Builtin::BI__builtin_stdc_bit_ceil: {
17249 APInt ValMinusOne = Val - 1;
17250 unsigned LZ = ValMinusOne.countl_zero();
17254 APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
17258 llvm_unreachable(
"Unknown stdc builtin");
17262 case Builtin::BI__builtin_elementwise_add_sat: {
17268 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
17271 case Builtin::BI__builtin_elementwise_sub_sat: {
17277 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
17280 case Builtin::BI__builtin_elementwise_max: {
17289 case Builtin::BI__builtin_elementwise_min: {
17298 case Builtin::BI__builtin_elementwise_clmul: {
17307 case Builtin::BI__builtin_elementwise_fshl:
17308 case Builtin::BI__builtin_elementwise_fshr: {
17315 switch (BuiltinOp) {
17316 case Builtin::BI__builtin_elementwise_fshl: {
17317 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
17320 case Builtin::BI__builtin_elementwise_fshr: {
17321 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
17325 llvm_unreachable(
"Fully covered switch above");
17327 case Builtin::BIstrlen:
17328 case Builtin::BIwcslen:
17330 if (Info.getLangOpts().CPlusPlus11)
17331 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17333 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17335 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17337 case Builtin::BI__builtin_strlen:
17338 case Builtin::BI__builtin_wcslen: {
17341 if (std::optional<uint64_t> StrLen =
17347 case Builtin::BIstrcmp:
17348 case Builtin::BIwcscmp:
17349 case Builtin::BIstrncmp:
17350 case Builtin::BIwcsncmp:
17351 case Builtin::BImemcmp:
17352 case Builtin::BIbcmp:
17353 case Builtin::BIwmemcmp:
17355 if (Info.getLangOpts().CPlusPlus11)
17356 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17358 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17360 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17362 case Builtin::BI__builtin_strcmp:
17363 case Builtin::BI__builtin_wcscmp:
17364 case Builtin::BI__builtin_strncmp:
17365 case Builtin::BI__builtin_wcsncmp:
17366 case Builtin::BI__builtin_memcmp:
17367 case Builtin::BI__builtin_bcmp:
17368 case Builtin::BI__builtin_wmemcmp: {
17369 LValue String1, String2;
17375 if (BuiltinOp != Builtin::BIstrcmp &&
17376 BuiltinOp != Builtin::BIwcscmp &&
17377 BuiltinOp != Builtin::BI__builtin_strcmp &&
17378 BuiltinOp != Builtin::BI__builtin_wcscmp) {
17382 MaxLength = N.getZExtValue();
17386 if (MaxLength == 0u)
17389 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17390 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17391 String1.Designator.Invalid || String2.Designator.Invalid)
17394 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
17395 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
17397 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
17398 BuiltinOp == Builtin::BIbcmp ||
17399 BuiltinOp == Builtin::BI__builtin_memcmp ||
17400 BuiltinOp == Builtin::BI__builtin_bcmp;
17402 assert(IsRawByte ||
17403 (Info.Ctx.hasSameUnqualifiedType(
17405 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
17412 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
17413 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
17418 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
17421 Char1.
isInt() && Char2.isInt();
17423 const auto &AdvanceElems = [&] {
17429 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
17430 BuiltinOp != Builtin::BIwmemcmp &&
17431 BuiltinOp != Builtin::BI__builtin_memcmp &&
17432 BuiltinOp != Builtin::BI__builtin_bcmp &&
17433 BuiltinOp != Builtin::BI__builtin_wmemcmp);
17434 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
17435 BuiltinOp == Builtin::BIwcsncmp ||
17436 BuiltinOp == Builtin::BIwmemcmp ||
17437 BuiltinOp == Builtin::BI__builtin_wcscmp ||
17438 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
17439 BuiltinOp == Builtin::BI__builtin_wmemcmp;
17441 for (; MaxLength; --MaxLength) {
17443 if (!ReadCurElems(Char1, Char2))
17451 if (StopAtNull && !Char1.
getInt())
17453 assert(!(StopAtNull && !Char2.
getInt()));
17454 if (!AdvanceElems())
17461 case Builtin::BI__atomic_always_lock_free:
17462 case Builtin::BI__atomic_is_lock_free:
17463 case Builtin::BI__c11_atomic_is_lock_free: {
17479 if (
Size.isPowerOfTwo()) {
17481 unsigned InlineWidthBits =
17482 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
17483 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
17484 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
17490 const Expr *PtrArg = E->
getArg(1);
17496 IntResult.isAligned(
Size.getAsAlign()))
17500 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
17503 if (ICE->getCastKind() == CK_BitCast)
17504 PtrArg = ICE->getSubExpr();
17507 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
17510 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
17518 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
17521 case Builtin::BI__builtin_addcb:
17522 case Builtin::BI__builtin_addcs:
17523 case Builtin::BI__builtin_addc:
17524 case Builtin::BI__builtin_addcl:
17525 case Builtin::BI__builtin_addcll:
17526 case Builtin::BI__builtin_subcb:
17527 case Builtin::BI__builtin_subcs:
17528 case Builtin::BI__builtin_subc:
17529 case Builtin::BI__builtin_subcl:
17530 case Builtin::BI__builtin_subcll: {
17531 LValue CarryOutLValue;
17543 bool FirstOverflowed =
false;
17544 bool SecondOverflowed =
false;
17545 switch (BuiltinOp) {
17547 llvm_unreachable(
"Invalid value for BuiltinOp");
17548 case Builtin::BI__builtin_addcb:
17549 case Builtin::BI__builtin_addcs:
17550 case Builtin::BI__builtin_addc:
17551 case Builtin::BI__builtin_addcl:
17552 case Builtin::BI__builtin_addcll:
17554 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
17556 case Builtin::BI__builtin_subcb:
17557 case Builtin::BI__builtin_subcs:
17558 case Builtin::BI__builtin_subc:
17559 case Builtin::BI__builtin_subcl:
17560 case Builtin::BI__builtin_subcll:
17562 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
17568 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
17574 case Builtin::BI__builtin_add_overflow:
17575 case Builtin::BI__builtin_sub_overflow:
17576 case Builtin::BI__builtin_mul_overflow:
17577 case Builtin::BI__builtin_sadd_overflow:
17578 case Builtin::BI__builtin_uadd_overflow:
17579 case Builtin::BI__builtin_uaddl_overflow:
17580 case Builtin::BI__builtin_uaddll_overflow:
17581 case Builtin::BI__builtin_usub_overflow:
17582 case Builtin::BI__builtin_usubl_overflow:
17583 case Builtin::BI__builtin_usubll_overflow:
17584 case Builtin::BI__builtin_umul_overflow:
17585 case Builtin::BI__builtin_umull_overflow:
17586 case Builtin::BI__builtin_umulll_overflow:
17587 case Builtin::BI__builtin_saddl_overflow:
17588 case Builtin::BI__builtin_saddll_overflow:
17589 case Builtin::BI__builtin_ssub_overflow:
17590 case Builtin::BI__builtin_ssubl_overflow:
17591 case Builtin::BI__builtin_ssubll_overflow:
17592 case Builtin::BI__builtin_smul_overflow:
17593 case Builtin::BI__builtin_smull_overflow:
17594 case Builtin::BI__builtin_smulll_overflow: {
17595 LValue ResultLValue;
17605 bool DidOverflow =
false;
17608 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17609 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17610 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17611 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
17613 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
17615 uint64_t LHSSize = LHS.getBitWidth();
17616 uint64_t RHSSize = RHS.getBitWidth();
17617 uint64_t ResultSize = Info.Ctx.getIntWidth(ResultType);
17618 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
17624 if (IsSigned && !AllSigned)
17627 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
17628 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
17633 switch (BuiltinOp) {
17635 llvm_unreachable(
"Invalid value for BuiltinOp");
17636 case Builtin::BI__builtin_add_overflow:
17637 case Builtin::BI__builtin_sadd_overflow:
17638 case Builtin::BI__builtin_saddl_overflow:
17639 case Builtin::BI__builtin_saddll_overflow:
17640 case Builtin::BI__builtin_uadd_overflow:
17641 case Builtin::BI__builtin_uaddl_overflow:
17642 case Builtin::BI__builtin_uaddll_overflow:
17643 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
17644 : LHS.uadd_ov(RHS, DidOverflow);
17646 case Builtin::BI__builtin_sub_overflow:
17647 case Builtin::BI__builtin_ssub_overflow:
17648 case Builtin::BI__builtin_ssubl_overflow:
17649 case Builtin::BI__builtin_ssubll_overflow:
17650 case Builtin::BI__builtin_usub_overflow:
17651 case Builtin::BI__builtin_usubl_overflow:
17652 case Builtin::BI__builtin_usubll_overflow:
17653 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
17654 : LHS.usub_ov(RHS, DidOverflow);
17656 case Builtin::BI__builtin_mul_overflow:
17657 case Builtin::BI__builtin_smul_overflow:
17658 case Builtin::BI__builtin_smull_overflow:
17659 case Builtin::BI__builtin_smulll_overflow:
17660 case Builtin::BI__builtin_umul_overflow:
17661 case Builtin::BI__builtin_umull_overflow:
17662 case Builtin::BI__builtin_umulll_overflow:
17663 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
17664 : LHS.umul_ov(RHS, DidOverflow);
17673 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getIntWidth(ResultType));
17678 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17679 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17680 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17681 if (!APSInt::isSameValue(Temp,
Result))
17682 DidOverflow =
true;
17689 return Success(DidOverflow, E);
17692 case Builtin::BI__builtin_reduce_add:
17693 case Builtin::BI__builtin_reduce_mul:
17694 case Builtin::BI__builtin_reduce_and:
17695 case Builtin::BI__builtin_reduce_or:
17696 case Builtin::BI__builtin_reduce_xor:
17697 case Builtin::BI__builtin_reduce_min:
17698 case Builtin::BI__builtin_reduce_max: {
17705 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
17706 switch (BuiltinOp) {
17709 case Builtin::BI__builtin_reduce_add: {
17712 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
17716 case Builtin::BI__builtin_reduce_mul: {
17719 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
17723 case Builtin::BI__builtin_reduce_and: {
17727 case Builtin::BI__builtin_reduce_or: {
17731 case Builtin::BI__builtin_reduce_xor: {
17735 case Builtin::BI__builtin_reduce_min: {
17739 case Builtin::BI__builtin_reduce_max: {
17749 case clang::X86::BI__builtin_ia32_addcarryx_u32:
17750 case clang::X86::BI__builtin_ia32_addcarryx_u64:
17751 case clang::X86::BI__builtin_ia32_subborrow_u32:
17752 case clang::X86::BI__builtin_ia32_subborrow_u64: {
17753 LValue ResultLValue;
17754 APSInt CarryIn, LHS, RHS;
17762 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
17763 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
17765 unsigned BitWidth = LHS.getBitWidth();
17766 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
17769 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
17770 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
17772 APInt Result = ExResult.extractBits(BitWidth, 0);
17773 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
17781 case clang::X86::BI__builtin_ia32_movmskps:
17782 case clang::X86::BI__builtin_ia32_movmskpd:
17783 case clang::X86::BI__builtin_ia32_pmovmskb128:
17784 case clang::X86::BI__builtin_ia32_pmovmskb256:
17785 case clang::X86::BI__builtin_ia32_movmskps256:
17786 case clang::X86::BI__builtin_ia32_movmskpd256: {
17793 unsigned ResultLen = Info.Ctx.getTypeSize(
17797 for (
unsigned I = 0; I != SourceLen; ++I) {
17799 if (ElemQT->isIntegerType()) {
17801 }
else if (ElemQT->isRealFloatingType()) {
17806 Result.setBitVal(I, Elem.isNegative());
17811 case clang::X86::BI__builtin_ia32_bextr_u32:
17812 case clang::X86::BI__builtin_ia32_bextr_u64:
17813 case clang::X86::BI__builtin_ia32_bextri_u32:
17814 case clang::X86::BI__builtin_ia32_bextri_u64: {
17820 unsigned BitWidth = Val.getBitWidth();
17822 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
17823 Length = Length > BitWidth ? BitWidth : Length;
17826 if (Length == 0 || Shift >= BitWidth)
17830 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
17834 case clang::X86::BI__builtin_ia32_bzhi_si:
17835 case clang::X86::BI__builtin_ia32_bzhi_di: {
17841 unsigned BitWidth = Val.getBitWidth();
17842 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
17843 if (Index < BitWidth)
17844 Val.clearHighBits(BitWidth - Index);
17848 case clang::X86::BI__builtin_ia32_ktestcqi:
17849 case clang::X86::BI__builtin_ia32_ktestchi:
17850 case clang::X86::BI__builtin_ia32_ktestcsi:
17851 case clang::X86::BI__builtin_ia32_ktestcdi: {
17857 return Success((~A & B) == 0, E);
17860 case clang::X86::BI__builtin_ia32_ktestzqi:
17861 case clang::X86::BI__builtin_ia32_ktestzhi:
17862 case clang::X86::BI__builtin_ia32_ktestzsi:
17863 case clang::X86::BI__builtin_ia32_ktestzdi: {
17869 return Success((A & B) == 0, E);
17872 case clang::X86::BI__builtin_ia32_kortestcqi:
17873 case clang::X86::BI__builtin_ia32_kortestchi:
17874 case clang::X86::BI__builtin_ia32_kortestcsi:
17875 case clang::X86::BI__builtin_ia32_kortestcdi: {
17881 return Success(~(A | B) == 0, E);
17884 case clang::X86::BI__builtin_ia32_kortestzqi:
17885 case clang::X86::BI__builtin_ia32_kortestzhi:
17886 case clang::X86::BI__builtin_ia32_kortestzsi:
17887 case clang::X86::BI__builtin_ia32_kortestzdi: {
17893 return Success((A | B) == 0, E);
17896 case clang::X86::BI__builtin_ia32_kunpckhi:
17897 case clang::X86::BI__builtin_ia32_kunpckdi:
17898 case clang::X86::BI__builtin_ia32_kunpcksi: {
17906 unsigned BW = A.getBitWidth();
17907 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
17911 case clang::X86::BI__builtin_ia32_lzcnt_u16:
17912 case clang::X86::BI__builtin_ia32_lzcnt_u32:
17913 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
17917 return Success(Val.countLeadingZeros(), E);
17920 case clang::X86::BI__builtin_ia32_tzcnt_u16:
17921 case clang::X86::BI__builtin_ia32_tzcnt_u32:
17922 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
17926 return Success(Val.countTrailingZeros(), E);
17929 case clang::X86::BI__builtin_ia32_pdep_si:
17930 case clang::X86::BI__builtin_ia32_pdep_di:
17931 case Builtin::BI__builtin_elementwise_pdep: {
17936 return Success(llvm::APIntOps::expandBits(Val, Msk), E);
17939 case clang::X86::BI__builtin_ia32_pext_si:
17940 case clang::X86::BI__builtin_ia32_pext_di:
17941 case Builtin::BI__builtin_elementwise_pext: {
17946 return Success(llvm::APIntOps::compressBits(Val, Msk), E);
17948 case X86::BI__builtin_ia32_ptestz128:
17949 case X86::BI__builtin_ia32_ptestz256:
17950 case X86::BI__builtin_ia32_vtestzps:
17951 case X86::BI__builtin_ia32_vtestzps256:
17952 case X86::BI__builtin_ia32_vtestzpd:
17953 case X86::BI__builtin_ia32_vtestzpd256: {
17955 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
17957 case X86::BI__builtin_ia32_ptestc128:
17958 case X86::BI__builtin_ia32_ptestc256:
17959 case X86::BI__builtin_ia32_vtestcps:
17960 case X86::BI__builtin_ia32_vtestcps256:
17961 case X86::BI__builtin_ia32_vtestcpd:
17962 case X86::BI__builtin_ia32_vtestcpd256: {
17964 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
17966 case X86::BI__builtin_ia32_ptestnzc128:
17967 case X86::BI__builtin_ia32_ptestnzc256:
17968 case X86::BI__builtin_ia32_vtestnzcps:
17969 case X86::BI__builtin_ia32_vtestnzcps256:
17970 case X86::BI__builtin_ia32_vtestnzcpd:
17971 case X86::BI__builtin_ia32_vtestnzcpd256: {
17972 return EvalTestOp([](
const APInt &A,
const APInt &B) {
17973 return ((A & B) != 0) && ((~A & B) != 0);
17976 case X86::BI__builtin_ia32_kandqi:
17977 case X86::BI__builtin_ia32_kandhi:
17978 case X86::BI__builtin_ia32_kandsi:
17979 case X86::BI__builtin_ia32_kanddi: {
17980 return HandleMaskBinOp(
17981 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
17984 case X86::BI__builtin_ia32_kandnqi:
17985 case X86::BI__builtin_ia32_kandnhi:
17986 case X86::BI__builtin_ia32_kandnsi:
17987 case X86::BI__builtin_ia32_kandndi: {
17988 return HandleMaskBinOp(
17989 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
17992 case X86::BI__builtin_ia32_korqi:
17993 case X86::BI__builtin_ia32_korhi:
17994 case X86::BI__builtin_ia32_korsi:
17995 case X86::BI__builtin_ia32_kordi: {
17996 return HandleMaskBinOp(
17997 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
18000 case X86::BI__builtin_ia32_kxnorqi:
18001 case X86::BI__builtin_ia32_kxnorhi:
18002 case X86::BI__builtin_ia32_kxnorsi:
18003 case X86::BI__builtin_ia32_kxnordi: {
18004 return HandleMaskBinOp(
18005 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
18008 case X86::BI__builtin_ia32_kxorqi:
18009 case X86::BI__builtin_ia32_kxorhi:
18010 case X86::BI__builtin_ia32_kxorsi:
18011 case X86::BI__builtin_ia32_kxordi: {
18012 return HandleMaskBinOp(
18013 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
18016 case X86::BI__builtin_ia32_knotqi:
18017 case X86::BI__builtin_ia32_knothi:
18018 case X86::BI__builtin_ia32_knotsi:
18019 case X86::BI__builtin_ia32_knotdi: {
18027 case X86::BI__builtin_ia32_kaddqi:
18028 case X86::BI__builtin_ia32_kaddhi:
18029 case X86::BI__builtin_ia32_kaddsi:
18030 case X86::BI__builtin_ia32_kadddi: {
18031 return HandleMaskBinOp(
18032 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
18035 case X86::BI__builtin_ia32_kmovb:
18036 case X86::BI__builtin_ia32_kmovw:
18037 case X86::BI__builtin_ia32_kmovd:
18038 case X86::BI__builtin_ia32_kmovq: {
18045 case X86::BI__builtin_ia32_kshiftliqi:
18046 case X86::BI__builtin_ia32_kshiftlihi:
18047 case X86::BI__builtin_ia32_kshiftlisi:
18048 case X86::BI__builtin_ia32_kshiftlidi: {
18049 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18050 unsigned Amt = RHS.getZExtValue() & 0xFF;
18051 if (Amt >= LHS.getBitWidth())
18052 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18053 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
18057 case X86::BI__builtin_ia32_kshiftriqi:
18058 case X86::BI__builtin_ia32_kshiftrihi:
18059 case X86::BI__builtin_ia32_kshiftrisi:
18060 case X86::BI__builtin_ia32_kshiftridi: {
18061 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18062 unsigned Amt = RHS.getZExtValue() & 0xFF;
18063 if (Amt >= LHS.getBitWidth())
18064 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18065 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
18069 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
18070 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
18071 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
18072 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
18073 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
18074 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
18075 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
18076 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
18077 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
18084 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18088 case clang::X86::BI__builtin_ia32_cvtb2mask128:
18089 case clang::X86::BI__builtin_ia32_cvtb2mask256:
18090 case clang::X86::BI__builtin_ia32_cvtb2mask512:
18091 case clang::X86::BI__builtin_ia32_cvtw2mask128:
18092 case clang::X86::BI__builtin_ia32_cvtw2mask256:
18093 case clang::X86::BI__builtin_ia32_cvtw2mask512:
18094 case clang::X86::BI__builtin_ia32_cvtd2mask128:
18095 case clang::X86::BI__builtin_ia32_cvtd2mask256:
18096 case clang::X86::BI__builtin_ia32_cvtd2mask512:
18097 case clang::X86::BI__builtin_ia32_cvtq2mask128:
18098 case clang::X86::BI__builtin_ia32_cvtq2mask256:
18099 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
18106 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
18107 llvm::APInt Bits(RetWidth, 0);
18109 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
18111 unsigned MSB = A[A.getBitWidth() - 1];
18112 Bits.setBitVal(ElemNum, MSB);
18115 APSInt RetMask(Bits,
true);
18119 case clang::X86::BI__builtin_ia32_cmpb128_mask:
18120 case clang::X86::BI__builtin_ia32_cmpw128_mask:
18121 case clang::X86::BI__builtin_ia32_cmpd128_mask:
18122 case clang::X86::BI__builtin_ia32_cmpq128_mask:
18123 case clang::X86::BI__builtin_ia32_cmpb256_mask:
18124 case clang::X86::BI__builtin_ia32_cmpw256_mask:
18125 case clang::X86::BI__builtin_ia32_cmpd256_mask:
18126 case clang::X86::BI__builtin_ia32_cmpq256_mask:
18127 case clang::X86::BI__builtin_ia32_cmpb512_mask:
18128 case clang::X86::BI__builtin_ia32_cmpw512_mask:
18129 case clang::X86::BI__builtin_ia32_cmpd512_mask:
18130 case clang::X86::BI__builtin_ia32_cmpq512_mask:
18131 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
18132 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
18133 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
18134 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
18135 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
18136 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
18137 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
18138 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
18139 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
18140 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
18141 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
18142 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
18146 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
18147 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
18160 unsigned RetWidth = Mask.getBitWidth();
18162 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18164 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
18169 switch (
Opcode.getExtValue() & 0x7) {
18174 Result = IsUnsigned ? A.ult(B) : A.slt(B);
18177 Result = IsUnsigned ? A.ule(B) : A.sle(B);
18186 Result = IsUnsigned ? A.uge(B) : A.sge(B);
18189 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
18196 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
18201 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
18202 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
18203 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
18216 unsigned NumBytesInQWord = 8;
18217 unsigned NumBitsInByte = 8;
18219 unsigned NumQWords = NumBytes / NumBytesInQWord;
18220 unsigned RetWidth = ZeroMask.getBitWidth();
18221 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18223 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
18224 APInt SourceQWord(64, 0);
18225 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18229 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
18232 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18233 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
18236 if (ZeroMask[SelIdx]) {
18237 RetMask.setBitVal(SelIdx, SourceQWord[M]);
18249 const LValue &LV) {
18252 if (!LV.getLValueBase())
18257 if (!LV.getLValueDesignator().Invalid &&
18258 !LV.getLValueDesignator().isOnePastTheEnd())
18268 if (LV.getLValueDesignator().Invalid)
18274 return LV.getLValueOffset() == Size;
18284class DataRecursiveIntBinOpEvaluator {
18285 struct EvalResult {
18287 bool Failed =
false;
18289 EvalResult() =
default;
18291 void swap(EvalResult &RHS) {
18293 Failed = RHS.Failed;
18294 RHS.Failed =
false;
18300 EvalResult LHSResult;
18301 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
18304 Job(Job &&) =
default;
18306 void startSpeculativeEval(EvalInfo &Info) {
18307 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
18311 SpeculativeEvaluationRAII SpecEvalRAII;
18314 SmallVector<Job, 16> Queue;
18316 IntExprEvaluator &IntEval;
18321 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
18322 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
18328 static bool shouldEnqueue(
const BinaryOperator *E) {
18335 bool Traverse(
const BinaryOperator *E) {
18337 EvalResult PrevResult;
18338 while (!Queue.empty())
18339 process(PrevResult);
18341 if (PrevResult.Failed)
return false;
18343 FinalResult.
swap(PrevResult.Val);
18354 bool Error(
const Expr *E) {
18355 return IntEval.Error(E);
18358 return IntEval.Error(E, D);
18361 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
18362 return Info.CCEDiag(E, D);
18366 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18367 bool &SuppressRHSDiags);
18369 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18372 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
18378 void process(EvalResult &
Result);
18380 void enqueue(
const Expr *E) {
18382 Queue.resize(Queue.size()+1);
18383 Queue.back().E = E;
18384 Queue.back().Kind = Job::AnyExprKind;
18390bool DataRecursiveIntBinOpEvaluator::
18391 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18392 bool &SuppressRHSDiags) {
18395 if (LHSResult.Failed)
18396 return Info.noteSideEffect();
18405 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
18406 Success(LHSAsBool, E, LHSResult.Val);
18410 LHSResult.Failed =
true;
18414 if (!Info.noteSideEffect())
18420 SuppressRHSDiags =
true;
18429 if (LHSResult.Failed && !Info.noteFailure())
18440 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
18442 uint64_t Offset64 = Offset.getQuantity();
18443 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
18445 : Offset64 + Index64);
18448bool DataRecursiveIntBinOpEvaluator::
18449 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18452 if (RHSResult.Failed)
18459 bool lhsResult, rhsResult;
18474 if (rhsResult == (E->
getOpcode() == BO_LOr))
18485 if (LHSResult.Failed || RHSResult.Failed)
18488 const APValue &LHSVal = LHSResult.Val;
18489 const APValue &RHSVal = RHSResult.Val;
18513 if (!LHSExpr || !RHSExpr)
18515 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
18516 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
18517 if (!LHSAddrExpr || !RHSAddrExpr)
18542void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
18543 Job &job = Queue.back();
18545 switch (job.Kind) {
18546 case Job::AnyExprKind: {
18547 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
18548 if (shouldEnqueue(Bop)) {
18549 job.Kind = Job::BinOpKind;
18550 enqueue(Bop->getLHS());
18555 EvaluateExpr(job.E,
Result);
18560 case Job::BinOpKind: {
18562 bool SuppressRHSDiags =
false;
18563 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
18567 if (SuppressRHSDiags)
18568 job.startSpeculativeEval(Info);
18569 job.LHSResult.swap(
Result);
18570 job.Kind = Job::BinOpVisitedLHSKind;
18575 case Job::BinOpVisitedLHSKind: {
18579 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
18585 llvm_unreachable(
"Invalid Job::Kind!");
18589enum class CmpResult {
18598template <
class SuccessCB,
class AfterCB>
18601 SuccessCB &&
Success, AfterCB &&DoAfter) {
18606 "unsupported binary expression evaluation");
18608 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
18622 if (!LHSOK && !Info.noteFailure())
18627 return Success(CmpResult::Less, E);
18629 return Success(CmpResult::Greater, E);
18630 return Success(CmpResult::Equal, E);
18634 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
18635 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
18638 if (!LHSOK && !Info.noteFailure())
18643 return Success(CmpResult::Less, E);
18645 return Success(CmpResult::Greater, E);
18646 return Success(CmpResult::Equal, E);
18650 ComplexValue LHS, RHS;
18659 LHS.makeComplexFloat();
18660 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
18665 if (!LHSOK && !Info.noteFailure())
18671 RHS.makeComplexFloat();
18672 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
18676 if (LHS.isComplexFloat()) {
18677 APFloat::cmpResult CR_r =
18678 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
18679 APFloat::cmpResult CR_i =
18680 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
18681 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
18682 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18684 assert(IsEquality &&
"invalid complex comparison");
18685 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
18686 LHS.getComplexIntImag() == RHS.getComplexIntImag();
18687 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18693 APFloat RHS(0.0), LHS(0.0);
18696 if (!LHSOK && !Info.noteFailure())
18703 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
18704 if (!Info.InConstantContext &&
18705 APFloatCmpResult == APFloat::cmpUnordered &&
18708 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
18711 auto GetCmpRes = [&]() {
18712 switch (APFloatCmpResult) {
18713 case APFloat::cmpEqual:
18714 return CmpResult::Equal;
18715 case APFloat::cmpLessThan:
18716 return CmpResult::Less;
18717 case APFloat::cmpGreaterThan:
18718 return CmpResult::Greater;
18719 case APFloat::cmpUnordered:
18720 return CmpResult::Unordered;
18722 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
18724 return Success(GetCmpRes(), E);
18728 LValue LHSValue, RHSValue;
18731 if (!LHSOK && !Info.noteFailure())
18742 if (Info.checkingPotentialConstantExpression() &&
18743 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
18745 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
18746 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
18747 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
18748 Info.FFDiag(E, DiagID)
18755 return DiagComparison(
18756 diag::note_constexpr_pointer_comparison_unspecified);
18762 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
18763 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
18764 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
18778 return DiagComparison(diag::note_constexpr_literal_comparison);
18780 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
18785 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
18789 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
18791 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18793 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
18795 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18801 return DiagComparison(
18802 diag::note_constexpr_pointer_comparison_zero_sized);
18803 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
18804 return DiagComparison(
18805 diag::note_constexpr_pointer_comparison_unspecified);
18807 return Success(CmpResult::Unequal, E);
18810 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
18811 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
18813 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
18814 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
18824 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
18825 bool WasArrayIndex;
18828 :
getType(LHSValue.Base).getNonReferenceType(),
18829 LHSDesignator, RHSDesignator, WasArrayIndex);
18836 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
18837 Mismatch < RHSDesignator.Entries.size()) {
18838 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
18839 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
18841 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
18843 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18844 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
18847 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18848 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
18853 diag::note_constexpr_pointer_comparison_differing_access)
18861 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
18864 assert(PtrSize <= 64 &&
"Unexpected pointer width");
18865 uint64_t Mask = ~0ULL >> (64 - PtrSize);
18866 CompareLHS &= Mask;
18867 CompareRHS &= Mask;
18872 if (!LHSValue.Base.
isNull() && IsRelational) {
18876 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
18877 uint64_t OffsetLimit = Size.getQuantity();
18878 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
18882 if (CompareLHS < CompareRHS)
18883 return Success(CmpResult::Less, E);
18884 if (CompareLHS > CompareRHS)
18885 return Success(CmpResult::Greater, E);
18886 return Success(CmpResult::Equal, E);
18890 assert(IsEquality &&
"unexpected member pointer operation");
18893 MemberPtr LHSValue, RHSValue;
18896 if (!LHSOK && !Info.noteFailure())
18904 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
18905 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18906 << LHSValue.getDecl();
18909 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
18910 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18911 << RHSValue.getDecl();
18918 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
18919 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
18920 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18925 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
18926 if (MD->isVirtual())
18927 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18928 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
18929 if (MD->isVirtual())
18930 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18936 bool Equal = LHSValue == RHSValue;
18937 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18942 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
18950 return Success(CmpResult::Equal, E);
18956bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
18960 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18963 case CmpResult::Unequal:
18964 llvm_unreachable(
"should never produce Unequal for three-way comparison");
18965 case CmpResult::Less:
18966 CCR = ComparisonCategoryResult::Less;
18968 case CmpResult::Equal:
18969 CCR = ComparisonCategoryResult::Equal;
18971 case CmpResult::Greater:
18972 CCR = ComparisonCategoryResult::Greater;
18974 case CmpResult::Unordered:
18975 CCR = ComparisonCategoryResult::Unordered;
18980 const ComparisonCategoryInfo &CmpInfo =
18981 Info.Ctx.CompCategories.getInfoForType(E->
getType());
18989 ConstantExprKind::Normal);
18992 return ExprEvaluatorBaseTy::VisitBinCmp(E);
18996bool RecordExprEvaluator::VisitCXXParenListInitExpr(
18997 const CXXParenListInitExpr *E) {
18998 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
19001bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19006 if (!Info.noteFailure())
19010 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
19011 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
19015 "DataRecursiveIntBinOpEvaluator should have handled integral types");
19020 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19021 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
19022 "should only produce Unequal for equality comparisons");
19023 bool IsEqual = CR == CmpResult::Equal,
19024 IsLess = CR == CmpResult::Less,
19025 IsGreater = CR == CmpResult::Greater;
19029 llvm_unreachable(
"unsupported binary operator");
19032 return Success(IsEqual == (Op == BO_EQ), E);
19036 return Success(IsGreater, E);
19038 return Success(IsEqual || IsLess, E);
19040 return Success(IsEqual || IsGreater, E);
19044 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19053 LValue LHSValue, RHSValue;
19056 if (!LHSOK && !Info.noteFailure())
19065 if (Info.checkingPotentialConstantExpression() &&
19066 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19069 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
19070 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
19072 auto DiagArith = [&](
unsigned DiagID) {
19073 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19074 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19075 Info.FFDiag(E, DiagID) << LHS << RHS;
19076 if (LHSExpr && LHSExpr == RHSExpr)
19078 diag::note_constexpr_repeated_literal_eval)
19083 if (!LHSExpr || !RHSExpr)
19084 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
19087 return DiagArith(diag::note_constexpr_literal_arith);
19089 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19090 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19091 if (!LHSAddrExpr || !RHSAddrExpr)
19099 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19100 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19102 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19103 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19109 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
19112 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
19117 CharUnits ElementSize;
19124 if (ElementSize.
isZero()) {
19125 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
19142 APSInt TrueResult = (LHS - RHS) / ElemSize;
19145 if (
Result.extend(65) != TrueResult &&
19151 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19156bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
19157 const UnaryExprOrTypeTraitExpr *E) {
19159 case UETT_PreferredAlignOf:
19160 case UETT_AlignOf: {
19169 case UETT_PtrAuthTypeDiscriminator: {
19175 case UETT_VecStep: {
19179 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
19191 case UETT_DataSizeOf:
19192 case UETT_SizeOf: {
19196 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
19207 case UETT_OpenMPRequiredSimdAlign:
19210 Info.Ctx.toCharUnitsFromBits(
19214 case UETT_VectorElements: {
19218 if (
const auto *VT = Ty->
getAs<VectorType>())
19222 if (Info.InConstantContext)
19223 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
19228 case UETT_CountOf: {
19234 if (
const auto *CAT =
19244 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
19246 if (VAT->getElementType()->isArrayType()) {
19249 if (!VAT->getSizeExpr()) {
19254 std::optional<APSInt> Res =
19255 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
19260 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
19261 Res->getZExtValue()};
19273 llvm_unreachable(
"unknown expr/type trait");
19276bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
19277 Info.Ctx.recordOffsetOfEvaluation(OOE);
19283 for (
unsigned i = 0; i != n; ++i) {
19291 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
19295 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
19296 Result += IdxResult.getSExtValue() * ElementSize;
19301 FieldDecl *MemberDecl = ON.
getField();
19306 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19308 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
19315 llvm_unreachable(
"dependent __builtin_offsetof");
19318 CXXBaseSpecifier *BaseSpec = ON.
getBase();
19327 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19330 CurrentType = BaseSpec->
getType();
19344bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19364 if (Info.checkingForUndefinedBehavior())
19365 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19366 diag::warn_integer_constant_overflow)
19394bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19396 QualType DestType = E->
getType();
19397 QualType SrcType = SubExpr->
getType();
19400 case CK_BaseToDerived:
19401 case CK_DerivedToBase:
19402 case CK_UncheckedDerivedToBase:
19405 case CK_ArrayToPointerDecay:
19406 case CK_FunctionToPointerDecay:
19407 case CK_NullToPointer:
19408 case CK_NullToMemberPointer:
19409 case CK_BaseToDerivedMemberPointer:
19410 case CK_DerivedToBaseMemberPointer:
19411 case CK_ReinterpretMemberPointer:
19412 case CK_ConstructorConversion:
19413 case CK_IntegralToPointer:
19415 case CK_VectorSplat:
19416 case CK_IntegralToFloating:
19417 case CK_FloatingCast:
19418 case CK_CPointerToObjCPointerCast:
19419 case CK_BlockPointerToObjCPointerCast:
19420 case CK_AnyPointerToBlockPointerCast:
19421 case CK_ObjCObjectLValueCast:
19422 case CK_FloatingRealToComplex:
19423 case CK_FloatingComplexToReal:
19424 case CK_FloatingComplexCast:
19425 case CK_FloatingComplexToIntegralComplex:
19426 case CK_IntegralRealToComplex:
19427 case CK_IntegralComplexCast:
19428 case CK_IntegralComplexToFloatingComplex:
19429 case CK_BuiltinFnToFnPtr:
19430 case CK_ZeroToOCLOpaqueType:
19431 case CK_NonAtomicToAtomic:
19432 case CK_AddressSpaceConversion:
19433 case CK_IntToOCLSampler:
19434 case CK_FloatingToFixedPoint:
19435 case CK_FixedPointToFloating:
19436 case CK_FixedPointCast:
19437 case CK_IntegralToFixedPoint:
19438 case CK_MatrixCast:
19439 case CK_HLSLAggregateSplatCast:
19440 llvm_unreachable(
"invalid cast kind for integral value");
19444 case CK_LValueBitCast:
19445 case CK_ARCProduceObject:
19446 case CK_ARCConsumeObject:
19447 case CK_ARCReclaimReturnedObject:
19448 case CK_ARCExtendBlockObject:
19449 case CK_CopyAndAutoreleaseBlockObject:
19452 case CK_UserDefinedConversion:
19453 case CK_LValueToRValue:
19454 case CK_AtomicToNonAtomic:
19456 case CK_LValueToRValueBitCast:
19457 case CK_HLSLArrayRValue:
19458 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19460 case CK_MemberPointerToBoolean:
19461 case CK_PointerToBoolean:
19462 case CK_IntegralToBoolean:
19463 case CK_FloatingToBoolean:
19464 case CK_BooleanToSignedIntegral:
19465 case CK_FloatingComplexToBoolean:
19466 case CK_IntegralComplexToBoolean: {
19471 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
19473 return Success(IntResult, E);
19476 case CK_FixedPointToIntegral: {
19477 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
19481 llvm::APSInt
Result = Src.convertToInt(
19482 Info.Ctx.getIntWidth(DestType),
19489 case CK_FixedPointToBoolean: {
19492 if (!
Evaluate(Val, Info, SubExpr))
19497 case CK_IntegralCast: {
19498 if (!Visit(SubExpr))
19508 if (
Result.isAddrLabelDiff()) {
19509 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
19510 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
19513 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
19516 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
19528 if (!ED->isFixed()) {
19532 ED->getValueRange(
Max,
Min);
19535 if (ED->getNumNegativeBits() &&
19536 (
Max.slt(
Result.getInt().getSExtValue()) ||
19537 Min.sgt(
Result.getInt().getSExtValue())))
19538 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19539 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
19540 <<
Max.getSExtValue() << ED;
19541 else if (!ED->getNumNegativeBits() &&
19542 Max.ult(
Result.getInt().getZExtValue()))
19543 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19544 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
19545 <<
Max.getZExtValue() << ED;
19553 case CK_PointerToIntegral: {
19554 CCEDiag(E, diag::note_constexpr_invalid_cast)
19555 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
19562 if (LV.getLValueBase()) {
19567 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
19570 LV.Designator.setInvalid();
19578 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
19579 llvm_unreachable(
"Can't cast this!");
19584 case CK_IntegralComplexToReal: {
19588 return Success(
C.getComplexIntReal(), E);
19591 case CK_FloatingToIntegral: {
19601 case CK_HLSLVectorTruncation: {
19607 case CK_HLSLMatrixTruncation: {
19613 case CK_HLSLElementwiseCast: {
19626 return Success(ResultVal, E);
19630 llvm_unreachable(
"unknown cast resulting in integral value");
19633bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
19638 if (!LV.isComplexInt())
19640 return Success(LV.getComplexIntReal(), E);
19646bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
19651 if (!LV.isComplexInt())
19653 return Success(LV.getComplexIntImag(), E);
19660bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
19664bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
19668bool IntExprEvaluator::VisitConceptSpecializationExpr(
19669 const ConceptSpecializationExpr *E) {
19673bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
19677bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19687 if (!
Result.isFixedPoint())
19690 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
19704bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19706 QualType DestType = E->
getType();
19708 "Expected destination type to be a fixed point type");
19709 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
19712 case CK_FixedPointCast: {
19713 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
19717 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
19719 if (Info.checkingForUndefinedBehavior())
19720 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19721 diag::warn_fixedpoint_constant_overflow)
19728 case CK_IntegralToFixedPoint: {
19734 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
19735 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
19738 if (Info.checkingForUndefinedBehavior())
19739 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19740 diag::warn_fixedpoint_constant_overflow)
19741 << IntResult.toString() << E->
getType();
19746 return Success(IntResult, E);
19748 case CK_FloatingToFixedPoint: {
19754 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
19755 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
19758 if (Info.checkingForUndefinedBehavior())
19759 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19760 diag::warn_fixedpoint_constant_overflow)
19769 case CK_LValueToRValue:
19770 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19776bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19778 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19780 const Expr *LHS = E->
getLHS();
19781 const Expr *RHS = E->
getRHS();
19783 Info.Ctx.getFixedPointSemantics(E->
getType());
19785 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
19788 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
19792 bool OpOverflow =
false, ConversionOverflow =
false;
19793 APFixedPoint
Result(LHSFX.getSemantics());
19796 Result = LHSFX.add(RHSFX, &OpOverflow)
19797 .convert(ResultFXSema, &ConversionOverflow);
19801 Result = LHSFX.sub(RHSFX, &OpOverflow)
19802 .convert(ResultFXSema, &ConversionOverflow);
19806 Result = LHSFX.mul(RHSFX, &OpOverflow)
19807 .convert(ResultFXSema, &ConversionOverflow);
19811 if (RHSFX.getValue() == 0) {
19812 Info.FFDiag(E, diag::note_expr_divide_by_zero);
19815 Result = LHSFX.div(RHSFX, &OpOverflow)
19816 .convert(ResultFXSema, &ConversionOverflow);
19822 llvm::APSInt RHSVal = RHSFX.getValue();
19825 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
19826 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
19830 if (RHSVal.isNegative())
19831 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
19832 else if (Amt != RHSVal)
19833 Info.CCEDiag(E, diag::note_constexpr_large_shift)
19834 << RHSVal << E->
getType() << ShiftBW;
19837 Result = LHSFX.shl(Amt, &OpOverflow);
19839 Result = LHSFX.shr(Amt, &OpOverflow);
19845 if (OpOverflow || ConversionOverflow) {
19846 if (Info.checkingForUndefinedBehavior())
19847 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19848 diag::warn_fixedpoint_constant_overflow)
19861class FloatExprEvaluator
19862 :
public ExprEvaluatorBase<FloatExprEvaluator> {
19865 FloatExprEvaluator(EvalInfo &info, APFloat &result)
19866 : ExprEvaluatorBaseTy(info),
Result(result) {}
19873 bool ZeroInitialization(
const Expr *E) {
19874 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
19878 bool VisitCallExpr(
const CallExpr *E);
19880 bool VisitUnaryOperator(
const UnaryOperator *E);
19881 bool VisitBinaryOperator(
const BinaryOperator *E);
19882 bool VisitFloatingLiteral(
const FloatingLiteral *E);
19883 bool VisitCastExpr(
const CastExpr *E);
19885 bool VisitUnaryReal(
const UnaryOperator *E);
19886 bool VisitUnaryImag(
const UnaryOperator *E);
19895 return FloatExprEvaluator(Info,
Result).Visit(E);
19902 llvm::APFloat &
Result) {
19904 if (!S)
return false;
19906 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
19912 fill = llvm::APInt(32, 0);
19913 else if (S->
getString().getAsInteger(0, fill))
19916 if (Context.getTargetInfo().isNan2008()) {
19918 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19920 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19928 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19930 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19936bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
19937 if (!IsConstantEvaluatedBuiltinCall(E))
19938 return ExprEvaluatorBaseTy::VisitCallExpr(E);
19944 case Builtin::BI__builtin_huge_val:
19945 case Builtin::BI__builtin_huge_valf:
19946 case Builtin::BI__builtin_huge_vall:
19947 case Builtin::BI__builtin_huge_valf16:
19948 case Builtin::BI__builtin_huge_valf128:
19949 case Builtin::BI__builtin_inf:
19950 case Builtin::BI__builtin_inff:
19951 case Builtin::BI__builtin_infl:
19952 case Builtin::BI__builtin_inff16:
19953 case Builtin::BI__builtin_inff128: {
19954 const llvm::fltSemantics &Sem =
19955 Info.Ctx.getFloatTypeSemantics(E->
getType());
19956 Result = llvm::APFloat::getInf(Sem);
19960 case Builtin::BI__builtin_nans:
19961 case Builtin::BI__builtin_nansf:
19962 case Builtin::BI__builtin_nansl:
19963 case Builtin::BI__builtin_nansf16:
19964 case Builtin::BI__builtin_nansf128:
19970 case Builtin::BI__builtin_nan:
19971 case Builtin::BI__builtin_nanf:
19972 case Builtin::BI__builtin_nanl:
19973 case Builtin::BI__builtin_nanf16:
19974 case Builtin::BI__builtin_nanf128:
19982 case Builtin::BI__builtin_elementwise_abs:
19983 case Builtin::BI__builtin_fabs:
19984 case Builtin::BI__builtin_fabsf:
19985 case Builtin::BI__builtin_fabsl:
19986 case Builtin::BI__builtin_fabsf128:
19995 if (
Result.isNegative())
19999 case Builtin::BI__arithmetic_fence:
20006 case Builtin::BI__builtin_copysign:
20007 case Builtin::BI__builtin_copysignf:
20008 case Builtin::BI__builtin_copysignl:
20009 case Builtin::BI__builtin_copysignf128: {
20018 case Builtin::BI__builtin_fmax:
20019 case Builtin::BI__builtin_fmaxf:
20020 case Builtin::BI__builtin_fmaxl:
20021 case Builtin::BI__builtin_fmaxf16:
20022 case Builtin::BI__builtin_fmaxf128: {
20031 case Builtin::BI__builtin_fmin:
20032 case Builtin::BI__builtin_fminf:
20033 case Builtin::BI__builtin_fminl:
20034 case Builtin::BI__builtin_fminf16:
20035 case Builtin::BI__builtin_fminf128: {
20044 case Builtin::BI__builtin_fmaximum_num:
20045 case Builtin::BI__builtin_fmaximum_numf:
20046 case Builtin::BI__builtin_fmaximum_numl:
20047 case Builtin::BI__builtin_fmaximum_numf16:
20048 case Builtin::BI__builtin_fmaximum_numf128: {
20057 case Builtin::BI__builtin_fminimum_num:
20058 case Builtin::BI__builtin_fminimum_numf:
20059 case Builtin::BI__builtin_fminimum_numl:
20060 case Builtin::BI__builtin_fminimum_numf16:
20061 case Builtin::BI__builtin_fminimum_numf128: {
20070 case Builtin::BI__builtin_elementwise_fma: {
20075 APFloat SourceY(0.), SourceZ(0.);
20081 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
20085 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
20092 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
20098bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20110bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20120 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
20121 Result = llvm::APFloat::getZero(Sem);
20125bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20127 default:
return Error(E);
20141bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20143 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20147 if (!LHSOK && !Info.noteFailure())
20153bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
20158bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20163 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20165 case CK_HLSLAggregateSplatCast:
20166 llvm_unreachable(
"invalid cast kind for floating value");
20168 case CK_IntegralToFloating: {
20171 Info.Ctx.getLangOpts());
20177 case CK_FixedPointToFloating: {
20178 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20182 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20186 case CK_FloatingCast: {
20187 if (!Visit(SubExpr))
20193 case CK_FloatingComplexToReal: {
20197 Result =
V.getComplexFloatReal();
20200 case CK_HLSLVectorTruncation: {
20206 case CK_HLSLMatrixTruncation: {
20212 case CK_HLSLElementwiseCast: {
20227 return Success(ResultVal, E);
20237class ComplexExprEvaluator
20238 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
20242 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
20250 bool ZeroInitialization(
const Expr *E);
20256 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
20257 bool VisitCastExpr(
const CastExpr *E);
20258 bool VisitBinaryOperator(
const BinaryOperator *E);
20259 bool VisitUnaryOperator(
const UnaryOperator *E);
20260 bool VisitInitListExpr(
const InitListExpr *E);
20261 bool VisitCallExpr(
const CallExpr *E);
20269 return ComplexExprEvaluator(Info,
Result).Visit(E);
20272bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
20273 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
20275 Result.makeComplexFloat();
20276 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
20280 Result.makeComplexInt();
20281 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
20288bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
20292 Result.makeComplexFloat();
20301 "Unexpected imaginary literal.");
20303 Result.makeComplexInt();
20308 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
20313bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20317 case CK_BaseToDerived:
20318 case CK_DerivedToBase:
20319 case CK_UncheckedDerivedToBase:
20322 case CK_ArrayToPointerDecay:
20323 case CK_FunctionToPointerDecay:
20324 case CK_NullToPointer:
20325 case CK_NullToMemberPointer:
20326 case CK_BaseToDerivedMemberPointer:
20327 case CK_DerivedToBaseMemberPointer:
20328 case CK_MemberPointerToBoolean:
20329 case CK_ReinterpretMemberPointer:
20330 case CK_ConstructorConversion:
20331 case CK_IntegralToPointer:
20332 case CK_PointerToIntegral:
20333 case CK_PointerToBoolean:
20335 case CK_VectorSplat:
20336 case CK_IntegralCast:
20337 case CK_BooleanToSignedIntegral:
20338 case CK_IntegralToBoolean:
20339 case CK_IntegralToFloating:
20340 case CK_FloatingToIntegral:
20341 case CK_FloatingToBoolean:
20342 case CK_FloatingCast:
20343 case CK_CPointerToObjCPointerCast:
20344 case CK_BlockPointerToObjCPointerCast:
20345 case CK_AnyPointerToBlockPointerCast:
20346 case CK_ObjCObjectLValueCast:
20347 case CK_FloatingComplexToReal:
20348 case CK_FloatingComplexToBoolean:
20349 case CK_IntegralComplexToReal:
20350 case CK_IntegralComplexToBoolean:
20351 case CK_ARCProduceObject:
20352 case CK_ARCConsumeObject:
20353 case CK_ARCReclaimReturnedObject:
20354 case CK_ARCExtendBlockObject:
20355 case CK_CopyAndAutoreleaseBlockObject:
20356 case CK_BuiltinFnToFnPtr:
20357 case CK_ZeroToOCLOpaqueType:
20358 case CK_NonAtomicToAtomic:
20359 case CK_AddressSpaceConversion:
20360 case CK_IntToOCLSampler:
20361 case CK_FloatingToFixedPoint:
20362 case CK_FixedPointToFloating:
20363 case CK_FixedPointCast:
20364 case CK_FixedPointToBoolean:
20365 case CK_FixedPointToIntegral:
20366 case CK_IntegralToFixedPoint:
20367 case CK_MatrixCast:
20368 case CK_HLSLVectorTruncation:
20369 case CK_HLSLMatrixTruncation:
20370 case CK_HLSLElementwiseCast:
20371 case CK_HLSLAggregateSplatCast:
20372 llvm_unreachable(
"invalid cast kind for complex value");
20374 case CK_LValueToRValue:
20375 case CK_AtomicToNonAtomic:
20377 case CK_LValueToRValueBitCast:
20378 case CK_HLSLArrayRValue:
20379 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20382 case CK_LValueBitCast:
20383 case CK_UserDefinedConversion:
20386 case CK_FloatingRealToComplex: {
20391 Result.makeComplexFloat();
20396 case CK_FloatingComplexCast: {
20400 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20408 case CK_FloatingComplexToIntegralComplex: {
20412 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20415 Result.makeComplexInt();
20422 case CK_IntegralRealToComplex: {
20427 Result.makeComplexInt();
20428 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
20432 case CK_IntegralComplexCast: {
20436 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20445 case CK_IntegralComplexToFloatingComplex: {
20450 Info.Ctx.getLangOpts());
20451 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20454 Result.makeComplexFloat();
20456 To,
Result.FloatReal) &&
20462 llvm_unreachable(
"unknown cast resulting in complex value");
20468 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
20469 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
20470 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
20471 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
20472 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
20473 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
20474 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
20475 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
20476 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
20477 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
20478 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
20479 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
20480 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
20481 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
20482 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
20483 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
20484 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
20485 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
20486 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
20487 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
20488 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
20489 0xcd, 0x1a, 0x41, 0x1c};
20491 return GFInv[Byte];
20496 unsigned NumBitsInByte = 8;
20499 for (
uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20501 AQword.lshr((7 -
static_cast<int32_t>(BitIdx)) * NumBitsInByte)
20508 Product = AByte & XByte;
20513 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
20514 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
20517 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
20518 RetByte |= (Temp ^ Parity) << BitIdx;
20528 unsigned NumBitsInByte = 8;
20529 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20530 if ((BByte >> BitIdx) & 0x1) {
20531 TWord = TWord ^ (AByte << BitIdx);
20539 for (
int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
20540 if ((TWord >> BitIdx) & 0x1) {
20541 TWord = TWord ^ (0x11B << (BitIdx - 8));
20544 return (TWord & 0xFF);
20548 APFloat &ResR, APFloat &ResI) {
20554 APFloat AC = A *
C;
20555 APFloat BD = B * D;
20556 APFloat AD = A * D;
20557 APFloat BC = B *
C;
20560 if (ResR.isNaN() && ResI.isNaN()) {
20561 bool Recalc =
false;
20562 if (A.isInfinity() || B.isInfinity()) {
20563 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20565 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20568 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20570 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20573 if (
C.isInfinity() || D.isInfinity()) {
20574 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20576 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20579 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20581 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20584 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
20585 BC.isInfinity())) {
20587 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20589 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20591 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20593 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20597 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
20598 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
20604 APFloat &ResR, APFloat &ResI) {
20611 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
20612 if (MaxCD.isFinite()) {
20613 DenomLogB =
ilogb(MaxCD);
20614 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
20615 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
20617 APFloat Denom =
C *
C + D * D;
20619 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20621 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20622 if (ResR.isNaN() && ResI.isNaN()) {
20623 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
20624 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
20625 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
20626 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
20628 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20630 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20632 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
20633 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
20634 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
20635 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20637 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20639 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
20640 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
20647 APSInt NormAmt = Amount;
20648 unsigned BitWidth =
Value.getBitWidth();
20649 unsigned AmtBitWidth = NormAmt.getBitWidth();
20650 if (BitWidth == 1) {
20652 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
20653 }
else if (BitWidth == 2) {
20658 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
20661 if (AmtBitWidth > BitWidth) {
20662 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
20664 Divisor = llvm::APInt(BitWidth, BitWidth);
20665 if (AmtBitWidth < BitWidth) {
20666 NormAmt = NormAmt.extend(BitWidth);
20671 if (NormAmt.isSigned()) {
20672 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
20673 if (NormAmt.isNegative()) {
20674 APSInt SignedDivisor(Divisor,
false);
20675 NormAmt += SignedDivisor;
20678 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
20685bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20687 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20691 bool LHSReal =
false, RHSReal =
false;
20699 Result.makeComplexFloat();
20703 LHSOK = Visit(E->
getLHS());
20705 if (!LHSOK && !Info.noteFailure())
20711 APFloat &Real = RHS.FloatReal;
20714 RHS.makeComplexFloat();
20715 RHS.FloatImag =
APFloat(Real.getSemantics());
20719 assert(!(LHSReal && RHSReal) &&
20720 "Cannot have both operands of a complex operation be real.");
20722 default:
return Error(E);
20724 if (
Result.isComplexFloat()) {
20725 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
20726 APFloat::rmNearestTiesToEven);
20728 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20730 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
20731 APFloat::rmNearestTiesToEven);
20733 Result.getComplexIntReal() += RHS.getComplexIntReal();
20734 Result.getComplexIntImag() += RHS.getComplexIntImag();
20738 if (
Result.isComplexFloat()) {
20739 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
20740 APFloat::rmNearestTiesToEven);
20742 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20743 Result.getComplexFloatImag().changeSign();
20744 }
else if (!RHSReal) {
20745 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
20746 APFloat::rmNearestTiesToEven);
20749 Result.getComplexIntReal() -= RHS.getComplexIntReal();
20750 Result.getComplexIntImag() -= RHS.getComplexIntImag();
20754 if (
Result.isComplexFloat()) {
20759 ComplexValue LHS =
Result;
20760 APFloat &A = LHS.getComplexFloatReal();
20761 APFloat &B = LHS.getComplexFloatImag();
20762 APFloat &
C = RHS.getComplexFloatReal();
20763 APFloat &D = RHS.getComplexFloatImag();
20767 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
20775 }
else if (RHSReal) {
20787 ComplexValue LHS =
Result;
20788 Result.getComplexIntReal() =
20789 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
20790 LHS.getComplexIntImag() * RHS.getComplexIntImag());
20791 Result.getComplexIntImag() =
20792 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
20793 LHS.getComplexIntImag() * RHS.getComplexIntReal());
20797 if (
Result.isComplexFloat()) {
20802 ComplexValue LHS =
Result;
20803 APFloat &A = LHS.getComplexFloatReal();
20804 APFloat &B = LHS.getComplexFloatImag();
20805 APFloat &
C = RHS.getComplexFloatReal();
20806 APFloat &D = RHS.getComplexFloatImag();
20820 B = APFloat::getZero(A.getSemantics());
20825 ComplexValue LHS =
Result;
20826 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
20827 RHS.getComplexIntImag() * RHS.getComplexIntImag();
20829 return Error(E, diag::note_expr_divide_by_zero);
20831 Result.getComplexIntReal() =
20832 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
20833 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
20834 Result.getComplexIntImag() =
20835 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
20836 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
20844bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20858 if (
Result.isComplexFloat()) {
20859 Result.getComplexFloatReal().changeSign();
20860 Result.getComplexFloatImag().changeSign();
20863 Result.getComplexIntReal() = -
Result.getComplexIntReal();
20864 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20868 if (
Result.isComplexFloat())
20869 Result.getComplexFloatImag().changeSign();
20871 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20876bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
20879 Result.makeComplexFloat();
20885 Result.makeComplexInt();
20893 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
20896bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20897 if (!IsConstantEvaluatedBuiltinCall(E))
20898 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20901 case Builtin::BI__builtin_complex:
20902 Result.makeComplexFloat();
20920class AtomicExprEvaluator :
20921 public ExprEvaluatorBase<AtomicExprEvaluator> {
20922 const LValue *
This;
20925 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
20933 bool ZeroInitialization(
const Expr *E) {
20934 ImplicitValueInitExpr VIE(
20942 bool VisitCastExpr(
const CastExpr *E) {
20945 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20946 case CK_NullToPointer:
20948 return ZeroInitialization(E);
20949 case CK_NonAtomicToAtomic:
20961 return AtomicExprEvaluator(Info,
This,
Result).Visit(E);
20970class VoidExprEvaluator
20971 :
public ExprEvaluatorBase<VoidExprEvaluator> {
20973 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
20977 bool ZeroInitialization(
const Expr *E) {
return true; }
20979 bool VisitCastExpr(
const CastExpr *E) {
20982 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20989 bool VisitCallExpr(
const CallExpr *E) {
20990 if (!IsConstantEvaluatedBuiltinCall(E))
20991 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20994 case Builtin::BI__assume:
20995 case Builtin::BI__builtin_assume:
20999 case Builtin::BI__builtin_operator_delete:
21007 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
21011bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
21013 if (Info.SpeculativeEvaluationDepth)
21017 if (!OperatorDelete
21018 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21019 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21029 if (
Pointer.Designator.Invalid)
21033 if (
Pointer.isNullPointer()) {
21037 if (!Info.getLangOpts().CPlusPlus20)
21038 Info.CCEDiag(E, diag::note_constexpr_new);
21046 QualType AllocType =
Pointer.Base.getDynamicAllocType();
21052 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
21061 if (VirtualDelete &&
21063 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21064 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21071 (*Alloc)->Value, AllocType))
21074 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
21079 Info.FFDiag(E, diag::note_constexpr_double_delete);
21089 return VoidExprEvaluator(Info).Visit(E);
21101 if (E->
isGLValue() || T->isFunctionType()) {
21106 }
else if (T->isVectorType()) {
21109 }
else if (T->isConstantMatrixType()) {
21112 }
else if (T->isIntegralOrEnumerationType()) {
21113 if (!IntExprEvaluator(Info,
Result).Visit(E))
21115 }
else if (T->hasPointerRepresentation()) {
21120 }
else if (T->isRealFloatingType()) {
21121 llvm::APFloat F(0.0);
21125 }
else if (T->isAnyComplexType()) {
21130 }
else if (T->isFixedPointType()) {
21131 if (!FixedPointExprEvaluator(Info,
Result).Visit(E))
return false;
21132 }
else if (T->isMemberPointerType()) {
21138 }
else if (T->isArrayType()) {
21141 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
21145 }
else if (T->isRecordType()) {
21148 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
21152 }
else if (T->isVoidType()) {
21153 if (!Info.getLangOpts().CPlusPlus11)
21154 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
21158 }
else if (T->isAtomicType()) {
21163 E, Unqual, ScopeKind::FullExpression, LV);
21171 }
else if (Info.getLangOpts().CPlusPlus11) {
21172 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
21175 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
21186 const Expr *E,
bool AllowNonLiteralTypes) {
21202 if (T->isArrayType())
21204 else if (T->isRecordType())
21206 else if (T->isAtomicType()) {
21228 if (Info.EnableNewConstInterp) {
21229 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E,
Result))
21232 ConstantExprKind::Normal);
21241 LV.setFrom(Info.Ctx,
Result);
21248 ConstantExprKind::Normal) &&
21256 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
21258 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
21263 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
21269 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
21275 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
21281 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
21282 if (CE->hasAPValueResult()) {
21283 APValue APV = CE->getAPValueResult();
21285 Result = std::move(APV);
21361 bool InConstantContext)
const {
21363 "Expression evaluator can't be called on a dependent expression.");
21364 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
21366 Info.InConstantContext = InConstantContext;
21367 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
21371 bool InConstantContext)
const {
21373 "Expression evaluator can't be called on a dependent expression.");
21374 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
21382 bool InConstantContext)
const {
21384 "Expression evaluator can't be called on a dependent expression.");
21385 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
21387 Info.InConstantContext = InConstantContext;
21388 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
21393 bool InConstantContext)
const {
21395 "Expression evaluator can't be called on a dependent expression.");
21396 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
21398 Info.InConstantContext = InConstantContext;
21399 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
21404 bool InConstantContext)
const {
21406 "Expression evaluator can't be called on a dependent expression.");
21408 if (!
getType()->isRealFloatingType())
21411 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
21423 bool InConstantContext)
const {
21425 "Expression evaluator can't be called on a dependent expression.");
21427 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
21429 Info.InConstantContext = InConstantContext;
21433 if (Info.EnableNewConstInterp) {
21434 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val,
21435 ConstantExprKind::Normal))
21438 LV.setFrom(Ctx,
Result.Val);
21441 ConstantExprKind::Normal, CheckedTemps);
21444 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
21445 Result.HasSideEffects ||
21448 ConstantExprKind::Normal, CheckedTemps))
21451 LV.moveInto(
Result.Val);
21458 bool IsConstantDestruction) {
21459 EvalInfo Info(Ctx, EStatus,
21462 Info.setEvaluatingDecl(
Base, DestroyedValue,
21463 EvalInfo::EvaluatingDeclKind::Dtor);
21464 Info.InConstantContext = IsConstantDestruction;
21473 if (!Info.discardCleanups())
21474 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21482 "Expression evaluator can't be called on a dependent expression.");
21488 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
21490 EvalInfo Info(Ctx,
Result, EM);
21491 Info.InConstantContext =
true;
21493 if (Info.EnableNewConstInterp) {
21494 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val, Kind))
21497 getStorageType(Ctx,
this),
Result.Val, Kind);
21502 if (Kind == ConstantExprKind::ClassTemplateArgument)
21518 FullExpressionRAII
Scope(Info);
21523 if (!Info.discardCleanups())
21524 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21534 if (Kind == ConstantExprKind::ClassTemplateArgument &&
21537 Result.HasSideEffects)) {
21548 bool IsConstantInitialization)
const {
21550 "Expression evaluator can't be called on a dependent expression.");
21551 assert(VD &&
"Need a valid VarDecl");
21553 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
21555 llvm::raw_string_ostream OS(Name);
21560 EvalInfo Info(Ctx, EStatus,
21561 (IsConstantInitialization &&
21565 Info.setEvaluatingDecl(VD, EStatus.
Val);
21566 Info.InConstantContext = IsConstantInitialization;
21571 if (Info.EnableNewConstInterp) {
21573 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this, EStatus.
Val))
21577 ConstantExprKind::Normal);
21592 FullExpressionRAII
Scope(Info);
21601 Info.performLifetimeExtension();
21603 if (!Info.discardCleanups())
21604 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21608 ConstantExprKind::Normal) &&
21615 EStatus.
Diag = &Notes;
21632 EvalInfo Info(Ctx, EStatus,
21635 Info.setEvaluatingDecl(
this, DestroyedValue,
21636 EvalInfo::EvaluatingDeclKind::Dtor);
21637 Info.InConstantContext = IsConstantDestruction;
21639 std::move(DestroyedValue)))
21646 getLocation(), EStatus, IsConstantDestruction) ||
21658 "Expression evaluator can't be called on a dependent expression.");
21667 "Expression evaluator can't be called on a dependent expression.");
21669 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
21672 Info.InConstantContext =
true;
21676 assert(
Result &&
"Could not evaluate expression");
21677 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
21679 return EVResult.Val.getInt();
21685 "Expression evaluator can't be called on a dependent expression.");
21687 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
21689 EVResult.Diag =
Diag;
21691 Info.InConstantContext =
true;
21692 Info.CheckingForUndefinedBehavior =
true;
21696 assert(
Result &&
"Could not evaluate expression");
21697 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
21699 return EVResult.Val.getInt();
21704 "Expression evaluator can't be called on a dependent expression.");
21706 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
21711 Info.CheckingForUndefinedBehavior =
true;
21717 assert(
Val.isLValue());
21743 IK_ICEIfUnevaluated,
21759static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
21766 Info.InConstantContext =
true;
21775 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
21780#define ABSTRACT_STMT(Node)
21781#define STMT(Node, Base) case Expr::Node##Class:
21782#define EXPR(Node, Base)
21783#include "clang/AST/StmtNodes.inc"
21784 case Expr::PredefinedExprClass:
21785 case Expr::FloatingLiteralClass:
21786 case Expr::ImaginaryLiteralClass:
21787 case Expr::StringLiteralClass:
21788 case Expr::ArraySubscriptExprClass:
21789 case Expr::MatrixSingleSubscriptExprClass:
21790 case Expr::MatrixSubscriptExprClass:
21791 case Expr::ArraySectionExprClass:
21792 case Expr::OMPArrayShapingExprClass:
21793 case Expr::OMPIteratorExprClass:
21794 case Expr::CompoundAssignOperatorClass:
21795 case Expr::CompoundLiteralExprClass:
21796 case Expr::ExtVectorElementExprClass:
21797 case Expr::MatrixElementExprClass:
21798 case Expr::DesignatedInitExprClass:
21799 case Expr::ArrayInitLoopExprClass:
21800 case Expr::ArrayInitIndexExprClass:
21801 case Expr::NoInitExprClass:
21802 case Expr::DesignatedInitUpdateExprClass:
21803 case Expr::ImplicitValueInitExprClass:
21804 case Expr::ParenListExprClass:
21805 case Expr::VAArgExprClass:
21806 case Expr::AddrLabelExprClass:
21807 case Expr::StmtExprClass:
21808 case Expr::CXXMemberCallExprClass:
21809 case Expr::CUDAKernelCallExprClass:
21810 case Expr::CXXAddrspaceCastExprClass:
21811 case Expr::CXXDynamicCastExprClass:
21812 case Expr::CXXTypeidExprClass:
21813 case Expr::CXXUuidofExprClass:
21814 case Expr::MSPropertyRefExprClass:
21815 case Expr::MSPropertySubscriptExprClass:
21816 case Expr::CXXNullPtrLiteralExprClass:
21817 case Expr::UserDefinedLiteralClass:
21818 case Expr::CXXThisExprClass:
21819 case Expr::CXXThrowExprClass:
21820 case Expr::CXXNewExprClass:
21821 case Expr::CXXDeleteExprClass:
21822 case Expr::CXXPseudoDestructorExprClass:
21823 case Expr::UnresolvedLookupExprClass:
21824 case Expr::RecoveryExprClass:
21825 case Expr::DependentScopeDeclRefExprClass:
21826 case Expr::CXXConstructExprClass:
21827 case Expr::CXXInheritedCtorInitExprClass:
21828 case Expr::CXXStdInitializerListExprClass:
21829 case Expr::CXXBindTemporaryExprClass:
21830 case Expr::ExprWithCleanupsClass:
21831 case Expr::CXXTemporaryObjectExprClass:
21832 case Expr::CXXUnresolvedConstructExprClass:
21833 case Expr::CXXDependentScopeMemberExprClass:
21834 case Expr::UnresolvedMemberExprClass:
21835 case Expr::ObjCStringLiteralClass:
21836 case Expr::ObjCBoxedExprClass:
21837 case Expr::ObjCArrayLiteralClass:
21838 case Expr::ObjCDictionaryLiteralClass:
21839 case Expr::ObjCEncodeExprClass:
21840 case Expr::ObjCMessageExprClass:
21841 case Expr::ObjCSelectorExprClass:
21842 case Expr::ObjCProtocolExprClass:
21843 case Expr::ObjCIvarRefExprClass:
21844 case Expr::ObjCPropertyRefExprClass:
21845 case Expr::ObjCSubscriptRefExprClass:
21846 case Expr::ObjCIsaExprClass:
21847 case Expr::ObjCAvailabilityCheckExprClass:
21848 case Expr::ShuffleVectorExprClass:
21849 case Expr::ConvertVectorExprClass:
21850 case Expr::BlockExprClass:
21852 case Expr::OpaqueValueExprClass:
21853 case Expr::PackExpansionExprClass:
21854 case Expr::SubstNonTypeTemplateParmPackExprClass:
21855 case Expr::FunctionParmPackExprClass:
21856 case Expr::AsTypeExprClass:
21857 case Expr::ObjCIndirectCopyRestoreExprClass:
21858 case Expr::MaterializeTemporaryExprClass:
21859 case Expr::PseudoObjectExprClass:
21860 case Expr::AtomicExprClass:
21861 case Expr::LambdaExprClass:
21862 case Expr::CXXFoldExprClass:
21863 case Expr::CoawaitExprClass:
21864 case Expr::DependentCoawaitExprClass:
21865 case Expr::CoyieldExprClass:
21866 case Expr::SYCLUniqueStableNameExprClass:
21867 case Expr::CXXParenListInitExprClass:
21868 case Expr::HLSLOutArgExprClass:
21871 case Expr::MemberExprClass: {
21874 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
21877 ME = M->getBase()->IgnoreParenImpCasts();
21879 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
21881 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
21889 case Expr::InitListExprClass: {
21900 case Expr::SizeOfPackExprClass:
21901 case Expr::GNUNullExprClass:
21902 case Expr::SourceLocExprClass:
21903 case Expr::EmbedExprClass:
21904 case Expr::OpenACCAsteriskSizeExprClass:
21907 case Expr::PackIndexingExprClass:
21910 case Expr::SubstNonTypeTemplateParmExprClass:
21914 case Expr::ConstantExprClass:
21917 case Expr::ParenExprClass:
21919 case Expr::GenericSelectionExprClass:
21921 case Expr::IntegerLiteralClass:
21922 case Expr::FixedPointLiteralClass:
21923 case Expr::CharacterLiteralClass:
21924 case Expr::ObjCBoolLiteralExprClass:
21925 case Expr::CXXBoolLiteralExprClass:
21926 case Expr::CXXScalarValueInitExprClass:
21927 case Expr::TypeTraitExprClass:
21928 case Expr::ConceptSpecializationExprClass:
21929 case Expr::RequiresExprClass:
21930 case Expr::ArrayTypeTraitExprClass:
21931 case Expr::ExpressionTraitExprClass:
21932 case Expr::CXXNoexceptExprClass:
21933 case Expr::CXXReflectExprClass:
21935 case Expr::CallExprClass:
21936 case Expr::CXXOperatorCallExprClass: {
21945 case Expr::CXXRewrittenBinaryOperatorClass:
21948 case Expr::DeclRefExprClass: {
21962 const VarDecl *VD = dyn_cast<VarDecl>(D);
21969 case Expr::UnaryOperatorClass: {
21992 llvm_unreachable(
"invalid unary operator class");
21994 case Expr::OffsetOfExprClass: {
22003 case Expr::UnaryExprOrTypeTraitExprClass: {
22005 if ((Exp->
getKind() == UETT_SizeOf) &&
22008 if (Exp->
getKind() == UETT_CountOf) {
22015 if (VAT->getElementType()->isArrayType())
22027 case Expr::BinaryOperatorClass: {
22072 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
22075 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22076 if (REval.isSigned() && REval.isAllOnes()) {
22078 if (LEval.isMinSignedValue())
22079 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22087 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
22088 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22094 return Worst(LHSResult, RHSResult);
22100 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
22110 return Worst(LHSResult, RHSResult);
22113 llvm_unreachable(
"invalid binary operator kind");
22115 case Expr::ImplicitCastExprClass:
22116 case Expr::CStyleCastExprClass:
22117 case Expr::CXXFunctionalCastExprClass:
22118 case Expr::CXXStaticCastExprClass:
22119 case Expr::CXXReinterpretCastExprClass:
22120 case Expr::CXXConstCastExprClass:
22121 case Expr::ObjCBridgedCastExprClass: {
22128 APSInt IgnoredVal(DestWidth, !DestSigned);
22133 if (FL->getValue().convertToInteger(IgnoredVal,
22134 llvm::APFloat::rmTowardZero,
22135 &Ignored) & APFloat::opInvalidOp)
22141 case CK_LValueToRValue:
22142 case CK_AtomicToNonAtomic:
22143 case CK_NonAtomicToAtomic:
22145 case CK_IntegralToBoolean:
22146 case CK_IntegralCast:
22152 case Expr::BinaryConditionalOperatorClass: {
22155 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
22157 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
22158 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
22159 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
22161 return FalseResult;
22163 case Expr::ConditionalOperatorClass: {
22171 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
22174 if (CondResult.Kind == IK_NotICE)
22180 if (TrueResult.Kind == IK_NotICE)
22182 if (FalseResult.Kind == IK_NotICE)
22183 return FalseResult;
22184 if (CondResult.Kind == IK_ICEIfUnevaluated)
22186 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
22192 return FalseResult;
22195 case Expr::CXXDefaultArgExprClass:
22197 case Expr::CXXDefaultInitExprClass:
22199 case Expr::ChooseExprClass: {
22202 case Expr::BuiltinBitCastExprClass: {
22203 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
22209 llvm_unreachable(
"Invalid StmtClass!");
22215 llvm::APSInt *
Value) {
22232 "Expression evaluator can't be called on a dependent expression.");
22234 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
22240 if (D.Kind != IK_ICE)
22245std::optional<llvm::APSInt>
22249 return std::nullopt;
22256 return std::nullopt;
22260 return std::nullopt;
22269 Info.InConstantContext =
true;
22272 llvm_unreachable(
"ICE cannot be evaluated!");
22279 "Expression evaluator can't be called on a dependent expression.");
22281 return CheckICE(
this, Ctx).Kind == IK_ICE;
22286 "Expression evaluator can't be called on a dependent expression.");
22296 *
Result = std::move(Scratch);
22308 Info.discardCleanups() && !Status.HasSideEffects;
22310 return IsConstExpr && !Status.DiagEmitted;
22318 "Expression evaluator can't be called on a dependent expression.");
22320 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
22322 llvm::raw_string_ostream OS(Name);
22330 Info.InConstantContext =
true;
22333 const LValue *ThisPtr =
nullptr;
22336 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
22337 assert(MD &&
"Don't provide `this` for non-methods.");
22338 assert(MD->isImplicitObjectMemberFunction() &&
22339 "Don't provide `this` for methods without an implicit object.");
22341 if (!
This->isValueDependent() &&
22343 !Info.EvalStatus.HasSideEffects)
22344 ThisPtr = &ThisVal;
22348 Info.EvalStatus.HasSideEffects =
false;
22351 CallRef
Call = Info.CurrentCall->createCall(Callee);
22354 unsigned Idx = I - Args.begin();
22355 if (Idx >= Callee->getNumParams())
22357 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
22358 if ((*I)->isValueDependent() ||
22360 Info.EvalStatus.HasSideEffects) {
22362 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
22368 Info.EvalStatus.HasSideEffects =
false;
22373 Info.discardCleanups();
22374 Info.EvalStatus.HasSideEffects =
false;
22377 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
22380 FullExpressionRAII
Scope(Info);
22382 !Info.EvalStatus.HasSideEffects;
22394 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
22396 llvm::raw_string_ostream OS(Name);
22403 Status.
Diag = &Diags;
22407 Info.InConstantContext =
true;
22408 Info.CheckingPotentialConstantExpression =
true;
22411 if (Info.EnableNewConstInterp) {
22412 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
22413 return Diags.empty();
22424 This.set({&VIE, Info.CurrentCall->Index});
22432 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
22438 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
22442 return Diags.empty();
22450 "Expression evaluator can't be called on a dependent expression.");
22453 Status.
Diag = &Diags;
22457 Info.InConstantContext =
true;
22458 Info.CheckingPotentialConstantExpression =
true;
22460 if (Info.EnableNewConstInterp) {
22461 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info, E, FD);
22462 return Diags.empty();
22467 nullptr, CallRef());
22471 return Diags.empty();
22475 unsigned Type)
const {
22476 if (!
getType()->isPointerType())
22477 return std::nullopt;
22481 if (Info.EnableNewConstInterp)
22482 return Info.Ctx.getInterpContext().tryEvaluateObjectSize(Info,
this,
Type);
22486static std::optional<uint64_t>
22488 std::string *StringResult) {
22490 return std::nullopt;
22495 return std::nullopt;
22500 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
22501 String.getLValueBase().dyn_cast<
const Expr *>())) {
22504 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
22507 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
22508 Str = Str.substr(Off);
22510 StringRef::size_type Pos = Str.find(0);
22511 if (Pos != StringRef::npos)
22512 Str = Str.substr(0, Pos);
22515 *StringResult = Str;
22523 for (uint64_t Strlen = 0; ; ++Strlen) {
22527 return std::nullopt;
22530 else if (StringResult)
22531 StringResult->push_back(Char.
getInt().getExtValue());
22533 return std::nullopt;
22540 std::string StringResult;
22542 if (Info.EnableNewConstInterp) {
22543 if (!Info.Ctx.getInterpContext().evaluateString(Info,
this, StringResult))
22544 return std::nullopt;
22545 return StringResult;
22549 return StringResult;
22550 return std::nullopt;
22553template <
typename T>
22555 const Expr *SizeExpression,
22556 const Expr *PtrExpression,
22560 Info.InConstantContext =
true;
22562 if (Info.EnableNewConstInterp)
22563 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
22567 FullExpressionRAII
Scope(Info);
22572 uint64_t Size = SizeValue.getZExtValue();
22575 if constexpr (std::is_same_v<APValue, T>)
22578 if (Size <
Result.max_size())
22585 for (uint64_t I = 0; I < Size; ++I) {
22591 if constexpr (std::is_same_v<APValue, T>) {
22592 Result.getArrayInitializedElt(I) = std::move(Char);
22596 assert(
C.getBitWidth() <= 8 &&
22597 "string element not representable in char");
22599 Result.push_back(
static_cast<char>(
C.getExtValue()));
22610 const Expr *SizeExpression,
22614 PtrExpression, Ctx, Status);
22618 const Expr *SizeExpression,
22622 PtrExpression, Ctx, Status);
22629 if (Info.EnableNewConstInterp)
22630 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this);
22635struct IsWithinLifetimeHandler {
22638 using result_type = std::optional<bool>;
22639 std::optional<bool> failed() {
return std::nullopt; }
22640 template <
typename T>
22641 std::optional<bool> found(T &Subobj,
QualType SubobjType,
22645 template <
typename T>
22646 std::optional<bool> found(T &Subobj, QualType SubobjType) {
22651std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
22652 const CallExpr *E) {
22653 EvalInfo &Info = IEE.Info;
22658 if (!Info.InConstantContext)
22659 return std::nullopt;
22661 const Expr *Arg = E->
getArg(0);
22663 return std::nullopt;
22666 return std::nullopt;
22668 if (Val.allowConstexprUnknown())
22672 bool CalledFromStd =
false;
22673 const auto *
Callee = Info.CurrentCall->getCallee();
22674 if (Callee &&
Callee->isInStdNamespace()) {
22675 const IdentifierInfo *Identifier =
Callee->getIdentifier();
22676 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
22678 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
22680 diag::err_invalid_is_within_lifetime)
22681 << (CalledFromStd ?
"std::is_within_lifetime"
22682 :
"__builtin_is_within_lifetime")
22684 return std::nullopt;
22694 if (Val.isNullPointer() || Val.getLValueBase().isNull())
22696 QualType T = Val.getLValueBase().getType();
22698 "Pointers to functions should have been typed as function pointers "
22699 "which would have been rejected earlier");
22702 if (Val.getLValueDesignator().isOnePastTheEnd())
22704 assert(Val.getLValueDesignator().isValidSubobject() &&
22705 "Unchecked case for valid subobject");
22709 CompleteObject CO =
22713 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
22718 IsWithinLifetimeHandler handler{Info};
22719 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 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 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 std::optional< uint64_t > tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, bool IsDynamic=false)
Tries to evaluate the __builtin_object_size for E. If successful, returns true and stores the 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 bool isModification(AccessKinds AK)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
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 EvaluateAsInitializer(const ASTContext &Ctx, const VarDecl *VD, EvalResult &Result, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
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...
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...
bool isCompatibleWith(ClangABI Version) const
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExpressibleAsConstantInitializer() const
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
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 isCountAttributedType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
SourceLocation getBeginLoc() const LLVM_READONLY
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
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 Sub(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool This(InterpState &S, CodePtr OpPC)
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
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)
const Expr * findStructFieldAccess(const Expr *E, const Expr **OutArrayIndex=nullptr, QualType *OutArrayElementTy=nullptr)
Walk E through parens, implicit casts, unary &/*, array subscripts and comma operators to find the he...
bool hasSpecificAttr(const Container &container)
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
Expr::ConstantExprKind ConstantExprKind
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
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)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 uint16_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
unsigned PathLength
The corresponding path length in the lvalue.
const CXXRecordDecl * Type
The dynamic class type of the object.
std::string ObjCEncodeStorage
Represents an element in a path from a derived class to a base class.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool isGlobalLValue() const
Return true if the evaluated lvalue expression is global.
EvalStatus is a struct with detailed info about an evaluation in progress.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
bool HasSideEffects
Whether the evaluated expression has side effects.
unsigned SuppressLambdaBody
Whether to suppress printing the body of a lambda.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
DenseMapInfo< APValue::LValueBase > Base
static unsigned getHashValue(const ObjectUnderConstruction &Object)
static bool isEqual(const ObjectUnderConstruction &LHS, const ObjectUnderConstruction &RHS)