62#include "llvm/ADT/APFixedPoint.h"
63#include "llvm/ADT/Sequence.h"
64#include "llvm/ADT/SmallBitVector.h"
65#include "llvm/ADT/StringExtras.h"
66#include "llvm/ADT/bit.h"
67#include "llvm/Support/CRC.h"
68#include "llvm/Support/Casting.h"
69#include "llvm/Support/Debug.h"
70#include "llvm/Support/MathExtras.h"
71#include "llvm/Support/SaveAndRestore.h"
72#include "llvm/Support/SipHash.h"
73#include "llvm/Support/TimeProfiler.h"
74#include "llvm/Support/raw_ostream.h"
80#define DEBUG_TYPE "exprconstant"
83using llvm::APFixedPoint;
87using llvm::FixedPointSemantics;
94 using SourceLocExprScopeGuard =
125 static unsigned countNonVirtualBases(
const CXXRecordDecl *RD) {
126 return llvm::count_if(RD->
bases(), [](
auto &B) { return !B.isVirtual(); });
133 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
141 if (
const auto *FE = dyn_cast<FullExpr>(E))
144 if (
const auto *Cast = dyn_cast<CastExpr>(E))
145 E = Cast->getSubExpr()->IgnoreParens();
147 if (
const auto *CE = dyn_cast<CallExpr>(E))
148 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
155 const auto *E =
Base.dyn_cast<
const Expr *>();
156 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
162 static const uint64_t AssumedSizeForUnsizedArray =
163 std::numeric_limits<uint64_t>::max() / 2;
173 bool &FirstEntryIsUnsizedArray) {
176 assert(!isBaseAnAllocSizeCall(
Base) &&
177 "Unsized arrays shouldn't appear here");
178 unsigned MostDerivedLength = 0;
183 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
187 MostDerivedLength = I + 1;
190 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
191 ArraySize = CAT->getZExtSize();
193 assert(I == 0 &&
"unexpected unsized array designator");
194 FirstEntryIsUnsizedArray =
true;
195 ArraySize = AssumedSizeForUnsizedArray;
201 MostDerivedLength = I + 1;
204 Type = VT->getElementType();
205 ArraySize = VT->getNumElements();
206 MostDerivedLength = I + 1;
208 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
209 Type = FD->getType();
211 MostDerivedLength = I + 1;
219 return MostDerivedLength;
223 struct SubobjectDesignator {
227 LLVM_PREFERRED_TYPE(
bool)
231 LLVM_PREFERRED_TYPE(
bool)
232 unsigned IsOnePastTheEnd : 1;
235 LLVM_PREFERRED_TYPE(
bool)
236 unsigned FirstEntryIsAnUnsizedArray : 1;
239 LLVM_PREFERRED_TYPE(
bool)
240 unsigned MostDerivedIsArrayElement : 1;
244 unsigned MostDerivedPathLength : 28;
253 uint64_t MostDerivedArraySize;
262 SubobjectDesignator() :
Invalid(
true) {}
265 :
Invalid(
false), IsOnePastTheEnd(
false),
266 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
267 MostDerivedPathLength(0), MostDerivedArraySize(0),
268 MostDerivedType(
T.isNull() ?
QualType() :
T.getNonReferenceType()) {}
271 :
Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
272 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
273 MostDerivedPathLength(0), MostDerivedArraySize(0) {
274 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
276 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
277 llvm::append_range(Entries,
V.getLValuePath());
278 if (
V.getLValueBase()) {
279 bool IsArray =
false;
280 bool FirstIsUnsizedArray =
false;
281 MostDerivedPathLength = findMostDerivedSubobject(
282 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
283 MostDerivedType, IsArray, FirstIsUnsizedArray);
284 MostDerivedIsArrayElement = IsArray;
285 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
291 unsigned NewLength) {
295 assert(
Base &&
"cannot truncate path for null pointer");
296 assert(NewLength <= Entries.size() &&
"not a truncation");
298 if (NewLength == Entries.size())
300 Entries.resize(NewLength);
302 bool IsArray =
false;
303 bool FirstIsUnsizedArray =
false;
304 MostDerivedPathLength = findMostDerivedSubobject(
305 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
306 FirstIsUnsizedArray);
307 MostDerivedIsArrayElement = IsArray;
308 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
318 bool isMostDerivedAnUnsizedArray()
const {
319 assert(!
Invalid &&
"Calling this makes no sense on invalid designators");
320 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
325 uint64_t getMostDerivedArraySize()
const {
326 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
327 return MostDerivedArraySize;
331 bool isOnePastTheEnd()
const {
335 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
336 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
337 MostDerivedArraySize)
345 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
346 if (
Invalid || isMostDerivedAnUnsizedArray())
352 bool IsArray = MostDerivedPathLength == Entries.size() &&
353 MostDerivedIsArrayElement;
354 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
355 : (uint64_t)IsOnePastTheEnd;
357 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
358 return {ArrayIndex, ArraySize - ArrayIndex};
362 bool isValidSubobject()
const {
365 return !isOnePastTheEnd();
373 assert(!
Invalid &&
"invalid designator has no subobject type");
374 return MostDerivedPathLength == Entries.size()
385 MostDerivedIsArrayElement =
true;
387 MostDerivedPathLength = Entries.size();
391 void addUnsizedArrayUnchecked(
QualType ElemTy) {
394 MostDerivedType = ElemTy;
395 MostDerivedIsArrayElement =
true;
399 MostDerivedArraySize = AssumedSizeForUnsizedArray;
400 MostDerivedPathLength = Entries.size();
404 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
408 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
409 MostDerivedType = FD->getType();
410 MostDerivedIsArrayElement =
false;
411 MostDerivedArraySize = 0;
412 MostDerivedPathLength = Entries.size();
416 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
421 MostDerivedType = EltTy;
422 MostDerivedIsArrayElement =
true;
423 MostDerivedArraySize = 2;
424 MostDerivedPathLength = Entries.size();
427 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
430 MostDerivedType = EltTy;
431 MostDerivedPathLength = Entries.size();
432 MostDerivedArraySize = 0;
433 MostDerivedIsArrayElement =
false;
436 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
437 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
440 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
const LValue &LV);
444 enum class ScopeKind {
452 CallRef() : OrigCallee(), CallIndex(0), Version() {}
453 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
454 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
456 explicit operator bool()
const {
return OrigCallee; }
482 CallStackFrame *Caller;
504 typedef std::pair<const void *, unsigned> MapKeyTy;
505 typedef std::map<MapKeyTy, APValue>
MapTy;
517 unsigned CurTempVersion = TempVersionStack.back();
519 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
521 void pushTempVersion() {
522 TempVersionStack.push_back(++CurTempVersion);
525 void popTempVersion() {
526 TempVersionStack.pop_back();
530 return {Callee, Index, ++CurTempVersion};
541 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
542 FieldDecl *LambdaThisCaptureField =
nullptr;
544 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
550 APValue *getTemporary(
const void *Key,
unsigned Version) {
551 MapKeyTy KV(Key, Version);
552 auto LB = Temporaries.lower_bound(KV);
553 if (LB != Temporaries.end() && LB->first == KV)
559 APValue *getCurrentTemporary(
const void *Key) {
560 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
561 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
562 return &std::prev(UB)->second;
567 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
568 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
569 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
570 return std::prev(UB)->first.second;
578 template<
typename KeyT>
580 ScopeKind
Scope, LValue &LV);
585 void describe(llvm::raw_ostream &OS)
const override;
587 Frame *getCaller()
const override {
return Caller; }
588 SourceRange getCallRange()
const override {
return CallRange; }
591 bool isStdFunction()
const {
592 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
593 if (DC->isStdNamespace())
600 bool CanEvalMSConstexpr =
false;
608 class ThisOverrideRAII {
610 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
611 : Frame(Frame), OldThis(Frame.This) {
613 Frame.This = NewThis;
615 ~ThisOverrideRAII() {
616 Frame.This = OldThis;
619 CallStackFrame &Frame;
620 const LValue *OldThis;
625 class ExprTimeTraceScope {
627 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
628 : TimeScope(Name, [E, &Ctx] {
633 llvm::TimeTraceScope TimeScope;
638 struct MSConstexprContextRAII {
639 CallStackFrame &Frame;
641 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
642 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
643 Frame.CanEvalMSConstexpr =
Value;
646 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
659 llvm::PointerIntPair<APValue*, 2, ScopeKind> Value;
660 APValue::LValueBase Base;
666 : Value(Val, Scope), Base(Base), T(T) {}
670 bool isDestroyedAtEndOf(ScopeKind K)
const {
671 return (
int)Value.getInt() >= (
int)K;
673 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
674 if (RunDestructors) {
676 if (
const ValueDecl *VD = Base.dyn_cast<
const ValueDecl*>())
677 Loc = VD->getLocation();
678 else if (
const Expr *E = Base.dyn_cast<
const Expr*>())
679 Loc = E->getExprLoc();
682 *Value.getPointer() =
APValue();
686 bool hasSideEffect() {
687 return T.isDestructedType();
692 struct ObjectUnderConstruction {
693 APValue::LValueBase Base;
694 ArrayRef<APValue::LValuePathEntry> Path;
695 friend bool operator==(
const ObjectUnderConstruction &LHS,
696 const ObjectUnderConstruction &RHS) {
697 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
699 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
700 return llvm::hash_combine(Obj.Base, Obj.Path);
703 enum class ConstructionPhase {
714template<>
struct DenseMapInfo<ObjectUnderConstruction> {
715 using Base = DenseMapInfo<APValue::LValueBase>;
719 static bool isEqual(
const ObjectUnderConstruction &LHS,
720 const ObjectUnderConstruction &RHS) {
734 const Expr *AllocExpr =
nullptr;
739 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
740 return NE->isArray() ? DynAllocKind::ArrayNew : DynAllocKind::New;
742 return DynAllocKind::StdAllocator;
748 struct DynAllocOrder {
749 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
771 CallStackFrame *CurrentCall;
774 unsigned CallStackDepth;
777 unsigned NextCallIndex;
786 CallStackFrame BottomFrame;
790 llvm::SmallVector<Cleanup, 16> CleanupStack;
794 APValue::LValueBase EvaluatingDecl;
796 enum class EvaluatingDeclKind {
803 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
812 SmallVector<const Stmt *> BreakContinueStack;
815 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
816 ObjectsUnderConstruction;
821 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
826 struct EvaluatingConstructorRAII {
828 ObjectUnderConstruction Object;
830 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
832 : EI(EI), Object(Object) {
834 EI.ObjectsUnderConstruction
835 .insert({Object, HasBases ? ConstructionPhase::Bases
836 : ConstructionPhase::AfterBases})
839 void finishedConstructingBases() {
840 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
842 void finishedConstructingFields() {
843 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
845 ~EvaluatingConstructorRAII() {
846 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
850 struct EvaluatingDestructorRAII {
852 ObjectUnderConstruction Object;
854 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
855 : EI(EI), Object(Object) {
856 DidInsert = EI.ObjectsUnderConstruction
857 .insert({Object, ConstructionPhase::Destroying})
860 void startedDestroyingBases() {
861 EI.ObjectsUnderConstruction[Object] =
862 ConstructionPhase::DestroyingBases;
864 ~EvaluatingDestructorRAII() {
866 EI.ObjectsUnderConstruction.erase(Object);
871 isEvaluatingCtorDtor(APValue::LValueBase Base,
872 ArrayRef<APValue::LValuePathEntry> Path) {
873 return ObjectsUnderConstruction.lookup({
Base, Path});
878 unsigned SpeculativeEvaluationDepth = 0;
884 EvalInfo(
const ASTContext &
C, SemaProxy *SProxy, Expr::EvalStatus &S,
886 : State(const_cast<ASTContext &>(
C), SProxy, S), CurrentCall(
nullptr),
887 CallStackDepth(0), NextCallIndex(1),
888 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
889 BottomFrame(*this, SourceLocation(),
nullptr,
892 EvaluatingDecl((const ValueDecl *)
nullptr),
901 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
902 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
903 EvaluatingDecl =
Base;
904 IsEvaluatingDecl = EDK;
905 EvaluatingDeclValue = &
Value;
908 bool CheckCallLimit(SourceLocation Loc) {
911 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
913 if (NextCallIndex == 0) {
915 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
918 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
920 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
921 << getLangOpts().ConstexprCallDepth;
926 uint64_t ElemCount,
bool Diag) {
932 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
934 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
943 uint64_t Limit = getLangOpts().ConstexprStepLimit;
944 if (Limit != 0 && ElemCount > Limit) {
946 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits, 1)
947 << ElemCount << Limit;
948 Note(Loc, diag::note_constexpr_steps);
955 std::pair<CallStackFrame *, unsigned>
956 getCallFrameAndDepth(
unsigned CallIndex) {
957 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
960 unsigned Depth = CallStackDepth;
961 CallStackFrame *Frame = CurrentCall;
962 while (Frame->Index > CallIndex) {
963 Frame = Frame->Caller;
966 if (Frame->Index == CallIndex)
967 return {Frame, Depth};
971 bool nextStep(
const Stmt *S) {
972 if (getLangOpts().ConstexprStepLimit == 0)
976 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded, 1)
977 << getLangOpts().ConstexprStepLimit;
985 APValue *createHeapAlloc(
const Expr *E, QualType
T, LValue &LV);
987 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
988 std::optional<DynAlloc *>
Result;
989 auto It = HeapAllocs.find(DA);
990 if (It != HeapAllocs.end())
996 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
997 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
998 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1003 struct StdAllocatorCaller {
1004 unsigned FrameIndex;
1007 explicit operator bool()
const {
return FrameIndex != 0; };
1010 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1011 for (
const CallStackFrame *
Call = CurrentCall;
Call->Caller !=
nullptr;
1013 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1016 const IdentifierInfo *FnII = MD->getIdentifier();
1017 if (!FnII || !FnII->
isStr(FnName))
1021 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1025 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1026 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1027 if (CTSD->isInStdNamespace() && ClassII &&
1028 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1030 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1036 void performLifetimeExtension() {
1038 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1039 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1046 bool discardCleanups() {
1047 for (Cleanup &
C : CleanupStack) {
1048 if (
C.hasSideEffect() && !noteSideEffect()) {
1049 CleanupStack.clear();
1053 CleanupStack.clear();
1058 const interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1060 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1061 bool stepsLeft()
const override {
return StepsLeft > 0; }
1074 [[nodiscard]]
bool noteFailure() {
1082 bool KeepGoing = keepEvaluatingAfterFailure();
1083 EvalStatus.HasSideEffects |= KeepGoing;
1087 class ArrayInitLoopIndex {
1092 ArrayInitLoopIndex(EvalInfo &Info)
1093 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1094 Info.ArrayInitIndex = 0;
1096 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1098 operator uint64_t&() {
return Info.ArrayInitIndex; }
1103 struct FoldConstant {
1106 bool HadNoPriorDiags;
1109 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1112 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1113 Info.EvalStatus.
Diag->empty() &&
1114 !Info.EvalStatus.HasSideEffects),
1115 OldMode(Info.EvalMode) {
1117 Info.EvalMode = EvaluationMode::ConstantFold;
1119 void keepDiagnostics() { Enabled =
false; }
1121 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1122 !Info.EvalStatus.HasSideEffects) {
1123 Info.EvalStatus.Diag->clear();
1124 Info.EvalStatus.DiagEmitted =
false;
1126 Info.EvalMode = OldMode;
1132 struct IgnoreSideEffectsRAII {
1135 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1136 : Info(Info), OldMode(Info.EvalMode) {
1137 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1140 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1145 class SpeculativeEvaluationRAII {
1146 EvalInfo *Info =
nullptr;
1147 Expr::EvalStatus OldStatus;
1148 unsigned OldSpeculativeEvaluationDepth = 0;
1150 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1152 OldStatus =
Other.OldStatus;
1153 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1154 Other.Info =
nullptr;
1157 void maybeRestoreState() {
1161 Info->EvalStatus = OldStatus;
1162 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1166 SpeculativeEvaluationRAII() =
default;
1168 SpeculativeEvaluationRAII(
1169 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1170 : Info(&Info), OldStatus(Info.EvalStatus),
1171 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1172 Info.EvalStatus.Diag = NewDiag;
1173 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1176 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1177 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1178 moveFromAndCancel(std::move(
Other));
1181 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1182 maybeRestoreState();
1183 moveFromAndCancel(std::move(
Other));
1187 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1192 template<ScopeKind Kind>
1195 unsigned OldStackSize;
1197 ScopeRAII(EvalInfo &Info)
1198 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1201 Info.CurrentCall->pushTempVersion();
1203 bool destroy(
bool RunDestructors =
true) {
1204 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1205 OldStackSize = std::numeric_limits<unsigned>::max();
1209 if (OldStackSize != std::numeric_limits<unsigned>::max())
1213 Info.CurrentCall->popTempVersion();
1216 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1217 unsigned OldStackSize) {
1218 assert(OldStackSize <= Info.CleanupStack.size() &&
1219 "running cleanups out of order?");
1224 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1225 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1226 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1234 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1235 if (Kind != ScopeKind::Block)
1237 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1238 return C.isDestroyedAtEndOf(Kind);
1240 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1244 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1245 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1246 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1249bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1253 if (isOnePastTheEnd()) {
1254 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1265void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1267 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1272void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1277 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1278 Info.CCEDiag(E, diag::note_constexpr_array_index)
1280 <<
static_cast<unsigned>(getMostDerivedArraySize());
1282 Info.CCEDiag(E, diag::note_constexpr_array_index)
1287CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1288 const FunctionDecl *Callee,
const LValue *This,
1289 const Expr *CallExpr, CallRef Call)
1291 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1292 Index(Info.NextCallIndex++) {
1293 Info.CurrentCall =
this;
1294 ++Info.CallStackDepth;
1297CallStackFrame::~CallStackFrame() {
1298 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1299 --Info.CallStackDepth;
1300 Info.CurrentCall = Caller;
1325 llvm_unreachable(
"unknown access kind");
1362 llvm_unreachable(
"unknown access kind");
1366 struct ComplexValue {
1374 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1376 void makeComplexFloat() { IsInt =
false; }
1377 bool isComplexFloat()
const {
return !IsInt; }
1378 APFloat &getComplexFloatReal() {
return FloatReal; }
1379 APFloat &getComplexFloatImag() {
return FloatImag; }
1381 void makeComplexInt() { IsInt =
true; }
1382 bool isComplexInt()
const {
return IsInt; }
1383 APSInt &getComplexIntReal() {
return IntReal; }
1384 APSInt &getComplexIntImag() {
return IntImag; }
1386 void moveInto(
APValue &v)
const {
1387 if (isComplexFloat())
1388 v =
APValue(FloatReal, FloatImag);
1390 v =
APValue(IntReal, IntImag);
1392 void setFrom(
const APValue &v) {
1407 APValue::LValueBase
Base;
1409 SubobjectDesignator Designator;
1411 bool InvalidBase : 1;
1413 bool AllowConstexprUnknown =
false;
1415 const APValue::LValueBase getLValueBase()
const {
return Base; }
1416 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1417 CharUnits &getLValueOffset() {
return Offset; }
1418 CharUnits getLValueOffset()
const {
return Offset; }
1419 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1420 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1421 bool isNullPointer()
const {
return IsNullPtr;}
1423 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1424 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1426 bool pointsToCompleteClass(
const CXXRecordDecl *D)
const {
1427 if (Designator.Entries.empty())
1434 if (Designator.Invalid)
1435 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1437 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1438 V =
APValue(Base, Offset, Designator.Entries,
1439 Designator.IsOnePastTheEnd, IsNullPtr);
1441 if (AllowConstexprUnknown)
1442 V.setConstexprUnknown();
1444 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1445 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1446 Base =
V.getLValueBase();
1447 Offset =
V.getLValueOffset();
1448 InvalidBase =
false;
1449 Designator = SubobjectDesignator(Ctx,
V);
1450 IsNullPtr =
V.isNullPointer();
1451 AllowConstexprUnknown =
V.allowConstexprUnknown();
1454 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1458 const auto *E = B.
get<
const Expr *>();
1460 "Unexpected type of invalid base");
1466 InvalidBase = BInvalid;
1467 Designator = SubobjectDesignator(
getType(B));
1469 AllowConstexprUnknown =
false;
1472 void setNull(ASTContext &Ctx, QualType PointerTy) {
1473 Base = (
const ValueDecl *)
nullptr;
1476 InvalidBase =
false;
1479 AllowConstexprUnknown =
false;
1482 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1486 std::string
toString(ASTContext &Ctx, QualType
T)
const {
1488 moveInto(Printable);
1495 template <
typename GenDiagType>
1496 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1497 if (Designator.Invalid)
1501 Designator.setInvalid();
1508 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1510 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1511 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1515 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1517 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1518 if (AK == AccessKinds::AK_Dereference)
1519 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1521 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1529 Designator.checkSubobject(Info, E, CSK);
1532 void addDecl(EvalInfo &Info,
const Expr *E,
1533 const Decl *D,
bool Virtual =
false) {
1535 Designator.addDeclUnchecked(D,
Virtual);
1537 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1538 if (!Designator.Entries.empty()) {
1539 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1540 Designator.setInvalid();
1544 assert(!Base ||
getType(Base).getNonReferenceType()->isPointerType() ||
1545 getType(Base).getNonReferenceType()->isArrayType());
1546 Designator.FirstEntryIsAnUnsizedArray =
true;
1547 Designator.addUnsizedArrayUnchecked(ElemTy);
1550 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1552 Designator.addArrayUnchecked(CAT);
1554 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1556 Designator.addComplexUnchecked(EltTy, Imag);
1558 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1559 uint64_t Size, uint64_t Idx) {
1561 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1563 void clearIsNullPointer() {
1566 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1567 const APSInt &Index, CharUnits ElementSize) {
1578 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1582 Designator.adjustIndex(Info, E, Index, *
this);
1583 clearIsNullPointer();
1585 void adjustOffset(CharUnits N) {
1588 clearIsNullPointer();
1594 explicit MemberPtr(
const ValueDecl *Decl)
1595 : DeclAndIsDerivedMember(
Decl,
false) {}
1599 const ValueDecl *getDecl()
const {
1600 return DeclAndIsDerivedMember.getPointer();
1603 bool isDerivedMember()
const {
1604 return DeclAndIsDerivedMember.getInt();
1607 const CXXRecordDecl *getContainingRecord()
const {
1609 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1613 V =
APValue(getDecl(), isDerivedMember(), Path);
1616 assert(
V.isMemberPointer());
1617 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1618 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1620 llvm::append_range(Path,
V.getMemberPointerPath());
1626 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1629 SmallVector<const CXXRecordDecl*, 4> Path;
1633 bool castBack(
const CXXRecordDecl *
Class) {
1634 assert(!Path.empty());
1635 const CXXRecordDecl *Expected;
1636 if (Path.size() >= 2)
1637 Expected = Path[Path.size() - 2];
1639 Expected = getContainingRecord();
1653 bool castToDerived(
const CXXRecordDecl *Derived) {
1656 if (!isDerivedMember()) {
1657 Path.push_back(Derived);
1660 if (!castBack(Derived))
1663 DeclAndIsDerivedMember.setInt(
false);
1671 DeclAndIsDerivedMember.setInt(
true);
1672 if (isDerivedMember()) {
1673 Path.push_back(Base);
1676 return castBack(Base);
1681 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1682 if (!LHS.getDecl() || !RHS.getDecl())
1683 return !LHS.getDecl() && !RHS.getDecl();
1684 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1686 return LHS.Path == RHS.Path;
1690void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1694 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1695 if (isMostDerivedAnUnsizedArray()) {
1696 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1701 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1709 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1711 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1714 if (N < -(
int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1715 if (!Info.checkingPotentialConstantExpression() ||
1716 !LV.AllowConstexprUnknown) {
1719 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1720 (llvm::APInt &)N += ArrayIndex;
1721 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1722 diagnosePointerArithmetic(Info, E, N);
1728 ArrayIndex += TruncatedN;
1729 assert(ArrayIndex <= ArraySize &&
1730 "bounds check succeeded for out-of-bounds index");
1733 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1735 IsOnePastTheEnd = (ArrayIndex != 0);
1740 const LValue &This,
const Expr *E,
1741 bool AllowNonLiteralTypes =
false);
1743 bool InvalidBaseOK =
false);
1745 bool InvalidBaseOK =
false);
1753static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1758static std::optional<uint64_t>
1760 std::string *StringResult =
nullptr);
1777 if (
Int.isUnsigned() ||
Int.isMinSignedValue()) {
1778 Int =
Int.extend(
Int.getBitWidth() + 1);
1779 Int.setIsSigned(
true);
1784template<
typename KeyT>
1785APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType
T,
1786 ScopeKind Scope, LValue &LV) {
1787 unsigned Version = getTempVersion();
1788 APValue::LValueBase
Base(Key, Index, Version);
1790 return createLocal(Base, Key,
T, Scope);
1794APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1796 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1797 APValue::LValueBase
Base(PVD, Index, Args.Version);
1802 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1805APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1806 QualType
T, ScopeKind Scope) {
1807 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1808 unsigned Version =
Base.getVersion();
1810 assert(
Result.isAbsent() &&
"local created multiple times");
1816 if (Index <= Info.SpeculativeEvaluationDepth) {
1817 if (
T.isDestructedType())
1818 Info.noteSideEffect();
1829 "should only be called on dynamically allocated blocks");
1831 "__builtin_operator_new should have been allowed only from "
1832 "std::allocator::allocate");
1838 assert(
TypeAlignment > 0 &&
"Unknown alignment for allocated type!");
1842 if (AllocSize == 0) {
1843 switch (AllocKind) {
1857 llvm_unreachable(
"Unhandled DynAllocKind");
1861 assert(
TypeAlignment <= AllocSize &&
"Invalid alignment/size for type!");
1862 assert(AllocSize %
TypeAlignment == 0 &&
"Invalid alignment/size for type!");
1872 switch (AllocKind) {
1888 std::min(DefaultNewAlign, uint64_t(1) << llvm::countr_zero(AllocSize)));
1910 uint64_t MaxFundamentalAlign =
1913 {DefaultNewAlign, MaxFundamentalAlign, llvm::bit_floor(AllocSize)}));
1917 llvm_unreachable(
"Unhandled DynAllocKind");
1923 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1927 DynamicAllocLValue DA(NumHeapAllocs++, DynAlloc::kindOfExpr(E));
1929 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1930 std::forward_as_tuple(DA), std::tuple<>());
1931 assert(
Result.second &&
"reused a heap alloc index?");
1932 Result.first->second.AllocExpr = E;
1933 return &
Result.first->second.Value;
1937void CallStackFrame::describe(raw_ostream &Out)
const {
1938 bool IsMemberCall =
false;
1939 bool ExplicitInstanceParam =
false;
1940 clang::PrintingPolicy PrintingPolicy = Info.Ctx.getPrintingPolicy();
1943 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1945 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1949 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1952 if (This && IsMemberCall) {
1953 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1954 const Expr *
Object = MCE->getImplicitObjectArgument();
1955 Object->printPretty(Out,
nullptr, PrintingPolicy,
1957 if (
Object->getType()->isPointerType())
1961 }
else if (
const auto *OCE =
1962 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1963 OCE->getArg(0)->printPretty(Out,
nullptr, PrintingPolicy,
1968 This->moveInto(Val);
1971 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
1974 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1980 llvm::ListSeparator
Comma;
1981 for (
const ParmVarDecl *Param :
1982 Callee->parameters().slice(ExplicitInstanceParam)) {
1984 const APValue *
V = Info.getParamSlot(Arguments, Param);
1986 V->printPretty(Out, Info.Ctx, Param->getType());
2002 return Info.noteSideEffect();
2007 const auto *BaseExpr =
2008 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
2031 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
2032 return VD->hasGlobalStorage();
2046 case Expr::CompoundLiteralExprClass: {
2050 case Expr::MaterializeTemporaryExprClass:
2055 case Expr::StringLiteralClass:
2056 case Expr::PredefinedExprClass:
2057 case Expr::ObjCStringLiteralClass:
2058 case Expr::ObjCEncodeExprClass:
2060 case Expr::ObjCBoxedExprClass:
2061 case Expr::ObjCArrayLiteralClass:
2062 case Expr::ObjCDictionaryLiteralClass:
2064 case Expr::CallExprClass:
2067 case Expr::AddrLabelExprClass:
2071 case Expr::BlockExprClass:
2075 case Expr::SourceLocExprClass:
2077 case Expr::ImplicitValueInitExprClass:
2087 llvm_unreachable(
"Unhandled stmt kind in switch with default?");
2104 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2109 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2110 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2118 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2119 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2120 Lit = PE->getFunctionName();
2125 AsString.
Bytes = Lit->getBytes();
2126 AsString.
CharWidth = Lit->getCharByteWidth();
2146 const LValue &RHS) {
2155 CharUnits Offset = RHS.Offset - LHS.Offset;
2156 if (Offset.isNegative()) {
2157 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2159 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2161 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2163 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2166 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2167 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2168 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2169 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2174 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2175 if (Shorter.size() + NullByte >= Longer.size())
2177 if (Longer[Shorter.size() + NullByte])
2183 return Shorter == Longer.take_front(Shorter.size());
2193 if (isa_and_nonnull<VarDecl>(
Decl)) {
2203 if (!A.getLValueBase())
2204 return !B.getLValueBase();
2205 if (!B.getLValueBase())
2208 if (A.getLValueBase().getOpaqueValue() !=
2209 B.getLValueBase().getOpaqueValue())
2212 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2213 A.getLValueVersion() == B.getLValueVersion();
2217 assert(
Base &&
"no location for a null lvalue");
2223 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2225 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2226 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2227 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2228 Idx < F->Callee->getNumParams()) {
2229 VD = F->Callee->getParamDecl(Idx);
2236 Info.Note(VD->
getLocation(), diag::note_declared_at);
2238 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2241 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2242 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2243 diag::note_constexpr_dynamic_alloc_here);
2265 bool IsCompleteClass =
true);
2277 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2286 int InvalidBaseKind = -1;
2289 InvalidBaseKind = 0;
2290 else if (isa_and_nonnull<StringLiteral>(BaseE))
2291 InvalidBaseKind = 1;
2292 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2293 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2294 InvalidBaseKind = 2;
2295 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2296 InvalidBaseKind = 3;
2297 Ident = PE->getIdentKindName();
2300 if (InvalidBaseKind != -1) {
2301 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2302 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2308 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2309 FD && FD->isImmediateFunction()) {
2310 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2312 Info.Note(FD->getLocation(), diag::note_declared_at);
2320 if (Info.getLangOpts().CPlusPlus11) {
2321 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2322 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2324 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2325 if (VarD && VarD->isConstexpr()) {
2331 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2343 assert((Info.checkingPotentialConstantExpression() ||
2344 LVal.getLValueCallIndex() == 0) &&
2345 "have call index for global lvalue");
2347 if (LVal.allowConstexprUnknown()) {
2349 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2358 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2359 << IsReferenceType << !
Designator.Entries.empty();
2365 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2367 if (Var->getTLSKind())
2376 !Var->isStaticLocal())
2380 if (Info.getLangOpts().CUDA && Var->hasAttr<HIPManagedAttr>())
2385 if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
2386 Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
2387 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2388 !Var->hasAttr<CUDAConstantAttr>() &&
2389 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2390 !Var->getType()->isCUDADeviceBuiltinTextureType()))
2394 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2406 FD->hasAttr<DLLImportAttr>())
2410 }
else if (
const auto *MTE =
2411 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2412 if (CheckedTemps.insert(MTE).second) {
2415 Info.FFDiag(MTE->getExprLoc(),
2416 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2421 APValue *
V = MTE->getOrCreateValue(
false);
2422 assert(
V &&
"evasluation result refers to uninitialised temporary");
2424 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2425 nullptr, CheckedTemps))
2432 if (!IsReferenceType)
2444 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2445 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2460 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2463 if (FD->isImmediateFunction()) {
2464 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2465 Info.Note(FD->getLocation(), diag::note_declared_at);
2469 !FD->hasAttr<DLLImportAttr>();
2475 const LValue *
This =
nullptr) {
2477 if (Info.getLangOpts().CPlusPlus23)
2496 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2500 if (Info.getLangOpts().CPlusPlus11)
2501 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2504 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2514 bool IsCompleteClass) {
2516 if (SubobjectDecl) {
2517 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2518 << 1 << SubobjectDecl;
2520 diag::note_constexpr_subobject_declared_here);
2522 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2531 Type = AT->getValueType();
2536 if (
Value.isArray()) {
2538 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2540 Value.getArrayInitializedElt(I), Kind,
2541 SubobjectDecl, CheckedTemps))
2544 if (!
Value.hasArrayFiller())
2547 Value.getArrayFiller(), Kind, SubobjectDecl,
2550 if (
Value.isUnion() &&
Value.getUnionField()) {
2553 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2555 if (
Value.isStruct()) {
2557 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2558 unsigned BaseIndex = 0;
2562 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2565 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2566 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2571 CheckedTemps,
false))
2576 for (
const auto *I : RD->fields()) {
2577 if (I->isUnnamedBitField())
2581 Value.getStructField(I->getFieldIndex()), Kind,
2586 if (IsCompleteClass) {
2587 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2588 unsigned BaseIndex = 0;
2590 assert(BS.isVirtual());
2591 const APValue &BaseValue =
Value.getStructVirtualBase(BaseIndex);
2594 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2595 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2599 BaseValue, Kind,
nullptr,
2600 CheckedTemps,
false))
2608 if (
Value.isLValue() &&
2611 LVal.setFrom(Info.Ctx,
Value);
2616 if (
Value.isMemberPointer() &&
2637 nullptr, CheckedTemps);
2647 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2653 if (!Info.HeapAllocs.empty()) {
2657 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2658 diag::note_constexpr_memory_leak)
2659 <<
unsigned(Info.HeapAllocs.size() - 1);
2667 if (!
Value.getLValueBase()) {
2721 llvm_unreachable(
"unknown APValue kind");
2727 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2737 Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType;
2738 if (
const auto *OBT = DestType->
getAs<OverflowBehaviorType>();
2739 OBT && OBT->isTrapKind()) {
2742 return Info.noteUndefinedBehavior();
2748 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2759 if (
Value.convertToInteger(
Result, llvm::APFloat::rmTowardZero, &ignored)
2760 & APFloat::opInvalidOp)
2771 llvm::RoundingMode RM =
2773 if (RM == llvm::RoundingMode::Dynamic)
2774 RM = llvm::RoundingMode::NearestTiesToEven;
2783 APFloat::opStatus St) {
2786 if (Info.InConstantContext)
2790 if ((St & APFloat::opInexact) &&
2794 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2798 if ((St != APFloat::opOK) &&
2801 FPO.getAllowFEnvAccess())) {
2802 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2806 if ((St & APFloat::opStatus::opInvalidOp) &&
2827 "HandleFloatToFloatCast has been checked with only CastExpr, "
2828 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2829 "the new expression or address the root cause of this usage.");
2831 APFloat::opStatus St;
2833 St =
Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2840 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2854 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2856 APFloat::opStatus St =
Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2862 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2864 if (!
Value.isInt()) {
2868 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2874 unsigned OldBitWidth =
Int.getBitWidth();
2876 if (NewBitWidth < OldBitWidth)
2877 Int =
Int.trunc(NewBitWidth).extend(OldBitWidth);
2884template<
typename Operation>
2887 unsigned BitWidth, Operation Op,
2889 if (LHS.isUnsigned()) {
2894 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2897 if (Info.checkingForUndefinedBehavior())
2898 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2899 diag::warn_integer_constant_overflow)
2912 bool HandleOverflowResult =
true;
2919 std::multiplies<APSInt>(),
Result);
2922 std::plus<APSInt>(),
Result);
2925 std::minus<APSInt>(),
Result);
2926 case BO_And:
Result = LHS & RHS;
return true;
2927 case BO_Xor:
Result = LHS ^ RHS;
return true;
2928 case BO_Or:
Result = LHS | RHS;
return true;
2932 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2938 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2939 LHS.isMinSignedValue())
2941 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2942 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2943 return HandleOverflowResult;
2945 if (Info.getLangOpts().OpenCL)
2947 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2948 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2950 else if (RHS.isSigned() && RHS.isNegative()) {
2953 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2954 if (!Info.noteUndefinedBehavior())
2962 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2964 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2965 << RHS << E->
getType() << LHS.getBitWidth();
2966 if (!Info.noteUndefinedBehavior())
2968 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2973 if (LHS.isNegative()) {
2974 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2975 if (!Info.noteUndefinedBehavior())
2977 }
else if (LHS.countl_zero() < SA) {
2978 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2979 if (!Info.noteUndefinedBehavior())
2987 if (Info.getLangOpts().OpenCL)
2989 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2990 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2992 else if (RHS.isSigned() && RHS.isNegative()) {
2995 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2996 if (!Info.noteUndefinedBehavior())
3004 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
3006 Info.CCEDiag(E, diag::note_constexpr_large_shift)
3007 << RHS << E->
getType() << LHS.getBitWidth();
3008 if (!Info.noteUndefinedBehavior())
3016 case BO_LT:
Result = LHS < RHS;
return true;
3017 case BO_GT:
Result = LHS > RHS;
return true;
3018 case BO_LE:
Result = LHS <= RHS;
return true;
3019 case BO_GE:
Result = LHS >= RHS;
return true;
3020 case BO_EQ:
Result = LHS == RHS;
return true;
3021 case BO_NE:
Result = LHS != RHS;
return true;
3023 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
3030 const APFloat &RHS) {
3032 APFloat::opStatus St;
3038 St = LHS.multiply(RHS, RM);
3041 St = LHS.add(RHS, RM);
3044 St = LHS.subtract(RHS, RM);
3050 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
3051 St = LHS.divide(RHS, RM);
3064 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
3065 return Info.noteUndefinedBehavior();
3073 const APInt &RHSValue, APInt &
Result) {
3074 bool LHS = (LHSValue != 0);
3075 bool RHS = (RHSValue != 0);
3077 if (Opcode == BO_LAnd)
3085 const APFloat &RHSValue, APInt &
Result) {
3086 bool LHS = !LHSValue.isZero();
3087 bool RHS = !RHSValue.isZero();
3089 if (Opcode == BO_LAnd)
3108template <
typename APTy>
3111 const APTy &RHSValue, APInt &
Result) {
3114 llvm_unreachable(
"unsupported binary operator");
3116 Result = (LHSValue == RHSValue);
3119 Result = (LHSValue != RHSValue);
3122 Result = (LHSValue < RHSValue);
3125 Result = (LHSValue > RHSValue);
3128 Result = (LHSValue <= RHSValue);
3131 Result = (LHSValue >= RHSValue);
3160 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3161 "Operation not supported on vector types");
3165 QualType EltTy = VT->getElementType();
3172 "A vector result that isn't a vector OR uncalculated LValue");
3178 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3182 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3187 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3197 RHSElt.
getInt(), EltResult);
3203 ResultElements.emplace_back(EltResult);
3208 "Mismatched LHS/RHS/Result Type");
3209 APFloat LHSFloat = LHSElt.
getFloat();
3217 ResultElements.emplace_back(LHSFloat);
3221 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3229 unsigned TruncatedElements) {
3230 SubobjectDesignator &D =
Result.Designator;
3233 if (TruncatedElements == D.Entries.size())
3235 assert(TruncatedElements >= D.MostDerivedPathLength &&
3236 "not casting to a derived class");
3242 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3246 if (isVirtualBaseClass(D.Entries[I]))
3252 D.Entries.resize(TruncatedElements);
3262 RL = &Info.Ctx.getASTRecordLayout(Derived);
3265 Obj.addDecl(Info, E,
Base,
false);
3266 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3278 RL = &Info.Ctx.getASTRecordLayout(Derived);
3281 Obj.addDecl(Info, E,
Base,
true);
3282 Obj.getLValueOffset() += RL->getVBaseClassOffset(
Base);
3291 if (!
Base->isVirtual())
3294 SubobjectDesignator &D = Obj.Designator;
3309 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3310 Obj.addDecl(Info, E, BaseDecl,
true);
3319 PathI != PathE; ++PathI) {
3323 Type = (*PathI)->getType();
3335 llvm_unreachable(
"Class must be derived from the passed in base class!");
3359 RL = &Info.Ctx.getASTRecordLayout(RD);
3363 LVal.addDecl(Info, E, FD);
3364 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3372 for (
const auto *
C : IFD->
chain())
3406 Size = Info.Ctx.getTypeSizeInChars(
Type);
3408 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3425 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3433 APSInt::get(Adjustment));
3448 LVal.Offset += SizeOfComponent;
3450 LVal.addComplex(Info, E, EltTy, Imag);
3456 uint64_t Size, uint64_t Idx) {
3461 LVal.Offset += SizeOfElement * Idx;
3463 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3477 const VarDecl *VD, CallStackFrame *Frame,
3481 bool AllowConstexprUnknown =
3486 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3498 if (!AllowConstexprUnknown || IsLocalVariable) {
3499 if (!Info.checkingPotentialConstantExpression())
3500 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3510 Result = Frame->getTemporary(VD, Version);
3512 return CheckUninitReference(
true);
3521 "missing value for local variable");
3522 if (Info.checkingPotentialConstantExpression())
3526 "A variable in a frame should either be a local or a parameter");
3532 if (Info.EvaluatingDecl ==
Base) {
3533 Result = Info.EvaluatingDeclValue;
3534 return CheckUninitReference(
false);
3542 if (AllowConstexprUnknown) {
3549 if (!Info.checkingPotentialConstantExpression() ||
3550 !Info.CurrentCall->Callee ||
3552 if (Info.getLangOpts().CPlusPlus11) {
3553 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3574 if (!
Init && !AllowConstexprUnknown) {
3577 if (!Info.checkingPotentialConstantExpression()) {
3578 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3589 if (
Init &&
Init->isValueDependent()) {
3590 if (!Info.checkingPotentialConstantExpression()) {
3592 Info.getLangOpts().CPlusPlus11
3593 ? diag::note_constexpr_ltor_non_constexpr
3594 : diag::note_constexpr_ltor_non_integral,
3602 if (
Init->containsErrors())
3621 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3637 !AllowConstexprUnknown) ||
3638 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3641 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3651 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3658 if (!
Result && !AllowConstexprUnknown)
3661 return CheckUninitReference(
false);
3684 llvm_unreachable(
"base class missing from derived class's bases list");
3691 "SourceLocExpr should have already been converted to a StringLiteral");
3694 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3696 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3697 assert(Index <= Str.size() &&
"Index too large");
3698 return APSInt::getUnsigned(Str.c_str()[Index]);
3701 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3702 Lit = PE->getFunctionName();
3705 Info.Ctx.getAsConstantArrayType(S->
getType());
3706 assert(CAT &&
"string literal isn't an array");
3708 assert(CharType->
isIntegerType() &&
"unexpected character type");
3711 if (Index < S->getLength())
3724 AllocType.isNull() ? S->
getType() : AllocType);
3725 assert(CAT &&
"string literal isn't an array");
3727 assert(CharType->
isIntegerType() &&
"unexpected character type");
3734 if (
Result.hasArrayFiller())
3736 for (
unsigned I = 0, N =
Result.getArrayInitializedElts(); I != N; ++I) {
3744 unsigned Size =
Array.getArraySize();
3745 assert(Index < Size);
3748 unsigned OldElts =
Array.getArrayInitializedElts();
3749 unsigned NewElts = std::max(Index+1, OldElts * 2);
3750 NewElts = std::min(Size, std::max(NewElts, 8u));
3754 for (
unsigned I = 0; I != OldElts; ++I)
3756 for (
unsigned I = OldElts; I != NewElts; ++I)
3760 Array.swap(NewValue);
3767 Vec =
APValue(Elts.data(), Elts.size());
3777 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3788 for (
auto *Field : RD->
fields())
3789 if (!Field->isUnnamedBitField() &&
3793 for (
auto &BaseSpec : RD->
bases())
3804 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3811 for (
auto *Field : RD->
fields()) {
3816 if (Field->isMutable() &&
3818 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3819 Info.Note(Field->getLocation(), diag::note_declared_at);
3827 for (
auto &BaseSpec : RD->
bases())
3837 bool MutableSubobject =
false) {
3842 switch (Info.IsEvaluatingDecl) {
3843 case EvalInfo::EvaluatingDeclKind::None:
3846 case EvalInfo::EvaluatingDeclKind::Ctor:
3848 if (Info.EvaluatingDecl ==
Base)
3853 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3854 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3855 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3858 case EvalInfo::EvaluatingDeclKind::Dtor:
3863 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3869 return T.isConstQualified() ||
T->isReferenceType();
3872 llvm_unreachable(
"unknown evaluating decl kind");
3877 return Info.CheckArraySize(
3897 uint64_t IntResult = BoolResult;
3900 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3901 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3906 Info.Ctx.getIntTypeForBitwidth(64,
false),
3909 Result = std::move(Result2);
3917 DestTy,
Result.getFloat());
3923 uint64_t IntResult = BoolResult;
3942 uint64_t IntResult = BoolResult;
3949 DestTy,
Result.getInt());
3953 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3966 {&
Result, ResultType, 0}};
3969 while (!WorkList.empty() && ElI < Elements.size()) {
3970 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3987 unsigned OldBitWidth =
Int.getBitWidth();
3988 unsigned NewBitWidth = BitWidth;
3989 if (NewBitWidth < OldBitWidth)
3990 Int =
Int.trunc(NewBitWidth).extend(OldBitWidth);
3999 for (
unsigned I = 0; I < NumEl; ++I) {
4005 *Res =
APValue(Vals.data(), NumEl);
4014 for (
int64_t I = Size - 1; I > -1; --I)
4015 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
4021 unsigned NumBases = 0;
4022 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
4023 NumBases = CXXRD->getNumBases();
4030 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4031 if (CXXRD->getNumBases() > 0) {
4032 assert(CXXRD->getNumBases() == 1);
4034 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
4041 if (FD->isUnnamedBitField())
4043 if (FD->isBitField()) {
4044 FDBW = FD->getBitWidthValue();
4047 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
4048 FD->getType(), FDBW);
4051 std::reverse(ReverseList.begin(), ReverseList.end());
4052 llvm::append_range(WorkList, ReverseList);
4055 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4068 assert((Elements.size() == SrcTypes.size()) &&
4069 (Elements.size() == DestTypes.size()));
4071 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
4072 APValue Original = Elements[I];
4076 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
4087 while (!WorkList.empty()) {
4110 for (uint64_t I = 0; I < ArrSize; ++I) {
4111 WorkList.push_back(ElTy);
4119 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4120 if (CXXRD->getNumBases() > 0) {
4121 assert(CXXRD->getNumBases() == 1);
4123 WorkList.push_back(BS.
getType());
4129 if (FD->isUnnamedBitField())
4131 WorkList.push_back(FD->getType());
4148 "Not a valid HLSLAggregateSplatCast.");
4168 unsigned Populated = 0;
4169 while (!WorkList.empty() && Populated < Size) {
4170 auto [Work,
Type] = WorkList.pop_back_val();
4172 if (Work.isFloat() || Work.isInt()) {
4173 Elements.push_back(Work);
4174 Types.push_back(
Type);
4178 if (Work.isVector()) {
4181 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4183 Elements.push_back(Work.getVectorElt(I));
4184 Types.push_back(ElTy);
4189 if (Work.isMatrix()) {
4192 QualType ElTy = MT->getElementType();
4194 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4196 for (
unsigned Col = 0;
4197 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4198 Elements.push_back(Work.getMatrixElt(Row, Col));
4199 Types.push_back(ElTy);
4205 if (Work.isArray()) {
4209 for (
int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4210 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4215 if (Work.isStruct()) {
4223 if (FD->isUnnamedBitField())
4225 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4229 std::reverse(ReverseList.begin(), ReverseList.end());
4230 llvm::append_range(WorkList, ReverseList);
4233 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4234 if (CXXRD->getNumBases() > 0) {
4235 assert(CXXRD->getNumBases() == 1);
4240 if (!
Base.isStruct())
4248 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4257struct CompleteObject {
4259 APValue::LValueBase
Base;
4269 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4280 if (!Info.getLangOpts().CPlusPlus14 &&
4281 AK != AccessKinds::AK_IsWithinLifetime)
4286 explicit operator bool()
const {
return !
Type.isNull(); }
4291 bool IsMutable =
false) {
4305template <
typename Sub
objectHandler>
4306static typename SubobjectHandler::result_type
4308 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4311 return handler.failed();
4312 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4313 if (Info.getLangOpts().CPlusPlus11)
4314 Info.FFDiag(E, Sub.isOnePastTheEnd()
4315 ? diag::note_constexpr_access_past_end
4316 : diag::note_constexpr_access_unsized_array)
4317 << handler.AccessKind;
4320 return handler.failed();
4326 const FieldDecl *VolatileField =
nullptr;
4329 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4340 if (!Info.checkingPotentialConstantExpression()) {
4341 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4346 return handler.failed();
4354 Info.isEvaluatingCtorDtor(
4355 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4356 ConstructionPhase::None) {
4357 ObjType = Info.Ctx.getCanonicalType(ObjType);
4366 if (Info.getLangOpts().CPlusPlus) {
4370 if (VolatileField) {
4373 Decl = VolatileField;
4376 Loc = VD->getLocation();
4383 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4384 << handler.AccessKind << DiagKind <<
Decl;
4385 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4387 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4389 return handler.failed();
4397 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4399 return handler.failed();
4403 if (!handler.found(*O, ObjType, Obj.Base))
4415 LastField =
nullptr;
4420 ObjType = Info.Ctx.getQualifiedType(AT->getValueType(),
4425 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4427 "vla in literal type?");
4428 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4429 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4430 CAT && CAT->
getSize().ule(Index)) {
4433 if (Info.getLangOpts().CPlusPlus11)
4434 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4435 << handler.AccessKind;
4438 return handler.failed();
4445 else if (!
isRead(handler.AccessKind)) {
4446 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4448 return handler.failed();
4456 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4458 if (Info.getLangOpts().CPlusPlus11)
4459 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4460 << handler.AccessKind;
4463 return handler.failed();
4469 assert(I == N - 1 &&
"extracting subobject of scalar?");
4479 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4480 unsigned NumElements = VT->getNumElements();
4481 if (Index == NumElements) {
4482 if (Info.getLangOpts().CPlusPlus11)
4483 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4484 << handler.AccessKind;
4487 return handler.failed();
4490 if (Index > NumElements) {
4491 Info.CCEDiag(E, diag::note_constexpr_array_index)
4492 << Index << 0 << NumElements;
4493 return handler.failed();
4496 ObjType = VT->getElementType();
4497 assert(I == N - 1 &&
"extracting subobject of scalar?");
4500 if (
isRead(handler.AccessKind)) {
4502 return handler.failed();
4506 assert(O->
isVector() &&
"unexpected object during vector element access");
4507 return handler.found(O->
getVectorElt(Index), ObjType, Obj.Base);
4508 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4509 if (Field->isMutable() &&
4510 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4511 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4512 << handler.AccessKind << Field;
4513 Info.Note(Field->getLocation(), diag::note_declared_at);
4514 return handler.failed();
4523 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4534 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4535 << handler.AccessKind << Field << !UnionField << UnionField;
4536 return handler.failed();
4545 if (Field->getType().isVolatileQualified())
4546 VolatileField = Field;
4554 if (BaseIndex >= NumNonVirtualBases) {
4565struct ExtractSubobjectHandler {
4571 typedef bool result_type;
4572 bool failed() {
return false; }
4573 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4583 bool found(APFloat &
Value, QualType SubobjType) {
4592 const CompleteObject &Obj,
4596 ExtractSubobjectHandler Handler = {Info, E,
Result, AK};
4601struct ModifySubobjectHandler {
4606 typedef bool result_type;
4609 bool checkConst(QualType QT) {
4612 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4618 bool failed() {
return false; }
4619 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4620 if (!checkConst(SubobjType))
4623 Subobj.
swap(NewVal);
4627 if (!checkConst(SubobjType))
4629 if (!NewVal.
isInt()) {
4637 bool found(APFloat &
Value, QualType SubobjType) {
4638 if (!checkConst(SubobjType))
4646const AccessKinds ModifySubobjectHandler::AccessKind;
4650 const CompleteObject &Obj,
4651 const SubobjectDesignator &Sub,
4653 ModifySubobjectHandler Handler = { Info, NewVal, E };
4660 const SubobjectDesignator &A,
4661 const SubobjectDesignator &B,
4662 bool &WasArrayIndex) {
4663 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4664 for (; I != N; ++I) {
4668 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4669 WasArrayIndex =
true;
4677 if (A.Entries[I].getAsBaseOrMember() !=
4678 B.Entries[I].getAsBaseOrMember()) {
4679 WasArrayIndex =
false;
4682 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4684 ObjType = FD->getType();
4690 WasArrayIndex =
false;
4697 const SubobjectDesignator &A,
4698 const SubobjectDesignator &B) {
4699 if (A.Entries.size() != B.Entries.size())
4702 bool IsArray = A.MostDerivedIsArrayElement;
4703 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4712 return CommonLength >= A.Entries.size() - IsArray;
4719 if (LVal.InvalidBase) {
4721 return CompleteObject();
4726 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4728 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4729 return CompleteObject();
4732 CallStackFrame *Frame =
nullptr;
4734 if (LVal.getLValueCallIndex()) {
4735 std::tie(Frame, Depth) =
4736 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4738 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4741 return CompleteObject();
4752 if (Info.getLangOpts().CPlusPlus)
4753 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4757 return CompleteObject();
4764 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4768 BaseVal = Info.EvaluatingDeclValue;
4771 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4774 Info.FFDiag(E, diag::note_constexpr_modify_global);
4775 return CompleteObject();
4779 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4781 return CompleteObject();
4783 return CompleteObject(LVal.Base, &
V, GD->getType());
4787 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4789 Info.FFDiag(E, diag::note_constexpr_modify_global);
4790 return CompleteObject();
4792 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4797 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4799 Info.FFDiag(E, diag::note_constexpr_modify_global);
4800 return CompleteObject();
4802 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4813 const VarDecl *VD = dyn_cast<VarDecl>(D);
4820 return CompleteObject();
4823 bool IsConstant = BaseType.isConstant(Info.Ctx);
4824 bool ConstexprVar =
false;
4825 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4837 }
else if (Info.getLangOpts().CPlusPlus14 &&
4844 Info.FFDiag(E, diag::note_constexpr_modify_global);
4845 return CompleteObject();
4848 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4850 return CompleteObject();
4853 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4854 Info.FFDiag(E, diag::note_constexpr_ltor_for_range_var) << VD;
4855 return CompleteObject();
4856 }
else if (BaseType->isIntegralOrEnumerationType()) {
4859 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4860 if (Info.getLangOpts().CPlusPlus) {
4861 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4862 Info.Note(VD->
getLocation(), diag::note_declared_at);
4866 return CompleteObject();
4868 }
else if (!IsAccess) {
4869 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4870 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4871 Info.checkingPotentialConstantExpression() &&
4872 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4874 }
else if (IsConstant) {
4878 if (Info.getLangOpts().CPlusPlus) {
4879 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4880 ? diag::note_constexpr_ltor_non_constexpr
4881 : diag::note_constexpr_ltor_non_integral, 1)
4883 Info.Note(VD->
getLocation(), diag::note_declared_at);
4889 if (Info.getLangOpts().CPlusPlus) {
4890 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4891 ? diag::note_constexpr_ltor_non_constexpr
4892 : diag::note_constexpr_ltor_non_integral, 1)
4894 Info.Note(VD->
getLocation(), diag::note_declared_at);
4898 return CompleteObject();
4907 return CompleteObject();
4912 if (!Info.checkingPotentialConstantExpression()) {
4913 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4915 Info.Note(VD->getLocation(), diag::note_declared_at);
4917 return CompleteObject();
4920 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4922 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4923 return CompleteObject();
4925 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4935 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4936 assert(MTE->getStorageDuration() ==
SD_Static &&
4937 "should have a frame for a non-global materialized temporary");
4964 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4967 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4968 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4969 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4970 return CompleteObject();
4973 BaseVal = MTE->getOrCreateValue(
false);
4974 assert(BaseVal &&
"got reference to unevaluated temporary");
4976 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4992 !CLETy.isConstant(Info.Ctx)) {
4994 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4995 return CompleteObject();
4998 BaseVal = &CLE->getStaticValue();
5001 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
5004 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
5007 Info.Ctx.getLValueReferenceType(LValType));
5009 return CompleteObject();
5013 assert(BaseVal &&
"missing value for temporary");
5024 unsigned VisibleDepth = Depth;
5025 if (llvm::isa_and_nonnull<ParmVarDecl>(
5028 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
5029 Info.EvalStatus.HasSideEffects) ||
5030 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
5031 return CompleteObject();
5033 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
5052 const LValue &LVal,
APValue &RVal,
5053 bool WantObjectRepresentation =
false) {
5054 if (LVal.Designator.Invalid)
5063 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
5067 assert(LVal.Designator.Entries.size() <= 1 &&
5068 "Can only read characters from string literals");
5069 if (LVal.Designator.Entries.empty()) {
5076 if (LVal.Designator.isOnePastTheEnd()) {
5077 if (Info.getLangOpts().CPlusPlus11)
5078 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
5083 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
5090 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
5104 LVal.setFrom(Info.Ctx, Val);
5120 if (LVal.Designator.Invalid)
5123 if (!Info.getLangOpts().CPlusPlus14) {
5133struct CompoundAssignSubobjectHandler {
5135 const CompoundAssignOperator *E;
5136 QualType PromotedLHSType;
5142 typedef bool result_type;
5144 bool checkConst(QualType QT) {
5147 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5153 bool failed() {
return false; }
5154 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5157 return found(Subobj.
getInt(), SubobjType);
5159 return found(Subobj.
getFloat(), SubobjType);
5166 return foundPointer(Subobj, SubobjType);
5168 return foundVector(Subobj, SubobjType);
5170 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5182 bool foundVector(
APValue &
Value, QualType SubobjType) {
5183 if (!checkConst(SubobjType))
5194 if (!checkConst(SubobjType))
5213 Info.Ctx.getLangOpts());
5216 PromotedLHSType, FValue) &&
5225 bool found(APFloat &
Value, QualType SubobjType) {
5226 return checkConst(SubobjType) &&
5232 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5233 if (!checkConst(SubobjType))
5236 QualType PointeeType;
5237 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5241 (Opcode != BO_Add && Opcode != BO_Sub)) {
5247 if (Opcode == BO_Sub)
5251 LVal.setFrom(Info.Ctx, Subobj);
5254 LVal.moveInto(Subobj);
5260const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5265 const LValue &LVal,
QualType LValType,
5269 if (LVal.Designator.Invalid)
5272 if (!Info.getLangOpts().CPlusPlus14) {
5278 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5280 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5284struct IncDecSubobjectHandler {
5286 const UnaryOperator *E;
5290 typedef bool result_type;
5292 bool checkConst(QualType QT) {
5295 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5301 bool failed() {
return false; }
5302 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5312 return found(Subobj.
getInt(), SubobjType);
5314 return found(Subobj.
getFloat(), SubobjType);
5317 SubobjType->
castAs<ComplexType>()->getElementType()
5321 SubobjType->
castAs<ComplexType>()->getElementType()
5324 return foundPointer(Subobj, SubobjType);
5332 if (!checkConst(SubobjType))
5354 bool WasNegative =
Value.isNegative();
5368 unsigned BitWidth =
Value.getBitWidth();
5369 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5370 ActualValue.setBit(BitWidth);
5376 bool found(APFloat &
Value, QualType SubobjType) {
5377 if (!checkConst(SubobjType))
5384 APFloat::opStatus St;
5386 St =
Value.add(One, RM);
5388 St =
Value.subtract(One, RM);
5391 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5392 if (!checkConst(SubobjType))
5395 QualType PointeeType;
5396 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5404 LVal.setFrom(Info.Ctx, Subobj);
5408 LVal.moveInto(Subobj);
5417 if (LVal.Designator.Invalid)
5420 if (!Info.getLangOpts().CPlusPlus14) {
5428 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5434 if (
Object->getType()->isPointerType() &&
Object->isPRValue())
5440 if (
Object->getType()->isLiteralType(Info.Ctx))
5443 if (
Object->getType()->isRecordType() &&
Object->isPRValue())
5446 Info.FFDiag(
Object, diag::note_constexpr_nonliteral) <<
Object->getType();
5465 bool IncludeMember =
true) {
5472 if (!MemPtr.getDecl()) {
5478 if (MemPtr.isDerivedMember()) {
5485 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5486 LV.Designator.Entries.size()) {
5490 unsigned PathLengthToMember =
5491 LV.Designator.Entries.size() - MemPtr.Path.size();
5492 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5494 LV.Designator.Entries[PathLengthToMember + I]);
5511 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5512 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5514 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5522 PathLengthToMember))
5524 }
else if (!MemPtr.Path.empty()) {
5526 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5527 MemPtr.Path.size() + IncludeMember);
5533 assert(RD &&
"member pointer access on non-class-type expression");
5535 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5543 MemPtr.getContainingRecord()))
5548 if (IncludeMember) {
5549 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5553 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5557 llvm_unreachable(
"can't construct reference to bound member function");
5561 return MemPtr.getDecl();
5567 bool IncludeMember =
true) {
5571 if (Info.noteFailure()) {
5579 BO->
getRHS(), IncludeMember);
5586 SubobjectDesignator &D =
Result.Designator;
5594 auto InvalidCast = [&]() {
5595 if (!Info.checkingPotentialConstantExpression() ||
5596 !
Result.AllowConstexprUnknown) {
5597 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5598 << D.MostDerivedType << TargetQT;
5604 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5605 return InvalidCast();
5609 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5612 if (NewEntriesSize == D.MostDerivedPathLength)
5615 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5617 return InvalidCast();
5626 bool IsCompleteClass =
true) {
5633 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5634 if (RD->isInvalidDecl()) {
5638 if (RD->isUnion()) {
5644 unsigned NonVirtualBases = countNonVirtualBases(RD);
5647 IsCompleteClass ? RD->getNumVBases() : 0);
5658 for (
const auto *I : RD->fields()) {
5659 if (I->isUnnamedBitField())
5662 I->getType(),
Result.getStructField(I->getFieldIndex()));
5665 if (IsCompleteClass) {
5668 for (
const auto &B : RD->vbases()) {
5670 Result.getStructVirtualBase(Index),
5676 assert(
Result.getStructNumVirtualBases() == 0);
5683 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5685 if (
Result.hasArrayFiller())
5696enum EvalStmtResult {
5725 if (!
Result.Designator.Invalid &&
Result.Designator.isOnePastTheEnd()) {
5743 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5744 ScopeKind::Block,
Result);
5749 return Info.noteSideEffect();
5770 const DecompositionDecl *DD);
5773 bool EvaluateConditionDecl =
false) {
5775 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5779 EvaluateConditionDecl && DD)
5789 if (
auto *VD = BD->getHoldingVar())
5797 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5806 if (Info.noteSideEffect())
5808 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5809 "reach invalid code path.");
5818 FullExpressionRAII
Scope(Info);
5825 return Scope.destroy();
5838struct TempVersionRAII {
5839 CallStackFrame &Frame;
5841 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5842 Frame.pushTempVersion();
5845 ~TempVersionRAII() {
5846 Frame.popTempVersion();
5854 const SwitchCase *SC =
nullptr);
5860 const Stmt *LoopOrSwitch,
5862 EvalStmtResult &ESR) {
5866 if (!IsSwitch && ESR == ESR_Succeeded) {
5871 if (ESR != ESR_Break && ESR != ESR_Continue)
5875 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5876 const Stmt *StackTop = Info.BreakContinueStack.back();
5877 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5878 Info.BreakContinueStack.pop_back();
5879 if (ESR == ESR_Break)
5880 ESR = ESR_Succeeded;
5885 for (BlockScopeRAII *S : Scopes) {
5886 if (!S->destroy()) {
5898 BlockScopeRAII
Scope(Info);
5901 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5910 BlockScopeRAII
Scope(Info);
5917 if (ESR != ESR_Succeeded) {
5918 if (ESR != ESR_Failed && !
Scope.destroy())
5924 FullExpressionRAII CondScope(Info);
5939 if (!CondScope.destroy())
5960 if (LHSValue <=
Value &&
Value <= RHSValue) {
5967 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5971 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5978 llvm_unreachable(
"Should have been converted to Succeeded");
5984 case ESR_CaseNotFound:
5987 Info.FFDiag(
Found->getBeginLoc(),
5988 diag::note_constexpr_stmt_expr_unsupported);
5991 llvm_unreachable(
"Invalid EvalStmtResult!");
6001 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
6011 if (!Info.nextStep(S))
6018 case Stmt::CompoundStmtClass:
6022 case Stmt::LabelStmtClass:
6023 case Stmt::AttributedStmtClass:
6024 case Stmt::DoStmtClass:
6027 case Stmt::CaseStmtClass:
6028 case Stmt::DefaultStmtClass:
6033 case Stmt::IfStmtClass: {
6040 BlockScopeRAII
Scope(Info);
6046 if (ESR != ESR_CaseNotFound) {
6047 assert(ESR != ESR_Succeeded);
6058 if (ESR == ESR_Failed)
6060 if (ESR != ESR_CaseNotFound)
6061 return Scope.destroy() ? ESR : ESR_Failed;
6063 return ESR_CaseNotFound;
6066 if (ESR == ESR_Failed)
6068 if (ESR != ESR_CaseNotFound)
6069 return Scope.destroy() ? ESR : ESR_Failed;
6070 return ESR_CaseNotFound;
6073 case Stmt::WhileStmtClass: {
6074 EvalStmtResult ESR =
6078 if (ESR != ESR_Continue)
6083 case Stmt::ForStmtClass: {
6085 BlockScopeRAII
Scope(Info);
6091 if (ESR != ESR_CaseNotFound) {
6092 assert(ESR != ESR_Succeeded);
6097 EvalStmtResult ESR =
6101 if (ESR != ESR_Continue)
6103 if (
const auto *Inc = FS->
getInc()) {
6104 if (Inc->isValueDependent()) {
6108 FullExpressionRAII IncScope(Info);
6116 case Stmt::DeclStmtClass: {
6120 for (
const auto *D : DS->
decls()) {
6121 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
6124 if (VD->hasLocalStorage() && !VD->getInit())
6132 return ESR_CaseNotFound;
6136 return ESR_CaseNotFound;
6142 if (
const Expr *E = dyn_cast<Expr>(S)) {
6151 FullExpressionRAII
Scope(Info);
6155 return ESR_Succeeded;
6161 case Stmt::NullStmtClass:
6162 return ESR_Succeeded;
6164 case Stmt::DeclStmtClass: {
6166 for (
const auto *D : DS->
decls()) {
6167 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
6171 if (
const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6172 assert(ESD->getInstantiations() &&
"not expanded?");
6177 FullExpressionRAII
Scope(Info);
6179 !Info.noteFailure())
6181 if (!
Scope.destroy())
6184 return ESR_Succeeded;
6187 case Stmt::ReturnStmtClass: {
6189 FullExpressionRAII
Scope(Info);
6200 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6203 case Stmt::CompoundStmtClass: {
6204 BlockScopeRAII
Scope(Info);
6207 for (
const auto *BI : CS->
body()) {
6209 if (ESR == ESR_Succeeded)
6211 else if (ESR != ESR_CaseNotFound) {
6212 if (ESR != ESR_Failed && !
Scope.destroy())
6218 return ESR_CaseNotFound;
6219 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6222 case Stmt::IfStmtClass: {
6226 BlockScopeRAII
Scope(Info);
6229 if (ESR != ESR_Succeeded) {
6230 if (ESR != ESR_Failed && !
Scope.destroy())
6240 if (!Info.InConstantContext)
6248 if (ESR != ESR_Succeeded) {
6249 if (ESR != ESR_Failed && !
Scope.destroy())
6254 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6257 case Stmt::WhileStmtClass: {
6260 BlockScopeRAII
Scope(Info);
6272 if (ESR != ESR_Continue) {
6273 if (ESR != ESR_Failed && !
Scope.destroy())
6277 if (!
Scope.destroy())
6280 return ESR_Succeeded;
6283 case Stmt::DoStmtClass: {
6290 if (ESR != ESR_Continue)
6299 FullExpressionRAII CondScope(Info);
6301 !CondScope.destroy())
6304 return ESR_Succeeded;
6307 case Stmt::ForStmtClass: {
6309 BlockScopeRAII ForScope(Info);
6312 if (ESR != ESR_Succeeded) {
6313 if (ESR != ESR_Failed && !ForScope.destroy())
6319 BlockScopeRAII IterScope(Info);
6320 bool Continue =
true;
6326 if (!IterScope.destroy())
6334 if (ESR != ESR_Continue) {
6335 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6340 if (
const auto *Inc = FS->
getInc()) {
6341 if (Inc->isValueDependent()) {
6345 FullExpressionRAII IncScope(Info);
6351 if (!IterScope.destroy())
6354 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6357 case Stmt::CXXForRangeStmtClass: {
6359 BlockScopeRAII
Scope(Info);
6364 if (ESR != ESR_Succeeded) {
6365 if (ESR != ESR_Failed && !
Scope.destroy())
6373 if (ESR != ESR_Succeeded) {
6374 if (ESR != ESR_Failed && !
Scope.destroy())
6386 if (ESR != ESR_Succeeded) {
6387 if (ESR != ESR_Failed && !
Scope.destroy())
6392 if (ESR != ESR_Succeeded) {
6393 if (ESR != ESR_Failed && !
Scope.destroy())
6406 bool Continue =
true;
6407 FullExpressionRAII CondExpr(Info);
6415 BlockScopeRAII InnerScope(Info);
6417 if (ESR != ESR_Succeeded) {
6418 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6427 if (ESR != ESR_Continue) {
6428 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6441 if (!InnerScope.destroy())
6445 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6448 case Stmt::CXXExpansionStmtInstantiationClass: {
6449 BlockScopeRAII
Scope(Info);
6451 for (
const Stmt *PreambleStmt : Expansion->getPreambleStmts()) {
6453 if (ESR != ESR_Succeeded) {
6454 if (ESR != ESR_Failed && !
Scope.destroy())
6462 EvalStmtResult ESR = ESR_Succeeded;
6463 for (
const Stmt *Instantiation : Expansion->getInstantiations()) {
6465 if (ESR == ESR_Failed ||
6468 if (ESR != ESR_Continue) {
6470 assert(ESR == ESR_Succeeded || ESR == ESR_Returned);
6476 if (ESR == ESR_Continue)
6477 ESR = ESR_Succeeded;
6479 return Scope.destroy() ? ESR : ESR_Failed;
6482 case Stmt::SwitchStmtClass:
6485 case Stmt::ContinueStmtClass:
6486 case Stmt::BreakStmtClass: {
6488 const Stmt *LoopOrSwitch =
nullptr;
6490 LoopOrSwitch = B->getNamedLoopOrSwitch();
6493 if (!LoopOrSwitch) {
6495 diag::note_break_continue_label_outside_context)
6501 Info.BreakContinueStack.push_back(LoopOrSwitch);
6505 case Stmt::LabelStmtClass:
6508 case Stmt::AttributedStmtClass: {
6510 const auto *SS = AS->getSubStmt();
6511 MSConstexprContextRAII ConstexprContext(
6515 auto LO = Info.Ctx.getLangOpts();
6516 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6517 for (
auto *
Attr : AS->getAttrs()) {
6518 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6522 auto *Assumption = AA->getAssumption();
6523 if (Assumption->isValueDependent())
6526 if (Assumption->HasSideEffects(Info.Ctx))
6533 Info.CCEDiag(Assumption->getExprLoc(),
6534 diag::note_constexpr_assumption_failed);
6543 case Stmt::CaseStmtClass:
6544 case Stmt::DefaultStmtClass:
6546 case Stmt::CXXTryStmtClass:
6558 bool IsValueInitialization) {
6565 if (!CD->
isConstexpr() && !IsValueInitialization) {
6566 if (Info.getLangOpts().CPlusPlus11) {
6569 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6571 Info.Note(CD->
getLocation(), diag::note_declared_at);
6573 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6587 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6595 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6604 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6607 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6613 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6623 StringRef Name = DiagDecl->
getName();
6625 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6627 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6632 if (Info.getLangOpts().CPlusPlus11) {
6635 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6636 if (CD && CD->isInheritingConstructor()) {
6637 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6638 if (!Inherited->isConstexpr())
6639 DiagDecl = CD = Inherited;
6645 if (CD && CD->isInheritingConstructor())
6646 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6647 << CD->getInheritedConstructor().getConstructor()->getParent();
6649 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6651 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6653 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6659struct CheckDynamicTypeHandler {
6661 typedef bool result_type;
6662 bool failed() {
return false; }
6663 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6666 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6667 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6675 if (
This.Designator.Invalid)
6687 if (
This.Designator.isOnePastTheEnd() ||
6688 This.Designator.isMostDerivedAnUnsizedArray()) {
6689 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6690 ? diag::note_constexpr_access_past_end
6691 : diag::note_constexpr_access_unsized_array)
6694 }
else if (Polymorphic) {
6697 if (!Info.checkingPotentialConstantExpression() ||
6698 !
This.AllowConstexprUnknown) {
6702 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6703 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6711 CheckDynamicTypeHandler Handler{AK};
6734 unsigned PathLength) {
6735 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6736 Designator.Entries.size() &&
"invalid path length");
6737 return (PathLength ==
Designator.MostDerivedPathLength)
6738 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6739 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6752 return std::nullopt;
6754 if (
This.Designator.Invalid)
6755 return std::nullopt;
6761 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6762 if (!Class || (!Info.getLangOpts().CPlusPlus26 && Class->getNumVBases())) {
6764 return std::nullopt;
6772 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6773 PathLength <= Path.size(); ++PathLength) {
6774 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6775 Path.slice(0, PathLength))) {
6776 case ConstructionPhase::Bases:
6777 case ConstructionPhase::DestroyingBases:
6782 case ConstructionPhase::None:
6783 case ConstructionPhase::AfterBases:
6784 case ConstructionPhase::AfterFields:
6785 case ConstructionPhase::Destroying:
6797 return std::nullopt;
6815 unsigned PathLength = DynType->PathLength;
6816 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6819 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6829 if (Callee->isPureVirtual()) {
6830 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6831 Info.Note(Callee->getLocation(), diag::note_declared_at);
6837 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6838 Found->getReturnType())) {
6839 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6840 for (
unsigned CovariantPathLength = PathLength + 1;
6841 CovariantPathLength !=
This.Designator.Entries.size();
6842 ++CovariantPathLength) {
6846 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6847 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6848 Next->getReturnType(), CovariantAdjustmentPath.back()))
6849 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6851 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6852 CovariantAdjustmentPath.back()))
6853 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6869 assert(
Result.isLValue() &&
6870 "unexpected kind of APValue for covariant return");
6871 if (
Result.isNullPointer())
6875 LVal.setFrom(Info.Ctx,
Result);
6877 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6878 for (
unsigned I = 1; I != Path.size(); ++I) {
6879 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6880 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6881 if (OldClass != NewClass &&
6884 OldClass = NewClass;
6896 if (BaseSpec.isVirtual())
6898 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6900 return BaseSpec.getAccessSpecifier() ==
AS_public;
6903 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6905 return BaseSpec.getAccessSpecifier() ==
AS_public;
6908 llvm_unreachable(
"Base is not a direct base of Derived");
6918 SubobjectDesignator &D = Ptr.Designator;
6924 if (Ptr.isNullPointer() && !E->
isGLValue())
6930 std::optional<DynamicType> DynType =
6942 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6950 Ptr.setNull(Info.Ctx, E->
getType());
6957 DynType->Type->isDerivedFrom(
C)))
6959 else if (!Paths || Paths->begin() == Paths->end())
6961 else if (Paths->isAmbiguous(CQT))
6964 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6967 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6968 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6969 << Info.Ctx.getCanonicalTagType(DynType->Type)
6977 for (
int PathLength = Ptr.Designator.Entries.size();
6978 PathLength >= (
int)DynType->PathLength; --PathLength) {
6983 if (PathLength > (
int)DynType->PathLength &&
6986 return RuntimeCheckFailed(
nullptr);
6993 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
7006 return RuntimeCheckFailed(&Paths);
7010struct StartLifetimeOfUnionMemberHandler {
7012 const Expr *LHSExpr;
7013 const FieldDecl *
Field;
7015 bool Failed =
false;
7018 typedef bool result_type;
7019 bool failed() {
return Failed; }
7020 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
7035 }
else if (DuringInit) {
7039 Info.FFDiag(LHSExpr,
7040 diag::note_constexpr_union_member_change_during_init);
7049 llvm_unreachable(
"wrong value kind for union object");
7051 bool found(APFloat &
Value, QualType SubobjType) {
7052 llvm_unreachable(
"wrong value kind for union object");
7057const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
7064 const Expr *LHSExpr,
7065 const LValue &LHS) {
7066 if (LHS.InvalidBase || LHS.Designator.Invalid)
7072 unsigned PathLength = LHS.Designator.Entries.size();
7073 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
7075 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
7076 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
7079 if (!FD || FD->getType()->isReferenceType())
7083 if (FD->getParent()->isUnion()) {
7088 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
7089 if (!RD || RD->hasTrivialDefaultConstructor())
7090 UnionPathLengths.push_back({PathLength - 1, FD});
7096 LHS.Designator.Entries[PathLength]
7097 .getAsBaseOrMember().getPointer()));
7101 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
7103 auto *
Base = ASE->getBase()->IgnoreImplicit();
7104 if (!
Base->getType()->isArrayType())
7110 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
7113 if (ICE->getCastKind() == CK_NoOp)
7115 if (ICE->getCastKind() != CK_DerivedToBase &&
7116 ICE->getCastKind() != CK_UncheckedDerivedToBase)
7120 if (Elt->isVirtual()) {
7129 LHS.Designator.Entries[PathLength]
7130 .getAsBaseOrMember().getPointer()));
7140 if (UnionPathLengths.empty())
7145 CompleteObject Obj =
7149 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
7150 llvm::reverse(UnionPathLengths)) {
7152 SubobjectDesignator D = LHS.Designator;
7153 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
7155 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
7156 ConstructionPhase::AfterBases;
7157 StartLifetimeOfUnionMemberHandler StartLifetime{
7158 Info, LHSExpr, LengthAndField.second, DuringInit};
7167 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
7168 APValue **EvaluatedArg =
nullptr) {
7175 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
7176 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
7177 ScopeKind::Call, LV);
7183 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
7184 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
7197 bool RightToLeft =
false,
7198 LValue *ObjectArg =
nullptr) {
7200 llvm::SmallBitVector ForbiddenNullArgs;
7201 if (Callee->hasAttr<NonNullAttr>()) {
7202 ForbiddenNullArgs.resize(Args.size());
7203 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
7204 if (!
Attr->args_size()) {
7205 ForbiddenNullArgs.set();
7208 for (
auto Idx :
Attr->args()) {
7209 unsigned ASTIdx = Idx.getASTIndex();
7210 if (ASTIdx >= Args.size())
7212 ForbiddenNullArgs[ASTIdx] =
true;
7216 for (
unsigned I = 0; I < Args.size(); I++) {
7217 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
7219 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
7220 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
7225 if (!Info.noteFailure())
7230 ObjectArg->setFrom(Info.Ctx, *That);
7239 bool CopyObjectRepresentation) {
7241 CallStackFrame *Frame = Info.CurrentCall;
7242 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
7250 RefLValue.setFrom(Info.Ctx, *RefValue);
7253 CopyObjectRepresentation);
7279 SemaProxy *SProxy = Info.getSemaProxy();
7281 Info.InConstantContext)
7288 const LValue *ObjectArg,
const Expr *E,
7290 const Stmt *Body, EvalInfo &Info,
7292 if (!Info.CheckCallLimit(CallLoc))
7305 auto IsTrivialMemoryOperation = [&](
const CXXMethodDecl *MD) {
7315 if (IsTrivialMemoryOperation(MD)) {
7327 ObjectArg->moveInto(
Result);
7336 if (!Info.checkingPotentialConstantExpression())
7338 Frame.LambdaThisCaptureField);
7341 StmtResult Ret = {
Result, ResultSlot};
7343 if (ESR == ESR_Succeeded) {
7344 if (Callee->getReturnType()->isVoidType())
7346 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7348 return ESR == ESR_Returned;
7355 bool IsCompleteClass =
true);
7361 bool IsCompleteClass =
true) {
7362 CallScopeRAII CallScope(Info);
7369 CallScope.destroy();
7377 bool IsCompleteClass) {
7380 if (!Info.CheckCallLimit(CallLoc))
7384 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7385 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7389 EvalInfo::EvaluatingConstructorRAII EvalObj(
7391 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7398 StmtResult Ret = {RetVal,
nullptr};
7403 if ((*I)->getInit()->isValueDependent()) {
7407 FullExpressionRAII InitScope(Info);
7409 !InitScope.destroy())
7432 if (!
Result.hasValue()) {
7434 unsigned NonVirtualBases = countNonVirtualBases(RD);
7446 BlockScopeRAII LifetimeExtendedScope(Info);
7449 unsigned BasesSeen = 0;
7450 unsigned VirtualBasesSeen = 0;
7451 unsigned NonVirtualBases = countNonVirtualBases(RD);
7454 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7459 assert(Indirect &&
"fields out of order?");
7465 assert(FieldIt != RD->
field_end() &&
"missing field?");
7466 if (!FieldIt->isUnnamedBitField())
7469 Result.getStructField(FieldIt->getFieldIndex()));
7474 LValue Subobject =
This;
7475 LValue SubobjectParent =
This;
7480 if (I->isBaseInitializer()) {
7481 QualType BaseType(I->getBaseClass(), 0);
7482 if (I->isBaseVirtual()) {
7483 if (
This.pointsToCompleteClass(RD)) {
7485 BaseType->getAsCXXRecordDecl(),
7488 Value = &
Result.getStructVirtualBase(VirtualBasesSeen++);
7495 BaseType->getAsCXXRecordDecl(), &Layout))
7499 }
else if ((FD = I->getMember())) {
7506 SkipToField(FD,
false);
7512 auto IndirectFieldChain = IFD->chain();
7513 for (
auto *
C : IndirectFieldChain) {
7522 (
Value->isUnion() &&
7535 if (
C == IndirectFieldChain.back())
7536 SubobjectParent = Subobject;
7542 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7543 SkipToField(FD,
true);
7548 llvm_unreachable(
"unknown base initializer kind");
7555 if (
Init->isValueDependent()) {
7559 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7561 FullExpressionRAII InitScope(Info);
7567 if (!Info.noteFailure())
7576 if (!Info.noteFailure())
7584 if (I->isBaseInitializer() && BasesSeen == NonVirtualBases)
7585 EvalObj.finishedConstructingBases();
7590 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7591 if (!FieldIt->isUnnamedBitField())
7594 Result.getStructField(FieldIt->getFieldIndex()));
7598 EvalObj.finishedConstructingFields();
7602 LifetimeExtendedScope.destroy();
7607 QualType T,
bool IsCompleteClass =
true) {
7612 if (
Value.isAbsent() && !
T->isNullPtrType()) {
7614 This.moveInto(Printable);
7616 diag::note_constexpr_destroy_out_of_lifetime)
7617 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
7633 LValue ElemLV =
This;
7634 ElemLV.addArray(Info, &LocE, CAT);
7641 if (Size && Size >
Value.getArrayInitializedElts())
7646 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7647 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7660 if (
T.isDestructedType()) {
7662 diag::note_constexpr_unsupported_destruction)
7671 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7672 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7700 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7711 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7715 EvalInfo::EvaluatingDestructorRAII EvalObj(
7717 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7718 unsigned NonVirtualBases = countNonVirtualBases(RD);
7720 unsigned BasesLeft = NonVirtualBases;
7721 if (!EvalObj.DidInsert) {
7728 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7735 StmtResult Ret = {RetVal,
nullptr};
7750 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7751 if (FD->isUnnamedBitField())
7754 LValue Subobject =
This;
7758 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7764 if (BasesLeft != 0 || NumVirtualBases != 0)
7765 EvalObj.startedDestroyingBases();
7769 if (
Base.isVirtual())
7774 LValue Subobject =
This;
7776 BaseType->getAsCXXRecordDecl(), &Layout))
7779 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7784 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7787 if (IsCompleteClass) {
7788 unsigned VirtualBasesLeft = NumVirtualBases;
7793 LValue Subobject =
This;
7795 BaseType->getAsCXXRecordDecl(),
7799 APValue *SubobjectValue = &
Value.getStructVirtualBase(VirtualBasesLeft);
7804 assert(VirtualBasesLeft == 0 &&
"NumVirtualBases was wrong?");
7813struct DestroyObjectHandler {
7819 typedef bool result_type;
7820 bool failed() {
return false; }
7821 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
7826 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7829 bool found(APFloat &
Value, QualType SubobjType) {
7830 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7851 if (Info.EvalStatus.HasSideEffects)
7862 if (Info.checkingPotentialConstantExpression() ||
7863 Info.SpeculativeEvaluationDepth)
7867 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7869 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7870 ? diag::note_constexpr_new_untyped
7871 : diag::note_constexpr_new);
7875 QualType ElemType = Caller.ElemType;
7878 diag::note_constexpr_new_not_complete_object_type)
7886 bool IsNothrow =
false;
7887 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7895 APInt Size, Remainder;
7896 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7897 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7898 if (Remainder != 0) {
7900 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7901 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7905 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7906 Size.getZExtValue(), !IsNothrow)) {
7914 QualType AllocType = Info.Ctx.getConstantArrayType(
7916 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType,
Result);
7925 return DD->isVirtual();
7932 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7944 auto PointerAsString = [&] {
7945 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7950 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7951 << PointerAsString();
7954 return std::nullopt;
7957 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7959 Info.FFDiag(E, diag::note_constexpr_double_delete);
7960 return std::nullopt;
7963 if (DeallocKind != (*Alloc)->getKind()) {
7965 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7966 << DeallocKind << (*Alloc)->getKind() << AllocType;
7968 return std::nullopt;
7971 bool Subobject =
false;
7973 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7974 Pointer.Designator.isOnePastTheEnd();
7976 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7977 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7980 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7981 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7982 return std::nullopt;
7990 if (Info.checkingPotentialConstantExpression() ||
7991 Info.SpeculativeEvaluationDepth)
7995 if (!Info.getStdAllocatorCaller(
"deallocate")) {
8003 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
8006 if (
Pointer.Designator.Invalid)
8011 if (
Pointer.isNullPointer()) {
8012 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
8028class BitCastBuffer {
8034 SmallVector<std::optional<unsigned char>, 32> Bytes;
8036 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
8037 "Need at least 8 bit unsigned char");
8039 bool TargetIsLittleEndian;
8042 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
8043 : Bytes(Width.getQuantity()),
8044 TargetIsLittleEndian(TargetIsLittleEndian) {}
8046 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
8047 SmallVectorImpl<unsigned char> &Output)
const {
8048 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
8051 if (!Bytes[I.getQuantity()])
8053 Output.push_back(*Bytes[I.getQuantity()]);
8055 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
8056 std::reverse(Output.begin(), Output.end());
8060 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
8061 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
8062 std::reverse(Input.begin(), Input.end());
8065 for (
unsigned char Byte : Input) {
8066 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
8072 size_t size() {
return Bytes.size(); }
8077class APValueToBufferConverter {
8079 BitCastBuffer Buffer;
8082 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
8085 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
8088 bool visit(
const APValue &Val, QualType Ty) {
8093 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
8094 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
8107 return visitInt(Val.
getInt(), Ty, Offset);
8109 return visitFloat(Val.
getFloat(), Ty, Offset);
8111 return visitArray(Val, Ty, Offset);
8113 return visitRecord(Val, Ty, Offset);
8115 return visitVector(Val, Ty, Offset);
8119 return visitComplex(Val, Ty, Offset);
8130 diag::note_constexpr_bit_cast_unsupported_type)
8135 llvm_unreachable(
"Unhandled APValue::ValueKind");
8138 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
8142 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8145 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8146 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8147 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8152 if (!
Base.isStruct())
8155 if (!visitRecord(Base, BS.
getType(),
8162 unsigned FieldIdx = 0;
8163 for (FieldDecl *FD : RD->
fields()) {
8164 if (FD->isBitField()) {
8166 diag::note_constexpr_bit_cast_unsupported_bitfield);
8172 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
8173 "only bit-fields can have sub-char alignment");
8174 CharUnits FieldOffset =
8175 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
8176 QualType FieldTy = FD->getType();
8185 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
8191 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
8195 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
8197 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
8204 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
8205 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
8213 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
8214 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
8216 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8221 Offset + (0 * EltSizeChars)))
8224 Offset + (1 * EltSizeChars)))
8228 Offset + (0 * EltSizeChars)))
8231 Offset + (1 * EltSizeChars)))
8238 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
8239 const VectorType *VTy = Ty->
castAs<VectorType>();
8252 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8254 llvm::APInt Res = llvm::APInt::getZero(NElts);
8255 for (
unsigned I = 0; I < NElts; ++I) {
8257 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
8258 "bool vector element must be 1-bit unsigned integer!");
8260 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
8263 SmallVector<uint8_t, 8> Bytes(NElts / 8);
8264 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
8265 Buffer.writeObject(Offset, Bytes);
8269 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8270 for (
unsigned I = 0; I < NElts; ++I) {
8271 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
8279 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
8280 APSInt AdjustedVal = Val;
8281 unsigned Width = AdjustedVal.getBitWidth();
8283 Width = Info.Ctx.getTypeSize(Ty);
8284 AdjustedVal = AdjustedVal.extend(Width);
8287 SmallVector<uint8_t, 8> Bytes(Width / 8);
8288 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
8289 Buffer.writeObject(Offset, Bytes);
8293 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
8294 APSInt AsInt(Val.bitcastToAPInt());
8295 return visitInt(AsInt, Ty, Offset);
8299 static std::optional<BitCastBuffer>
8301 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
8302 APValueToBufferConverter Converter(Info, DstSize, BCE);
8304 return std::nullopt;
8305 return Converter.Buffer;
8310class BufferToAPValueConverter {
8312 const BitCastBuffer &Buffer;
8315 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
8317 : Info(Info), Buffer(Buffer), BCE(BCE) {}
8322 std::nullopt_t unsupportedType(QualType Ty) {
8324 diag::note_constexpr_bit_cast_unsupported_type)
8326 return std::nullopt;
8329 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
8331 diag::note_constexpr_bit_cast_unrepresentable_value)
8333 return std::nullopt;
8336 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
8337 const EnumType *EnumSugar =
nullptr) {
8339 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(
T, 0));
8340 return APValue((Expr *)
nullptr,
8342 APValue::NoLValuePath{},
true);
8345 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(
T);
8351 const llvm::fltSemantics &Semantics =
8352 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8353 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8354 assert(NumBits % 8 == 0);
8360 SmallVector<uint8_t, 8> Bytes;
8361 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8364 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8368 if (!IsStdByte && !IsUChar) {
8369 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
8371 diag::note_constexpr_bit_cast_indet_dest)
8372 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8373 return std::nullopt;
8379 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8380 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8385 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(
T, 0));
8386 if (IntWidth != Val.getBitWidth()) {
8387 APSInt Truncated = Val.trunc(IntWidth);
8388 if (Truncated.extend(Val.getBitWidth()) != Val)
8389 return unrepresentableValue(QualType(
T, 0), Val);
8397 const llvm::fltSemantics &Semantics =
8398 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8402 return unsupportedType(QualType(
T, 0));
8405 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8406 const RecordDecl *RD = RTy->getAsRecordDecl();
8408 return std::nullopt;
8409 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8411 unsigned NumBases = 0;
8412 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8413 NumBases = CXXRD->getNumBases();
8418 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8419 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8420 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8423 std::optional<APValue> SubObj = visitType(
8426 return std::nullopt;
8427 ResultVal.getStructBase(I) = *SubObj;
8432 unsigned FieldIdx = 0;
8433 for (FieldDecl *FD : RD->
fields()) {
8436 if (FD->isBitField()) {
8438 diag::note_constexpr_bit_cast_unsupported_bitfield);
8439 return std::nullopt;
8443 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8445 CharUnits FieldOffset =
8448 QualType FieldTy = FD->getType();
8449 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8451 return std::nullopt;
8452 ResultVal.getStructField(FieldIdx) = *SubObj;
8459 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8460 QualType RepresentationType =
8461 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8462 assert(!RepresentationType.
isNull() &&
8463 "enum forward decl should be caught by Sema");
8464 const auto *AsBuiltin =
8468 return visit(AsBuiltin, Offset, Ty);
8471 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8473 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8475 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8476 for (
size_t I = 0; I !=
Size; ++I) {
8477 std::optional<APValue> ElementValue =
8480 return std::nullopt;
8481 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8487 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8489 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8490 bool IsInt = ElementType->isIntegerType();
8492 std::optional<APValue> Values[2];
8493 for (
unsigned I = 0; I != 2; ++I) {
8494 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8496 return std::nullopt;
8500 return APValue(Values[0]->getInt(), Values[1]->getInt());
8501 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8504 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8510 SmallVector<APValue, 4> Elts;
8511 Elts.reserve(NElts);
8521 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8523 SmallVector<uint8_t, 8> Bytes;
8524 Bytes.reserve(NElts / 8);
8526 return std::nullopt;
8528 APSInt SValInt(NElts,
true);
8529 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8531 for (
unsigned I = 0; I < NElts; ++I) {
8533 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8540 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8541 for (
unsigned I = 0; I < NElts; ++I) {
8542 std::optional<APValue> EltValue =
8543 visitType(EltTy, Offset + I * EltSizeChars);
8545 return std::nullopt;
8546 Elts.push_back(std::move(*EltValue));
8550 return APValue(Elts.data(), Elts.size());
8553 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8554 return unsupportedType(QualType(Ty, 0));
8557 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8561#define TYPE(Class, Base) \
8563 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8564#define ABSTRACT_TYPE(Class, Base)
8565#define NON_CANONICAL_TYPE(Class, Base) \
8567 llvm_unreachable("non-canonical type should be impossible!");
8568#define DEPENDENT_TYPE(Class, Base) \
8571 "dependent types aren't supported in the constant evaluator!");
8572#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8574 llvm_unreachable("either dependent or not canonical!");
8575#include "clang/AST/TypeNodes.inc"
8577 llvm_unreachable(
"Unhandled Type::TypeClass");
8582 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8584 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8589static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8590 QualType Ty, EvalInfo *Info,
8591 const ASTContext &Ctx,
8592 bool CheckingDest) {
8595 auto diag = [&](
int Reason) {
8597 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8598 << CheckingDest << (Reason == 4) << Reason;
8601 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8603 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8604 << NoteTy << Construct << Ty;
8618 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8619 for (CXXBaseSpecifier &BS : CXXRD->bases())
8620 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8624 for (FieldDecl *FD :
Record->fields()) {
8625 if (FD->getType()->isReferenceType())
8627 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8629 return note(0, FD->getType(), FD->getBeginLoc());
8635 Info, Ctx, CheckingDest))
8638 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8650 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8651 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8661 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8670static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8671 const ASTContext &Ctx,
8673 bool DestOK = checkBitCastConstexprEligibilityType(
8675 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8681static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8684 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8685 "no host or target supports non 8-bit chars");
8687 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8691 std::optional<BitCastBuffer> Buffer =
8692 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8697 std::optional<APValue> MaybeDestValue =
8698 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8699 if (!MaybeDestValue)
8702 DestValue = std::move(*MaybeDestValue);
8706static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8709 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8710 "no host or target supports non 8-bit chars");
8712 "LValueToRValueBitcast requires an lvalue operand!");
8714 LValue SourceLValue;
8716 SourceLValue.setFrom(Info.Ctx, SourceValue);
8719 SourceRValue,
true))
8722 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8725template <
class Derived>
8726class ExprEvaluatorBase
8727 :
public ConstStmtVisitor<Derived, bool> {
8729 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8730 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8731 return getDerived().Success(
V, E);
8733 bool DerivedZeroInitialization(
const Expr *E) {
8734 return getDerived().ZeroInitialization(E);
8740 template<
typename ConditionalOperator>
8741 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8742 assert(Info.checkingPotentialConstantExpression());
8745 SmallVector<PartialDiagnosticAt, 8>
Diag;
8747 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8754 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8756 Info.EvalStatus.DiagEmitted =
false;
8762 Error(E, diag::note_constexpr_conditional_never_const);
8766 template<
typename ConditionalOperator>
8767 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8770 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8771 CheckPotentialConstantConditional(E);
8774 if (Info.noteFailure()) {
8782 return StmtVisitorTy::Visit(EvalExpr);
8787 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8788 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8790 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8791 return Info.CCEDiag(E, D);
8794 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8796 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8798 return BuiltinOp != 0 &&
8799 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8803 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8805 EvalInfo &getEvalInfo() {
return Info; }
8813 bool Error(
const Expr *E) {
8814 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8817 bool VisitStmt(
const Stmt *) {
8818 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8820 bool VisitExpr(
const Expr *E) {
8824 bool VisitEmbedExpr(
const EmbedExpr *E) {
8825 const auto It = E->
begin();
8826 return StmtVisitorTy::Visit(*It);
8829 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8832 bool VisitConstantExpr(
const ConstantExpr *E) {
8836 return StmtVisitorTy::Visit(E->
getSubExpr());
8839 bool VisitParenExpr(
const ParenExpr *E)
8840 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8841 bool VisitUnaryExtension(
const UnaryOperator *E)
8842 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8843 bool VisitUnaryPlus(
const UnaryOperator *E)
8844 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8845 bool VisitChooseExpr(
const ChooseExpr *E)
8847 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8849 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8851 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8852 TempVersionRAII RAII(*Info.CurrentCall);
8853 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8854 return StmtVisitorTy::Visit(E->
getExpr());
8856 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8857 TempVersionRAII RAII(*Info.CurrentCall);
8861 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8862 return StmtVisitorTy::Visit(E->
getExpr());
8865 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8866 FullExpressionRAII Scope(Info);
8867 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8872 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8873 return StmtVisitorTy::Visit(E->
getSubExpr());
8876 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8878 CCEDiag(E, diag::note_constexpr_invalid_cast)
8879 << diag::ConstexprInvalidCastKind::Reinterpret;
8880 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8882 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8883 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8884 CCEDiag(E, diag::note_constexpr_invalid_cast)
8885 << diag::ConstexprInvalidCastKind::Dynamic;
8886 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8888 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8889 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8892 bool VisitBinaryOperator(
const BinaryOperator *E) {
8898 VisitIgnoredValue(E->
getLHS());
8899 return StmtVisitorTy::Visit(E->
getRHS());
8909 return DerivedSuccess(
Result, E);
8914 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8918 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8922 if (!
Evaluate(Info.CurrentCall->createTemporary(
8925 ScopeKind::FullExpression, CommonLV),
8929 return HandleConditionalOperator(E);
8932 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8933 bool IsBcpCall =
false;
8938 if (
const CallExpr *CallCE =
8940 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8947 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8950 FoldConstant Fold(Info, IsBcpCall);
8951 if (!HandleConditionalOperator(E)) {
8952 Fold.keepDiagnostics();
8959 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8960 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8962 return DerivedSuccess(*
Value, E);
8968 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8971 return StmtVisitorTy::Visit(Source);
8974 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8975 for (
const Expr *SemE : E->
semantics()) {
8976 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8985 if (OVE->isUnique())
8989 if (!
Evaluate(Info.CurrentCall->createTemporary(
8990 OVE, getStorageType(Info.Ctx, OVE),
8991 ScopeKind::FullExpression, LV),
8992 Info, OVE->getSourceExpr()))
8995 if (!StmtVisitorTy::Visit(SemE))
9005 bool VisitCallExpr(
const CallExpr *E) {
9007 if (!handleCallExpr(E,
Result,
nullptr))
9009 return DerivedSuccess(
Result, E);
9013 const LValue *ResultSlot) {
9014 CallScopeRAII CallScope(Info);
9017 QualType CalleeType =
Callee->getType();
9019 const FunctionDecl *FD =
nullptr;
9020 LValue *
This =
nullptr, ObjectArg;
9022 bool HasQualifier =
false;
9028 const CXXMethodDecl *
Member =
nullptr;
9029 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
9033 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
9035 return Error(Callee);
9037 HasQualifier = ME->hasQualifier();
9038 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
9040 const ValueDecl *D =
9044 Member = dyn_cast<CXXMethodDecl>(D);
9046 return Error(Callee);
9048 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
9049 if (!Info.getLangOpts().CPlusPlus20)
9050 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
9054 return Error(Callee);
9061 if (!CalleeLV.getLValueOffset().isZero())
9062 return Error(Callee);
9063 if (CalleeLV.isNullPointer()) {
9064 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
9065 <<
const_cast<Expr *
>(
Callee);
9068 FD = dyn_cast_or_null<FunctionDecl>(
9069 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
9071 return Error(Callee);
9074 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
9081 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
9082 if (OCE && OCE->isAssignmentOp()) {
9083 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
9084 Call = Info.CurrentCall->createCall(FD);
9085 bool HasThis =
false;
9086 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
9087 HasThis = MD->isImplicitObjectMemberFunction();
9095 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
9115 if (Info.getLangOpts().CPlusPlus20 && OCE &&
9116 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
9120 Args = Args.slice(1);
9126 const CXXRecordDecl *ClosureClass = MD->
getParent();
9128 ClosureClass->
captures().empty() &&
9129 "Number of captures must be zero for conversion to function-ptr");
9131 const CXXMethodDecl *LambdaCallOp =
9140 "A generic lambda's static-invoker function must be a "
9141 "template specialization");
9143 FunctionTemplateDecl *CallOpTemplate =
9145 llvm::FoldingSetInsertToken InsertToken;
9146 FunctionDecl *CorrespondingCallOpSpecialization =
9148 assert(CorrespondingCallOpSpecialization &&
9149 "We must always have a function call operator specialization "
9150 "that corresponds to our static invoker specialization");
9152 FD = CorrespondingCallOpSpecialization;
9161 return CallScope.destroy();
9171 Call = Info.CurrentCall->createCall(FD);
9177 SmallVector<QualType, 4> CovariantAdjustmentPath;
9179 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
9180 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
9183 CovariantAdjustmentPath);
9186 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
9196 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
9197 assert(This &&
"no 'this' pointer for destructor call");
9199 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
9200 CallScope.destroy();
9220 if (!CovariantAdjustmentPath.empty() &&
9222 CovariantAdjustmentPath))
9225 return CallScope.destroy();
9228 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9231 bool VisitInitListExpr(
const InitListExpr *E) {
9233 return DerivedZeroInitialization(E);
9235 return StmtVisitorTy::Visit(E->
getInit(0));
9238 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
9239 return DerivedZeroInitialization(E);
9241 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
9242 return DerivedZeroInitialization(E);
9244 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
9245 return DerivedZeroInitialization(E);
9249 bool VisitMemberExpr(
const MemberExpr *E) {
9250 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
9251 "missing temporary materialization conversion");
9252 assert(!E->
isArrow() &&
"missing call to bound member function?");
9260 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
9261 if (!FD)
return Error(E);
9265 "record / field mismatch");
9270 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
9271 SubobjectDesignator Designator(BaseTy);
9272 Designator.addDeclUnchecked(FD);
9276 DerivedSuccess(
Result, E);
9279 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
9285 SmallVector<uint32_t, 4> Indices;
9287 if (Indices.size() == 1) {
9289 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
9292 SmallVector<APValue, 4> Elts;
9293 for (
unsigned I = 0; I < Indices.size(); ++I) {
9296 APValue VecResult(Elts.data(), Indices.size());
9297 return DerivedSuccess(VecResult, E);
9304 bool VisitCastExpr(
const CastExpr *E) {
9309 case CK_AtomicToNonAtomic: {
9316 return DerivedSuccess(AtomicVal, E);
9320 case CK_UserDefinedConversion:
9321 return StmtVisitorTy::Visit(E->
getSubExpr());
9323 case CK_HLSLArrayRValue: {
9329 return DerivedSuccess(Val, E);
9340 return DerivedSuccess(RVal, E);
9342 case CK_LValueToRValue: {
9351 return DerivedSuccess(RVal, E);
9353 case CK_LValueToRValueBitCast: {
9354 APValue DestValue, SourceValue;
9357 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9359 return DerivedSuccess(DestValue, E);
9362 case CK_AddressSpaceConversion: {
9366 return DerivedSuccess(
Value, E);
9373 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9374 return VisitUnaryPostIncDec(UO);
9376 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9377 return VisitUnaryPostIncDec(UO);
9379 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9380 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9390 return DerivedSuccess(RVal, UO);
9393 bool VisitStmtExpr(
const StmtExpr *E) {
9396 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9403 BlockScopeRAII Scope(Info);
9408 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9410 Info.FFDiag((*BI)->getBeginLoc(),
9411 diag::note_constexpr_stmt_expr_unsupported);
9414 return this->Visit(FinalExpr) && Scope.destroy();
9420 if (ESR != ESR_Succeeded) {
9424 if (ESR != ESR_Failed)
9425 Info.FFDiag((*BI)->getBeginLoc(),
9426 diag::note_constexpr_stmt_expr_unsupported);
9431 llvm_unreachable(
"Return from function from the loop above.");
9434 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9439 void VisitIgnoredValue(
const Expr *E) {
9444 void VisitIgnoredBaseExpression(
const Expr *E) {
9447 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9449 VisitIgnoredValue(E);
9459template<
class Derived>
9460class LValueExprEvaluatorBase
9461 :
public ExprEvaluatorBase<Derived> {
9465 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9466 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9468 bool Success(APValue::LValueBase B) {
9473 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9478 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9480 InvalidBaseOK(InvalidBaseOK) {}
9483 Result.setFrom(this->Info.Ctx,
V);
9487 bool VisitMemberExpr(
const MemberExpr *E) {
9499 EvalOK = this->Visit(E->
getBase());
9510 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9513 "record / field mismatch");
9517 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9521 return this->
Error(E);
9533 bool VisitBinaryOperator(
const BinaryOperator *E) {
9536 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9544 bool VisitCastExpr(
const CastExpr *E) {
9547 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9549 case CK_DerivedToBase:
9550 case CK_UncheckedDerivedToBase:
9597class LValueExprEvaluator
9598 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9600 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9601 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9603 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9604 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9606 bool VisitCallExpr(
const CallExpr *E);
9607 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9608 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9609 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9610 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9611 bool VisitMemberExpr(
const MemberExpr *E);
9612 bool VisitStringLiteral(
const StringLiteral *E) {
9614 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9616 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9617 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9618 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9619 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9620 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9621 bool VisitUnaryDeref(
const UnaryOperator *E);
9622 bool VisitUnaryReal(
const UnaryOperator *E);
9623 bool VisitUnaryImag(
const UnaryOperator *E);
9624 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9625 return VisitUnaryPreIncDec(UO);
9627 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9628 return VisitUnaryPreIncDec(UO);
9630 bool VisitBinAssign(
const BinaryOperator *BO);
9631 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9633 bool VisitCastExpr(
const CastExpr *E) {
9636 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9638 case CK_LValueBitCast:
9639 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9640 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9644 Result.Designator.setInvalid();
9647 case CK_BaseToDerived:
9664 bool LValueToRValueConversion) {
9668 assert(Info.CurrentCall->This ==
nullptr &&
9669 "This should not be set for a static call operator");
9677 if (
Self->getType()->isReferenceType()) {
9678 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9680 Result.setFrom(Info.Ctx, *RefValue);
9682 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9683 CallStackFrame *Frame =
9684 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9686 unsigned Version = Info.CurrentCall->Arguments.Version;
9687 Result.set({VD, Frame->Index, Version});
9690 Result = *Info.CurrentCall->This;
9700 if (LValueToRValueConversion) {
9704 Result.setFrom(Info.Ctx, RVal);
9715 bool InvalidBaseOK) {
9719 return LValueExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
9722bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9723 const ValueDecl *D = E->
getDecl();
9735 if (Info.checkingPotentialConstantExpression())
9738 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9745 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9746 UnnamedGlobalConstantDecl>(D))
9748 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9749 return VisitVarDecl(E, VD);
9750 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9751 return Visit(BD->getBinding());
9755bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9756 CallStackFrame *Frame =
nullptr;
9757 unsigned Version = 0;
9765 CallStackFrame *CurrFrame = Info.CurrentCall;
9770 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9771 if (CurrFrame->Arguments) {
9772 VD = CurrFrame->Arguments.getOrigParam(PVD);
9774 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9775 Version = CurrFrame->Arguments.Version;
9779 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9786 Result.set({VD, Frame->Index, Version});
9792 if (!Info.getLangOpts().CPlusPlus11) {
9793 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9795 Info.Note(VD->
getLocation(), diag::note_declared_at);
9804 Result.AllowConstexprUnknown =
true;
9811bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9812 if (!IsConstantEvaluatedBuiltinCall(E))
9813 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9818 case Builtin::BIas_const:
9819 case Builtin::BIforward:
9820 case Builtin::BIforward_like:
9821 case Builtin::BImove:
9822 case Builtin::BImove_if_noexcept:
9824 return Visit(E->
getArg(0));
9828 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9831bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9832 const MaterializeTemporaryExpr *E) {
9840 for (
const Expr *E : CommaLHSs)
9849 if (Info.EvalMode == EvaluationMode::ConstantFold)
9856 Value = &Info.CurrentCall->createTemporary(
9872 for (
unsigned I = Adjustments.size(); I != 0; ) {
9874 switch (Adjustments[I].Kind) {
9879 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9885 Type = Adjustments[I].Field->getType();
9890 Adjustments[I].
Ptr.RHS))
9892 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9901LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9902 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9903 "lvalue compound literal in c++?");
9915 assert(!Info.getLangOpts().CPlusPlus);
9917 ScopeKind::Block,
Result);
9929bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9930 TypeInfoLValue TypeInfo;
9938 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9939 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9947 std::optional<DynamicType> DynType =
9952 TypeInfo = TypeInfoLValue(
9953 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9959bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9963bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9965 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9966 VisitIgnoredBaseExpression(E->
getBase());
9967 return VisitVarDecl(E, VD);
9971 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9972 if (MD->isStatic()) {
9973 VisitIgnoredBaseExpression(E->
getBase());
9979 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9982bool LValueExprEvaluator::VisitExtVectorElementExpr(
9983 const ExtVectorElementExpr *E) {
9988 if (!Info.noteFailure())
9996 if (Indices.size() > 1)
10000 Result.setFrom(Info.Ctx, Val);
10004 const auto *VT = BaseType->
castAs<VectorType>();
10006 VT->getNumElements(), Indices[0]);
10012bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
10022 if (!Info.noteFailure())
10028 if (!Info.noteFailure())
10034 Result.setFrom(Info.Ctx, Val);
10036 VT->getNumElements(), Index.getZExtValue());
10044 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
10045 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
10047 if (!Info.noteFailure())
10057bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
10068 Info.noteUndefinedBehavior();
10071bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
10080bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
10082 "lvalue __imag__ on scalar?");
10089bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
10090 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
10101bool LValueExprEvaluator::VisitCompoundAssignOperator(
10102 const CompoundAssignOperator *CAO) {
10103 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
10111 if (!Info.noteFailure())
10126bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
10127 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
10135 if (!Info.noteFailure())
10143 if (Info.getLangOpts().CPlusPlus20 &&
10158 const LValue &LVal,
10160 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
10161 "Can't get the size of a non alloc_size function");
10162 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
10164 std::optional<llvm::APInt> Size =
10165 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
10169 Result = std::move(*Size);
10188 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
10193 if (!
Init ||
Init->getType().isNull())
10196 const Expr *E =
Init->IgnoreParens();
10197 if (!tryUnwrapAllocSizeCall(E))
10205 Result.addUnsizedArray(Info, E, Pointee);
10210class PointerExprEvaluator
10211 :
public ExprEvaluatorBase<PointerExprEvaluator> {
10213 bool InvalidBaseOK;
10215 bool Success(
const Expr *E) {
10220 bool evaluateLValue(
const Expr *E, LValue &
Result) {
10224 bool evaluatePointer(
const Expr *E, LValue &
Result) {
10228 bool visitNonBuiltinCallExpr(
const CallExpr *E);
10231 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
10233 InvalidBaseOK(InvalidBaseOK) {}
10239 bool ZeroInitialization(
const Expr *E) {
10244 bool VisitBinaryOperator(
const BinaryOperator *E);
10245 bool VisitCastExpr(
const CastExpr* E);
10246 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10247 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
10249 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
10252 if (Info.noteFailure())
10256 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
10259 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
10262 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
10264 bool VisitCallExpr(
const CallExpr *E);
10265 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
10266 bool VisitBlockExpr(
const BlockExpr *E) {
10271 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
10272 auto DiagnoseInvalidUseOfThis = [&] {
10273 if (Info.getLangOpts().CPlusPlus11)
10274 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
10280 if (Info.checkingPotentialConstantExpression())
10283 bool IsExplicitLambda =
10285 if (!IsExplicitLambda) {
10286 if (!Info.CurrentCall->This) {
10287 DiagnoseInvalidUseOfThis();
10291 Result = *Info.CurrentCall->This;
10299 if (!Info.CurrentCall->LambdaThisCaptureField) {
10300 if (IsExplicitLambda && !Info.CurrentCall->This) {
10301 DiagnoseInvalidUseOfThis();
10310 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
10316 bool VisitCXXNewExpr(
const CXXNewExpr *E);
10318 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
10319 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
10321 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
10322 Result.setFrom(Info.Ctx, LValResult);
10326 bool VisitEmbedExpr(
const EmbedExpr *E) {
10327 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
10331 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
10332 std::string ResultStr = E->
ComputeName(Info.Ctx);
10334 QualType CharTy = Info.Ctx.CharTy.withConst();
10335 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
10336 ResultStr.size() + 1);
10337 QualType ArrayTy = Info.Ctx.getConstantArrayType(
10338 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
10340 StringLiteral *SL =
10341 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
10344 evaluateLValue(SL,
Result);
10354 bool InvalidBaseOK) {
10357 return PointerExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
10360bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10363 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10365 const Expr *PExp = E->
getLHS();
10366 const Expr *IExp = E->
getRHS();
10368 std::swap(PExp, IExp);
10370 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10371 if (!EvalPtrOK && !Info.noteFailure())
10374 llvm::APSInt Offset;
10385bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10393 if (!Info.getLangOpts().CPlusPlus) {
10395 if (
const auto *Deref = dyn_cast<UnaryOperator>(Sub);
10396 Deref && Deref->getOpcode() == UO_Deref)
10397 return evaluatePointer(Deref->getSubExpr(),
Result);
10407 if (!FnII || !FnII->
isStr(
"current"))
10410 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10418bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10425 case CK_CPointerToObjCPointerCast:
10426 case CK_BlockPointerToObjCPointerCast:
10427 case CK_AnyPointerToBlockPointerCast:
10428 case CK_AddressSpaceConversion:
10429 if (!Visit(SubExpr))
10435 CCEDiag(E, diag::note_constexpr_invalid_cast)
10436 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10437 << Info.Ctx.getLangOpts().CPlusPlus;
10438 Result.Designator.setInvalid();
10446 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10448 bool VoidPtrCastMaybeOK =
10451 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10460 if (VoidPtrCastMaybeOK &&
10461 (Info.getStdAllocatorCaller(
"allocate") ||
10463 Info.getLangOpts().CPlusPlus26)) {
10467 Info.getLangOpts().CPlusPlus) {
10468 if (HasValidResult)
10469 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10470 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10471 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10474 CCEDiag(E, diag::note_constexpr_invalid_cast)
10475 << diag::ConstexprInvalidCastKind::CastFrom
10478 CCEDiag(E, diag::note_constexpr_invalid_cast)
10479 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10480 << Info.Ctx.getLangOpts().CPlusPlus;
10481 Result.Designator.setInvalid();
10485 ZeroInitialization(E);
10488 case CK_DerivedToBase:
10489 case CK_UncheckedDerivedToBase:
10501 case CK_BaseToDerived:
10513 case CK_NullToPointer:
10515 return ZeroInitialization(E);
10517 case CK_IntegralToPointer: {
10518 CCEDiag(E, diag::note_constexpr_invalid_cast)
10519 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10520 << Info.Ctx.getLangOpts().CPlusPlus;
10526 if (
Value.isInt()) {
10527 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10528 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10529 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10532 Result.Base = (Expr *)
nullptr;
10533 Result.InvalidBase =
false;
10535 Result.Designator.setInvalid();
10536 Result.IsNullPtr =
false;
10544 if (!
Value.isLValue())
10553 case CK_ArrayToPointerDecay: {
10555 if (!evaluateLValue(SubExpr,
Result))
10559 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10564 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10565 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10566 Result.addArray(Info, E, CAT);
10568 Result.addUnsizedArray(Info, E, AT->getElementType());
10572 case CK_FunctionToPointerDecay:
10573 return evaluateLValue(SubExpr,
Result);
10575 case CK_LValueToRValue: {
10584 return InvalidBaseOK &&
10590 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10594 UnaryExprOrTypeTrait ExprKind) {
10598 T =
T.getNonReferenceType();
10600 if (
T.getQualifiers().hasUnaligned())
10603 const bool AlignOfReturnsPreferred =
10609 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10612 else if (ExprKind == UETT_AlignOf)
10615 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10630 unsigned BuiltinOp) {
10654 switch (OwningTarget->
getTriple().getArch()) {
10655 case llvm::Triple::x86:
10656 case llvm::Triple::x86_64:
10669 UnaryExprOrTypeTrait ExprKind) {
10678 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10682 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10691 return Info.Ctx.getDeclAlign(VD);
10692 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10703 EvalInfo &Info,
APSInt &Alignment) {
10706 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10707 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10710 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10711 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10712 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10713 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10714 << MaxValue << ForType << Alignment;
10720 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10721 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10722 "Alignment should not be changed by ext/trunc");
10723 Alignment = ExtAlignment;
10724 assert(Alignment.getBitWidth() == SrcWidth);
10729bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10730 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10738 Result.addUnsizedArray(Info, E, PointeeTy);
10742bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10743 if (!IsConstantEvaluatedBuiltinCall(E))
10744 return visitNonBuiltinCallExpr(E);
10751 return T->isCharType() ||
T->isChar8Type();
10754bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10755 unsigned BuiltinOp) {
10759 switch (BuiltinOp) {
10760 case Builtin::BIaddressof:
10761 case Builtin::BI__addressof:
10762 case Builtin::BI__builtin_addressof:
10764 case Builtin::BI__builtin_assume_aligned: {
10771 LValue OffsetResult(
Result);
10783 int64_t AdditionalOffset = -Offset.getZExtValue();
10788 if (OffsetResult.Base) {
10791 if (BaseAlignment < Align) {
10792 Result.Designator.setInvalid();
10793 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10800 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10801 Result.Designator.setInvalid();
10805 diag::note_constexpr_baa_insufficient_alignment)
10808 diag::note_constexpr_baa_value_insufficient_alignment))
10809 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10815 case Builtin::BI__builtin_align_up:
10816 case Builtin::BI__builtin_align_down: {
10826 if (
Result.Offset.isZero())
10832 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10850 assert(Alignment.getBitWidth() <= 64 &&
10851 "Cannot handle > 64-bit address-space");
10852 uint64_t Alignment64 = Alignment.getZExtValue();
10854 BuiltinOp == Builtin::BI__builtin_align_down
10855 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10856 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10862 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10866 case Builtin::BI__builtin_operator_new:
10868 case Builtin::BI__builtin_launder:
10870 case Builtin::BIstrchr:
10871 case Builtin::BIwcschr:
10872 case Builtin::BImemchr:
10873 case Builtin::BIwmemchr:
10874 if (Info.getLangOpts().CPlusPlus11)
10875 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10877 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10879 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10881 case Builtin::BI__builtin_strchr:
10882 case Builtin::BI__builtin_wcschr:
10883 case Builtin::BI__builtin_memchr:
10884 case Builtin::BI__builtin_char_memchr:
10885 case Builtin::BI__builtin_wmemchr: {
10886 if (!Visit(E->
getArg(0)))
10892 if (BuiltinOp != Builtin::BIstrchr &&
10893 BuiltinOp != Builtin::BIwcschr &&
10894 BuiltinOp != Builtin::BI__builtin_strchr &&
10895 BuiltinOp != Builtin::BI__builtin_wcschr) {
10899 MaxLength = N.getZExtValue();
10902 if (MaxLength == 0u)
10903 return ZeroInitialization(E);
10904 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10905 Result.Designator.Invalid)
10907 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10908 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10909 BuiltinOp == Builtin::BI__builtin_memchr;
10910 assert(IsRawByte ||
10911 Info.Ctx.hasSameUnqualifiedType(
10915 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10921 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10922 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10928 bool StopAtNull =
false;
10929 switch (BuiltinOp) {
10930 case Builtin::BIstrchr:
10931 case Builtin::BI__builtin_strchr:
10934 case Builtin::BImemchr:
10935 case Builtin::BI__builtin_memchr:
10936 case Builtin::BI__builtin_char_memchr:
10940 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10943 case Builtin::BIwcschr:
10944 case Builtin::BI__builtin_wcschr:
10947 case Builtin::BIwmemchr:
10948 case Builtin::BI__builtin_wmemchr:
10950 DesiredVal = Desired.getZExtValue();
10954 for (; MaxLength; --MaxLength) {
10959 if (Char.
getInt().getZExtValue() == DesiredVal)
10961 if (StopAtNull && !Char.
getInt())
10967 return ZeroInitialization(E);
10970 case Builtin::BImemcpy:
10971 case Builtin::BImemmove:
10972 case Builtin::BIwmemcpy:
10973 case Builtin::BIwmemmove:
10974 if (Info.getLangOpts().CPlusPlus11)
10975 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10977 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10979 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10981 case Builtin::BI__builtin_memcpy:
10982 case Builtin::BI__builtin_memmove:
10983 case Builtin::BI__builtin_wmemcpy:
10984 case Builtin::BI__builtin_wmemmove: {
10985 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10986 BuiltinOp == Builtin::BIwmemmove ||
10987 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10988 BuiltinOp == Builtin::BI__builtin_wmemmove;
10989 bool Move = BuiltinOp == Builtin::BImemmove ||
10990 BuiltinOp == Builtin::BIwmemmove ||
10991 BuiltinOp == Builtin::BI__builtin_memmove ||
10992 BuiltinOp == Builtin::BI__builtin_wmemmove;
10995 if (!Visit(E->
getArg(0)))
11006 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
11016 if (!Src.Base || !Dest.Base) {
11018 (!Src.Base ? Src : Dest).moveInto(Val);
11019 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
11020 <<
Move << WChar << !!Src.Base
11024 if (Src.Designator.Invalid || Dest.Designator.Invalid)
11030 QualType
T = Dest.Designator.getType(Info.Ctx);
11031 QualType SrcT = Src.Designator.getType(Info.Ctx);
11032 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
11034 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
11038 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
11041 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
11042 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
11047 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
11052 llvm::APInt OrigN = N;
11053 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
11055 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
11057 << (unsigned)TSize;
11065 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
11066 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
11067 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
11068 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
11069 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
11073 uint64_t NElems = N.getZExtValue();
11079 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
11080 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
11081 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
11084 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
11092 }
else if (!Move && SrcOffset >= DestOffset &&
11093 SrcOffset - DestOffset < NBytes) {
11095 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
11124 QualType AllocType);
11127 const CXXConstructExpr *CCE,
11128 QualType AllocType);
11130bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
11131 if (!Info.getLangOpts().CPlusPlus20)
11132 Info.CCEDiag(E, diag::note_constexpr_new);
11135 if (Info.SpeculativeEvaluationDepth)
11140 QualType TargetType = AllocType;
11142 bool IsNothrow =
false;
11143 bool IsPlacement =
false;
11159 if (OperatorNew->isReservedGlobalPlacementOperator()) {
11160 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
11161 (Info.CurrentCall->CanEvalMSConstexpr &&
11162 OperatorNew->hasAttr<MSConstexprAttr>())) {
11165 if (
Result.Designator.Invalid)
11168 IsPlacement =
true;
11170 Info.FFDiag(E, diag::note_constexpr_new_placement)
11175 Info.FFDiag(E, diag::note_constexpr_new_placement)
11178 }
else if (!OperatorNew
11179 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
11183 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
11186 }
else if (HasNothrowArg) {
11194 const InitListExpr *ResizedArrayILE =
nullptr;
11195 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
11196 bool ValueInit =
false;
11198 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
11199 const Expr *Stripped = *ArraySize;
11200 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
11201 Stripped = ICE->getSubExpr())
11202 if (ICE->getCastKind() != CK_NoOp &&
11203 ICE->getCastKind() != CK_IntegralCast)
11216 return ZeroInitialization(E);
11218 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
11219 <<
ArrayBound << (*ArraySize)->getSourceRange();
11225 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
11230 return ZeroInitialization(E);
11242 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
11243 ResizedArrayCCE = CCE;
11245 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
11246 assert(CAT &&
"unexpected type for array initializer");
11250 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
11251 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
11252 if (InitBound.ugt(AllocBound)) {
11254 return ZeroInitialization(E);
11256 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
11257 <<
toString(AllocBound, 10,
false)
11259 << (*ArraySize)->getSourceRange();
11265 if (InitBound != AllocBound)
11269 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
11270 ArraySizeModifier::Normal, 0);
11280 "array allocation with non-array new");
11286 struct FindObjectHandler {
11289 QualType AllocType;
11293 typedef bool result_type;
11294 bool failed() {
return false; }
11295 bool checkConst(QualType QT) {
11297 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
11302 bool found(
APValue &Subobj, QualType SubobjType,
11303 APValue::LValueBase Base) {
11304 if (!checkConst(SubobjType))
11308 if (!Info.Ctx.hasSimilarType(SubobjType, AllocType)) {
11309 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
11310 << SubobjType << AllocType;
11317 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11320 bool found(APFloat &
Value, QualType SubobjType) {
11321 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11324 } Handler = {Info, E, AllocType, AK,
nullptr};
11327 Result.Designator.MostDerivedIsArrayElement &&
11328 Result.Designator.Entries.back().getAsArrayIndex() == 0) {
11333 QualType AllocElementType =
11334 Info.Ctx.getAsArrayType(AllocType)->getElementType();
11335 if (Info.Ctx.hasSimilarType(AllocElementType,
11336 Result.Designator.MostDerivedType)) {
11338 Result.Designator.MostDerivedPathLength - 1);
11346 Val = Handler.Value;
11355 Val = Info.createHeapAlloc(E, AllocType,
Result);
11361 ImplicitValueInitExpr VIE(AllocType);
11364 }
else if (ResizedArrayILE) {
11368 }
else if (ResizedArrayCCE) {
11392class ReflectionEvaluator :
public ExprEvaluatorBase<ReflectionEvaluator> {
11394 using BaseType = ExprEvaluatorBase<ReflectionEvaluator>;
11407 bool VisitCXXReflectExpr(
const CXXReflectExpr *E);
11408 bool ZeroInitialization(
const Expr *E);
11411bool ReflectionEvaluator::VisitCXXReflectExpr(
const CXXReflectExpr *E) {
11413 case ReflectionKind::Null: {
11414 assert(
false &&
"null reflection can't be constructed from parsing a "
11415 "reflection operand");
11418 case ReflectionKind::Type: {
11420 return Success(ReflectionValue, E);
11423 assert(
false &&
"unknown or unimplemented reflection entities");
11427bool ReflectionEvaluator::ZeroInitialization(
const Expr *E) {
11436 return ReflectionEvaluator(Info,
Result).Visit(E);
11441 unsigned BuiltinOp,
11443 switch (BuiltinOp) {
11444 case Builtin::BI__builtin_meta_is_type: {
11454 llvm_unreachable(
"unknown metafunction builtin");
11463class MemberPointerExprEvaluator
11464 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
11467 bool Success(
const ValueDecl *D) {
11473 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
11480 bool ZeroInitialization(
const Expr *E) {
11481 return Success((
const ValueDecl*)
nullptr);
11484 bool VisitCastExpr(
const CastExpr *E);
11485 bool VisitUnaryAddrOf(
const UnaryOperator *E);
11493 return MemberPointerExprEvaluator(Info,
Result).Visit(E);
11496bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11499 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11501 case CK_NullToMemberPointer:
11503 return ZeroInitialization(E);
11505 case CK_BaseToDerivedMemberPointer: {
11513 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11515 PathI != PathE; ++PathI) {
11516 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11517 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11518 if (!
Result.castToDerived(Derived))
11522 ->
castAs<MemberPointerType>()
11523 ->getMostRecentCXXRecordDecl()))
11528 case CK_DerivedToBaseMemberPointer:
11532 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11533 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11534 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11535 if (!
Result.castToBase(Base))
11542bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11553 class RecordExprEvaluator
11554 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11555 const LValue &
This;
11559 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11566 bool ZeroInitialization(
const Expr *E) {
11567 return ZeroInitialization(E, E->
getType());
11569 bool ZeroInitialization(
const Expr *E, QualType
T);
11571 bool VisitCallExpr(
const CallExpr *E) {
11572 return handleCallExpr(E,
Result, &This);
11574 bool VisitCastExpr(
const CastExpr *E);
11575 bool VisitInitListExpr(
const InitListExpr *E);
11576 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11577 return VisitCXXConstructExpr(E, E->
getType());
11580 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11581 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
11582 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11583 bool VisitBinCmp(
const BinaryOperator *E);
11584 bool VisitTypeTraitExpr(
const TypeTraitExpr *E);
11585 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11586 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11587 ArrayRef<Expr *> Args);
11588 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
11602 bool IsCompleteClass =
true) {
11603 assert(!RD->
isUnion() &&
"Expected non-union class type");
11607 unsigned NonVirtualBases = countNonVirtualBases(CD);
11619 unsigned Index = 0;
11621 for (
const auto &B : CD->
bases()) {
11625 LValue Subobject =
This;
11629 Result.getStructBase(Index),
11636 for (
const auto *I : RD->
fields()) {
11638 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11641 LValue Subobject =
This;
11647 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11651 if (CD &&
This.pointsToCompleteClass(CD)) {
11652 unsigned Index = 0;
11653 for (
const auto &B : CD->
vbases()) {
11655 LValue Subobject =
This;
11659 Result.getStructVirtualBase(Index),
11669bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
11676 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11683 LValue Subobject =
This;
11687 ImplicitValueInitExpr VIE(I->getType());
11691 if (!Info.getLangOpts().CPlusPlus26) {
11692 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11693 CXXRD && CXXRD->getNumVBases()) {
11694 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11702bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11705 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11707 case CK_ConstructorConversion:
11710 case CK_DerivedToBase:
11711 case CK_UncheckedDerivedToBase: {
11722 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11723 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11724 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11731 case CK_HLSLAggregateSplatCast: {
11751 case CK_HLSLElementwiseCast: {
11769 LValue Subobject =
This;
11776 if (
Field->isBitField()) {
11786bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11789 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11792bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11796 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11797 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11799 EvalInfo::EvaluatingConstructorRAII EvalObj(
11801 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11802 CXXRD && CXXRD->getNumBases());
11805 const FieldDecl *
Field;
11806 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11807 Field = ILE->getInitializedFieldInUnion();
11808 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11809 Field = PLIE->getInitializedFieldInUnion();
11812 "Expression is neither an init list nor a C++ paren list");
11824 ImplicitValueInitExpr VIE(
Field->getType());
11825 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11827 LValue Subobject =
This;
11832 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11836 if (
Field->isBitField())
11846 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11848 unsigned ElementNo = 0;
11852 if (CXXRD && CXXRD->getNumBases()) {
11853 for (
const auto &Base : CXXRD->bases()) {
11854 assert(ElementNo < Args.size() &&
"missing init for base class");
11855 const Expr *
Init = Args[ElementNo];
11857 LValue Subobject =
This;
11863 if (!Info.noteFailure())
11870 EvalObj.finishedConstructingBases();
11874 for (
const auto *Field : RD->
fields()) {
11877 if (
Field->isUnnamedBitField())
11880 LValue Subobject =
This;
11882 bool HaveInit = ElementNo < Args.size();
11887 Subobject, Field, &Layout))
11892 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11893 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11900 if (
Field->getType()->isIncompleteArrayType()) {
11901 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11905 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11912 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11916 if (
Field->getType()->isReferenceType()) {
11920 if (!Info.noteFailure())
11925 (
Field->isBitField() &&
11927 if (!Info.noteFailure())
11933 EvalObj.finishedConstructingFields();
11938bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11948 return ZeroInitialization(E,
T);
11968 const Expr *SrcObj = E->
getArg(0);
11970 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11971 if (
const MaterializeTemporaryExpr *ME =
11972 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11973 return Visit(ME->getSubExpr());
11976 if (ZeroInit && !ZeroInitialization(E,
T))
11985bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11986 const CXXInheritedCtorInitExpr *E) {
11987 if (!Info.CurrentCall) {
11988 assert(Info.checkingPotentialConstantExpression());
12009bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
12010 const CXXStdInitializerListExpr *E) {
12011 const ConstantArrayType *ArrayType =
12018 assert(ArrayType &&
"unexpected type for array initializer");
12021 Array.addArray(Info, E, ArrayType);
12029 assert(Field !=
Record->field_end() &&
12030 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
12032 "Expected std::initializer_list first field to be const E *");
12034 assert(Field !=
Record->field_end() &&
12035 "Expected std::initializer_list to have two fields");
12037 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
12042 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
12044 "Expected std::initializer_list second field to be const E *");
12052 assert(++Field ==
Record->field_end() &&
12053 "Expected std::initializer_list to only have two fields");
12058bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
12063 const size_t NumFields = ClosureClass->
getNumFields();
12067 "The number of lambda capture initializers should equal the number of "
12068 "fields within the closure type");
12075 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
12076 for (
const auto *Field : ClosureClass->
fields()) {
12079 Expr *
const CurFieldInit = *CaptureInitIt++;
12086 LValue Subobject =
This;
12093 if (!Info.keepEvaluatingAfterFailure())
12101bool RecordExprEvaluator::VisitDesignatedInitUpdateExpr(
12102 const DesignatedInitUpdateExpr *E) {
12112 "can't evaluate expression as a record rvalue");
12113 return RecordExprEvaluator(Info,
This,
Result).Visit(E);
12124class TemporaryExprEvaluator
12125 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
12127 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
12128 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
12131 bool VisitConstructExpr(
const Expr *E) {
12137 bool VisitCastExpr(
const CastExpr *E) {
12140 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
12142 case CK_ConstructorConversion:
12146 bool VisitInitListExpr(
const InitListExpr *E) {
12147 return VisitConstructExpr(E);
12149 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
12150 return VisitConstructExpr(E);
12152 bool VisitCallExpr(
const CallExpr *E) {
12153 return VisitConstructExpr(E);
12155 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
12156 return VisitConstructExpr(E);
12159 return VisitConstructExpr(E);
12168 return TemporaryExprEvaluator(Info,
Result).Visit(E);
12176 class VectorExprEvaluator
12177 :
public ExprEvaluatorBase<VectorExprEvaluator> {
12184 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
12185 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
12191 assert(
V.isVector());
12195 bool ZeroInitialization(
const Expr *E);
12197 bool VisitUnaryReal(
const UnaryOperator *E)
12199 bool VisitCastExpr(
const CastExpr* E);
12200 bool VisitInitListExpr(
const InitListExpr *E);
12201 bool VisitUnaryImag(
const UnaryOperator *E);
12202 bool VisitBinaryOperator(
const BinaryOperator *E);
12203 bool VisitUnaryOperator(
const UnaryOperator *E);
12204 bool VisitCallExpr(
const CallExpr *E);
12205 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
12206 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
12215 "not a vector prvalue");
12216 return VectorExprEvaluator(Info,
Result).Visit(E);
12220 assert(Val.
isVector() &&
"expected vector APValue");
12224 llvm::APInt
Result(NumElts, 0);
12226 for (
unsigned I = 0; I < NumElts; ++I) {
12228 assert(Elt.
isInt() &&
"expected integer element in bool vector");
12230 if (Elt.
getInt().getBoolValue())
12237bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
12238 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
12242 QualType SETy = SE->
getType();
12245 case CK_VectorSplat: {
12251 Val =
APValue(std::move(IntResult));
12256 Val =
APValue(std::move(FloatResult));
12273 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
12274 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
12275 << Info.Ctx.getLangOpts().CPlusPlus;
12279 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
12284 case CK_HLSLVectorTruncation: {
12289 for (
unsigned I = 0; I < NElts; I++)
12293 case CK_HLSLMatrixTruncation: {
12299 for (
unsigned Row = 0;
12301 for (
unsigned Col = 0;
12306 case CK_HLSLAggregateSplatCast: {
12323 case CK_HLSLElementwiseCast: {
12336 return Success(ResultEls, E);
12338 case CK_IntegralToFloating:
12339 case CK_FloatingToIntegral:
12340 case CK_IntegralCast:
12341 case CK_FloatingCast:
12342 case CK_FloatingToBoolean:
12343 case CK_IntegralToBoolean: {
12345 assert(SETy->
isVectorType() &&
"expected vector source type");
12351 QualType SrcEltTy = SETy->
castAs<VectorType>()->getElementType();
12356 for (
unsigned I = 0; I < NElts; ++I) {
12361 return Success(ResultEls, E);
12364 return ExprEvaluatorBaseTy::VisitCastExpr(E);
12369VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
12386 unsigned CountInits = 0, CountElts = 0;
12387 while (CountElts < NumElements) {
12389 if (CountInits < NumInits
12395 for (
unsigned j = 0; j < vlen; j++)
12399 llvm::APSInt sInt(32);
12400 if (CountInits < NumInits) {
12404 sInt = Info.Ctx.MakeIntValue(0, EltTy);
12405 Elements.push_back(
APValue(sInt));
12408 llvm::APFloat f(0.0);
12409 if (CountInits < NumInits) {
12413 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
12414 Elements.push_back(
APValue(f));
12423VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
12427 if (EltTy->isIntegerType())
12428 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
12431 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
12437bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
12439 return ZeroInitialization(E);
12442bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
12444 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
12445 "Operation not supported on vector types");
12447 if (Op == BO_Comma)
12448 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
12450 Expr *LHS = E->
getLHS();
12451 Expr *RHS = E->
getRHS();
12456 "Must both be vector types");
12459 assert(LHSType->
castAs<VectorType>()->getNumElements() ==
12461 RHSType->
castAs<VectorType>()->getNumElements() ==
12463 "All operands must be the same size.");
12467 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
12468 if (!LHSOK && !Info.noteFailure())
12470 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
12492 "Vector can only be int or float type");
12500 "Vector operator ~ can only be int");
12501 Elt.
getInt().flipAllBits();
12511 "Vector can only be int or float type");
12517 EltResult.setAllBits();
12519 EltResult.clearAllBits();
12525 return std::nullopt;
12529bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
12535 const QualType ResultEltTy = VD->getElementType();
12539 if (!
Evaluate(SubExprValue, Info, SubExpr))
12552 "Vector length doesn't match type?");
12555 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
12557 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12560 ResultElements.push_back(*Elt);
12562 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12573 DestTy,
Result.getFloat());
12589 DestTy,
Result.getInt());
12593 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12594 << SourceTy << DestTy;
12599 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12608 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12609 "pack builtin LHSVecLen must equal to RHSVecLen");
12612 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12618 const unsigned SrcPerLane = 128 / SrcBits;
12619 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12622 Out.reserve(LHSVecLen + RHSVecLen);
12624 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12625 unsigned base = Lane * SrcPerLane;
12626 for (
unsigned I = 0; I != SrcPerLane; ++I)
12629 for (
unsigned I = 0; I != SrcPerLane; ++I)
12640 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12647 unsigned ShuffleMask = 0;
12649 bool IsVectorMask =
false;
12650 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12652 if (IsSingleOperand) {
12655 IsVectorMask =
true;
12664 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12674 IsVectorMask =
true;
12683 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12694 ResultElements.reserve(NumElts);
12696 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12697 if (IsVectorMask) {
12698 ShuffleMask =
static_cast<unsigned>(
12699 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12701 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12707 ResultElements.push_back(
12708 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12714 ResultElements.push_back(
APValue());
12717 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12722 Out =
APValue(ResultElements.data(), ResultElements.size());
12728 if (OrigVal.isInfinity()) {
12729 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12732 if (OrigVal.isNaN()) {
12733 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12737 APFloat Val = OrigVal;
12738 bool LosesInfo =
false;
12739 APFloat::opStatus Status = Val.convert(
12740 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12742 if (LosesInfo || Val.isDenormal()) {
12743 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12747 if (Status != APFloat::opOK) {
12748 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12757 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12758 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12765 assert(
Call->getNumArgs() == 2);
12769 Call->getArg(1)->getType()->isVectorType());
12772 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12773 unsigned DestLen = Source.getVectorLength();
12776 unsigned NumBitsInQWord = 64;
12777 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12779 Result.reserve(DestLen);
12781 uint64_t CountLQWord = 0;
12782 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12784 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12787 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12788 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12789 if (CountLQWord < DestEltWidth) {
12791 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12794 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12802 std::optional<APSInt> RoundingMode,
12804 APSInt DefaultMode(APInt(32, 4),
true);
12805 if (RoundingMode.value_or(DefaultMode) != 4)
12806 return std::nullopt;
12807 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12808 B.isInfinity() || B.isDenormal())
12809 return std::nullopt;
12810 if (A.isZero() && B.isZero())
12812 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12815bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12816 if (!IsConstantEvaluatedBuiltinCall(E))
12817 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12821 auto EvaluateBinOpExpr =
12823 APValue SourceLHS, SourceRHS;
12829 QualType DestEltTy = DestTy->getElementType();
12830 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12833 ResultElements.reserve(SourceLen);
12835 if (SourceRHS.
isInt()) {
12837 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12839 ResultElements.push_back(
12843 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12846 ResultElements.push_back(
12853 auto EvaluateFpBinOpExpr =
12854 [&](llvm::function_ref<std::optional<APFloat>(
12855 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12857 bool IsScalar =
false) {
12867 std::optional<APSInt> RoundingMode;
12872 RoundingMode = Imm;
12877 ResultElements.reserve(NumElems);
12879 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12880 if (IsScalar && EltNum > 0) {
12886 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12894 auto EvaluateScalarFpRoundMaskBinOp =
12895 [&](llvm::function_ref<std::optional<APFloat>(
12896 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12900 APSInt MaskVal, Rounding;
12911 ResultElements.reserve(NumElems);
12913 if (MaskVal.getZExtValue() & 1) {
12916 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12924 for (
unsigned I = 1; I < NumElems; ++I)
12930 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12938 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12942 for (
unsigned I = 1; I < Len; ++I)
12944 APValue V(Res.data(), Res.size());
12948 auto EvalVectorDotProduct = [&](
bool IsSaturating) ->
bool {
12949 APValue Source, OperandA, OperandB;
12958 unsigned ElemsPerLane = NumOperandElems / NumSrcElems;
12963 Result.reserve(NumSrcElems);
12964 for (
unsigned I = 0; I != NumSrcElems; ++I) {
12966 DotProduct = DotProduct.extend(64);
12967 for (
unsigned J = 0; J != ElemsPerLane; ++J) {
12974 DotProduct += OpA * OpB;
12976 if (IsSaturating) {
12977 DotProduct =
APSInt(DotProduct.truncSSat(32),
false);
12979 DotProduct =
APSInt(DotProduct.trunc(32),
false);
12987 switch (BuiltinOp) {
12990 case Builtin::BI__builtin_elementwise_popcount:
12991 case Builtin::BI__builtin_elementwise_bitreverse: {
12996 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12999 ResultElements.reserve(SourceLen);
13001 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13003 switch (BuiltinOp) {
13004 case Builtin::BI__builtin_elementwise_popcount:
13005 ResultElements.push_back(
APValue(
13006 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
13009 case Builtin::BI__builtin_elementwise_bitreverse:
13010 ResultElements.push_back(
13017 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13019 case Builtin::BI__builtin_elementwise_abs: {
13024 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13027 ResultElements.reserve(SourceLen);
13029 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13034 CurrentEle.getInt().
abs(),
13035 DestEltTy->isUnsignedIntegerOrEnumerationType()));
13036 ResultElements.push_back(Val);
13039 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13042 case Builtin::BI__builtin_elementwise_add_sat:
13043 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13044 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
13047 case Builtin::BI__builtin_elementwise_sub_sat:
13048 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13049 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
13052 case X86::BI__builtin_ia32_extract128i256:
13053 case X86::BI__builtin_ia32_vextractf128_pd256:
13054 case X86::BI__builtin_ia32_vextractf128_ps256:
13055 case X86::BI__builtin_ia32_vextractf128_si256: {
13056 APValue SourceVec, SourceImm;
13065 unsigned RetLen = RetVT->getNumElements();
13066 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
13069 ResultElements.reserve(RetLen);
13071 for (
unsigned I = 0; I < RetLen; I++)
13072 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
13077 case clang::X86::BI__builtin_ia32_cvtmask2b128:
13078 case clang::X86::BI__builtin_ia32_cvtmask2b256:
13079 case clang::X86::BI__builtin_ia32_cvtmask2b512:
13080 case clang::X86::BI__builtin_ia32_cvtmask2w128:
13081 case clang::X86::BI__builtin_ia32_cvtmask2w256:
13082 case clang::X86::BI__builtin_ia32_cvtmask2w512:
13083 case clang::X86::BI__builtin_ia32_cvtmask2d128:
13084 case clang::X86::BI__builtin_ia32_cvtmask2d256:
13085 case clang::X86::BI__builtin_ia32_cvtmask2d512:
13086 case clang::X86::BI__builtin_ia32_cvtmask2q128:
13087 case clang::X86::BI__builtin_ia32_cvtmask2q256:
13088 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
13094 QualType VecTy = E->
getType();
13095 const VectorType *VT = VecTy->
castAs<VectorType>();
13098 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
13101 for (
unsigned I = 0; I != VectorLen; ++I) {
13102 bool BitSet = Mask[I];
13103 APSInt ElemVal(ElemWidth,
false);
13105 ElemVal.setAllBits();
13107 Elems.push_back(
APValue(ElemVal));
13112 case X86::BI__builtin_ia32_extracti32x4_256_mask:
13113 case X86::BI__builtin_ia32_extractf32x4_256_mask:
13114 case X86::BI__builtin_ia32_extracti32x4_mask:
13115 case X86::BI__builtin_ia32_extractf32x4_mask:
13116 case X86::BI__builtin_ia32_extracti32x8_mask:
13117 case X86::BI__builtin_ia32_extractf32x8_mask:
13118 case X86::BI__builtin_ia32_extracti64x2_256_mask:
13119 case X86::BI__builtin_ia32_extractf64x2_256_mask:
13120 case X86::BI__builtin_ia32_extracti64x2_512_mask:
13121 case X86::BI__builtin_ia32_extractf64x2_512_mask:
13122 case X86::BI__builtin_ia32_extracti64x4_mask:
13123 case X86::BI__builtin_ia32_extractf64x4_mask: {
13134 unsigned RetLen = RetVT->getNumElements();
13139 unsigned Lanes = SrcLen / RetLen;
13140 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
13141 unsigned Base = Lane * RetLen;
13144 ResultElements.reserve(RetLen);
13145 for (
unsigned I = 0; I < RetLen; ++I) {
13147 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
13151 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13154 case clang::X86::BI__builtin_ia32_pavgb128:
13155 case clang::X86::BI__builtin_ia32_pavgw128:
13156 case clang::X86::BI__builtin_ia32_pavgb256:
13157 case clang::X86::BI__builtin_ia32_pavgw256:
13158 case clang::X86::BI__builtin_ia32_pavgb512:
13159 case clang::X86::BI__builtin_ia32_pavgw512:
13160 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
13162 case clang::X86::BI__builtin_ia32_pmulhrsw128:
13163 case clang::X86::BI__builtin_ia32_pmulhrsw256:
13164 case clang::X86::BI__builtin_ia32_pmulhrsw512:
13165 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13166 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
13167 .extractBits(16, 1);
13170 case clang::X86::BI__builtin_ia32_psadbw128:
13171 case clang::X86::BI__builtin_ia32_psadbw256:
13172 case clang::X86::BI__builtin_ia32_psadbw512: {
13173 APValue SourceLHS, SourceRHS;
13181 assert((SourceLen % 8) == 0);
13184 QualType DestEltTy = DestTy->getElementType();
13185 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13187 ResultElements.reserve(SourceLen / 8);
13189 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 8) {
13191 for (
unsigned I = 0; I != 8; ++I) {
13194 Sum += llvm::APIntOps::abdu(LHS, RHS).zext(64);
13196 ResultElements.push_back(
APValue(
APSInt(Sum, DestUnsigned)));
13199 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13202 case clang::X86::BI__builtin_ia32_pmaddubsw128:
13203 case clang::X86::BI__builtin_ia32_pmaddubsw256:
13204 case clang::X86::BI__builtin_ia32_pmaddubsw512:
13205 case clang::X86::BI__builtin_ia32_pmaddwd128:
13206 case clang::X86::BI__builtin_ia32_pmaddwd256:
13207 case clang::X86::BI__builtin_ia32_pmaddwd512: {
13208 APValue SourceLHS, SourceRHS;
13214 QualType DestEltTy = DestTy->getElementType();
13216 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13218 ResultElements.reserve(SourceLen / 2);
13220 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
13225 unsigned BitWidth = 2 * LoLHS.getBitWidth();
13227 switch (BuiltinOp) {
13228 case clang::X86::BI__builtin_ia32_pmaddubsw128:
13229 case clang::X86::BI__builtin_ia32_pmaddubsw256:
13230 case clang::X86::BI__builtin_ia32_pmaddubsw512:
13231 ResultElements.push_back(
APValue(
13232 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
13233 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
13236 case clang::X86::BI__builtin_ia32_pmaddwd128:
13237 case clang::X86::BI__builtin_ia32_pmaddwd256:
13238 case clang::X86::BI__builtin_ia32_pmaddwd512:
13239 ResultElements.push_back(
13240 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
13241 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
13247 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13250 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v16hi:
13251 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v32hi:
13252 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi:
13253 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi: {
13264 APValue SourceA, SourceB, SourceC;
13271 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi ||
13273 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi;
13276 assert(SourceLen % 16 == 0 &&
"BMM operates on 256-bit lanes of 16 x i16");
13278 QualType DestEltTy = DestTy->getElementType();
13279 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13282 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 16) {
13283 for (
unsigned I = 0; I != 16; ++I) {
13288 for (
unsigned J = 0; J != 16; ++J) {
13292 unsigned Bit = (Dst >> J) & 1u;
13293 for (
unsigned K = 0; K != 16; ++K) {
13297 unsigned Product = ((A >> K) & 1u) & ((B >> J) & 1u);
13298 Bit = IsXor ? (Bit ^ Product) : (Bit | Product);
13302 ResultElements[Lane + I] =
13306 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13309 case clang::X86::BI__builtin_ia32_dbpsadbw128:
13310 case clang::X86::BI__builtin_ia32_dbpsadbw256:
13311 case clang::X86::BI__builtin_ia32_dbpsadbw512: {
13312 APValue SourceA, SourceB, SourceImm;
13319 constexpr unsigned LaneSize = 16;
13320 unsigned Imm = SourceImm.
getInt().getZExtValue();
13323 QualType DestEltTy = DestTy->getElementType();
13324 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13326 ResultElements.reserve(SourceLen / 2);
13332 for (
unsigned I = 0; I < SourceLen; I += LaneSize) {
13333 for (
unsigned J = 0; J < 4; ++J) {
13334 unsigned Part = (Imm >> (2 * J)) & 3;
13335 for (
unsigned K = 0; K < 4; ++K) {
13336 Shuffled[I + 4 * J + K] =
static_cast<uint8_t>(
13337 SourceB.
getVectorElt(I + 4 * Part + K).getInt().getZExtValue());
13345 unsigned Size = SourceLen / 2;
13346 for (
unsigned I = 0; I <
Size; I += 4) {
13347 unsigned Sad[4] = {0, 0, 0, 0};
13348 for (
unsigned J = 0; J < 4; ++J) {
13350 SourceA.
getVectorElt(2 * I + J).getInt().getZExtValue());
13352 SourceA.
getVectorElt(2 * I + J + 4).getInt().getZExtValue());
13353 uint8_t B0 = Shuffled[2 * I + J];
13354 uint8_t B1 = Shuffled[2 * I + J + 1];
13355 uint8_t B2 = Shuffled[2 * I + J + 2];
13356 uint8_t B3 = Shuffled[2 * I + J + 3];
13357 Sad[0] += (A1 > B0) ? (A1 - B0) : (B0 - A1);
13358 Sad[1] += (A1 > B1) ? (A1 - B1) : (B1 - A1);
13359 Sad[2] += (A2 > B2) ? (A2 - B2) : (B2 - A2);
13360 Sad[3] += (A2 > B3) ? (A2 - B3) : (B3 - A2);
13362 for (
unsigned R = 0;
R < 4; ++
R)
13363 ResultElements.push_back(
13367 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13370 case clang::X86::BI__builtin_ia32_mpsadbw128:
13371 case clang::X86::BI__builtin_ia32_mpsadbw256: {
13379 constexpr unsigned LaneSize = 16;
13380 assert((SourceLen == LaneSize || SourceLen == 2 * LaneSize) &&
13381 "MPSADBW operates on 128-bit or 256-bit vectors");
13382 unsigned NumLanes = SourceLen / LaneSize;
13383 unsigned Imm = SourceImm.getZExtValue();
13385 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13388 ResultElements.reserve(SourceLen / 2);
13390 for (
unsigned Lane = 0; Lane != NumLanes; ++Lane) {
13391 unsigned Ctrl = (Imm >> (3 * Lane)) & 0x7;
13392 unsigned AOff = ((Ctrl >> 2) & 1) * 4;
13393 unsigned BOff = (Ctrl & 3) * 4;
13394 for (
unsigned J = 0; J != 8; ++J) {
13396 for (
unsigned K = 0; K != 4; ++K) {
13405 Sad += (A > B) ? (A - B) : (B - A);
13410 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13413 case clang::X86::BI__builtin_ia32_pmulhuw128:
13414 case clang::X86::BI__builtin_ia32_pmulhuw256:
13415 case clang::X86::BI__builtin_ia32_pmulhuw512:
13416 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
13418 case clang::X86::BI__builtin_ia32_pmulhw128:
13419 case clang::X86::BI__builtin_ia32_pmulhw256:
13420 case clang::X86::BI__builtin_ia32_pmulhw512:
13421 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
13423 case clang::X86::BI__builtin_ia32_psllv2di:
13424 case clang::X86::BI__builtin_ia32_psllv4di:
13425 case clang::X86::BI__builtin_ia32_psllv4si:
13426 case clang::X86::BI__builtin_ia32_psllv8di:
13427 case clang::X86::BI__builtin_ia32_psllv8hi:
13428 case clang::X86::BI__builtin_ia32_psllv8si:
13429 case clang::X86::BI__builtin_ia32_psllv16hi:
13430 case clang::X86::BI__builtin_ia32_psllv16si:
13431 case clang::X86::BI__builtin_ia32_psllv32hi:
13432 case clang::X86::BI__builtin_ia32_psllwi128:
13433 case clang::X86::BI__builtin_ia32_pslldi128:
13434 case clang::X86::BI__builtin_ia32_psllqi128:
13435 case clang::X86::BI__builtin_ia32_psllwi256:
13436 case clang::X86::BI__builtin_ia32_pslldi256:
13437 case clang::X86::BI__builtin_ia32_psllqi256:
13438 case clang::X86::BI__builtin_ia32_psllwi512:
13439 case clang::X86::BI__builtin_ia32_pslldi512:
13440 case clang::X86::BI__builtin_ia32_psllqi512:
13441 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13442 if (RHS.uge(LHS.getBitWidth())) {
13443 return APInt::getZero(LHS.getBitWidth());
13445 return LHS.shl(RHS.getZExtValue());
13448 case clang::X86::BI__builtin_ia32_psrav4si:
13449 case clang::X86::BI__builtin_ia32_psrav8di:
13450 case clang::X86::BI__builtin_ia32_psrav8hi:
13451 case clang::X86::BI__builtin_ia32_psrav8si:
13452 case clang::X86::BI__builtin_ia32_psrav16hi:
13453 case clang::X86::BI__builtin_ia32_psrav16si:
13454 case clang::X86::BI__builtin_ia32_psrav32hi:
13455 case clang::X86::BI__builtin_ia32_psravq128:
13456 case clang::X86::BI__builtin_ia32_psravq256:
13457 case clang::X86::BI__builtin_ia32_psrawi128:
13458 case clang::X86::BI__builtin_ia32_psradi128:
13459 case clang::X86::BI__builtin_ia32_psraqi128:
13460 case clang::X86::BI__builtin_ia32_psrawi256:
13461 case clang::X86::BI__builtin_ia32_psradi256:
13462 case clang::X86::BI__builtin_ia32_psraqi256:
13463 case clang::X86::BI__builtin_ia32_psrawi512:
13464 case clang::X86::BI__builtin_ia32_psradi512:
13465 case clang::X86::BI__builtin_ia32_psraqi512:
13466 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13467 if (RHS.uge(LHS.getBitWidth())) {
13468 return LHS.ashr(LHS.getBitWidth() - 1);
13470 return LHS.ashr(RHS.getZExtValue());
13473 case clang::X86::BI__builtin_ia32_psrlv2di:
13474 case clang::X86::BI__builtin_ia32_psrlv4di:
13475 case clang::X86::BI__builtin_ia32_psrlv4si:
13476 case clang::X86::BI__builtin_ia32_psrlv8di:
13477 case clang::X86::BI__builtin_ia32_psrlv8hi:
13478 case clang::X86::BI__builtin_ia32_psrlv8si:
13479 case clang::X86::BI__builtin_ia32_psrlv16hi:
13480 case clang::X86::BI__builtin_ia32_psrlv16si:
13481 case clang::X86::BI__builtin_ia32_psrlv32hi:
13482 case clang::X86::BI__builtin_ia32_psrlwi128:
13483 case clang::X86::BI__builtin_ia32_psrldi128:
13484 case clang::X86::BI__builtin_ia32_psrlqi128:
13485 case clang::X86::BI__builtin_ia32_psrlwi256:
13486 case clang::X86::BI__builtin_ia32_psrldi256:
13487 case clang::X86::BI__builtin_ia32_psrlqi256:
13488 case clang::X86::BI__builtin_ia32_psrlwi512:
13489 case clang::X86::BI__builtin_ia32_psrldi512:
13490 case clang::X86::BI__builtin_ia32_psrlqi512:
13491 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13492 if (RHS.uge(LHS.getBitWidth())) {
13493 return APInt::getZero(LHS.getBitWidth());
13495 return LHS.lshr(RHS.getZExtValue());
13497 case X86::BI__builtin_ia32_packsswb128:
13498 case X86::BI__builtin_ia32_packsswb256:
13499 case X86::BI__builtin_ia32_packsswb512:
13500 case X86::BI__builtin_ia32_packssdw128:
13501 case X86::BI__builtin_ia32_packssdw256:
13502 case X86::BI__builtin_ia32_packssdw512:
13504 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
13506 case X86::BI__builtin_ia32_packusdw128:
13507 case X86::BI__builtin_ia32_packusdw256:
13508 case X86::BI__builtin_ia32_packusdw512:
13509 case X86::BI__builtin_ia32_packuswb128:
13510 case X86::BI__builtin_ia32_packuswb256:
13511 case X86::BI__builtin_ia32_packuswb512:
13513 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
13515 case clang::X86::BI__builtin_ia32_selectss_128:
13516 return EvalSelectScalar(4);
13517 case clang::X86::BI__builtin_ia32_selectsd_128:
13518 return EvalSelectScalar(2);
13519 case clang::X86::BI__builtin_ia32_selectsh_128:
13520 case clang::X86::BI__builtin_ia32_selectsbf_128:
13521 return EvalSelectScalar(8);
13522 case clang::X86::BI__builtin_ia32_pmuldq128:
13523 case clang::X86::BI__builtin_ia32_pmuldq256:
13524 case clang::X86::BI__builtin_ia32_pmuldq512:
13525 case clang::X86::BI__builtin_ia32_pmuludq128:
13526 case clang::X86::BI__builtin_ia32_pmuludq256:
13527 case clang::X86::BI__builtin_ia32_pmuludq512: {
13528 APValue SourceLHS, SourceRHS;
13535 ResultElements.reserve(SourceLen / 2);
13537 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
13541 switch (BuiltinOp) {
13542 case clang::X86::BI__builtin_ia32_pmuludq128:
13543 case clang::X86::BI__builtin_ia32_pmuludq256:
13544 case clang::X86::BI__builtin_ia32_pmuludq512:
13545 ResultElements.push_back(
13546 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
13548 case clang::X86::BI__builtin_ia32_pmuldq128:
13549 case clang::X86::BI__builtin_ia32_pmuldq256:
13550 case clang::X86::BI__builtin_ia32_pmuldq512:
13551 ResultElements.push_back(
13552 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
13557 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13560 case X86::BI__builtin_ia32_vpmadd52luq128:
13561 case X86::BI__builtin_ia32_vpmadd52luq256:
13562 case X86::BI__builtin_ia32_vpmadd52luq512: {
13571 ResultElements.reserve(ALen);
13573 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13576 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13577 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
13578 ResultElements.push_back(
APValue(ResElt));
13581 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13583 case X86::BI__builtin_ia32_vpmadd52huq128:
13584 case X86::BI__builtin_ia32_vpmadd52huq256:
13585 case X86::BI__builtin_ia32_vpmadd52huq512: {
13594 ResultElements.reserve(ALen);
13596 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13599 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13600 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
13601 ResultElements.push_back(
APValue(ResElt));
13604 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13607 case clang::X86::BI__builtin_ia32_vprotbi:
13608 case clang::X86::BI__builtin_ia32_vprotdi:
13609 case clang::X86::BI__builtin_ia32_vprotqi:
13610 case clang::X86::BI__builtin_ia32_vprotwi:
13611 case clang::X86::BI__builtin_ia32_prold128:
13612 case clang::X86::BI__builtin_ia32_prold256:
13613 case clang::X86::BI__builtin_ia32_prold512:
13614 case clang::X86::BI__builtin_ia32_prolq128:
13615 case clang::X86::BI__builtin_ia32_prolq256:
13616 case clang::X86::BI__builtin_ia32_prolq512:
13617 return EvaluateBinOpExpr(
13618 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
13620 case clang::X86::BI__builtin_ia32_prord128:
13621 case clang::X86::BI__builtin_ia32_prord256:
13622 case clang::X86::BI__builtin_ia32_prord512:
13623 case clang::X86::BI__builtin_ia32_prorq128:
13624 case clang::X86::BI__builtin_ia32_prorq256:
13625 case clang::X86::BI__builtin_ia32_prorq512:
13626 return EvaluateBinOpExpr(
13627 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
13629 case Builtin::BI__builtin_elementwise_max:
13630 case Builtin::BI__builtin_elementwise_min: {
13631 APValue SourceLHS, SourceRHS;
13636 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13643 ResultElements.reserve(SourceLen);
13645 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13648 switch (BuiltinOp) {
13649 case Builtin::BI__builtin_elementwise_max:
13650 ResultElements.push_back(
13654 case Builtin::BI__builtin_elementwise_min:
13655 ResultElements.push_back(
13662 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13664 case X86::BI__builtin_ia32_vpshldd128:
13665 case X86::BI__builtin_ia32_vpshldd256:
13666 case X86::BI__builtin_ia32_vpshldd512:
13667 case X86::BI__builtin_ia32_vpshldq128:
13668 case X86::BI__builtin_ia32_vpshldq256:
13669 case X86::BI__builtin_ia32_vpshldq512:
13670 case X86::BI__builtin_ia32_vpshldw128:
13671 case X86::BI__builtin_ia32_vpshldw256:
13672 case X86::BI__builtin_ia32_vpshldw512: {
13673 APValue SourceHi, SourceLo, SourceAmt;
13679 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13682 ResultElements.reserve(SourceLen);
13685 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13688 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
13689 ResultElements.push_back(
13693 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13695 case X86::BI__builtin_ia32_vpshrdd128:
13696 case X86::BI__builtin_ia32_vpshrdd256:
13697 case X86::BI__builtin_ia32_vpshrdd512:
13698 case X86::BI__builtin_ia32_vpshrdq128:
13699 case X86::BI__builtin_ia32_vpshrdq256:
13700 case X86::BI__builtin_ia32_vpshrdq512:
13701 case X86::BI__builtin_ia32_vpshrdw128:
13702 case X86::BI__builtin_ia32_vpshrdw256:
13703 case X86::BI__builtin_ia32_vpshrdw512: {
13705 APValue SourceHi, SourceLo, SourceAmt;
13711 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13714 ResultElements.reserve(SourceLen);
13717 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13720 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
13721 ResultElements.push_back(
13725 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13727 case X86::BI__builtin_ia32_compressdf128_mask:
13728 case X86::BI__builtin_ia32_compressdf256_mask:
13729 case X86::BI__builtin_ia32_compressdf512_mask:
13730 case X86::BI__builtin_ia32_compressdi128_mask:
13731 case X86::BI__builtin_ia32_compressdi256_mask:
13732 case X86::BI__builtin_ia32_compressdi512_mask:
13733 case X86::BI__builtin_ia32_compresshi128_mask:
13734 case X86::BI__builtin_ia32_compresshi256_mask:
13735 case X86::BI__builtin_ia32_compresshi512_mask:
13736 case X86::BI__builtin_ia32_compressqi128_mask:
13737 case X86::BI__builtin_ia32_compressqi256_mask:
13738 case X86::BI__builtin_ia32_compressqi512_mask:
13739 case X86::BI__builtin_ia32_compresssf128_mask:
13740 case X86::BI__builtin_ia32_compresssf256_mask:
13741 case X86::BI__builtin_ia32_compresssf512_mask:
13742 case X86::BI__builtin_ia32_compresssi128_mask:
13743 case X86::BI__builtin_ia32_compresssi256_mask:
13744 case X86::BI__builtin_ia32_compresssi512_mask: {
13755 ResultElements.reserve(NumElts);
13757 for (
unsigned I = 0; I != NumElts; ++I) {
13761 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
13765 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13767 case X86::BI__builtin_ia32_expanddf128_mask:
13768 case X86::BI__builtin_ia32_expanddf256_mask:
13769 case X86::BI__builtin_ia32_expanddf512_mask:
13770 case X86::BI__builtin_ia32_expanddi128_mask:
13771 case X86::BI__builtin_ia32_expanddi256_mask:
13772 case X86::BI__builtin_ia32_expanddi512_mask:
13773 case X86::BI__builtin_ia32_expandhi128_mask:
13774 case X86::BI__builtin_ia32_expandhi256_mask:
13775 case X86::BI__builtin_ia32_expandhi512_mask:
13776 case X86::BI__builtin_ia32_expandqi128_mask:
13777 case X86::BI__builtin_ia32_expandqi256_mask:
13778 case X86::BI__builtin_ia32_expandqi512_mask:
13779 case X86::BI__builtin_ia32_expandsf128_mask:
13780 case X86::BI__builtin_ia32_expandsf256_mask:
13781 case X86::BI__builtin_ia32_expandsf512_mask:
13782 case X86::BI__builtin_ia32_expandsi128_mask:
13783 case X86::BI__builtin_ia32_expandsi256_mask:
13784 case X86::BI__builtin_ia32_expandsi512_mask: {
13795 ResultElements.reserve(NumElts);
13797 unsigned SourceIdx = 0;
13798 for (
unsigned I = 0; I != NumElts; ++I) {
13800 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
13804 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13806 case X86::BI__builtin_ia32_vpconflictsi_128:
13807 case X86::BI__builtin_ia32_vpconflictsi_256:
13808 case X86::BI__builtin_ia32_vpconflictsi_512:
13809 case X86::BI__builtin_ia32_vpconflictdi_128:
13810 case X86::BI__builtin_ia32_vpconflictdi_256:
13811 case X86::BI__builtin_ia32_vpconflictdi_512: {
13819 ResultElements.reserve(SourceLen);
13822 bool DestUnsigned =
13823 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
13825 for (
unsigned I = 0; I != SourceLen; ++I) {
13828 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
13829 for (
unsigned J = 0; J != I; ++J) {
13831 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
13833 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
13835 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13837 case X86::BI__builtin_ia32_blendpd:
13838 case X86::BI__builtin_ia32_blendpd256:
13839 case X86::BI__builtin_ia32_blendps:
13840 case X86::BI__builtin_ia32_blendps256:
13841 case X86::BI__builtin_ia32_pblendw128:
13842 case X86::BI__builtin_ia32_pblendw256:
13843 case X86::BI__builtin_ia32_pblendd128:
13844 case X86::BI__builtin_ia32_pblendd256: {
13845 APValue SourceF, SourceT, SourceC;
13854 ResultElements.reserve(SourceLen);
13855 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13858 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
13861 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13864 case X86::BI__builtin_ia32_psignb128:
13865 case X86::BI__builtin_ia32_psignb256:
13866 case X86::BI__builtin_ia32_psignw128:
13867 case X86::BI__builtin_ia32_psignw256:
13868 case X86::BI__builtin_ia32_psignd128:
13869 case X86::BI__builtin_ia32_psignd256:
13870 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13871 if (BElem.isZero())
13872 return APInt::getZero(AElem.getBitWidth());
13873 if (BElem.isNegative())
13878 case X86::BI__builtin_ia32_blendvpd:
13879 case X86::BI__builtin_ia32_blendvpd256:
13880 case X86::BI__builtin_ia32_blendvps:
13881 case X86::BI__builtin_ia32_blendvps256:
13882 case X86::BI__builtin_ia32_pblendvb128:
13883 case X86::BI__builtin_ia32_pblendvb256: {
13885 APValue SourceF, SourceT, SourceC;
13893 ResultElements.reserve(SourceLen);
13895 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13899 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13900 ResultElements.push_back(M.isNegative() ?
T : F);
13903 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13905 case X86::BI__builtin_ia32_selectb_128:
13906 case X86::BI__builtin_ia32_selectb_256:
13907 case X86::BI__builtin_ia32_selectb_512:
13908 case X86::BI__builtin_ia32_selectw_128:
13909 case X86::BI__builtin_ia32_selectw_256:
13910 case X86::BI__builtin_ia32_selectw_512:
13911 case X86::BI__builtin_ia32_selectd_128:
13912 case X86::BI__builtin_ia32_selectd_256:
13913 case X86::BI__builtin_ia32_selectd_512:
13914 case X86::BI__builtin_ia32_selectq_128:
13915 case X86::BI__builtin_ia32_selectq_256:
13916 case X86::BI__builtin_ia32_selectq_512:
13917 case X86::BI__builtin_ia32_selectph_128:
13918 case X86::BI__builtin_ia32_selectph_256:
13919 case X86::BI__builtin_ia32_selectph_512:
13920 case X86::BI__builtin_ia32_selectpbf_128:
13921 case X86::BI__builtin_ia32_selectpbf_256:
13922 case X86::BI__builtin_ia32_selectpbf_512:
13923 case X86::BI__builtin_ia32_selectps_128:
13924 case X86::BI__builtin_ia32_selectps_256:
13925 case X86::BI__builtin_ia32_selectps_512:
13926 case X86::BI__builtin_ia32_selectpd_128:
13927 case X86::BI__builtin_ia32_selectpd_256:
13928 case X86::BI__builtin_ia32_selectpd_512: {
13930 APValue SourceMask, SourceLHS, SourceRHS;
13939 ResultElements.reserve(SourceLen);
13941 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13944 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13947 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13950 case X86::BI__builtin_ia32_cvtsd2ss: {
13963 Elements.push_back(ResultVal);
13966 for (
unsigned I = 1; I < NumEltsA; ++I) {
13972 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13973 APValue VecA, VecB, VecSrc, MaskValue;
13981 unsigned Mask = MaskValue.
getInt().getZExtValue();
13989 Elements.push_back(ResultVal);
13995 for (
unsigned I = 1; I < NumEltsA; ++I) {
14001 case X86::BI__builtin_ia32_cvtpd2ps:
14002 case X86::BI__builtin_ia32_cvtpd2ps256:
14003 case X86::BI__builtin_ia32_cvtpd2ps_mask:
14004 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
14006 const auto BuiltinID = BuiltinOp;
14007 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
14008 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
14015 unsigned Mask = 0xFFFFFFFF;
14016 bool NeedsMerge =
false;
14021 Mask = MaskValue.
getInt().getZExtValue();
14022 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
14023 for (
unsigned I = 0; I < NumEltsResult; ++I) {
14024 if (!((Mask >> I) & 1)) {
14035 unsigned NumEltsResult =
14039 for (
unsigned I = 0; I < NumEltsResult; ++I) {
14040 if (IsMasked && !((Mask >> I) & 1)) {
14048 if (I >= NumEltsInput) {
14049 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
14058 Elements.push_back(ResultVal);
14063 case X86::BI__builtin_ia32_shufps:
14064 case X86::BI__builtin_ia32_shufps256:
14065 case X86::BI__builtin_ia32_shufps512: {
14069 [](
unsigned DstIdx,
14070 unsigned ShuffleMask) -> std::pair<unsigned, int> {
14071 constexpr unsigned LaneBits = 128u;
14072 unsigned NumElemPerLane = LaneBits / 32;
14073 unsigned NumSelectableElems = NumElemPerLane / 2;
14074 unsigned BitsPerElem = 2;
14075 unsigned IndexMask = (1u << BitsPerElem) - 1;
14076 unsigned MaskBits = 8;
14077 unsigned Lane = DstIdx / NumElemPerLane;
14078 unsigned ElemInLane = DstIdx % NumElemPerLane;
14079 unsigned LaneOffset = Lane * NumElemPerLane;
14080 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
14081 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
14082 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
14083 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
14088 case X86::BI__builtin_ia32_shufpd:
14089 case X86::BI__builtin_ia32_shufpd256:
14090 case X86::BI__builtin_ia32_shufpd512: {
14094 [](
unsigned DstIdx,
14095 unsigned ShuffleMask) -> std::pair<unsigned, int> {
14096 constexpr unsigned LaneBits = 128u;
14097 unsigned NumElemPerLane = LaneBits / 64;
14098 unsigned NumSelectableElems = NumElemPerLane / 2;
14099 unsigned BitsPerElem = 1;
14100 unsigned IndexMask = (1u << BitsPerElem) - 1;
14101 unsigned MaskBits = 8;
14102 unsigned Lane = DstIdx / NumElemPerLane;
14103 unsigned ElemInLane = DstIdx % NumElemPerLane;
14104 unsigned LaneOffset = Lane * NumElemPerLane;
14105 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
14106 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
14107 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
14108 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
14113 case X86::BI__builtin_ia32_insertps128: {
14117 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14119 if ((Mask & (1 << DstIdx)) != 0) {
14124 unsigned SrcElem = (Mask >> 6) & 0x3;
14125 unsigned DstElem = (Mask >> 4) & 0x3;
14126 if (DstIdx == DstElem) {
14128 return {1,
static_cast<int>(SrcElem)};
14131 return {0,
static_cast<int>(DstIdx)};
14137 case X86::BI__builtin_ia32_pshufb128:
14138 case X86::BI__builtin_ia32_pshufb256:
14139 case X86::BI__builtin_ia32_pshufb512: {
14143 [](
unsigned DstIdx,
14144 unsigned ShuffleMask) -> std::pair<unsigned, int> {
14147 return std::make_pair(0, -1);
14149 unsigned LaneBase = (DstIdx / 16) * 16;
14150 unsigned SrcOffset = Ctlb & 0x0F;
14151 unsigned SrcIdx = LaneBase + SrcOffset;
14152 return std::make_pair(0,
static_cast<int>(SrcIdx));
14158 case X86::BI__builtin_ia32_pshuflw:
14159 case X86::BI__builtin_ia32_pshuflw256:
14160 case X86::BI__builtin_ia32_pshuflw512: {
14164 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14165 constexpr unsigned LaneBits = 128u;
14166 constexpr unsigned ElemBits = 16u;
14167 constexpr unsigned LaneElts = LaneBits / ElemBits;
14168 constexpr unsigned HalfSize = 4;
14169 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
14170 unsigned LaneIdx = DstIdx % LaneElts;
14171 if (LaneIdx < HalfSize) {
14172 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
14173 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
14175 return std::make_pair(0,
static_cast<int>(DstIdx));
14181 case X86::BI__builtin_ia32_pshufhw:
14182 case X86::BI__builtin_ia32_pshufhw256:
14183 case X86::BI__builtin_ia32_pshufhw512: {
14187 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14188 constexpr unsigned LaneBits = 128u;
14189 constexpr unsigned ElemBits = 16u;
14190 constexpr unsigned LaneElts = LaneBits / ElemBits;
14191 constexpr unsigned HalfSize = 4;
14192 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
14193 unsigned LaneIdx = DstIdx % LaneElts;
14194 if (LaneIdx >= HalfSize) {
14195 unsigned Rel = LaneIdx - HalfSize;
14196 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
14197 return std::make_pair(
14198 0,
static_cast<int>(LaneBase + HalfSize + Sel));
14200 return std::make_pair(0,
static_cast<int>(DstIdx));
14206 case X86::BI__builtin_ia32_pshufd:
14207 case X86::BI__builtin_ia32_pshufd256:
14208 case X86::BI__builtin_ia32_pshufd512:
14209 case X86::BI__builtin_ia32_vpermilps:
14210 case X86::BI__builtin_ia32_vpermilps256:
14211 case X86::BI__builtin_ia32_vpermilps512: {
14215 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14216 constexpr unsigned LaneBits = 128u;
14217 constexpr unsigned ElemBits = 32u;
14218 constexpr unsigned LaneElts = LaneBits / ElemBits;
14219 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
14220 unsigned LaneIdx = DstIdx % LaneElts;
14221 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
14222 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
14228 case X86::BI__builtin_ia32_vpermilvarpd:
14229 case X86::BI__builtin_ia32_vpermilvarpd256:
14230 case X86::BI__builtin_ia32_vpermilvarpd512: {
14234 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14235 unsigned NumElemPerLane = 2;
14236 unsigned Lane = DstIdx / NumElemPerLane;
14237 unsigned Offset = Mask & 0b10 ? 1 : 0;
14238 return std::make_pair(
14239 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14245 case X86::BI__builtin_ia32_vpermilpd:
14246 case X86::BI__builtin_ia32_vpermilpd256:
14247 case X86::BI__builtin_ia32_vpermilpd512: {
14250 unsigned NumElemPerLane = 2;
14251 unsigned BitsPerElem = 1;
14252 unsigned MaskBits = 8;
14253 unsigned IndexMask = 0x1;
14254 unsigned Lane = DstIdx / NumElemPerLane;
14255 unsigned LaneOffset = Lane * NumElemPerLane;
14256 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
14257 unsigned Index = (Control >> BitIndex) & IndexMask;
14258 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
14264 case X86::BI__builtin_ia32_permdf256:
14265 case X86::BI__builtin_ia32_permdi256: {
14270 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
14271 return std::make_pair(0,
static_cast<int>(Index));
14277 case X86::BI__builtin_ia32_vpermilvarps:
14278 case X86::BI__builtin_ia32_vpermilvarps256:
14279 case X86::BI__builtin_ia32_vpermilvarps512: {
14283 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14284 unsigned NumElemPerLane = 4;
14285 unsigned Lane = DstIdx / NumElemPerLane;
14286 unsigned Offset = Mask & 0b11;
14287 return std::make_pair(
14288 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14294 case X86::BI__builtin_ia32_vpmultishiftqb128:
14295 case X86::BI__builtin_ia32_vpmultishiftqb256:
14296 case X86::BI__builtin_ia32_vpmultishiftqb512: {
14304 unsigned NumBytesInQWord = 8;
14305 unsigned NumBitsInByte = 8;
14307 unsigned NumQWords = NumBytes / NumBytesInQWord;
14309 Result.reserve(NumBytes);
14311 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
14312 APInt BQWord(64, 0);
14313 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14314 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14316 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
14319 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14320 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14324 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
14325 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
14333 case X86::BI__builtin_ia32_phminposuw128: {
14340 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
14342 APInt MinIndex(ElemBitWidth, 0);
14344 for (
unsigned I = 1; I != SourceLen; ++I) {
14346 if (MinVal.ugt(Val)) {
14355 ->isUnsignedIntegerOrEnumerationType();
14358 Result.reserve(SourceLen);
14360 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
14361 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
14367 case X86::BI__builtin_ia32_psraq128:
14368 case X86::BI__builtin_ia32_psraq256:
14369 case X86::BI__builtin_ia32_psraq512:
14370 case X86::BI__builtin_ia32_psrad128:
14371 case X86::BI__builtin_ia32_psrad256:
14372 case X86::BI__builtin_ia32_psrad512:
14373 case X86::BI__builtin_ia32_psraw128:
14374 case X86::BI__builtin_ia32_psraw256:
14375 case X86::BI__builtin_ia32_psraw512: {
14379 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
14380 [](
const APInt &Elt,
unsigned Width) {
14381 return Elt.ashr(Width - 1);
14387 case X86::BI__builtin_ia32_psllq128:
14388 case X86::BI__builtin_ia32_psllq256:
14389 case X86::BI__builtin_ia32_psllq512:
14390 case X86::BI__builtin_ia32_pslld128:
14391 case X86::BI__builtin_ia32_pslld256:
14392 case X86::BI__builtin_ia32_pslld512:
14393 case X86::BI__builtin_ia32_psllw128:
14394 case X86::BI__builtin_ia32_psllw256:
14395 case X86::BI__builtin_ia32_psllw512: {
14399 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
14400 [](
const APInt &Elt,
unsigned Width) {
14401 return APInt::getZero(Width);
14407 case X86::BI__builtin_ia32_psrlq128:
14408 case X86::BI__builtin_ia32_psrlq256:
14409 case X86::BI__builtin_ia32_psrlq512:
14410 case X86::BI__builtin_ia32_psrld128:
14411 case X86::BI__builtin_ia32_psrld256:
14412 case X86::BI__builtin_ia32_psrld512:
14413 case X86::BI__builtin_ia32_psrlw128:
14414 case X86::BI__builtin_ia32_psrlw256:
14415 case X86::BI__builtin_ia32_psrlw512: {
14419 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
14420 [](
const APInt &Elt,
unsigned Width) {
14421 return APInt::getZero(Width);
14427 case X86::BI__builtin_ia32_pternlogd128_mask:
14428 case X86::BI__builtin_ia32_pternlogd256_mask:
14429 case X86::BI__builtin_ia32_pternlogd512_mask:
14430 case X86::BI__builtin_ia32_pternlogq128_mask:
14431 case X86::BI__builtin_ia32_pternlogq256_mask:
14432 case X86::BI__builtin_ia32_pternlogq512_mask: {
14433 APValue AValue, BValue, CValue, ImmValue, UValue;
14441 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14447 ResultElements.reserve(ResultLen);
14449 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14455 unsigned BitWidth = ALane.getBitWidth();
14456 APInt ResLane(BitWidth, 0);
14458 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14459 unsigned ABit = ALane[Bit];
14460 unsigned BBit = BLane[Bit];
14461 unsigned CBit = CLane[Bit];
14463 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14464 ResLane.setBitVal(Bit, Imm[Idx]);
14466 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14468 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
14471 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14473 case X86::BI__builtin_ia32_pternlogd128_maskz:
14474 case X86::BI__builtin_ia32_pternlogd256_maskz:
14475 case X86::BI__builtin_ia32_pternlogd512_maskz:
14476 case X86::BI__builtin_ia32_pternlogq128_maskz:
14477 case X86::BI__builtin_ia32_pternlogq256_maskz:
14478 case X86::BI__builtin_ia32_pternlogq512_maskz: {
14479 APValue AValue, BValue, CValue, ImmValue, UValue;
14487 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14493 ResultElements.reserve(ResultLen);
14495 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14500 unsigned BitWidth = ALane.getBitWidth();
14501 APInt ResLane(BitWidth, 0);
14504 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14505 unsigned ABit = ALane[Bit];
14506 unsigned BBit = BLane[Bit];
14507 unsigned CBit = CLane[Bit];
14509 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14510 ResLane.setBitVal(Bit, Imm[Idx]);
14513 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14515 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14518 case Builtin::BI__builtin_elementwise_clzg:
14519 case Builtin::BI__builtin_elementwise_ctzg: {
14521 std::optional<APValue> Fallback;
14528 Fallback = FallbackTmp;
14531 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14534 ResultElements.reserve(SourceLen);
14536 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14541 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
14543 Builtin::BI__builtin_elementwise_ctzg);
14546 ResultElements.push_back(Fallback->getVectorElt(EltNum));
14549 switch (BuiltinOp) {
14550 case Builtin::BI__builtin_elementwise_clzg:
14551 ResultElements.push_back(
APValue(
14552 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
14555 case Builtin::BI__builtin_elementwise_ctzg:
14556 ResultElements.push_back(
APValue(
14557 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
14563 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14566 case Builtin::BI__builtin_elementwise_fma: {
14567 APValue SourceX, SourceY, SourceZ;
14575 ResultElements.reserve(SourceLen);
14577 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14582 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
14585 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14588 case clang::X86::BI__builtin_ia32_phaddw128:
14589 case clang::X86::BI__builtin_ia32_phaddw256:
14590 case clang::X86::BI__builtin_ia32_phaddd128:
14591 case clang::X86::BI__builtin_ia32_phaddd256:
14592 case clang::X86::BI__builtin_ia32_phaddsw128:
14593 case clang::X86::BI__builtin_ia32_phaddsw256:
14595 case clang::X86::BI__builtin_ia32_phsubw128:
14596 case clang::X86::BI__builtin_ia32_phsubw256:
14597 case clang::X86::BI__builtin_ia32_phsubd128:
14598 case clang::X86::BI__builtin_ia32_phsubd256:
14599 case clang::X86::BI__builtin_ia32_phsubsw128:
14600 case clang::X86::BI__builtin_ia32_phsubsw256: {
14601 APValue SourceLHS, SourceRHS;
14605 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14609 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
14610 unsigned EltsPerLane = 128 / EltBits;
14612 ResultElements.reserve(NumElts);
14614 for (
unsigned LaneStart = 0; LaneStart != NumElts;
14615 LaneStart += EltsPerLane) {
14616 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14619 switch (BuiltinOp) {
14620 case clang::X86::BI__builtin_ia32_phaddw128:
14621 case clang::X86::BI__builtin_ia32_phaddw256:
14622 case clang::X86::BI__builtin_ia32_phaddd128:
14623 case clang::X86::BI__builtin_ia32_phaddd256: {
14624 APSInt Res(LHSA + LHSB, DestUnsigned);
14625 ResultElements.push_back(
APValue(Res));
14628 case clang::X86::BI__builtin_ia32_phaddsw128:
14629 case clang::X86::BI__builtin_ia32_phaddsw256: {
14630 APSInt Res(LHSA.sadd_sat(LHSB));
14631 ResultElements.push_back(
APValue(Res));
14634 case clang::X86::BI__builtin_ia32_phsubw128:
14635 case clang::X86::BI__builtin_ia32_phsubw256:
14636 case clang::X86::BI__builtin_ia32_phsubd128:
14637 case clang::X86::BI__builtin_ia32_phsubd256: {
14638 APSInt Res(LHSA - LHSB, DestUnsigned);
14639 ResultElements.push_back(
APValue(Res));
14642 case clang::X86::BI__builtin_ia32_phsubsw128:
14643 case clang::X86::BI__builtin_ia32_phsubsw256: {
14644 APSInt Res(LHSA.ssub_sat(LHSB));
14645 ResultElements.push_back(
APValue(Res));
14650 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14653 switch (BuiltinOp) {
14654 case clang::X86::BI__builtin_ia32_phaddw128:
14655 case clang::X86::BI__builtin_ia32_phaddw256:
14656 case clang::X86::BI__builtin_ia32_phaddd128:
14657 case clang::X86::BI__builtin_ia32_phaddd256: {
14658 APSInt Res(RHSA + RHSB, DestUnsigned);
14659 ResultElements.push_back(
APValue(Res));
14662 case clang::X86::BI__builtin_ia32_phaddsw128:
14663 case clang::X86::BI__builtin_ia32_phaddsw256: {
14664 APSInt Res(RHSA.sadd_sat(RHSB));
14665 ResultElements.push_back(
APValue(Res));
14668 case clang::X86::BI__builtin_ia32_phsubw128:
14669 case clang::X86::BI__builtin_ia32_phsubw256:
14670 case clang::X86::BI__builtin_ia32_phsubd128:
14671 case clang::X86::BI__builtin_ia32_phsubd256: {
14672 APSInt Res(RHSA - RHSB, DestUnsigned);
14673 ResultElements.push_back(
APValue(Res));
14676 case clang::X86::BI__builtin_ia32_phsubsw128:
14677 case clang::X86::BI__builtin_ia32_phsubsw256: {
14678 APSInt Res(RHSA.ssub_sat(RHSB));
14679 ResultElements.push_back(
APValue(Res));
14685 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14687 case clang::X86::BI__builtin_ia32_haddpd:
14688 case clang::X86::BI__builtin_ia32_haddps:
14689 case clang::X86::BI__builtin_ia32_haddps256:
14690 case clang::X86::BI__builtin_ia32_haddpd256:
14691 case clang::X86::BI__builtin_ia32_hsubpd:
14692 case clang::X86::BI__builtin_ia32_hsubps:
14693 case clang::X86::BI__builtin_ia32_hsubps256:
14694 case clang::X86::BI__builtin_ia32_hsubpd256: {
14695 APValue SourceLHS, SourceRHS;
14701 ResultElements.reserve(NumElts);
14703 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14704 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
14705 unsigned NumLanes = NumElts * EltBits / 128;
14706 unsigned NumElemsPerLane = NumElts / NumLanes;
14707 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
14709 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
14710 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14713 switch (BuiltinOp) {
14714 case clang::X86::BI__builtin_ia32_haddpd:
14715 case clang::X86::BI__builtin_ia32_haddps:
14716 case clang::X86::BI__builtin_ia32_haddps256:
14717 case clang::X86::BI__builtin_ia32_haddpd256:
14718 LHSA.add(LHSB, RM);
14720 case clang::X86::BI__builtin_ia32_hsubpd:
14721 case clang::X86::BI__builtin_ia32_hsubps:
14722 case clang::X86::BI__builtin_ia32_hsubps256:
14723 case clang::X86::BI__builtin_ia32_hsubpd256:
14724 LHSA.subtract(LHSB, RM);
14727 ResultElements.push_back(
APValue(LHSA));
14729 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14732 switch (BuiltinOp) {
14733 case clang::X86::BI__builtin_ia32_haddpd:
14734 case clang::X86::BI__builtin_ia32_haddps:
14735 case clang::X86::BI__builtin_ia32_haddps256:
14736 case clang::X86::BI__builtin_ia32_haddpd256:
14737 RHSA.add(RHSB, RM);
14739 case clang::X86::BI__builtin_ia32_hsubpd:
14740 case clang::X86::BI__builtin_ia32_hsubps:
14741 case clang::X86::BI__builtin_ia32_hsubps256:
14742 case clang::X86::BI__builtin_ia32_hsubpd256:
14743 RHSA.subtract(RHSB, RM);
14746 ResultElements.push_back(
APValue(RHSA));
14749 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14751 case clang::X86::BI__builtin_ia32_addsubpd:
14752 case clang::X86::BI__builtin_ia32_addsubps:
14753 case clang::X86::BI__builtin_ia32_addsubpd256:
14754 case clang::X86::BI__builtin_ia32_addsubps256: {
14757 APValue SourceLHS, SourceRHS;
14763 ResultElements.reserve(NumElems);
14766 for (
unsigned I = 0; I != NumElems; ++I) {
14771 LHS.subtract(RHS, RM);
14776 ResultElements.push_back(
APValue(LHS));
14778 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14780 case clang::X86::BI__builtin_ia32_pclmulqdq128:
14781 case clang::X86::BI__builtin_ia32_pclmulqdq256:
14782 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
14786 APValue SourceLHS, SourceRHS;
14796 bool SelectUpperA = (Imm8 & 0x01) != 0;
14797 bool SelectUpperB = (Imm8 & 0x10) != 0;
14801 ResultElements.reserve(NumElems);
14802 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14806 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
14815 APInt A = SelectUpperA ? A1 : A0;
14816 APInt B = SelectUpperB ? B1 : B0;
14819 APInt A128 = A.zext(128);
14820 APInt B128 = B.zext(128);
14823 APInt Result = llvm::APIntOps::clmul(A128, B128);
14826 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
14827 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
14829 ResultElements.push_back(
APValue(ResultLow));
14830 ResultElements.push_back(
APValue(ResultHigh));
14833 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14835 case Builtin::BI__builtin_elementwise_clmul:
14836 return EvaluateBinOpExpr(llvm::APIntOps::clmul);
14837 case Builtin::BI__builtin_elementwise_pext:
14838 return EvaluateBinOpExpr(llvm::APIntOps::pext);
14839 case Builtin::BI__builtin_elementwise_pdep:
14840 return EvaluateBinOpExpr(llvm::APIntOps::pdep);
14841 case Builtin::BI__builtin_elementwise_fshl:
14842 case Builtin::BI__builtin_elementwise_fshr: {
14843 APValue SourceHi, SourceLo, SourceShift;
14849 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14855 ResultElements.reserve(SourceLen);
14856 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14860 switch (BuiltinOp) {
14861 case Builtin::BI__builtin_elementwise_fshl:
14862 ResultElements.push_back(
APValue(
14863 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14865 case Builtin::BI__builtin_elementwise_fshr:
14866 ResultElements.push_back(
APValue(
14867 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14872 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14875 case X86::BI__builtin_ia32_shuf_f32x4_256:
14876 case X86::BI__builtin_ia32_shuf_i32x4_256:
14877 case X86::BI__builtin_ia32_shuf_f64x2_256:
14878 case X86::BI__builtin_ia32_shuf_i64x2_256:
14879 case X86::BI__builtin_ia32_shuf_f32x4:
14880 case X86::BI__builtin_ia32_shuf_i32x4:
14881 case X86::BI__builtin_ia32_shuf_f64x2:
14882 case X86::BI__builtin_ia32_shuf_i64x2: {
14896 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14897 unsigned LaneBits = 128u;
14898 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14899 unsigned NumElemsPerLane = LaneBits / ElemBits;
14903 ResultElements.reserve(DstLen);
14908 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14909 -> std::pair<unsigned, int> {
14911 unsigned BitsPerElem = NumLanes / 2;
14912 unsigned IndexMask = (1u << BitsPerElem) - 1;
14913 unsigned Lane = DstIdx / NumElemsPerLane;
14914 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14915 unsigned BitIdx = BitsPerElem * Lane;
14916 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14917 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14918 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14919 return {SrcIdx, IdxToPick};
14925 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14926 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14927 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14928 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14929 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14930 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14942 bool IsInverse =
false;
14943 switch (BuiltinOp) {
14944 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14945 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14946 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14951 unsigned NumBitsInByte = 8;
14952 unsigned NumBytesInQWord = 8;
14953 unsigned NumBitsInQWord = 64;
14955 unsigned NumQWords = NumBytes / NumBytesInQWord;
14957 Result.reserve(NumBytes);
14960 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14962 APInt XQWord(NumBitsInQWord, 0);
14963 APInt AQWord(NumBitsInQWord, 0);
14964 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14965 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14966 APInt XByte =
X.getVectorElt(Idx).getInt();
14968 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14969 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14972 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14974 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14983 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14984 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14985 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14996 Result.reserve(NumBytes);
14998 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
15008 case X86::BI__builtin_ia32_insertf32x4_256:
15009 case X86::BI__builtin_ia32_inserti32x4_256:
15010 case X86::BI__builtin_ia32_insertf64x2_256:
15011 case X86::BI__builtin_ia32_inserti64x2_256:
15012 case X86::BI__builtin_ia32_insertf32x4:
15013 case X86::BI__builtin_ia32_inserti32x4:
15014 case X86::BI__builtin_ia32_insertf64x2_512:
15015 case X86::BI__builtin_ia32_inserti64x2_512:
15016 case X86::BI__builtin_ia32_insertf32x8:
15017 case X86::BI__builtin_ia32_inserti32x8:
15018 case X86::BI__builtin_ia32_insertf64x4:
15019 case X86::BI__builtin_ia32_inserti64x4:
15020 case X86::BI__builtin_ia32_vinsertf128_ps256:
15021 case X86::BI__builtin_ia32_vinsertf128_pd256:
15022 case X86::BI__builtin_ia32_vinsertf128_si256:
15023 case X86::BI__builtin_ia32_insert128i256: {
15024 APValue SourceDst, SourceSub;
15036 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
15037 unsigned NumLanes = DstLen / SubLen;
15038 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
15041 ResultElements.reserve(DstLen);
15043 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
15044 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
15045 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
15047 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
15050 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15053 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
15054 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
15055 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
15056 case clang::X86::BI__builtin_ia32_vec_set_v4si:
15057 case clang::X86::BI__builtin_ia32_vec_set_v2di:
15058 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
15059 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
15060 case clang::X86::BI__builtin_ia32_vec_set_v8si:
15061 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
15069 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
15070 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
15072 Scalar.setIsUnsigned(ElemUnsigned);
15078 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
15081 Elems.reserve(NumElems);
15082 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
15083 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
15088 case X86::BI__builtin_ia32_pslldqi128_byteshift:
15089 case X86::BI__builtin_ia32_pslldqi256_byteshift:
15090 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
15094 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
15095 unsigned LaneBase = (DstIdx / 16) * 16;
15096 unsigned LaneIdx = DstIdx % 16;
15097 if (LaneIdx < Shift)
15098 return std::make_pair(0, -1);
15100 return std::make_pair(
15101 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
15107 case X86::BI__builtin_ia32_psrldqi128_byteshift:
15108 case X86::BI__builtin_ia32_psrldqi256_byteshift:
15109 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
15113 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
15114 unsigned LaneBase = (DstIdx / 16) * 16;
15115 unsigned LaneIdx = DstIdx % 16;
15116 if (LaneIdx + Shift < 16)
15117 return std::make_pair(
15118 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
15120 return std::make_pair(0, -1);
15126 case X86::BI__builtin_ia32_palignr128:
15127 case X86::BI__builtin_ia32_palignr256:
15128 case X86::BI__builtin_ia32_palignr512: {
15132 unsigned VecIdx = 1;
15135 int Lane = DstIdx / 16;
15136 int Offset = DstIdx % 16;
15139 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
15140 if (ShiftedIdx < 16) {
15141 ElemIdx = ShiftedIdx + (Lane * 16);
15142 }
else if (ShiftedIdx < 32) {
15144 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
15147 return std::pair<unsigned, int>{VecIdx, ElemIdx};
15152 case X86::BI__builtin_ia32_alignd128:
15153 case X86::BI__builtin_ia32_alignd256:
15154 case X86::BI__builtin_ia32_alignd512:
15155 case X86::BI__builtin_ia32_alignq128:
15156 case X86::BI__builtin_ia32_alignq256:
15157 case X86::BI__builtin_ia32_alignq512: {
15159 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
15161 [NumElems](
unsigned DstIdx,
unsigned Shift) {
15162 unsigned Imm =
Shift & 0xFF;
15163 unsigned EffectiveShift = Imm & (NumElems - 1);
15164 unsigned SourcePos = DstIdx + EffectiveShift;
15165 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
15166 unsigned ElemIdx = SourcePos & (NumElems - 1);
15168 return std::pair<unsigned, int>{
15169 VecIdx,
static_cast<int>(ElemIdx)};
15174 case X86::BI__builtin_ia32_permvarsi256:
15175 case X86::BI__builtin_ia32_permvarsf256:
15176 case X86::BI__builtin_ia32_permvardf512:
15177 case X86::BI__builtin_ia32_permvardi512:
15178 case X86::BI__builtin_ia32_permvarhi128: {
15181 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15182 int Offset = ShuffleMask & 0x7;
15183 return std::pair<unsigned, int>{0, Offset};
15188 case X86::BI__builtin_ia32_permvarqi128:
15189 case X86::BI__builtin_ia32_permvarhi256:
15190 case X86::BI__builtin_ia32_permvarsi512:
15191 case X86::BI__builtin_ia32_permvarsf512: {
15194 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15195 int Offset = ShuffleMask & 0xF;
15196 return std::pair<unsigned, int>{0, Offset};
15201 case X86::BI__builtin_ia32_permvardi256:
15202 case X86::BI__builtin_ia32_permvardf256: {
15205 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15206 int Offset = ShuffleMask & 0x3;
15207 return std::pair<unsigned, int>{0, Offset};
15212 case X86::BI__builtin_ia32_permvarqi256:
15213 case X86::BI__builtin_ia32_permvarhi512: {
15216 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15217 int Offset = ShuffleMask & 0x1F;
15218 return std::pair<unsigned, int>{0, Offset};
15223 case X86::BI__builtin_ia32_permvarqi512: {
15226 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15227 int Offset = ShuffleMask & 0x3F;
15228 return std::pair<unsigned, int>{0, Offset};
15233 case X86::BI__builtin_ia32_vpermi2varq128:
15234 case X86::BI__builtin_ia32_vpermi2varpd128: {
15237 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15238 int Offset = ShuffleMask & 0x1;
15239 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
15240 return std::pair<unsigned, int>{SrcIdx, Offset};
15245 case X86::BI__builtin_ia32_vpermi2vard128:
15246 case X86::BI__builtin_ia32_vpermi2varps128:
15247 case X86::BI__builtin_ia32_vpermi2varq256:
15248 case X86::BI__builtin_ia32_vpermi2varpd256: {
15251 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15252 int Offset = ShuffleMask & 0x3;
15253 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
15254 return std::pair<unsigned, int>{SrcIdx, Offset};
15259 case X86::BI__builtin_ia32_vpermi2varhi128:
15260 case X86::BI__builtin_ia32_vpermi2vard256:
15261 case X86::BI__builtin_ia32_vpermi2varps256:
15262 case X86::BI__builtin_ia32_vpermi2varq512:
15263 case X86::BI__builtin_ia32_vpermi2varpd512: {
15266 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15267 int Offset = ShuffleMask & 0x7;
15268 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
15269 return std::pair<unsigned, int>{SrcIdx, Offset};
15274 case X86::BI__builtin_ia32_vpermi2varqi128:
15275 case X86::BI__builtin_ia32_vpermi2varhi256:
15276 case X86::BI__builtin_ia32_vpermi2vard512:
15277 case X86::BI__builtin_ia32_vpermi2varps512: {
15280 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15281 int Offset = ShuffleMask & 0xF;
15282 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
15283 return std::pair<unsigned, int>{SrcIdx, Offset};
15288 case X86::BI__builtin_ia32_vpermi2varqi256:
15289 case X86::BI__builtin_ia32_vpermi2varhi512: {
15292 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15293 int Offset = ShuffleMask & 0x1F;
15294 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
15295 return std::pair<unsigned, int>{SrcIdx, Offset};
15300 case X86::BI__builtin_ia32_vpermi2varqi512: {
15303 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15304 int Offset = ShuffleMask & 0x3F;
15305 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
15306 return std::pair<unsigned, int>{SrcIdx, Offset};
15312 case clang::X86::BI__builtin_ia32_minps:
15313 case clang::X86::BI__builtin_ia32_minpd:
15314 case clang::X86::BI__builtin_ia32_minps256:
15315 case clang::X86::BI__builtin_ia32_minpd256:
15316 case clang::X86::BI__builtin_ia32_minps512:
15317 case clang::X86::BI__builtin_ia32_minpd512:
15318 case clang::X86::BI__builtin_ia32_minph128:
15319 case clang::X86::BI__builtin_ia32_minph256:
15320 case clang::X86::BI__builtin_ia32_minph512:
15321 return EvaluateFpBinOpExpr(
15322 [](
const APFloat &A,
const APFloat &B,
15323 std::optional<APSInt>) -> std::optional<APFloat> {
15324 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15325 B.isInfinity() || B.isDenormal())
15326 return std::nullopt;
15327 if (A.isZero() && B.isZero())
15329 return llvm::minimum(A, B);
15332 case clang::X86::BI__builtin_ia32_minss:
15333 case clang::X86::BI__builtin_ia32_minsd:
15334 return EvaluateFpBinOpExpr(
15335 [](
const APFloat &A,
const APFloat &B,
15336 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15341 case clang::X86::BI__builtin_ia32_minsd_round_mask:
15342 case clang::X86::BI__builtin_ia32_minss_round_mask:
15343 case clang::X86::BI__builtin_ia32_minsh_round_mask:
15344 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
15345 case clang::X86::BI__builtin_ia32_maxss_round_mask:
15346 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
15347 bool IsMin = BuiltinOp == clang::X86::BI__builtin_ia32_minsd_round_mask ||
15348 BuiltinOp == clang::X86::BI__builtin_ia32_minss_round_mask ||
15349 BuiltinOp == clang::X86::BI__builtin_ia32_minsh_round_mask;
15350 return EvaluateScalarFpRoundMaskBinOp(
15351 [IsMin](
const APFloat &A,
const APFloat &B,
15352 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15357 case clang::X86::BI__builtin_ia32_maxps:
15358 case clang::X86::BI__builtin_ia32_maxpd:
15359 case clang::X86::BI__builtin_ia32_maxps256:
15360 case clang::X86::BI__builtin_ia32_maxpd256:
15361 case clang::X86::BI__builtin_ia32_maxps512:
15362 case clang::X86::BI__builtin_ia32_maxpd512:
15363 case clang::X86::BI__builtin_ia32_maxph128:
15364 case clang::X86::BI__builtin_ia32_maxph256:
15365 case clang::X86::BI__builtin_ia32_maxph512:
15366 return EvaluateFpBinOpExpr(
15367 [](
const APFloat &A,
const APFloat &B,
15368 std::optional<APSInt>) -> std::optional<APFloat> {
15369 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15370 B.isInfinity() || B.isDenormal())
15371 return std::nullopt;
15372 if (A.isZero() && B.isZero())
15374 return llvm::maximum(A, B);
15377 case clang::X86::BI__builtin_ia32_maxss:
15378 case clang::X86::BI__builtin_ia32_maxsd:
15379 return EvaluateFpBinOpExpr(
15380 [](
const APFloat &A,
const APFloat &B,
15381 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15386 case clang::X86::BI__builtin_ia32_vcvtps2ph:
15387 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
15397 unsigned SrcNumElems = SrcVTy->getNumElements();
15399 unsigned DstNumElems = DstVTy->getNumElements();
15400 QualType DstElemTy = DstVTy->getElementType();
15402 const llvm::fltSemantics &HalfSem =
15403 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
15405 int ImmVal = Imm.getZExtValue();
15406 bool UseMXCSR = (ImmVal & 4) != 0;
15407 bool IsFPConstrained =
15410 llvm::RoundingMode RM;
15412 switch (ImmVal & 3) {
15414 RM = llvm::RoundingMode::NearestTiesToEven;
15417 RM = llvm::RoundingMode::TowardNegative;
15420 RM = llvm::RoundingMode::TowardPositive;
15423 RM = llvm::RoundingMode::TowardZero;
15426 llvm_unreachable(
"Invalid immediate rounding mode");
15429 RM = llvm::RoundingMode::NearestTiesToEven;
15433 ResultElements.reserve(DstNumElems);
15435 for (
unsigned I = 0; I < SrcNumElems; ++I) {
15439 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
15441 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
15442 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
15446 APSInt DstInt(SrcVal.bitcastToAPInt(),
15448 ResultElements.push_back(
APValue(DstInt));
15451 if (DstNumElems > SrcNumElems) {
15452 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
15453 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
15458 return Success(ResultElements, E);
15460 case X86::BI__builtin_ia32_vperm2f128_pd256:
15461 case X86::BI__builtin_ia32_vperm2f128_ps256:
15462 case X86::BI__builtin_ia32_vperm2f128_si256:
15463 case X86::BI__builtin_ia32_permti256: {
15464 unsigned NumElements =
15466 unsigned PreservedBitsCnt = NumElements >> 2;
15470 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
15471 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
15472 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
15474 if (ControlBits & 0b1000)
15475 return std::make_pair(0u, -1);
15477 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
15478 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
15479 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
15480 (DstIdx & PreservedBitsMask);
15481 return std::make_pair(SrcVecIdx, SrcIdx);
15486 case X86::BI__builtin_ia32_vpdpwssd128:
15487 case X86::BI__builtin_ia32_vpdpwssd256:
15488 case X86::BI__builtin_ia32_vpdpwssd512:
15489 case X86::BI__builtin_ia32_vpdpbusd128:
15490 case X86::BI__builtin_ia32_vpdpbusd256:
15491 case X86::BI__builtin_ia32_vpdpbusd512:
15492 return EvalVectorDotProduct(
false);
15493 case X86::BI__builtin_ia32_vpdpwssds128:
15494 case X86::BI__builtin_ia32_vpdpwssds256:
15495 case X86::BI__builtin_ia32_vpdpwssds512:
15496 case X86::BI__builtin_ia32_vpdpbusds128:
15497 case X86::BI__builtin_ia32_vpdpbusds256:
15498 case X86::BI__builtin_ia32_vpdpbusds512:
15499 return EvalVectorDotProduct(
true);
15500 case X86::BI__builtin_ia32_cvtpd2dq:
15501 case X86::BI__builtin_ia32_cvtps2dq:
15502 case X86::BI__builtin_ia32_cvttpd2dq:
15503 case X86::BI__builtin_ia32_cvttps2dq:
15504 case X86::BI__builtin_ia32_cvtpd2dq256:
15505 case X86::BI__builtin_ia32_cvtps2dq256:
15506 case X86::BI__builtin_ia32_cvttpd2dq256:
15507 case X86::BI__builtin_ia32_cvttps2dq256: {
15514 bool isUnsigned = EltTy->isUnsignedIntegerType();
15515 unsigned BitWidth = Info.Ctx.getIntWidth(EltTy);
15521 for (
unsigned i = 0; i != NumDstElems; ++i) {
15522 if (i < NumSrcElems) {
15524 llvm::APSInt IntResult(BitWidth,
isUnsigned);
15525 bool IsExact =
false;
15528 FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
15532 ResultElts.push_back(
APValue(IntResult));
15537 return Success(ResultElts, E);
15542bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
15548 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
15549 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
15555 ResultElements.reserve(SourceLen);
15556 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
15561 ResultElements.push_back(std::move(Elt));
15564 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15569 APValue const &VecVal2,
unsigned EltNum,
15571 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
15572 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
15582 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
15588 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
15589 llvm_unreachable(
"Out of bounds shuffle index");
15591 if (
index >= TotalElementsInInputVector1)
15598bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
15603 const Expr *Vec1 = E->
getExpr(0);
15607 const Expr *Vec2 = E->
getExpr(1);
15611 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
15617 ResultElements.reserve(TotalElementsInOutputVector);
15618 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
15622 ResultElements.push_back(std::move(Elt));
15625 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15633class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
15640 bool Success(ArrayRef<APValue> M,
const Expr *E) {
15642 assert(M.size() == CMTy->getNumElementsFlattened());
15644 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
15648 assert(M.
isMatrix() &&
"expected matrix");
15653 bool VisitCastExpr(
const CastExpr *E);
15654 bool VisitInitListExpr(
const InitListExpr *E);
15660 "not a matrix prvalue");
15661 return MatrixExprEvaluator(Info,
Result).Visit(E);
15664bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15665 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15666 unsigned NumRows = MT->getNumRows();
15667 unsigned NumCols = MT->getNumColumns();
15668 unsigned NElts = NumRows * NumCols;
15669 QualType EltTy = MT->getElementType();
15673 case CK_HLSLAggregateSplatCast: {
15688 case CK_HLSLElementwiseCast: {
15701 return Success(ResultEls, E);
15704 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15708bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
15709 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15710 QualType EltTy = MT->getElementType();
15712 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
15713 "Expected number of elements in initializer list to match the number "
15714 "of matrix elements");
15717 Elements.reserve(MT->getNumElementsFlattened());
15722 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
15723 if (EltTy->isIntegerType()) {
15724 llvm::APSInt IntVal;
15727 Elements.push_back(
APValue(IntVal));
15729 llvm::APFloat FloatVal(0.0);
15732 Elements.push_back(
APValue(FloatVal));
15744 class ArrayExprEvaluator
15745 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
15746 const LValue &
This;
15750 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
15754 assert(
V.isArray() &&
"expected array");
15759 bool ZeroInitialization(
const Expr *E) {
15760 const ConstantArrayType *CAT =
15761 Info.Ctx.getAsConstantArrayType(E->
getType());
15775 if (!
Result.hasArrayFiller())
15779 LValue Subobject =
This;
15780 Subobject.addArray(Info, E, CAT);
15785 bool VisitCallExpr(
const CallExpr *E) {
15786 return handleCallExpr(E,
Result, &This);
15788 bool VisitCastExpr(
const CastExpr *E);
15789 bool VisitInitListExpr(
const InitListExpr *E,
15790 QualType AllocType = QualType());
15791 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
15792 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
15793 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
15794 const LValue &Subobject,
15796 bool VisitStringLiteral(
const StringLiteral *E,
15797 QualType AllocType = QualType()) {
15801 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
15802 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
15803 ArrayRef<Expr *> Args,
15804 const Expr *ArrayFiller,
15805 QualType AllocType = QualType());
15806 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
15814 "not an array prvalue");
15815 return ArrayExprEvaluator(Info,
This,
Result).Visit(E);
15823 "not an array prvalue");
15824 return ArrayExprEvaluator(Info,
This,
Result)
15825 .VisitInitListExpr(ILE, AllocType);
15834 "not an array prvalue");
15835 return ArrayExprEvaluator(Info,
This,
Result)
15836 .VisitCXXConstructExpr(CCE,
This, &
Result, AllocType);
15845 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
15846 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
15851 if (ILE->hasArrayFiller() &&
15860bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15865 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15866 case CK_HLSLAggregateSplatCast: {
15886 case CK_HLSLElementwiseCast: {
15903bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15904 QualType AllocType) {
15905 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15918 return VisitStringLiteral(SL, AllocType);
15923 "transparent array list initialization is not string literal init?");
15929bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15931 QualType AllocType) {
15932 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15937 unsigned NumEltsToInit = Args.size();
15942 if (NumEltsToInit != NumElts &&
15944 NumEltsToInit = NumElts;
15947 for (
auto *
Init : Args) {
15948 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15949 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15952 if (NumEltsToInit > NumElts)
15953 NumEltsToInit = NumElts;
15957 if (
Result.hasValue() && NumEltsToInit <
Result.getArrayInitializedElts())
15958 NumEltsToInit =
Result.getArrayInitializedElts();
15961 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15962 << NumEltsToInit <<
".\n");
15964 if (!
Result.hasValue()) {
15965 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15966 }
else if (
Result.getArrayInitializedElts() != NumEltsToInit) {
15977 APValue NewResult =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15979 unsigned NumOldElts =
Result.getArrayInitializedElts();
15980 for (
unsigned I = 0; I < NumOldElts; ++I) {
15982 std::move(
Result.getArrayInitializedElt(I));
15985 for (
unsigned I =
Result.getArrayInitializedElts(); I < NumEltsToInit; ++I)
15989 Result = std::move(NewResult);
15992 LValue Subobject =
This;
15993 Subobject.addArray(Info, ExprToVisit, CAT);
15994 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15995 if (
Init->isValueDependent())
16004 Subobject,
Init) ||
16007 if (!Info.noteFailure())
16013 unsigned ArrayIndex = 0;
16016 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
16017 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
16018 if (ArrayIndex >= NumEltsToInit)
16020 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
16021 StringLiteral *SL = EmbedS->getDataStringLiteral();
16022 for (
unsigned I = EmbedS->getStartingElementPos(),
16023 N = EmbedS->getDataElementCount();
16024 I != EmbedS->getStartingElementPos() + N; ++I) {
16030 const FPOptions FPO =
16031 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
16036 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
16041 if (!Eval(
Init, ArrayIndex))
16047 if (!
Result.hasArrayFiller())
16052 assert(ArrayFiller &&
"no array filler for incomplete init list");
16058bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
16061 !
Evaluate(Info.CurrentCall->createTemporary(
16064 ScopeKind::FullExpression, CommonLV),
16073 Result =
APValue(APValue::UninitArray(), Elements, Elements);
16075 LValue Subobject =
This;
16076 Subobject.addArray(Info, E, CAT);
16079 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
16088 FullExpressionRAII Scope(Info);
16094 if (!Info.noteFailure())
16106bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
16107 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
16110bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
16111 const LValue &Subobject,
16114 bool HadZeroInit =
Value->hasValue();
16116 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
16123 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
16126 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
16127 if (FinalSize == 0)
16133 LValue ArrayElt = Subobject;
16134 ArrayElt.addArray(Info, E, CAT);
16140 for (
const unsigned N : {1u, FinalSize}) {
16141 unsigned OldElts =
Value->getArrayInitializedElts();
16146 APValue NewValue(APValue::UninitArray(), N, FinalSize);
16147 for (
unsigned I = 0; I < OldElts; ++I)
16148 NewValue.getArrayInitializedElt(I).swap(
16149 Value->getArrayInitializedElt(I));
16150 Value->swap(NewValue);
16153 for (
unsigned I = OldElts; I < N; ++I)
16154 Value->getArrayInitializedElt(I) = Filler;
16156 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
16159 APValue &FirstResult =
Value->getArrayInitializedElt(0);
16160 for (
unsigned I = OldElts; I < FinalSize; ++I)
16161 Value->getArrayInitializedElt(I) = FirstResult;
16163 for (
unsigned I = OldElts; I < N; ++I) {
16164 if (!VisitCXXConstructExpr(E, ArrayElt,
16165 &
Value->getArrayInitializedElt(I),
16172 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
16173 !Info.keepEvaluatingAfterFailure())
16182 if (!
Type->isRecordType())
16185 return RecordExprEvaluator(Info, Subobject, *
Value)
16186 .VisitCXXConstructExpr(E,
Type);
16189bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
16190 const CXXParenListInitExpr *E) {
16192 "Expression result is not a constant array type");
16194 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
16198bool ArrayExprEvaluator::VisitDesignatedInitUpdateExpr(
16199 const DesignatedInitUpdateExpr *E) {
16214class IntExprEvaluator
16215 :
public ExprEvaluatorBase<IntExprEvaluator> {
16218 IntExprEvaluator(EvalInfo &info,
APValue &result)
16219 : ExprEvaluatorBaseTy(
info),
Result(result) {}
16223 "Invalid evaluation result.");
16225 "Invalid evaluation result.");
16226 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
16227 "Invalid evaluation result.");
16231 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
16237 "Invalid evaluation result.");
16238 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
16239 "Invalid evaluation result.");
16241 Result.getInt().setIsUnsigned(
16245 bool Success(
const llvm::APInt &I,
const Expr *E) {
16251 "Invalid evaluation result.");
16259 bool Success(CharUnits Size,
const Expr *E) {
16266 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
16267 V.allowConstexprUnknown()) {
16274 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
16276 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
16283 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
16286 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
16290 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
16291 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
16292 if (CheckReferencedDecl(E, E->
getDecl()))
16295 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
16297 bool VisitMemberExpr(
const MemberExpr *E) {
16299 VisitIgnoredBaseExpression(E->
getBase());
16303 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
16306 bool VisitCallExpr(
const CallExpr *E);
16307 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
16308 bool VisitBinaryOperator(
const BinaryOperator *E);
16309 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
16310 bool VisitUnaryOperator(
const UnaryOperator *E);
16312 bool VisitCastExpr(
const CastExpr* E);
16313 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
16315 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
16319 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
16323 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
16324 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
16330 return Success(Info.ArrayInitIndex, E);
16334 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
16335 return ZeroInitialization(E);
16338 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
16347 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
16351 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
16355 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
16362 bool VisitUnaryReal(
const UnaryOperator *E);
16363 bool VisitUnaryImag(
const UnaryOperator *E);
16365 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
16366 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
16367 bool VisitSourceLocExpr(
const SourceLocExpr *E);
16368 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
16373class FixedPointExprEvaluator
16374 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
16378 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
16379 : ExprEvaluatorBaseTy(
info),
Result(result) {}
16381 bool Success(
const llvm::APInt &I,
const Expr *E) {
16383 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16388 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16392 return Success(
V.getFixedPoint(), E);
16395 bool Success(
const APFixedPoint &
V,
const Expr *E) {
16397 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
16398 "Invalid evaluation result.");
16403 bool ZeroInitialization(
const Expr *E) {
16411 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
16415 bool VisitCastExpr(
const CastExpr *E);
16416 bool VisitUnaryOperator(
const UnaryOperator *E);
16417 bool VisitBinaryOperator(
const BinaryOperator *E);
16433 return IntExprEvaluator(Info,
Result).Visit(E);
16441 if (!Val.
isInt()) {
16444 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16451bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
16453 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
16462 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
16477 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
16481 Result = APFixedPoint(Val, FXSema);
16492bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
16494 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
16496 bool SameSign = (ECD->getInitVal().isSigned()
16498 bool SameWidth = (ECD->getInitVal().
getBitWidth()
16499 == Info.Ctx.getIntWidth(E->
getType()));
16500 if (SameSign && SameWidth)
16501 return Success(ECD->getInitVal(), E);
16505 llvm::APSInt Val = ECD->getInitVal();
16507 Val.setIsSigned(!ECD->getInitVal().isSigned());
16509 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
16520 assert(!
T->isDependentType() &&
"unexpected dependent type");
16525#define TYPE(ID, BASE)
16526#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
16527#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
16528#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
16529#include "clang/AST/TypeNodes.inc"
16531 case Type::DeducedTemplateSpecialization:
16532 llvm_unreachable(
"unexpected non-canonical or dependent type");
16534 case Type::Builtin:
16536#define BUILTIN_TYPE(ID, SINGLETON_ID)
16537#define SIGNED_TYPE(ID, SINGLETON_ID) \
16538 case BuiltinType::ID: return GCCTypeClass::Integer;
16539#define FLOATING_TYPE(ID, SINGLETON_ID) \
16540 case BuiltinType::ID: return GCCTypeClass::RealFloat;
16541#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
16542 case BuiltinType::ID: break;
16543#include "clang/AST/BuiltinTypes.def"
16544 case BuiltinType::Void:
16547 case BuiltinType::Bool:
16550 case BuiltinType::Char_U:
16551 case BuiltinType::UChar:
16552 case BuiltinType::WChar_U:
16553 case BuiltinType::Char8:
16554 case BuiltinType::Char16:
16555 case BuiltinType::Char32:
16556 case BuiltinType::UShort:
16557 case BuiltinType::UInt:
16558 case BuiltinType::ULong:
16559 case BuiltinType::ULongLong:
16560 case BuiltinType::UInt128:
16563 case BuiltinType::UShortAccum:
16564 case BuiltinType::UAccum:
16565 case BuiltinType::ULongAccum:
16566 case BuiltinType::UShortFract:
16567 case BuiltinType::UFract:
16568 case BuiltinType::ULongFract:
16569 case BuiltinType::SatUShortAccum:
16570 case BuiltinType::SatUAccum:
16571 case BuiltinType::SatULongAccum:
16572 case BuiltinType::SatUShortFract:
16573 case BuiltinType::SatUFract:
16574 case BuiltinType::SatULongFract:
16577 case BuiltinType::NullPtr:
16579 case BuiltinType::ObjCId:
16580 case BuiltinType::ObjCClass:
16581 case BuiltinType::ObjCSel:
16582#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
16583 case BuiltinType::Id:
16584#include "clang/Basic/OpenCLImageTypes.def"
16585#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
16586 case BuiltinType::Id:
16587#include "clang/Basic/OpenCLExtensionTypes.def"
16588 case BuiltinType::OCLSampler:
16589 case BuiltinType::OCLEvent:
16590 case BuiltinType::OCLClkEvent:
16591 case BuiltinType::OCLQueue:
16592 case BuiltinType::OCLReserveID:
16593#define SVE_TYPE(Name, Id, SingletonId) \
16594 case BuiltinType::Id:
16595#include "clang/Basic/AArch64ACLETypes.def"
16596#define PPC_VECTOR_TYPE(Name, Id, Size) \
16597 case BuiltinType::Id:
16598#include "clang/Basic/PPCTypes.def"
16599#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16600#include "clang/Basic/RISCVVTypes.def"
16601#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16602#include "clang/Basic/WebAssemblyReferenceTypes.def"
16603#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
16604#include "clang/Basic/AMDGPUTypes.def"
16605#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16606#include "clang/Basic/HLSLIntangibleTypes.def"
16607#define HLSL_PACKED_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16608#include "clang/Basic/HLSLPackedTypes.def"
16609#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16610#include "clang/Basic/SPIRVTypes.def"
16611 case BuiltinType::MetaInfo:
16614 case BuiltinType::Dependent:
16615 llvm_unreachable(
"unexpected dependent type");
16617 llvm_unreachable(
"unexpected placeholder type");
16622 case Type::Pointer:
16623 case Type::ConstantArray:
16624 case Type::VariableArray:
16625 case Type::IncompleteArray:
16626 case Type::FunctionNoProto:
16627 case Type::FunctionProto:
16628 case Type::ArrayParameter:
16631 case Type::MemberPointer:
16636 case Type::Complex:
16649 case Type::ExtVector:
16652 case Type::BlockPointer:
16653 case Type::ConstantMatrix:
16654 case Type::ObjCObject:
16655 case Type::ObjCInterface:
16656 case Type::ObjCObjectPointer:
16658 case Type::HLSLAttributedResource:
16659 case Type::HLSLInlineSpirv:
16660 case Type::OverflowBehavior:
16668 case Type::LValueReference:
16669 case Type::RValueReference:
16670 llvm_unreachable(
"invalid type for expression");
16673 llvm_unreachable(
"unexpected type class");
16698 if (
Base.isNull()) {
16701 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
16720 SpeculativeEvaluationRAII SpeculativeEval(Info);
16725 FoldConstant Fold(Info,
true);
16743 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
16744 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
16745 ArgType->isNullPtrType()) {
16748 Fold.keepDiagnostics();
16757 return V.hasValue();
16768 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
16792 const auto *Cast = dyn_cast<CastExpr>(NoParens);
16793 if (Cast ==
nullptr)
16798 auto CastKind = Cast->getCastKind();
16800 CastKind != CK_AddressSpaceConversion)
16803 const auto *SubExpr = Cast->getSubExpr();
16825 assert(!LVal.Designator.Invalid);
16827 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
16835 auto &
Base = LVal.getLValueBase();
16836 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
16837 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
16838 if (!IsLastOrInvalidFieldDecl(FD))
16840 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
16841 for (
auto *FD : IFD->chain()) {
16850 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
16854 if (BaseType->isIncompleteArrayType())
16860 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
16861 const auto &Entry = LVal.Designator.Entries[I];
16862 if (BaseType->isArrayType()) {
16868 uint64_t Index = Entry.getAsArrayIndex();
16872 }
else if (BaseType->isAnyComplexType()) {
16873 const auto *CT = BaseType->castAs<
ComplexType>();
16874 uint64_t Index = Entry.getAsArrayIndex();
16877 BaseType = CT->getElementType();
16878 }
else if (
auto *FD = getAsField(Entry)) {
16879 if (!IsLastOrInvalidFieldDecl(FD))
16883 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
16895 if (LVal.Designator.Invalid)
16898 if (!LVal.Designator.Entries.empty())
16899 return LVal.Designator.isMostDerivedAnUnsizedArray();
16901 if (!LVal.InvalidBase)
16913 const SubobjectDesignator &
Designator = LVal.Designator;
16925 auto isFlexibleArrayMember = [&] {
16927 FAMKind StrictFlexArraysLevel =
16930 if (
Designator.isMostDerivedAnUnsizedArray())
16933 if (StrictFlexArraysLevel == FAMKind::Default)
16936 if (
Designator.getMostDerivedArraySize() == 0 &&
16937 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
16940 if (
Designator.getMostDerivedArraySize() == 1 &&
16941 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16947 return LVal.InvalidBase &&
16949 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16957 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16958 if (
Int.ugt(CharUnitsMax))
16968 if (!
T.isNull() &&
T->isStructureType() &&
16969 T->castAsRecordDecl()->hasFlexibleArrayMember())
16970 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16971 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16983 unsigned Type,
const LValue &LVal,
17002 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
17004 if (
Type == 3 && !DetermineForCompleteObject)
17007 llvm::APInt APEndOffset;
17008 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
17012 if (LVal.InvalidBase)
17016 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
17022 const SubobjectDesignator &
Designator = LVal.Designator;
17034 llvm::APInt APEndOffset;
17035 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
17047 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
17056 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
17057 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
17058 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
17060 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
17063 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
17073static std::optional<uint64_t>
17075 bool IsDynamic =
false) {
17083 SpeculativeEvaluationRAII SpeculativeEval(Info);
17084 IgnoreSideEffectsRAII Fold(Info);
17091 return std::nullopt;
17092 LVal.setFrom(Info.Ctx, RVal);
17095 return std::nullopt;
17100 if (LVal.getLValueOffset().isNegative())
17115 const auto *FD = ME ? dyn_cast<FieldDecl>(ME->getMemberDecl()) :
nullptr;
17117 return std::nullopt;
17122 return std::nullopt;
17126 if (EndOffset <= LVal.getLValueOffset())
17128 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
17131bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
17132 if (!IsConstantEvaluatedBuiltinCall(E))
17133 return ExprEvaluatorBaseTy::VisitCallExpr(E);
17150 Info.FFDiag(E->
getArg(0));
17156 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
17157 "Bit widths must be the same");
17174 if (!Ptr.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17175 Ptr.Designator.Invalid)
17178 if (Ptr.Designator.isMostDerivedAnUnsizedArray())
17185 if (PtrAlign < RequiredAlign) {
17186 Info.FFDiag(E, diag::note_constexpr_load8_unaligned)
17193 QualType CharTy = Ptr.Designator.getType(Info.Ctx);
17194 unsigned ByteWidth = Info.Ctx.getTypeSize(E->
getType()) / 8;
17195 uint64_t RemainingElems = Ptr.Designator.validIndexAdjustments().second;
17196 if (ByteWidth > RemainingElems) {
17197 uint64_t ArrayIndex = Ptr.Designator.MostDerivedIsArrayElement
17198 ? Ptr.Designator.Entries.back().getAsArrayIndex()
17199 : (uint64_t)Ptr.Designator.IsOnePastTheEnd;
17200 APSInt Index = APSInt::get(ArrayIndex + ByteWidth - 1);
17201 Ptr.Designator.diagnosePointerArithmetic(Info, E, Index);
17208 uint64_t ResultBits = 0;
17209 LValue BytePtr = Ptr;
17210 for (
unsigned I = 0; I < ByteWidth; ++I) {
17214 unsigned Shift = 8 * (IsBE ? ByteWidth - I - 1 : I);
17215 ResultBits |= ByteVal.
getInt().getZExtValue() << Shift;
17216 if (I + 1 < ByteWidth)
17222 Result =
APSInt(APInt(ByteWidth * 8, ResultBits), !IsSigned);
17226bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
17227 unsigned BuiltinOp) {
17228 if (Info.Ctx.BuiltinInfo.isReflectionMetafunctionBuiltin(BuiltinOp)) {
17235 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
17237 APValue SourceLHS, SourceRHS;
17245 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
17247 APInt AWide(LaneWidth * SourceLen, 0);
17248 APInt BWide(LaneWidth * SourceLen, 0);
17250 for (
unsigned I = 0; I != SourceLen; ++I) {
17253 if (ElemQT->isIntegerType()) {
17256 }
else if (ElemQT->isFloatingType()) {
17264 AWide.insertBits(ALane, I * LaneWidth);
17265 BWide.insertBits(BLane, I * LaneWidth);
17270 auto HandleMaskBinOp =
17283 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
17289 uint64_t CRCVal = CRC.getZExtValue();
17293 static const uint32_t CRC32C_POLY = 0x82F63B78;
17296 static_cast<uint32_t>(CRCVal), DataVal, DataBytes, CRC32C_POLY);
17301 switch (BuiltinOp) {
17305 case X86::BI__builtin_ia32_crc32qi:
17306 return HandleCRC32(1);
17307 case X86::BI__builtin_ia32_crc32hi:
17308 return HandleCRC32(2);
17309 case X86::BI__builtin_ia32_crc32si:
17310 return HandleCRC32(4);
17311 case X86::BI__builtin_ia32_crc32di:
17312 return HandleCRC32(8);
17314 case Builtin::BI__builtin_dynamic_object_size:
17315 case Builtin::BI__builtin_object_size: {
17319 if (TypeValue < 0 || TypeValue > 3) {
17320 Info.FFDiag(E->
getArg(1), diag::note_constexpr_builtin_arg_out_of_range)
17321 << TypeValue << 0 << 3;
17324 unsigned Type = TypeValue.getZExtValue();
17326 bool IsDynamic = BuiltinOp == Builtin::BI__builtin_dynamic_object_size;
17327 if (std::optional<uint64_t> Size =
17336 switch (Info.EvalMode) {
17337 case EvaluationMode::ConstantExpression:
17338 case EvaluationMode::ConstantFold:
17339 case EvaluationMode::IgnoreSideEffects:
17342 case EvaluationMode::ConstantExpressionUnevaluated:
17347 llvm_unreachable(
"unexpected EvalMode");
17350 case Builtin::BI__builtin_os_log_format_buffer_size: {
17351 analyze_os_log::OSLogBufferLayout Layout;
17356 case Builtin::BI__builtin_is_aligned: {
17364 Ptr.setFrom(Info.Ctx, Src);
17367 if (
Ptr.Offset.isZero())
17370 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
17382 assert(Alignment.isPowerOf2());
17395 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
17399 assert(Src.
isInt());
17400 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
17402 case Builtin::BI__builtin_align_up: {
17410 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
17411 Src.
getInt().isUnsigned());
17412 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17413 return Success(AlignedVal, E);
17415 case Builtin::BI__builtin_align_down: {
17424 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17425 return Success(AlignedVal, E);
17428 case Builtin::BI__builtin_bitreverseg:
17429 case Builtin::BI__builtin_bitreverse8:
17430 case Builtin::BI__builtin_bitreverse16:
17431 case Builtin::BI__builtin_bitreverse32:
17432 case Builtin::BI__builtin_bitreverse64:
17433 case Builtin::BI__builtin_elementwise_bitreverse: {
17438 return Success(Val.reverseBits(), E);
17440 case Builtin::BI__builtin_bswapg:
17441 case Builtin::BI__builtin_bswap16:
17442 case Builtin::BI__builtin_bswap32:
17443 case Builtin::BI__builtin_bswap64:
17444 case Builtin::BIstdc_memreverse8u8:
17445 case Builtin::BIstdc_memreverse8u16:
17446 case Builtin::BIstdc_memreverse8u32:
17447 case Builtin::BIstdc_memreverse8u64: {
17451 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
17454 return Success(Val.byteSwap(), E);
17457 case Builtin::BIstdc_load8_leu8:
17458 case Builtin::BIstdc_load8_leu16:
17459 case Builtin::BIstdc_load8_leu32:
17460 case Builtin::BIstdc_load8_leu64:
17461 case Builtin::BIstdc_load8_les8:
17462 case Builtin::BIstdc_load8_les16:
17463 case Builtin::BIstdc_load8_les32:
17464 case Builtin::BIstdc_load8_les64: {
17472 case Builtin::BIstdc_load8_aligned_leu8:
17473 case Builtin::BIstdc_load8_aligned_leu16:
17474 case Builtin::BIstdc_load8_aligned_leu32:
17475 case Builtin::BIstdc_load8_aligned_leu64:
17476 case Builtin::BIstdc_load8_aligned_les8:
17477 case Builtin::BIstdc_load8_aligned_les16:
17478 case Builtin::BIstdc_load8_aligned_les32:
17479 case Builtin::BIstdc_load8_aligned_les64: {
17486 case Builtin::BIstdc_load8_beu8:
17487 case Builtin::BIstdc_load8_beu16:
17488 case Builtin::BIstdc_load8_beu32:
17489 case Builtin::BIstdc_load8_beu64:
17490 case Builtin::BIstdc_load8_bes8:
17491 case Builtin::BIstdc_load8_bes16:
17492 case Builtin::BIstdc_load8_bes32:
17493 case Builtin::BIstdc_load8_bes64: {
17500 case Builtin::BIstdc_load8_aligned_beu8:
17501 case Builtin::BIstdc_load8_aligned_beu16:
17502 case Builtin::BIstdc_load8_aligned_beu32:
17503 case Builtin::BIstdc_load8_aligned_beu64:
17504 case Builtin::BIstdc_load8_aligned_bes8:
17505 case Builtin::BIstdc_load8_aligned_bes16:
17506 case Builtin::BIstdc_load8_aligned_bes32:
17507 case Builtin::BIstdc_load8_aligned_bes64: {
17514 case Builtin::BI__builtin_classify_type:
17517 case Builtin::BI__builtin_clrsb:
17518 case Builtin::BI__builtin_clrsbl:
17519 case Builtin::BI__builtin_clrsbll: {
17524 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
17527 case Builtin::BI__builtin_clz:
17528 case Builtin::BI__builtin_clzl:
17529 case Builtin::BI__builtin_clzll:
17530 case Builtin::BI__builtin_clzs:
17531 case Builtin::BI__builtin_clzg:
17532 case Builtin::BI__builtin_elementwise_clzg:
17533 case Builtin::BI__lzcnt16:
17534 case Builtin::BI__lzcnt:
17535 case Builtin::BI__lzcnt64: {
17546 std::optional<APSInt> Fallback;
17547 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
17548 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
17553 Fallback = FallbackTemp;
17558 return Success(*Fallback, E);
17563 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
17564 BuiltinOp != Builtin::BI__lzcnt &&
17565 BuiltinOp != Builtin::BI__lzcnt64;
17567 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
17568 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17572 if (ZeroIsUndefined)
17576 return Success(Val.countl_zero(), E);
17579 case Builtin::BI__builtin_constant_p: {
17580 const Expr *Arg = E->
getArg(0);
17589 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17593 case Builtin::BI__noop:
17597 case Builtin::BI__builtin_is_constant_evaluated: {
17598 const auto *
Callee = Info.CurrentCall->getCallee();
17599 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
17600 (Info.CallStackDepth == 1 ||
17601 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
17602 Callee->getIdentifier() &&
17603 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
17605 if (Info.EvalStatus.Diag)
17606 Info.report((Info.CallStackDepth == 1)
17608 : Info.CurrentCall->getCallRange().getBegin(),
17609 diag::warn_is_constant_evaluated_always_true_constexpr)
17610 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
17611 :
"std::is_constant_evaluated");
17614 return Success(Info.InConstantContext, E);
17617 case Builtin::BI__builtin_is_within_lifetime:
17618 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
17622 case Builtin::BI__builtin_ctz:
17623 case Builtin::BI__builtin_ctzl:
17624 case Builtin::BI__builtin_ctzll:
17625 case Builtin::BI__builtin_ctzs:
17626 case Builtin::BI__builtin_ctzg:
17627 case Builtin::BI__builtin_elementwise_ctzg: {
17638 std::optional<APSInt> Fallback;
17639 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
17640 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
17645 Fallback = FallbackTemp;
17650 return Success(*Fallback, E);
17652 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
17653 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17659 return Success(Val.countr_zero(), E);
17662 case Builtin::BI__builtin_eh_return_data_regno: {
17664 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
17668 case Builtin::BI__builtin_elementwise_abs: {
17673 return Success(Val.abs(), E);
17676 case Builtin::BI__builtin_expect:
17677 case Builtin::BI__builtin_expect_with_probability:
17678 return Visit(E->
getArg(0));
17680 case Builtin::BI__builtin_ptrauth_string_discriminator: {
17687 case Builtin::BI__builtin_infer_alloc_token: {
17693 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
17696 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
17698 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
17699 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
17700 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
17702 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
17703 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
17705 return Error(E, diag::note_constexpr_infer_alloc_token_unsupported_mode);
17706 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
17709 case Builtin::BI__builtin_ffs:
17710 case Builtin::BI__builtin_ffsl:
17711 case Builtin::BI__builtin_ffsll: {
17716 unsigned N = Val.countr_zero();
17717 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
17720 case Builtin::BI__builtin_fpclassify: {
17725 switch (Val.getCategory()) {
17726 case APFloat::fcNaN: Arg = 0;
break;
17727 case APFloat::fcInfinity: Arg = 1;
break;
17728 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
17729 case APFloat::fcZero: Arg = 4;
break;
17731 return Visit(E->
getArg(Arg));
17734 case Builtin::BI__builtin_isinf_sign: {
17737 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
17740 case Builtin::BI__builtin_isinf: {
17743 Success(Val.isInfinity() ? 1 : 0, E);
17746 case Builtin::BI__builtin_isfinite: {
17749 Success(Val.isFinite() ? 1 : 0, E);
17752 case Builtin::BI__builtin_isnan: {
17755 Success(Val.isNaN() ? 1 : 0, E);
17758 case Builtin::BI__builtin_isnormal: {
17761 Success(Val.isNormal() ? 1 : 0, E);
17764 case Builtin::BI__builtin_issubnormal: {
17767 Success(Val.isDenormal() ? 1 : 0, E);
17770 case Builtin::BI__builtin_iszero: {
17773 Success(Val.isZero() ? 1 : 0, E);
17776 case Builtin::BI__builtin_signbit:
17777 case Builtin::BI__builtin_signbitf:
17778 case Builtin::BI__builtin_signbitl: {
17781 Success(Val.isNegative() ? 1 : 0, E);
17784 case Builtin::BI__builtin_isgreater:
17785 case Builtin::BI__builtin_isgreaterequal:
17786 case Builtin::BI__builtin_isless:
17787 case Builtin::BI__builtin_islessequal:
17788 case Builtin::BI__builtin_islessgreater:
17789 case Builtin::BI__builtin_isunordered: {
17798 switch (BuiltinOp) {
17799 case Builtin::BI__builtin_isgreater:
17801 case Builtin::BI__builtin_isgreaterequal:
17803 case Builtin::BI__builtin_isless:
17805 case Builtin::BI__builtin_islessequal:
17807 case Builtin::BI__builtin_islessgreater: {
17808 APFloat::cmpResult cmp = LHS.compare(RHS);
17809 return cmp == APFloat::cmpResult::cmpLessThan ||
17810 cmp == APFloat::cmpResult::cmpGreaterThan;
17812 case Builtin::BI__builtin_isunordered:
17813 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
17815 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
17816 "point comparison function");
17824 case Builtin::BI__builtin_issignaling: {
17827 Success(Val.isSignaling() ? 1 : 0, E);
17830 case Builtin::BI__builtin_isfpclass: {
17834 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
17837 Success((Val.classify() & Test) ? 1 : 0, E);
17840 case Builtin::BI__builtin_parity:
17841 case Builtin::BI__builtin_parityl:
17842 case Builtin::BI__builtin_parityll: {
17847 return Success(Val.popcount() % 2, E);
17850 case Builtin::BI__builtin_abs:
17851 case Builtin::BI__builtin_labs:
17852 case Builtin::BI__builtin_llabs: {
17856 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
17859 if (Val.isNegative())
17864 case Builtin::BI__builtin_popcount:
17865 case Builtin::BI__builtin_popcountl:
17866 case Builtin::BI__builtin_popcountll:
17867 case Builtin::BI__builtin_popcountg:
17868 case Builtin::BI__builtin_elementwise_popcount:
17869 case Builtin::BI__popcnt16:
17870 case Builtin::BI__popcnt:
17871 case Builtin::BI__popcnt64: {
17882 return Success(Val.popcount(), E);
17885 case Builtin::BI__builtin_rotateleft8:
17886 case Builtin::BI__builtin_rotateleft16:
17887 case Builtin::BI__builtin_rotateleft32:
17888 case Builtin::BI__builtin_rotateleft64:
17889 case Builtin::BI__builtin_rotateright8:
17890 case Builtin::BI__builtin_rotateright16:
17891 case Builtin::BI__builtin_rotateright32:
17892 case Builtin::BI__builtin_rotateright64:
17893 case Builtin::BI__builtin_stdc_rotate_left:
17894 case Builtin::BI__builtin_stdc_rotate_right:
17895 case Builtin::BIstdc_rotate_left_uc:
17896 case Builtin::BIstdc_rotate_left_us:
17897 case Builtin::BIstdc_rotate_left_ui:
17898 case Builtin::BIstdc_rotate_left_ul:
17899 case Builtin::BIstdc_rotate_left_ull:
17900 case Builtin::BIstdc_rotate_right_uc:
17901 case Builtin::BIstdc_rotate_right_us:
17902 case Builtin::BIstdc_rotate_right_ui:
17903 case Builtin::BIstdc_rotate_right_ul:
17904 case Builtin::BIstdc_rotate_right_ull:
17905 case Builtin::BI_rotl8:
17906 case Builtin::BI_rotl16:
17907 case Builtin::BI_rotl:
17908 case Builtin::BI_lrotl:
17909 case Builtin::BI_rotl64:
17910 case Builtin::BI_rotr8:
17911 case Builtin::BI_rotr16:
17912 case Builtin::BI_rotr:
17913 case Builtin::BI_lrotr:
17914 case Builtin::BI_rotr64: {
17922 switch (BuiltinOp) {
17923 case Builtin::BI__builtin_rotateright8:
17924 case Builtin::BI__builtin_rotateright16:
17925 case Builtin::BI__builtin_rotateright32:
17926 case Builtin::BI__builtin_rotateright64:
17927 case Builtin::BI__builtin_stdc_rotate_right:
17928 case Builtin::BIstdc_rotate_right_uc:
17929 case Builtin::BIstdc_rotate_right_us:
17930 case Builtin::BIstdc_rotate_right_ui:
17931 case Builtin::BIstdc_rotate_right_ul:
17932 case Builtin::BIstdc_rotate_right_ull:
17933 case Builtin::BI_rotr8:
17934 case Builtin::BI_rotr16:
17935 case Builtin::BI_rotr:
17936 case Builtin::BI_lrotr:
17937 case Builtin::BI_rotr64:
17946 case Builtin::BIstdc_leading_zeros_uc:
17947 case Builtin::BIstdc_leading_zeros_us:
17948 case Builtin::BIstdc_leading_zeros_ui:
17949 case Builtin::BIstdc_leading_zeros_ul:
17950 case Builtin::BIstdc_leading_zeros_ull:
17951 case Builtin::BIstdc_leading_ones_uc:
17952 case Builtin::BIstdc_leading_ones_us:
17953 case Builtin::BIstdc_leading_ones_ui:
17954 case Builtin::BIstdc_leading_ones_ul:
17955 case Builtin::BIstdc_leading_ones_ull:
17956 case Builtin::BIstdc_trailing_zeros_uc:
17957 case Builtin::BIstdc_trailing_zeros_us:
17958 case Builtin::BIstdc_trailing_zeros_ui:
17959 case Builtin::BIstdc_trailing_zeros_ul:
17960 case Builtin::BIstdc_trailing_zeros_ull:
17961 case Builtin::BIstdc_trailing_ones_uc:
17962 case Builtin::BIstdc_trailing_ones_us:
17963 case Builtin::BIstdc_trailing_ones_ui:
17964 case Builtin::BIstdc_trailing_ones_ul:
17965 case Builtin::BIstdc_trailing_ones_ull:
17966 case Builtin::BIstdc_first_leading_zero_uc:
17967 case Builtin::BIstdc_first_leading_zero_us:
17968 case Builtin::BIstdc_first_leading_zero_ui:
17969 case Builtin::BIstdc_first_leading_zero_ul:
17970 case Builtin::BIstdc_first_leading_zero_ull:
17971 case Builtin::BIstdc_first_leading_one_uc:
17972 case Builtin::BIstdc_first_leading_one_us:
17973 case Builtin::BIstdc_first_leading_one_ui:
17974 case Builtin::BIstdc_first_leading_one_ul:
17975 case Builtin::BIstdc_first_leading_one_ull:
17976 case Builtin::BIstdc_first_trailing_zero_uc:
17977 case Builtin::BIstdc_first_trailing_zero_us:
17978 case Builtin::BIstdc_first_trailing_zero_ui:
17979 case Builtin::BIstdc_first_trailing_zero_ul:
17980 case Builtin::BIstdc_first_trailing_zero_ull:
17981 case Builtin::BIstdc_first_trailing_one_uc:
17982 case Builtin::BIstdc_first_trailing_one_us:
17983 case Builtin::BIstdc_first_trailing_one_ui:
17984 case Builtin::BIstdc_first_trailing_one_ul:
17985 case Builtin::BIstdc_first_trailing_one_ull:
17986 case Builtin::BIstdc_count_zeros_uc:
17987 case Builtin::BIstdc_count_zeros_us:
17988 case Builtin::BIstdc_count_zeros_ui:
17989 case Builtin::BIstdc_count_zeros_ul:
17990 case Builtin::BIstdc_count_zeros_ull:
17991 case Builtin::BIstdc_count_ones_uc:
17992 case Builtin::BIstdc_count_ones_us:
17993 case Builtin::BIstdc_count_ones_ui:
17994 case Builtin::BIstdc_count_ones_ul:
17995 case Builtin::BIstdc_count_ones_ull:
17996 case Builtin::BIstdc_has_single_bit_uc:
17997 case Builtin::BIstdc_has_single_bit_us:
17998 case Builtin::BIstdc_has_single_bit_ui:
17999 case Builtin::BIstdc_has_single_bit_ul:
18000 case Builtin::BIstdc_has_single_bit_ull:
18001 case Builtin::BIstdc_bit_width_uc:
18002 case Builtin::BIstdc_bit_width_us:
18003 case Builtin::BIstdc_bit_width_ui:
18004 case Builtin::BIstdc_bit_width_ul:
18005 case Builtin::BIstdc_bit_width_ull:
18006 case Builtin::BIstdc_bit_floor_uc:
18007 case Builtin::BIstdc_bit_floor_us:
18008 case Builtin::BIstdc_bit_floor_ui:
18009 case Builtin::BIstdc_bit_floor_ul:
18010 case Builtin::BIstdc_bit_floor_ull:
18011 case Builtin::BIstdc_bit_ceil_uc:
18012 case Builtin::BIstdc_bit_ceil_us:
18013 case Builtin::BIstdc_bit_ceil_ui:
18014 case Builtin::BIstdc_bit_ceil_ul:
18015 case Builtin::BIstdc_bit_ceil_ull:
18016 case Builtin::BI__builtin_stdc_leading_zeros:
18017 case Builtin::BI__builtin_stdc_leading_ones:
18018 case Builtin::BI__builtin_stdc_trailing_zeros:
18019 case Builtin::BI__builtin_stdc_trailing_ones:
18020 case Builtin::BI__builtin_stdc_first_leading_zero:
18021 case Builtin::BI__builtin_stdc_first_leading_one:
18022 case Builtin::BI__builtin_stdc_first_trailing_zero:
18023 case Builtin::BI__builtin_stdc_first_trailing_one:
18024 case Builtin::BI__builtin_stdc_count_zeros:
18025 case Builtin::BI__builtin_stdc_count_ones:
18026 case Builtin::BI__builtin_stdc_has_single_bit:
18027 case Builtin::BI__builtin_stdc_bit_width:
18028 case Builtin::BI__builtin_stdc_bit_floor:
18029 case Builtin::BI__builtin_stdc_bit_ceil: {
18034 unsigned BitWidth = Val.getBitWidth();
18035 const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->
getType());
18037 switch (BuiltinOp) {
18038 case Builtin::BIstdc_leading_zeros_uc:
18039 case Builtin::BIstdc_leading_zeros_us:
18040 case Builtin::BIstdc_leading_zeros_ui:
18041 case Builtin::BIstdc_leading_zeros_ul:
18042 case Builtin::BIstdc_leading_zeros_ull:
18043 case Builtin::BI__builtin_stdc_leading_zeros:
18044 return Success(
APInt(ResBitWidth, Val.countl_zero()), E);
18045 case Builtin::BIstdc_leading_ones_uc:
18046 case Builtin::BIstdc_leading_ones_us:
18047 case Builtin::BIstdc_leading_ones_ui:
18048 case Builtin::BIstdc_leading_ones_ul:
18049 case Builtin::BIstdc_leading_ones_ull:
18050 case Builtin::BI__builtin_stdc_leading_ones:
18051 return Success(
APInt(ResBitWidth, Val.countl_one()), E);
18052 case Builtin::BIstdc_trailing_zeros_uc:
18053 case Builtin::BIstdc_trailing_zeros_us:
18054 case Builtin::BIstdc_trailing_zeros_ui:
18055 case Builtin::BIstdc_trailing_zeros_ul:
18056 case Builtin::BIstdc_trailing_zeros_ull:
18057 case Builtin::BI__builtin_stdc_trailing_zeros:
18058 return Success(
APInt(ResBitWidth, Val.countr_zero()), E);
18059 case Builtin::BIstdc_trailing_ones_uc:
18060 case Builtin::BIstdc_trailing_ones_us:
18061 case Builtin::BIstdc_trailing_ones_ui:
18062 case Builtin::BIstdc_trailing_ones_ul:
18063 case Builtin::BIstdc_trailing_ones_ull:
18064 case Builtin::BI__builtin_stdc_trailing_ones:
18065 return Success(
APInt(ResBitWidth, Val.countr_one()), E);
18066 case Builtin::BIstdc_first_leading_zero_uc:
18067 case Builtin::BIstdc_first_leading_zero_us:
18068 case Builtin::BIstdc_first_leading_zero_ui:
18069 case Builtin::BIstdc_first_leading_zero_ul:
18070 case Builtin::BIstdc_first_leading_zero_ull:
18071 case Builtin::BI__builtin_stdc_first_leading_zero:
18073 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
18074 case Builtin::BIstdc_first_leading_one_uc:
18075 case Builtin::BIstdc_first_leading_one_us:
18076 case Builtin::BIstdc_first_leading_one_ui:
18077 case Builtin::BIstdc_first_leading_one_ul:
18078 case Builtin::BIstdc_first_leading_one_ull:
18079 case Builtin::BI__builtin_stdc_first_leading_one:
18081 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
18082 case Builtin::BIstdc_first_trailing_zero_uc:
18083 case Builtin::BIstdc_first_trailing_zero_us:
18084 case Builtin::BIstdc_first_trailing_zero_ui:
18085 case Builtin::BIstdc_first_trailing_zero_ul:
18086 case Builtin::BIstdc_first_trailing_zero_ull:
18087 case Builtin::BI__builtin_stdc_first_trailing_zero:
18089 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
18090 case Builtin::BIstdc_first_trailing_one_uc:
18091 case Builtin::BIstdc_first_trailing_one_us:
18092 case Builtin::BIstdc_first_trailing_one_ui:
18093 case Builtin::BIstdc_first_trailing_one_ul:
18094 case Builtin::BIstdc_first_trailing_one_ull:
18095 case Builtin::BI__builtin_stdc_first_trailing_one:
18097 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
18098 case Builtin::BIstdc_count_zeros_uc:
18099 case Builtin::BIstdc_count_zeros_us:
18100 case Builtin::BIstdc_count_zeros_ui:
18101 case Builtin::BIstdc_count_zeros_ul:
18102 case Builtin::BIstdc_count_zeros_ull:
18103 case Builtin::BI__builtin_stdc_count_zeros: {
18104 APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
18107 case Builtin::BIstdc_count_ones_uc:
18108 case Builtin::BIstdc_count_ones_us:
18109 case Builtin::BIstdc_count_ones_ui:
18110 case Builtin::BIstdc_count_ones_ul:
18111 case Builtin::BIstdc_count_ones_ull:
18112 case Builtin::BI__builtin_stdc_count_ones: {
18113 APInt Cnt(ResBitWidth, Val.popcount());
18116 case Builtin::BIstdc_has_single_bit_uc:
18117 case Builtin::BIstdc_has_single_bit_us:
18118 case Builtin::BIstdc_has_single_bit_ui:
18119 case Builtin::BIstdc_has_single_bit_ul:
18120 case Builtin::BIstdc_has_single_bit_ull:
18121 case Builtin::BI__builtin_stdc_has_single_bit: {
18122 APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
18125 case Builtin::BIstdc_bit_width_uc:
18126 case Builtin::BIstdc_bit_width_us:
18127 case Builtin::BIstdc_bit_width_ui:
18128 case Builtin::BIstdc_bit_width_ul:
18129 case Builtin::BIstdc_bit_width_ull:
18130 case Builtin::BI__builtin_stdc_bit_width:
18131 return Success(
APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
18132 case Builtin::BIstdc_bit_floor_uc:
18133 case Builtin::BIstdc_bit_floor_us:
18134 case Builtin::BIstdc_bit_floor_ui:
18135 case Builtin::BIstdc_bit_floor_ul:
18136 case Builtin::BIstdc_bit_floor_ull:
18137 case Builtin::BI__builtin_stdc_bit_floor: {
18140 unsigned Exp = BitWidth - Val.countl_zero() - 1;
18142 APSInt(APInt::getOneBitSet(BitWidth, Exp),
true), E);
18144 case Builtin::BIstdc_bit_ceil_uc:
18145 case Builtin::BIstdc_bit_ceil_us:
18146 case Builtin::BIstdc_bit_ceil_ui:
18147 case Builtin::BIstdc_bit_ceil_ul:
18148 case Builtin::BIstdc_bit_ceil_ull:
18149 case Builtin::BI__builtin_stdc_bit_ceil: {
18152 APInt ValMinusOne = Val - 1;
18153 unsigned LZ = ValMinusOne.countl_zero();
18157 APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
18161 llvm_unreachable(
"Unknown stdc builtin");
18165 case Builtin::BI__builtin_elementwise_add_sat: {
18171 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
18174 case Builtin::BI__builtin_elementwise_sub_sat: {
18180 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
18183 case Builtin::BI__builtin_elementwise_max: {
18192 case Builtin::BI__builtin_elementwise_min: {
18201 case Builtin::BI__builtin_elementwise_clmul: {
18210 case Builtin::BI__builtin_elementwise_fshl:
18211 case Builtin::BI__builtin_elementwise_fshr: {
18218 switch (BuiltinOp) {
18219 case Builtin::BI__builtin_elementwise_fshl: {
18220 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
18223 case Builtin::BI__builtin_elementwise_fshr: {
18224 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
18228 llvm_unreachable(
"Fully covered switch above");
18230 case Builtin::BIstrlen:
18231 case Builtin::BIwcslen:
18233 if (Info.getLangOpts().CPlusPlus11)
18234 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
18236 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
18238 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
18240 case Builtin::BI__builtin_strlen:
18241 case Builtin::BI__builtin_wcslen: {
18244 if (std::optional<uint64_t> StrLen =
18250 case Builtin::BIstrcmp:
18251 case Builtin::BIwcscmp:
18252 case Builtin::BIstrncmp:
18253 case Builtin::BIwcsncmp:
18254 case Builtin::BImemcmp:
18255 case Builtin::BIbcmp:
18256 case Builtin::BIwmemcmp:
18258 if (Info.getLangOpts().CPlusPlus11)
18259 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
18261 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
18263 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
18265 case Builtin::BI__builtin_strcmp:
18266 case Builtin::BI__builtin_wcscmp:
18267 case Builtin::BI__builtin_strncmp:
18268 case Builtin::BI__builtin_wcsncmp:
18269 case Builtin::BI__builtin_memcmp:
18270 case Builtin::BI__builtin_bcmp:
18271 case Builtin::BI__builtin_wmemcmp: {
18272 LValue String1, String2;
18278 if (BuiltinOp != Builtin::BIstrcmp &&
18279 BuiltinOp != Builtin::BIwcscmp &&
18280 BuiltinOp != Builtin::BI__builtin_strcmp &&
18281 BuiltinOp != Builtin::BI__builtin_wcscmp) {
18285 MaxLength = N.getZExtValue();
18289 if (MaxLength == 0u)
18292 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
18293 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
18294 String1.Designator.Invalid || String2.Designator.Invalid)
18297 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
18298 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
18300 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
18301 BuiltinOp == Builtin::BIbcmp ||
18302 BuiltinOp == Builtin::BI__builtin_memcmp ||
18303 BuiltinOp == Builtin::BI__builtin_bcmp;
18305 assert(IsRawByte ||
18306 (Info.Ctx.hasSameUnqualifiedType(
18308 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
18315 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
18316 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
18321 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
18324 Char1.
isInt() && Char2.isInt();
18326 const auto &AdvanceElems = [&] {
18332 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
18333 BuiltinOp != Builtin::BIwmemcmp &&
18334 BuiltinOp != Builtin::BI__builtin_memcmp &&
18335 BuiltinOp != Builtin::BI__builtin_bcmp &&
18336 BuiltinOp != Builtin::BI__builtin_wmemcmp);
18337 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
18338 BuiltinOp == Builtin::BIwcsncmp ||
18339 BuiltinOp == Builtin::BIwmemcmp ||
18340 BuiltinOp == Builtin::BI__builtin_wcscmp ||
18341 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
18342 BuiltinOp == Builtin::BI__builtin_wmemcmp;
18344 for (; MaxLength; --MaxLength) {
18346 if (!ReadCurElems(Char1, Char2))
18354 if (StopAtNull && !Char1.
getInt())
18356 assert(!(StopAtNull && !Char2.
getInt()));
18357 if (!AdvanceElems())
18364 case Builtin::BI__atomic_always_lock_free:
18365 case Builtin::BI__atomic_is_lock_free:
18366 case Builtin::BI__c11_atomic_is_lock_free: {
18382 if (
Size.isPowerOfTwo()) {
18384 unsigned InlineWidthBits =
18385 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
18386 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
18387 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
18393 const Expr *PtrArg = E->
getArg(1);
18399 IntResult.isAligned(
Size.getAsAlign()))
18403 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
18406 if (ICE->getCastKind() == CK_BitCast)
18407 PtrArg = ICE->getSubExpr();
18410 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
18413 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
18421 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
18424 case Builtin::BI__builtin_addcb:
18425 case Builtin::BI__builtin_addcs:
18426 case Builtin::BI__builtin_addc:
18427 case Builtin::BI__builtin_addcl:
18428 case Builtin::BI__builtin_addcll:
18429 case Builtin::BI__builtin_subcb:
18430 case Builtin::BI__builtin_subcs:
18431 case Builtin::BI__builtin_subc:
18432 case Builtin::BI__builtin_subcl:
18433 case Builtin::BI__builtin_subcll: {
18434 LValue CarryOutLValue;
18446 bool FirstOverflowed =
false;
18447 bool SecondOverflowed =
false;
18448 switch (BuiltinOp) {
18450 llvm_unreachable(
"Invalid value for BuiltinOp");
18451 case Builtin::BI__builtin_addcb:
18452 case Builtin::BI__builtin_addcs:
18453 case Builtin::BI__builtin_addc:
18454 case Builtin::BI__builtin_addcl:
18455 case Builtin::BI__builtin_addcll:
18457 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
18459 case Builtin::BI__builtin_subcb:
18460 case Builtin::BI__builtin_subcs:
18461 case Builtin::BI__builtin_subc:
18462 case Builtin::BI__builtin_subcl:
18463 case Builtin::BI__builtin_subcll:
18465 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
18471 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
18477 case Builtin::BI__builtin_add_overflow:
18478 case Builtin::BI__builtin_sub_overflow:
18479 case Builtin::BI__builtin_mul_overflow:
18480 case Builtin::BI__builtin_sadd_overflow:
18481 case Builtin::BI__builtin_uadd_overflow:
18482 case Builtin::BI__builtin_uaddl_overflow:
18483 case Builtin::BI__builtin_uaddll_overflow:
18484 case Builtin::BI__builtin_usub_overflow:
18485 case Builtin::BI__builtin_usubl_overflow:
18486 case Builtin::BI__builtin_usubll_overflow:
18487 case Builtin::BI__builtin_umul_overflow:
18488 case Builtin::BI__builtin_umull_overflow:
18489 case Builtin::BI__builtin_umulll_overflow:
18490 case Builtin::BI__builtin_saddl_overflow:
18491 case Builtin::BI__builtin_saddll_overflow:
18492 case Builtin::BI__builtin_ssub_overflow:
18493 case Builtin::BI__builtin_ssubl_overflow:
18494 case Builtin::BI__builtin_ssubll_overflow:
18495 case Builtin::BI__builtin_smul_overflow:
18496 case Builtin::BI__builtin_smull_overflow:
18497 case Builtin::BI__builtin_smulll_overflow: {
18498 LValue ResultLValue;
18508 bool DidOverflow =
false;
18511 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18512 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18513 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18514 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
18516 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
18518 uint64_t LHSSize = LHS.getBitWidth();
18519 uint64_t RHSSize = RHS.getBitWidth();
18520 uint64_t ResultSize = Info.Ctx.getIntWidth(ResultType);
18521 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
18527 if (IsSigned && !AllSigned)
18530 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
18531 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
18536 switch (BuiltinOp) {
18538 llvm_unreachable(
"Invalid value for BuiltinOp");
18539 case Builtin::BI__builtin_add_overflow:
18540 case Builtin::BI__builtin_sadd_overflow:
18541 case Builtin::BI__builtin_saddl_overflow:
18542 case Builtin::BI__builtin_saddll_overflow:
18543 case Builtin::BI__builtin_uadd_overflow:
18544 case Builtin::BI__builtin_uaddl_overflow:
18545 case Builtin::BI__builtin_uaddll_overflow:
18546 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
18547 : LHS.uadd_ov(RHS, DidOverflow);
18549 case Builtin::BI__builtin_sub_overflow:
18550 case Builtin::BI__builtin_ssub_overflow:
18551 case Builtin::BI__builtin_ssubl_overflow:
18552 case Builtin::BI__builtin_ssubll_overflow:
18553 case Builtin::BI__builtin_usub_overflow:
18554 case Builtin::BI__builtin_usubl_overflow:
18555 case Builtin::BI__builtin_usubll_overflow:
18556 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
18557 : LHS.usub_ov(RHS, DidOverflow);
18559 case Builtin::BI__builtin_mul_overflow:
18560 case Builtin::BI__builtin_smul_overflow:
18561 case Builtin::BI__builtin_smull_overflow:
18562 case Builtin::BI__builtin_smulll_overflow:
18563 case Builtin::BI__builtin_umul_overflow:
18564 case Builtin::BI__builtin_umull_overflow:
18565 case Builtin::BI__builtin_umulll_overflow:
18566 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
18567 : LHS.umul_ov(RHS, DidOverflow);
18576 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getIntWidth(ResultType));
18581 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18582 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18583 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18584 if (!APSInt::isSameValue(Temp,
Result))
18585 DidOverflow =
true;
18592 return Success(DidOverflow, E);
18595 case Builtin::BI__builtin_reduce_add:
18596 case Builtin::BI__builtin_reduce_mul:
18597 case Builtin::BI__builtin_reduce_and:
18598 case Builtin::BI__builtin_reduce_or:
18599 case Builtin::BI__builtin_reduce_xor:
18600 case Builtin::BI__builtin_reduce_min:
18601 case Builtin::BI__builtin_reduce_max: {
18608 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
18609 switch (BuiltinOp) {
18612 case Builtin::BI__builtin_reduce_add: {
18615 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
18619 case Builtin::BI__builtin_reduce_mul: {
18622 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
18626 case Builtin::BI__builtin_reduce_and: {
18630 case Builtin::BI__builtin_reduce_or: {
18634 case Builtin::BI__builtin_reduce_xor: {
18638 case Builtin::BI__builtin_reduce_min: {
18642 case Builtin::BI__builtin_reduce_max: {
18652 case clang::X86::BI__builtin_ia32_addcarryx_u32:
18653 case clang::X86::BI__builtin_ia32_addcarryx_u64:
18654 case clang::X86::BI__builtin_ia32_subborrow_u32:
18655 case clang::X86::BI__builtin_ia32_subborrow_u64: {
18656 LValue ResultLValue;
18657 APSInt CarryIn, LHS, RHS;
18665 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
18666 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
18668 unsigned BitWidth = LHS.getBitWidth();
18669 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
18672 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
18673 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
18675 APInt Result = ExResult.extractBits(BitWidth, 0);
18676 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
18684 case clang::X86::BI__builtin_ia32_movmskps:
18685 case clang::X86::BI__builtin_ia32_movmskpd:
18686 case clang::X86::BI__builtin_ia32_pmovmskb128:
18687 case clang::X86::BI__builtin_ia32_pmovmskb256:
18688 case clang::X86::BI__builtin_ia32_movmskps256:
18689 case clang::X86::BI__builtin_ia32_movmskpd256: {
18696 unsigned ResultLen = Info.Ctx.getTypeSize(
18700 for (
unsigned I = 0; I != SourceLen; ++I) {
18702 if (ElemQT->isIntegerType()) {
18704 }
else if (ElemQT->isRealFloatingType()) {
18709 Result.setBitVal(I, Elem.isNegative());
18714 case clang::X86::BI__builtin_ia32_bextr_u32:
18715 case clang::X86::BI__builtin_ia32_bextr_u64:
18716 case clang::X86::BI__builtin_ia32_bextri_u32:
18717 case clang::X86::BI__builtin_ia32_bextri_u64: {
18723 unsigned BitWidth = Val.getBitWidth();
18725 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
18726 Length = Length > BitWidth ? BitWidth : Length;
18729 if (Length == 0 || Shift >= BitWidth)
18733 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
18737 case clang::X86::BI__builtin_ia32_bzhi_si:
18738 case clang::X86::BI__builtin_ia32_bzhi_di: {
18744 unsigned BitWidth = Val.getBitWidth();
18745 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
18746 if (Index < BitWidth)
18747 Val.clearHighBits(BitWidth - Index);
18751 case clang::X86::BI__builtin_ia32_ktestcqi:
18752 case clang::X86::BI__builtin_ia32_ktestchi:
18753 case clang::X86::BI__builtin_ia32_ktestcsi:
18754 case clang::X86::BI__builtin_ia32_ktestcdi: {
18760 return Success((~A & B) == 0, E);
18763 case clang::X86::BI__builtin_ia32_ktestzqi:
18764 case clang::X86::BI__builtin_ia32_ktestzhi:
18765 case clang::X86::BI__builtin_ia32_ktestzsi:
18766 case clang::X86::BI__builtin_ia32_ktestzdi: {
18772 return Success((A & B) == 0, E);
18775 case clang::X86::BI__builtin_ia32_kortestcqi:
18776 case clang::X86::BI__builtin_ia32_kortestchi:
18777 case clang::X86::BI__builtin_ia32_kortestcsi:
18778 case clang::X86::BI__builtin_ia32_kortestcdi: {
18784 return Success(~(A | B) == 0, E);
18787 case clang::X86::BI__builtin_ia32_kortestzqi:
18788 case clang::X86::BI__builtin_ia32_kortestzhi:
18789 case clang::X86::BI__builtin_ia32_kortestzsi:
18790 case clang::X86::BI__builtin_ia32_kortestzdi: {
18796 return Success((A | B) == 0, E);
18799 case clang::X86::BI__builtin_ia32_kunpckhi:
18800 case clang::X86::BI__builtin_ia32_kunpckdi:
18801 case clang::X86::BI__builtin_ia32_kunpcksi: {
18809 unsigned BW = A.getBitWidth();
18810 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
18814 case clang::X86::BI__builtin_ia32_lzcnt_u16:
18815 case clang::X86::BI__builtin_ia32_lzcnt_u32:
18816 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
18820 return Success(Val.countLeadingZeros(), E);
18823 case clang::X86::BI__builtin_ia32_tzcnt_u16:
18824 case clang::X86::BI__builtin_ia32_tzcnt_u32:
18825 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
18829 return Success(Val.countTrailingZeros(), E);
18832 case Builtin::BI__builtin_elementwise_pdep: {
18837 return Success(llvm::APIntOps::pdep(Val, Msk), E);
18840 case Builtin::BI__builtin_elementwise_pext: {
18845 return Success(llvm::APIntOps::pext(Val, Msk), E);
18848 case X86::BI__builtin_ia32_ptestz128:
18849 case X86::BI__builtin_ia32_ptestz256:
18850 case X86::BI__builtin_ia32_vtestzps:
18851 case X86::BI__builtin_ia32_vtestzps256:
18852 case X86::BI__builtin_ia32_vtestzpd:
18853 case X86::BI__builtin_ia32_vtestzpd256: {
18855 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
18857 case X86::BI__builtin_ia32_ptestc128:
18858 case X86::BI__builtin_ia32_ptestc256:
18859 case X86::BI__builtin_ia32_vtestcps:
18860 case X86::BI__builtin_ia32_vtestcps256:
18861 case X86::BI__builtin_ia32_vtestcpd:
18862 case X86::BI__builtin_ia32_vtestcpd256: {
18864 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
18866 case X86::BI__builtin_ia32_ptestnzc128:
18867 case X86::BI__builtin_ia32_ptestnzc256:
18868 case X86::BI__builtin_ia32_vtestnzcps:
18869 case X86::BI__builtin_ia32_vtestnzcps256:
18870 case X86::BI__builtin_ia32_vtestnzcpd:
18871 case X86::BI__builtin_ia32_vtestnzcpd256: {
18872 return EvalTestOp([](
const APInt &A,
const APInt &B) {
18873 return ((A & B) != 0) && ((~A & B) != 0);
18876 case X86::BI__builtin_ia32_kandqi:
18877 case X86::BI__builtin_ia32_kandhi:
18878 case X86::BI__builtin_ia32_kandsi:
18879 case X86::BI__builtin_ia32_kanddi: {
18880 return HandleMaskBinOp(
18881 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
18884 case X86::BI__builtin_ia32_kandnqi:
18885 case X86::BI__builtin_ia32_kandnhi:
18886 case X86::BI__builtin_ia32_kandnsi:
18887 case X86::BI__builtin_ia32_kandndi: {
18888 return HandleMaskBinOp(
18889 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
18892 case X86::BI__builtin_ia32_korqi:
18893 case X86::BI__builtin_ia32_korhi:
18894 case X86::BI__builtin_ia32_korsi:
18895 case X86::BI__builtin_ia32_kordi: {
18896 return HandleMaskBinOp(
18897 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
18900 case X86::BI__builtin_ia32_kxnorqi:
18901 case X86::BI__builtin_ia32_kxnorhi:
18902 case X86::BI__builtin_ia32_kxnorsi:
18903 case X86::BI__builtin_ia32_kxnordi: {
18904 return HandleMaskBinOp(
18905 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
18908 case X86::BI__builtin_ia32_kxorqi:
18909 case X86::BI__builtin_ia32_kxorhi:
18910 case X86::BI__builtin_ia32_kxorsi:
18911 case X86::BI__builtin_ia32_kxordi: {
18912 return HandleMaskBinOp(
18913 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
18916 case X86::BI__builtin_ia32_knotqi:
18917 case X86::BI__builtin_ia32_knothi:
18918 case X86::BI__builtin_ia32_knotsi:
18919 case X86::BI__builtin_ia32_knotdi: {
18927 case X86::BI__builtin_ia32_kaddqi:
18928 case X86::BI__builtin_ia32_kaddhi:
18929 case X86::BI__builtin_ia32_kaddsi:
18930 case X86::BI__builtin_ia32_kadddi: {
18931 return HandleMaskBinOp(
18932 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
18935 case X86::BI__builtin_ia32_kmovb:
18936 case X86::BI__builtin_ia32_kmovw:
18937 case X86::BI__builtin_ia32_kmovd:
18938 case X86::BI__builtin_ia32_kmovq: {
18945 case X86::BI__builtin_ia32_kshiftliqi:
18946 case X86::BI__builtin_ia32_kshiftlihi:
18947 case X86::BI__builtin_ia32_kshiftlisi:
18948 case X86::BI__builtin_ia32_kshiftlidi: {
18949 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18950 unsigned Amt = RHS.getZExtValue() & 0xFF;
18951 if (Amt >= LHS.getBitWidth())
18952 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18953 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
18957 case X86::BI__builtin_ia32_kshiftriqi:
18958 case X86::BI__builtin_ia32_kshiftrihi:
18959 case X86::BI__builtin_ia32_kshiftrisi:
18960 case X86::BI__builtin_ia32_kshiftridi: {
18961 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18962 unsigned Amt = RHS.getZExtValue() & 0xFF;
18963 if (Amt >= LHS.getBitWidth())
18964 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18965 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
18969 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
18970 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
18971 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
18972 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
18973 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
18974 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
18975 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
18976 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
18977 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
18984 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18988 case clang::X86::BI__builtin_ia32_cvtb2mask128:
18989 case clang::X86::BI__builtin_ia32_cvtb2mask256:
18990 case clang::X86::BI__builtin_ia32_cvtb2mask512:
18991 case clang::X86::BI__builtin_ia32_cvtw2mask128:
18992 case clang::X86::BI__builtin_ia32_cvtw2mask256:
18993 case clang::X86::BI__builtin_ia32_cvtw2mask512:
18994 case clang::X86::BI__builtin_ia32_cvtd2mask128:
18995 case clang::X86::BI__builtin_ia32_cvtd2mask256:
18996 case clang::X86::BI__builtin_ia32_cvtd2mask512:
18997 case clang::X86::BI__builtin_ia32_cvtq2mask128:
18998 case clang::X86::BI__builtin_ia32_cvtq2mask256:
18999 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
19006 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
19007 llvm::APInt Bits(RetWidth, 0);
19009 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
19011 unsigned MSB = A[A.getBitWidth() - 1];
19012 Bits.setBitVal(ElemNum, MSB);
19015 APSInt RetMask(Bits,
true);
19019 case clang::X86::BI__builtin_ia32_cmpb128_mask:
19020 case clang::X86::BI__builtin_ia32_cmpw128_mask:
19021 case clang::X86::BI__builtin_ia32_cmpd128_mask:
19022 case clang::X86::BI__builtin_ia32_cmpq128_mask:
19023 case clang::X86::BI__builtin_ia32_cmpb256_mask:
19024 case clang::X86::BI__builtin_ia32_cmpw256_mask:
19025 case clang::X86::BI__builtin_ia32_cmpd256_mask:
19026 case clang::X86::BI__builtin_ia32_cmpq256_mask:
19027 case clang::X86::BI__builtin_ia32_cmpb512_mask:
19028 case clang::X86::BI__builtin_ia32_cmpw512_mask:
19029 case clang::X86::BI__builtin_ia32_cmpd512_mask:
19030 case clang::X86::BI__builtin_ia32_cmpq512_mask:
19031 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
19032 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
19033 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
19034 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
19035 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
19036 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
19037 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
19038 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
19039 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
19040 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
19041 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
19042 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
19046 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
19047 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
19060 unsigned RetWidth = Mask.getBitWidth();
19062 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
19064 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
19069 switch (
Opcode.getExtValue() & 0x7) {
19074 Result = IsUnsigned ? A.ult(B) : A.slt(B);
19077 Result = IsUnsigned ? A.ule(B) : A.sle(B);
19086 Result = IsUnsigned ? A.uge(B) : A.sge(B);
19089 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
19096 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
19101 case X86::BI__builtin_ia32_cvtss2si:
19102 case X86::BI__builtin_ia32_cvtsd2si:
19103 case X86::BI__builtin_ia32_cvttss2si:
19104 case X86::BI__builtin_ia32_cvttsd2si:
19105 case X86::BI__builtin_ia32_cvtss2si64:
19106 case X86::BI__builtin_ia32_cvtsd2si64:
19107 case X86::BI__builtin_ia32_cvttss2si64:
19108 case X86::BI__builtin_ia32_cvttsd2si64: {
19113 assert(ArgVal.
isVector() &&
"Expected a vector argument");
19115 unsigned BitWidth = Info.Ctx.getIntWidth(E->
getType());
19118 llvm::APSInt IntResult(BitWidth,
isUnsigned);
19119 bool IsExact =
false;
19122 FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
19127 return Success(IntResult, E);
19129 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
19130 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
19131 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
19144 unsigned NumBytesInQWord = 8;
19145 unsigned NumBitsInByte = 8;
19147 unsigned NumQWords = NumBytes / NumBytesInQWord;
19148 unsigned RetWidth = ZeroMask.getBitWidth();
19149 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
19151 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
19152 APInt SourceQWord(64, 0);
19153 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
19157 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
19160 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
19161 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
19164 if (ZeroMask[SelIdx]) {
19165 RetMask.setBitVal(SelIdx, SourceQWord[M]);
19177 const LValue &LV) {
19180 if (!LV.getLValueBase())
19185 if (!LV.getLValueDesignator().Invalid &&
19186 !LV.getLValueDesignator().isOnePastTheEnd())
19196 if (LV.getLValueDesignator().Invalid)
19202 return LV.getLValueOffset() == Size;
19212class DataRecursiveIntBinOpEvaluator {
19213 struct EvalResult {
19215 bool Failed =
false;
19217 EvalResult() =
default;
19219 void swap(EvalResult &RHS) {
19221 Failed = RHS.Failed;
19222 RHS.Failed =
false;
19228 EvalResult LHSResult;
19229 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
19232 Job(Job &&) =
default;
19234 void startSpeculativeEval(EvalInfo &Info) {
19235 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
19239 SpeculativeEvaluationRAII SpecEvalRAII;
19242 SmallVector<Job, 16> Queue;
19244 IntExprEvaluator &IntEval;
19249 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
19250 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
19256 static bool shouldEnqueue(
const BinaryOperator *E) {
19263 bool Traverse(
const BinaryOperator *E) {
19265 EvalResult PrevResult;
19266 while (!Queue.empty())
19267 process(PrevResult);
19269 if (PrevResult.Failed)
return false;
19271 FinalResult.
swap(PrevResult.Val);
19282 bool Error(
const Expr *E) {
19283 return IntEval.Error(E);
19286 return IntEval.Error(E, D);
19289 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
19290 return Info.CCEDiag(E, D);
19294 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
19295 bool &SuppressRHSDiags);
19297 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
19300 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
19306 void process(EvalResult &
Result);
19308 void enqueue(
const Expr *E) {
19310 Queue.resize(Queue.size()+1);
19311 Queue.back().E = E;
19312 Queue.back().Kind = Job::AnyExprKind;
19318bool DataRecursiveIntBinOpEvaluator::
19319 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
19320 bool &SuppressRHSDiags) {
19323 if (LHSResult.Failed)
19324 return Info.noteSideEffect();
19333 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
19334 Success(LHSAsBool, E, LHSResult.Val);
19338 LHSResult.Failed =
true;
19342 if (!Info.noteSideEffect())
19348 SuppressRHSDiags =
true;
19357 if (LHSResult.Failed && !Info.noteFailure())
19368 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
19370 uint64_t Offset64 = Offset.getQuantity();
19371 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
19373 : Offset64 + Index64);
19376bool DataRecursiveIntBinOpEvaluator::
19377 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
19380 if (RHSResult.Failed)
19387 bool lhsResult, rhsResult;
19402 if (rhsResult == (E->
getOpcode() == BO_LOr))
19413 if (LHSResult.Failed || RHSResult.Failed)
19416 const APValue &LHSVal = LHSResult.Val;
19417 const APValue &RHSVal = RHSResult.Val;
19441 if (!LHSExpr || !RHSExpr)
19443 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19444 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19445 if (!LHSAddrExpr || !RHSAddrExpr)
19470void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
19471 Job &job = Queue.back();
19473 switch (job.Kind) {
19474 case Job::AnyExprKind: {
19475 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
19476 if (shouldEnqueue(Bop)) {
19477 job.Kind = Job::BinOpKind;
19478 enqueue(Bop->getLHS());
19483 EvaluateExpr(job.E,
Result);
19488 case Job::BinOpKind: {
19490 bool SuppressRHSDiags =
false;
19491 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
19495 if (SuppressRHSDiags)
19496 job.startSpeculativeEval(Info);
19497 job.LHSResult.swap(
Result);
19498 job.Kind = Job::BinOpVisitedLHSKind;
19503 case Job::BinOpVisitedLHSKind: {
19507 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
19513 llvm_unreachable(
"Invalid Job::Kind!");
19517enum class CmpResult {
19526template <
class SuccessCB,
class AfterCB>
19529 SuccessCB &&
Success, AfterCB &&DoAfter) {
19534 "unsupported binary expression evaluation");
19536 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
19550 if (!LHSOK && !Info.noteFailure())
19555 return Success(CmpResult::Less, E);
19557 return Success(CmpResult::Greater, E);
19558 return Success(CmpResult::Equal, E);
19562 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
19563 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
19566 if (!LHSOK && !Info.noteFailure())
19571 return Success(CmpResult::Less, E);
19573 return Success(CmpResult::Greater, E);
19574 return Success(CmpResult::Equal, E);
19578 ComplexValue LHS, RHS;
19587 LHS.makeComplexFloat();
19588 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
19593 if (!LHSOK && !Info.noteFailure())
19599 RHS.makeComplexFloat();
19600 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
19604 if (LHS.isComplexFloat()) {
19605 APFloat::cmpResult CR_r =
19606 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
19607 APFloat::cmpResult CR_i =
19608 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
19609 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
19610 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19612 assert(IsEquality &&
"invalid complex comparison");
19613 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
19614 LHS.getComplexIntImag() == RHS.getComplexIntImag();
19615 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19621 APFloat RHS(0.0), LHS(0.0);
19624 if (!LHSOK && !Info.noteFailure())
19631 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
19632 if (!Info.InConstantContext &&
19633 APFloatCmpResult == APFloat::cmpUnordered &&
19636 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
19639 auto GetCmpRes = [&]() {
19640 switch (APFloatCmpResult) {
19641 case APFloat::cmpEqual:
19642 return CmpResult::Equal;
19643 case APFloat::cmpLessThan:
19644 return CmpResult::Less;
19645 case APFloat::cmpGreaterThan:
19646 return CmpResult::Greater;
19647 case APFloat::cmpUnordered:
19648 return CmpResult::Unordered;
19650 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
19652 return Success(GetCmpRes(), E);
19656 LValue LHSValue, RHSValue;
19659 if (!LHSOK && !Info.noteFailure())
19670 if (Info.checkingPotentialConstantExpression() &&
19671 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19673 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
19674 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19675 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19676 Info.FFDiag(E, DiagID)
19683 return DiagComparison(
19684 diag::note_constexpr_pointer_comparison_unspecified);
19690 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
19691 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
19692 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
19706 return DiagComparison(diag::note_constexpr_literal_comparison);
19708 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
19713 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
19717 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
19719 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19721 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
19723 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19729 return DiagComparison(
19730 diag::note_constexpr_pointer_comparison_zero_sized);
19731 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
19732 return DiagComparison(
19733 diag::note_constexpr_pointer_comparison_unspecified);
19735 return Success(CmpResult::Unequal, E);
19738 CharUnits LHSOffset = LHSValue.getLValueOffset();
19739 CharUnits RHSOffset = RHSValue.getLValueOffset();
19741 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19742 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19752 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
19753 bool WasArrayIndex;
19756 :
getType(LHSValue.Base).getNonReferenceType(),
19757 LHSDesignator, RHSDesignator, WasArrayIndex);
19764 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
19765 Mismatch < RHSDesignator.Entries.size()) {
19766 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
19767 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
19769 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
19771 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19772 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
19775 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19776 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
19781 diag::note_constexpr_pointer_comparison_differing_access)
19789 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
19792 assert(PtrSize <= 64 &&
"Unexpected pointer width");
19793 uint64_t Mask = ~0ULL >> (64 - PtrSize);
19794 CompareLHS &= Mask;
19795 CompareRHS &= Mask;
19800 if (!LHSValue.Base.
isNull() && IsRelational) {
19804 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
19805 uint64_t OffsetLimit = Size.getQuantity();
19806 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
19810 if (CompareLHS < CompareRHS)
19811 return Success(CmpResult::Less, E);
19812 if (CompareLHS > CompareRHS)
19813 return Success(CmpResult::Greater, E);
19814 return Success(CmpResult::Equal, E);
19818 assert(IsEquality &&
"unexpected member pointer operation");
19821 MemberPtr LHSValue, RHSValue;
19824 if (!LHSOK && !Info.noteFailure())
19832 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
19833 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19834 << LHSValue.getDecl();
19837 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
19838 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19839 << RHSValue.getDecl();
19846 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
19847 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
19848 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19853 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
19854 if (MD->isVirtual())
19855 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19856 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
19857 if (MD->isVirtual())
19858 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19864 bool Equal = LHSValue == RHSValue;
19865 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19870 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
19878 return Success(CmpResult::Equal, E);
19883 llvm::FoldingSetNodeID LID, RID;
19893 return Success(CmpResult::Equal, E);
19895 return Success(CmpResult::Unequal, E);
19905 Info.Ctx.CompCategories.getInfoForType(E->
getType());
19914 ConstantExprKind::Normal);
19917bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
19921 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19924 case CmpResult::Unequal:
19925 llvm_unreachable(
"should never produce Unequal for three-way comparison");
19926 case CmpResult::Less:
19927 CCR = ComparisonCategoryResult::Less;
19929 case CmpResult::Equal:
19930 CCR = ComparisonCategoryResult::Equal;
19932 case CmpResult::Greater:
19933 CCR = ComparisonCategoryResult::Greater;
19935 case CmpResult::Unordered:
19936 CCR = ComparisonCategoryResult::Unordered;
19942 return ExprEvaluatorBaseTy::VisitBinCmp(E);
19946bool RecordExprEvaluator::VisitTypeTraitExpr(
const TypeTraitExpr *E) {
19951 "expected a strong_ordering type trait with a stored value");
19958bool RecordExprEvaluator::VisitCXXParenListInitExpr(
19959 const CXXParenListInitExpr *E) {
19960 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
19963bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19968 if (!Info.noteFailure())
19972 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
19973 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
19977 "DataRecursiveIntBinOpEvaluator should have handled integral types");
19982 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19983 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
19984 "should only produce Unequal for equality comparisons");
19985 bool IsEqual = CR == CmpResult::Equal,
19986 IsLess = CR == CmpResult::Less,
19987 IsGreater = CR == CmpResult::Greater;
19991 llvm_unreachable(
"unsupported binary operator");
19994 return Success(IsEqual == (Op == BO_EQ), E);
19998 return Success(IsGreater, E);
20000 return Success(IsEqual || IsLess, E);
20002 return Success(IsEqual || IsGreater, E);
20006 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20015 LValue LHSValue, RHSValue;
20018 if (!LHSOK && !Info.noteFailure())
20027 if (Info.checkingPotentialConstantExpression() &&
20028 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
20031 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
20032 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
20034 auto DiagArith = [&](
unsigned DiagID) {
20035 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
20036 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
20037 Info.FFDiag(E, DiagID) << LHS << RHS;
20038 if (LHSExpr && LHSExpr == RHSExpr)
20040 diag::note_constexpr_repeated_literal_eval)
20045 if (!LHSExpr || !RHSExpr)
20046 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
20049 return DiagArith(diag::note_constexpr_literal_arith);
20051 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
20052 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
20053 if (!LHSAddrExpr || !RHSAddrExpr)
20061 CharUnits LHSOffset = LHSValue.getLValueOffset();
20062 CharUnits RHSOffset = RHSValue.getLValueOffset();
20064 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
20065 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
20071 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
20074 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
20079 CharUnits ElementSize;
20086 if (ElementSize.
isZero()) {
20087 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
20104 APSInt TrueResult = (LHS - RHS) / ElemSize;
20107 if (
Result.extend(65) != TrueResult &&
20113 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20118bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
20119 const UnaryExprOrTypeTraitExpr *E) {
20121 case UETT_PreferredAlignOf:
20122 case UETT_AlignOf: {
20131 case UETT_PtrAuthTypeDiscriminator: {
20137 case UETT_VecStep: {
20141 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
20153 case UETT_DataSizeOf:
20154 case UETT_SizeOf: {
20158 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
20169 case UETT_OpenMPRequiredSimdAlign:
20172 Info.Ctx.toCharUnitsFromBits(
20176 case UETT_VectorElements: {
20180 if (
const auto *VT = Ty->
getAs<VectorType>())
20184 if (Info.InConstantContext)
20185 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
20190 case UETT_CountOf: {
20196 if (
const auto *CAT =
20206 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
20208 if (VAT->getElementType()->isArrayType()) {
20211 if (!VAT->getSizeExpr()) {
20216 std::optional<APSInt> Res =
20217 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
20222 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
20223 Res->getZExtValue()};
20235 llvm_unreachable(
"unknown expr/type trait");
20238bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
20239 Info.Ctx.recordOffsetOfEvaluation(OOE);
20245 for (
unsigned i = 0; i != n; ++i) {
20253 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
20257 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
20260 if (IdxResult.isNegative() || IdxResult.getActiveBits() > 63)
20262 int64_t IdxVal = IdxResult.getExtValue();
20265 ElemSize > std::numeric_limits<int64_t>::max() / IdxVal)
20266 return Error(OOE, diag::note_constexpr_offsetof_overflow);
20267 int64_t Offset = IdxVal * ElemSize;
20268 if (
Result.getQuantity() > std::numeric_limits<int64_t>::max() - Offset)
20269 return Error(OOE, diag::note_constexpr_offsetof_overflow);
20275 FieldDecl *MemberDecl = ON.
getField();
20280 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
20282 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
20289 llvm_unreachable(
"dependent __builtin_offsetof");
20292 CXXBaseSpecifier *BaseSpec = ON.
getBase();
20301 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
20304 CurrentType = BaseSpec->
getType();
20318bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20338 if (Info.checkingForUndefinedBehavior())
20339 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20340 diag::warn_integer_constant_overflow)
20368bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20370 QualType DestType = E->
getType();
20371 QualType SrcType = SubExpr->
getType();
20374 case CK_BaseToDerived:
20375 case CK_DerivedToBase:
20376 case CK_UncheckedDerivedToBase:
20379 case CK_ArrayToPointerDecay:
20380 case CK_FunctionToPointerDecay:
20381 case CK_NullToPointer:
20382 case CK_NullToMemberPointer:
20383 case CK_BaseToDerivedMemberPointer:
20384 case CK_DerivedToBaseMemberPointer:
20385 case CK_ReinterpretMemberPointer:
20386 case CK_ConstructorConversion:
20387 case CK_IntegralToPointer:
20389 case CK_VectorSplat:
20390 case CK_IntegralToFloating:
20391 case CK_FloatingCast:
20392 case CK_CPointerToObjCPointerCast:
20393 case CK_BlockPointerToObjCPointerCast:
20394 case CK_AnyPointerToBlockPointerCast:
20395 case CK_ObjCObjectLValueCast:
20396 case CK_FloatingRealToComplex:
20397 case CK_FloatingComplexToReal:
20398 case CK_FloatingComplexCast:
20399 case CK_FloatingComplexToIntegralComplex:
20400 case CK_IntegralRealToComplex:
20401 case CK_IntegralComplexCast:
20402 case CK_IntegralComplexToFloatingComplex:
20403 case CK_BuiltinFnToFnPtr:
20404 case CK_ZeroToOCLOpaqueType:
20405 case CK_NonAtomicToAtomic:
20406 case CK_AddressSpaceConversion:
20407 case CK_IntToOCLSampler:
20408 case CK_FloatingToFixedPoint:
20409 case CK_FixedPointToFloating:
20410 case CK_FixedPointCast:
20411 case CK_IntegralToFixedPoint:
20412 case CK_MatrixCast:
20413 case CK_HLSLAggregateSplatCast:
20414 llvm_unreachable(
"invalid cast kind for integral value");
20417 case CK_LValueBitCast:
20418 case CK_ARCProduceObject:
20419 case CK_ARCConsumeObject:
20420 case CK_ARCReclaimReturnedObject:
20421 case CK_ARCExtendBlockObject:
20422 case CK_CopyAndAutoreleaseBlockObject:
20425 case CK_UserDefinedConversion:
20426 case CK_LValueToRValue:
20427 case CK_AtomicToNonAtomic:
20429 case CK_LValueToRValueBitCast:
20430 case CK_HLSLArrayRValue:
20431 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20435 if (!
Evaluate(Src, Info, SubExpr))
20438 if (!handleRValueToRValueBitCast(Info, Dst, Src, E))
20443 case CK_MemberPointerToBoolean:
20444 case CK_PointerToBoolean:
20445 case CK_IntegralToBoolean:
20446 case CK_FloatingToBoolean:
20447 case CK_BooleanToSignedIntegral:
20448 case CK_FloatingComplexToBoolean:
20449 case CK_IntegralComplexToBoolean: {
20454 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
20456 return Success(IntResult, E);
20459 case CK_FixedPointToIntegral: {
20460 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
20464 llvm::APSInt
Result = Src.convertToInt(
20465 Info.Ctx.getIntWidth(DestType),
20472 case CK_FixedPointToBoolean: {
20475 if (!
Evaluate(Val, Info, SubExpr))
20480 case CK_IntegralCast: {
20481 if (!Visit(SubExpr))
20491 if (
Result.isAddrLabelDiff()) {
20492 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
20493 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
20496 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
20499 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
20511 if (!ED->isFixed()) {
20515 ED->getValueRange(
Max,
Min);
20518 if (ED->getNumNegativeBits() &&
20519 (
Max.slt(
Result.getInt().getSExtValue()) ||
20520 Min.sgt(
Result.getInt().getSExtValue())))
20521 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20522 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
20523 <<
Max.getSExtValue() << ED;
20524 else if (!ED->getNumNegativeBits() &&
20525 Max.ult(
Result.getInt().getZExtValue()))
20526 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20527 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
20528 <<
Max.getZExtValue() << ED;
20536 case CK_PointerToIntegral: {
20537 CCEDiag(E, diag::note_constexpr_invalid_cast_ptrtoint)
20538 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
20545 if (LV.getLValueBase()) {
20546 CCEDiag(E, diag::note_constexpr_has_lvalue) << E->
getSourceRange();
20551 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
20554 LV.Designator.setInvalid();
20562 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
20563 llvm_unreachable(
"Can't cast this!");
20568 case CK_IntegralComplexToReal: {
20572 return Success(
C.getComplexIntReal(), E);
20575 case CK_FloatingToIntegral: {
20585 case CK_HLSLVectorTruncation: {
20591 case CK_HLSLMatrixTruncation: {
20597 case CK_HLSLElementwiseCast: {
20610 return Success(ResultVal, E);
20614 llvm_unreachable(
"unknown cast resulting in integral value");
20617bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20622 if (!LV.isComplexInt())
20624 return Success(LV.getComplexIntReal(), E);
20630bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20635 if (!LV.isComplexInt())
20637 return Success(LV.getComplexIntImag(), E);
20644bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
20648bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
20652bool IntExprEvaluator::VisitConceptSpecializationExpr(
20653 const ConceptSpecializationExpr *E) {
20657bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
20661bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20671 if (!
Result.isFixedPoint())
20674 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
20688bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20690 QualType DestType = E->
getType();
20692 "Expected destination type to be a fixed point type");
20693 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
20696 case CK_FixedPointCast: {
20697 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20701 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
20703 if (Info.checkingForUndefinedBehavior())
20704 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20705 diag::warn_fixedpoint_constant_overflow)
20712 case CK_IntegralToFixedPoint: {
20718 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
20719 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20722 if (Info.checkingForUndefinedBehavior())
20723 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20724 diag::warn_fixedpoint_constant_overflow)
20725 << IntResult.toString() << E->
getType();
20730 return Success(IntResult, E);
20732 case CK_FloatingToFixedPoint: {
20738 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
20739 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20742 if (Info.checkingForUndefinedBehavior())
20743 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20744 diag::warn_fixedpoint_constant_overflow)
20753 case CK_LValueToRValue:
20754 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20760bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20762 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20764 const Expr *LHS = E->
getLHS();
20765 const Expr *RHS = E->
getRHS();
20767 Info.Ctx.getFixedPointSemantics(E->
getType());
20769 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
20772 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
20776 bool OpOverflow =
false, ConversionOverflow =
false;
20777 APFixedPoint
Result(LHSFX.getSemantics());
20780 Result = LHSFX.add(RHSFX, &OpOverflow)
20781 .convert(ResultFXSema, &ConversionOverflow);
20785 Result = LHSFX.sub(RHSFX, &OpOverflow)
20786 .convert(ResultFXSema, &ConversionOverflow);
20790 Result = LHSFX.mul(RHSFX, &OpOverflow)
20791 .convert(ResultFXSema, &ConversionOverflow);
20795 if (RHSFX.getValue() == 0) {
20796 Info.FFDiag(E, diag::note_expr_divide_by_zero);
20799 Result = LHSFX.div(RHSFX, &OpOverflow)
20800 .convert(ResultFXSema, &ConversionOverflow);
20806 llvm::APSInt RHSVal = RHSFX.getValue();
20809 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
20810 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
20814 if (RHSVal.isNegative())
20815 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
20816 else if (Amt != RHSVal)
20817 Info.CCEDiag(E, diag::note_constexpr_large_shift)
20818 << RHSVal << E->
getType() << ShiftBW;
20821 Result = LHSFX.shl(Amt, &OpOverflow);
20823 Result = LHSFX.shr(Amt, &OpOverflow);
20829 if (OpOverflow || ConversionOverflow) {
20830 if (Info.checkingForUndefinedBehavior())
20831 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20832 diag::warn_fixedpoint_constant_overflow)
20845class FloatExprEvaluator
20846 :
public ExprEvaluatorBase<FloatExprEvaluator> {
20849 FloatExprEvaluator(EvalInfo &info, APFloat &result)
20850 : ExprEvaluatorBaseTy(
info),
Result(result) {}
20857 bool ZeroInitialization(
const Expr *E) {
20858 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20862 bool VisitCallExpr(
const CallExpr *E);
20864 bool VisitUnaryOperator(
const UnaryOperator *E);
20865 bool VisitBinaryOperator(
const BinaryOperator *E);
20866 bool VisitFloatingLiteral(
const FloatingLiteral *E);
20867 bool VisitCastExpr(
const CastExpr *E);
20869 bool VisitUnaryReal(
const UnaryOperator *E);
20870 bool VisitUnaryImag(
const UnaryOperator *E);
20879 return FloatExprEvaluator(Info,
Result).Visit(E);
20886 llvm::APFloat &
Result) {
20891 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
20897 fill = llvm::APInt(32, 0);
20898 else if (S->
getString().getAsInteger(0, fill))
20901 if (Context.getTargetInfo().isNan2008()) {
20903 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20905 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20913 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20915 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20921bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20922 if (!IsConstantEvaluatedBuiltinCall(E))
20923 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20927 switch (BuiltinOp) {
20931 case Builtin::BI__builtin_huge_val:
20932 case Builtin::BI__builtin_huge_valf:
20933 case Builtin::BI__builtin_huge_vall:
20934 case Builtin::BI__builtin_huge_valf16:
20935 case Builtin::BI__builtin_huge_valf128:
20936 case Builtin::BI__builtin_inf:
20937 case Builtin::BI__builtin_inff:
20938 case Builtin::BI__builtin_infl:
20939 case Builtin::BI__builtin_inff16:
20940 case Builtin::BI__builtin_inff128: {
20941 const llvm::fltSemantics &Sem =
20942 Info.Ctx.getFloatTypeSemantics(E->
getType());
20943 Result = llvm::APFloat::getInf(Sem);
20947 case Builtin::BI__builtin_nans:
20948 case Builtin::BI__builtin_nansf:
20949 case Builtin::BI__builtin_nansl:
20950 case Builtin::BI__builtin_nansf16:
20951 case Builtin::BI__builtin_nansf128:
20957 case Builtin::BI__builtin_nan:
20958 case Builtin::BI__builtin_nanf:
20959 case Builtin::BI__builtin_nanl:
20960 case Builtin::BI__builtin_nanf16:
20961 case Builtin::BI__builtin_nanf128:
20969 case Builtin::BI__builtin_elementwise_abs:
20970 case Builtin::BI__builtin_fabs:
20971 case Builtin::BI__builtin_fabsf:
20972 case Builtin::BI__builtin_fabsl:
20973 case Builtin::BI__builtin_fabsf128:
20982 if (
Result.isNegative())
20986 case Builtin::BI__arithmetic_fence:
20993 case Builtin::BI__builtin_copysign:
20994 case Builtin::BI__builtin_copysignf:
20995 case Builtin::BI__builtin_copysignl:
20996 case Builtin::BI__builtin_copysignf128: {
21005 case Builtin::BI__builtin_fmax:
21006 case Builtin::BI__builtin_fmaxf:
21007 case Builtin::BI__builtin_fmaxl:
21008 case Builtin::BI__builtin_fmaxf16:
21009 case Builtin::BI__builtin_fmaxf128: {
21018 case Builtin::BI__builtin_fmin:
21019 case Builtin::BI__builtin_fminf:
21020 case Builtin::BI__builtin_fminl:
21021 case Builtin::BI__builtin_fminf16:
21022 case Builtin::BI__builtin_fminf128: {
21031 case Builtin::BI__builtin_fmaximum_num:
21032 case Builtin::BI__builtin_fmaximum_numf:
21033 case Builtin::BI__builtin_fmaximum_numl:
21034 case Builtin::BI__builtin_fmaximum_numf16:
21035 case Builtin::BI__builtin_fmaximum_numf128: {
21044 case Builtin::BI__builtin_fminimum_num:
21045 case Builtin::BI__builtin_fminimum_numf:
21046 case Builtin::BI__builtin_fminimum_numl:
21047 case Builtin::BI__builtin_fminimum_numf16:
21048 case Builtin::BI__builtin_fminimum_numf128: {
21057 case Builtin::BI__builtin_elementwise_fma: {
21062 APFloat SourceY(0.), SourceZ(0.);
21068 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
21072 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
21079 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
21085bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
21097bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
21107 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
21108 Result = llvm::APFloat::getZero(Sem);
21112bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
21114 default:
return Error(E);
21128bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
21130 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
21134 if (!LHSOK && !Info.noteFailure())
21140bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
21145bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
21150 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21152 case CK_HLSLAggregateSplatCast:
21153 llvm_unreachable(
"invalid cast kind for floating value");
21155 case CK_IntegralToFloating: {
21158 Info.Ctx.getLangOpts());
21164 case CK_FixedPointToFloating: {
21165 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
21169 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
21173 case CK_FloatingCast: {
21174 if (!Visit(SubExpr))
21180 case CK_FloatingComplexToReal: {
21184 Result =
V.getComplexFloatReal();
21187 case CK_HLSLVectorTruncation: {
21193 case CK_HLSLMatrixTruncation: {
21199 case CK_HLSLElementwiseCast: {
21213 return Success(ResultVal, E);
21223class ComplexExprEvaluator
21224 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
21228 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
21236 bool ZeroInitialization(
const Expr *E);
21242 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
21243 bool VisitCastExpr(
const CastExpr *E);
21244 bool VisitBinaryOperator(
const BinaryOperator *E);
21245 bool VisitUnaryOperator(
const UnaryOperator *E);
21246 bool VisitInitListExpr(
const InitListExpr *E);
21247 bool VisitCallExpr(
const CallExpr *E);
21255 return ComplexExprEvaluator(Info,
Result).Visit(E);
21258bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
21259 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
21261 Result.makeComplexFloat();
21262 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
21266 Result.makeComplexInt();
21267 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
21274bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
21278 Result.makeComplexFloat();
21287 "Unexpected imaginary literal.");
21289 Result.makeComplexInt();
21294 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
21299bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
21303 case CK_BaseToDerived:
21304 case CK_DerivedToBase:
21305 case CK_UncheckedDerivedToBase:
21308 case CK_ArrayToPointerDecay:
21309 case CK_FunctionToPointerDecay:
21310 case CK_NullToPointer:
21311 case CK_NullToMemberPointer:
21312 case CK_BaseToDerivedMemberPointer:
21313 case CK_DerivedToBaseMemberPointer:
21314 case CK_MemberPointerToBoolean:
21315 case CK_ReinterpretMemberPointer:
21316 case CK_ConstructorConversion:
21317 case CK_IntegralToPointer:
21318 case CK_PointerToIntegral:
21319 case CK_PointerToBoolean:
21321 case CK_VectorSplat:
21322 case CK_IntegralCast:
21323 case CK_BooleanToSignedIntegral:
21324 case CK_IntegralToBoolean:
21325 case CK_IntegralToFloating:
21326 case CK_FloatingToIntegral:
21327 case CK_FloatingToBoolean:
21328 case CK_FloatingCast:
21329 case CK_CPointerToObjCPointerCast:
21330 case CK_BlockPointerToObjCPointerCast:
21331 case CK_AnyPointerToBlockPointerCast:
21332 case CK_ObjCObjectLValueCast:
21333 case CK_FloatingComplexToReal:
21334 case CK_FloatingComplexToBoolean:
21335 case CK_IntegralComplexToReal:
21336 case CK_IntegralComplexToBoolean:
21337 case CK_ARCProduceObject:
21338 case CK_ARCConsumeObject:
21339 case CK_ARCReclaimReturnedObject:
21340 case CK_ARCExtendBlockObject:
21341 case CK_CopyAndAutoreleaseBlockObject:
21342 case CK_BuiltinFnToFnPtr:
21343 case CK_ZeroToOCLOpaqueType:
21344 case CK_NonAtomicToAtomic:
21345 case CK_AddressSpaceConversion:
21346 case CK_IntToOCLSampler:
21347 case CK_FloatingToFixedPoint:
21348 case CK_FixedPointToFloating:
21349 case CK_FixedPointCast:
21350 case CK_FixedPointToBoolean:
21351 case CK_FixedPointToIntegral:
21352 case CK_IntegralToFixedPoint:
21353 case CK_MatrixCast:
21354 case CK_HLSLVectorTruncation:
21355 case CK_HLSLMatrixTruncation:
21356 case CK_HLSLElementwiseCast:
21357 case CK_HLSLAggregateSplatCast:
21358 llvm_unreachable(
"invalid cast kind for complex value");
21360 case CK_LValueToRValue:
21361 case CK_AtomicToNonAtomic:
21363 case CK_LValueToRValueBitCast:
21364 case CK_HLSLArrayRValue:
21365 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21368 case CK_LValueBitCast:
21369 case CK_UserDefinedConversion:
21372 case CK_FloatingRealToComplex: {
21377 Result.makeComplexFloat();
21382 case CK_FloatingComplexCast: {
21386 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21394 case CK_FloatingComplexToIntegralComplex: {
21398 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21401 Result.makeComplexInt();
21408 case CK_IntegralRealToComplex: {
21413 Result.makeComplexInt();
21414 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
21418 case CK_IntegralComplexCast: {
21422 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21431 case CK_IntegralComplexToFloatingComplex: {
21436 Info.Ctx.getLangOpts());
21437 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21440 Result.makeComplexFloat();
21442 To,
Result.FloatReal) &&
21448 llvm_unreachable(
"unknown cast resulting in complex value");
21454 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
21455 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
21456 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
21457 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
21458 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
21459 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
21460 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
21461 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
21462 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
21463 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
21464 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
21465 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
21466 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
21467 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
21468 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
21469 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
21470 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
21471 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
21472 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
21473 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
21474 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
21475 0xcd, 0x1a, 0x41, 0x1c};
21477 return GFInv[Byte];
21482 unsigned NumBitsInByte = 8;
21485 for (
uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21487 AQword.lshr((7 -
static_cast<int32_t>(BitIdx)) * NumBitsInByte)
21494 Product = AByte & XByte;
21499 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
21500 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
21503 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
21504 RetByte |= (Temp ^ Parity) << BitIdx;
21514 unsigned NumBitsInByte = 8;
21515 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21516 if ((BByte >> BitIdx) & 0x1) {
21517 TWord = TWord ^ (AByte << BitIdx);
21525 for (
int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
21526 if ((TWord >> BitIdx) & 0x1) {
21527 TWord = TWord ^ (0x11B << (BitIdx - 8));
21530 return (TWord & 0xFF);
21534 APFloat &ResR, APFloat &ResI) {
21540 APFloat AC = A *
C;
21541 APFloat BD = B * D;
21542 APFloat AD = A * D;
21543 APFloat BC = B *
C;
21546 if (ResR.isNaN() && ResI.isNaN()) {
21547 bool Recalc =
false;
21548 if (A.isInfinity() || B.isInfinity()) {
21549 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21551 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21554 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21556 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21559 if (
C.isInfinity() || D.isInfinity()) {
21560 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21562 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21565 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21567 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21570 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
21571 BC.isInfinity())) {
21573 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21575 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21577 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21579 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21583 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
21584 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
21590 APFloat &ResR, APFloat &ResI) {
21597 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
21598 if (MaxCD.isFinite()) {
21599 DenomLogB =
ilogb(MaxCD);
21600 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
21601 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
21603 APFloat Denom =
C *
C + D * D;
21605 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21607 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21608 if (ResR.isNaN() && ResI.isNaN()) {
21609 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
21610 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
21611 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
21612 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
21614 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21616 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21618 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
21619 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
21620 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
21621 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21623 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21625 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
21626 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
21633 APSInt NormAmt = Amount;
21634 unsigned BitWidth =
Value.getBitWidth();
21635 unsigned AmtBitWidth = NormAmt.getBitWidth();
21636 if (BitWidth == 1) {
21638 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
21639 }
else if (BitWidth == 2) {
21644 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
21647 if (AmtBitWidth > BitWidth) {
21648 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
21650 Divisor = llvm::APInt(BitWidth, BitWidth);
21651 if (AmtBitWidth < BitWidth) {
21652 NormAmt = NormAmt.extend(BitWidth);
21657 if (NormAmt.isSigned()) {
21658 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
21659 if (NormAmt.isNegative()) {
21660 APSInt SignedDivisor(Divisor,
false);
21661 NormAmt += SignedDivisor;
21664 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
21671bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
21673 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
21677 bool LHSReal =
false, RHSReal =
false;
21685 Result.makeComplexFloat();
21689 LHSOK = Visit(E->
getLHS());
21691 if (!LHSOK && !Info.noteFailure())
21697 APFloat &Real = RHS.FloatReal;
21700 RHS.makeComplexFloat();
21701 RHS.FloatImag =
APFloat(Real.getSemantics());
21705 assert(!(LHSReal && RHSReal) &&
21706 "Cannot have both operands of a complex operation be real.");
21708 default:
return Error(E);
21710 if (
Result.isComplexFloat()) {
21711 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
21712 APFloat::rmNearestTiesToEven);
21714 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21716 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
21717 APFloat::rmNearestTiesToEven);
21719 Result.getComplexIntReal() += RHS.getComplexIntReal();
21720 Result.getComplexIntImag() += RHS.getComplexIntImag();
21724 if (
Result.isComplexFloat()) {
21725 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
21726 APFloat::rmNearestTiesToEven);
21728 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21729 Result.getComplexFloatImag().changeSign();
21730 }
else if (!RHSReal) {
21731 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
21732 APFloat::rmNearestTiesToEven);
21735 Result.getComplexIntReal() -= RHS.getComplexIntReal();
21736 Result.getComplexIntImag() -= RHS.getComplexIntImag();
21740 if (
Result.isComplexFloat()) {
21745 ComplexValue LHS =
Result;
21746 APFloat &A = LHS.getComplexFloatReal();
21747 APFloat &B = LHS.getComplexFloatImag();
21748 APFloat &
C = RHS.getComplexFloatReal();
21749 APFloat &D = RHS.getComplexFloatImag();
21753 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
21761 }
else if (RHSReal) {
21773 ComplexValue LHS =
Result;
21774 Result.getComplexIntReal() =
21775 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
21776 LHS.getComplexIntImag() * RHS.getComplexIntImag());
21777 Result.getComplexIntImag() =
21778 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
21779 LHS.getComplexIntImag() * RHS.getComplexIntReal());
21783 if (
Result.isComplexFloat()) {
21788 ComplexValue LHS =
Result;
21789 APFloat &A = LHS.getComplexFloatReal();
21790 APFloat &B = LHS.getComplexFloatImag();
21791 APFloat &
C = RHS.getComplexFloatReal();
21792 APFloat &D = RHS.getComplexFloatImag();
21806 B = APFloat::getZero(A.getSemantics());
21811 ComplexValue LHS =
Result;
21812 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
21813 RHS.getComplexIntImag() * RHS.getComplexIntImag();
21815 return Error(E, diag::note_expr_divide_by_zero);
21817 Result.getComplexIntReal() =
21818 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
21819 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
21820 Result.getComplexIntImag() =
21821 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
21822 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
21830bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
21844 if (
Result.isComplexFloat()) {
21845 Result.getComplexFloatReal().changeSign();
21846 Result.getComplexFloatImag().changeSign();
21849 Result.getComplexIntReal() = -
Result.getComplexIntReal();
21850 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21854 if (
Result.isComplexFloat())
21855 Result.getComplexFloatImag().changeSign();
21857 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21862bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
21865 Result.makeComplexFloat();
21871 Result.makeComplexInt();
21879 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
21882bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
21883 if (!IsConstantEvaluatedBuiltinCall(E))
21884 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21887 case Builtin::BI__builtin_complex:
21888 Result.makeComplexFloat();
21906class AtomicExprEvaluator :
21907 public ExprEvaluatorBase<AtomicExprEvaluator> {
21908 const LValue *
This;
21911 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
21919 bool ZeroInitialization(
const Expr *E) {
21920 ImplicitValueInitExpr VIE(
21928 bool VisitCastExpr(
const CastExpr *E) {
21931 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21932 case CK_NullToPointer:
21934 return ZeroInitialization(E);
21935 case CK_NonAtomicToAtomic:
21947 return AtomicExprEvaluator(Info,
This,
Result).Visit(E);
21956class VoidExprEvaluator
21957 :
public ExprEvaluatorBase<VoidExprEvaluator> {
21959 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
21963 bool ZeroInitialization(
const Expr *E) {
return true; }
21965 bool VisitCastExpr(
const CastExpr *E) {
21968 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21975 bool VisitCallExpr(
const CallExpr *E) {
21976 if (!IsConstantEvaluatedBuiltinCall(E))
21977 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21980 case Builtin::BI__assume:
21981 case Builtin::BI__builtin_assume:
21985 case Builtin::BI__builtin_operator_delete:
21988 case Builtin::BIstdc_memreverse8:
21989 case Builtin::BI__builtin_stdc_memreverse8: {
21993 uint64_t NElems = N.getZExtValue();
21999 if (!
Ptr.checkNullPointerForFoldAccess(Info, E,
AK_Assign) ||
22000 Ptr.Designator.Invalid)
22003 QualType CharTy =
Ptr.Designator.getType(Info.Ctx);
22004 uint64_t RemainingElems =
Ptr.Designator.validIndexAdjustments().second;
22005 if (NElems > RemainingElems) {
22007 Ptr.Designator.MostDerivedIsArrayElement
22008 ?
Ptr.Designator.Entries.back().getAsArrayIndex()
22011 APSInt::getUnsigned(llvm::SaturatingAdd(ArrayIndex, NElems - 1));
22012 Ptr.Designator.diagnosePointerArithmetic(Info, E, Index);
22024 for (uint64_t I = 0,
Half = NElems / 2; I <
Half; ++I) {
22042 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
22046bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
22048 if (Info.SpeculativeEvaluationDepth)
22052 if (!OperatorDelete
22053 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
22054 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
22064 if (
Pointer.Designator.Invalid)
22068 if (
Pointer.isNullPointer()) {
22072 if (!Info.getLangOpts().CPlusPlus20)
22073 Info.CCEDiag(E, diag::note_constexpr_new);
22079 E->
isArrayForm() ? DynAllocKind::ArrayNew : DynAllocKind::New);
22082 QualType AllocType =
Pointer.Base.getDynamicAllocType();
22088 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
22097 if (VirtualDelete &&
22099 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
22100 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
22107 (*Alloc)->Value, AllocType))
22110 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
22115 Info.FFDiag(E, diag::note_constexpr_double_delete);
22125 return VoidExprEvaluator(Info).Visit(E);
22137 if (E->
isGLValue() ||
T->isFunctionType()) {
22142 }
else if (
T->isVectorType()) {
22145 }
else if (
T->isConstantMatrixType()) {
22148 }
else if (
T->isIntegralOrEnumerationType()) {
22149 if (!IntExprEvaluator(Info,
Result).Visit(E))
22151 }
else if (
T->isMetaInfoType()) {
22154 }
else if (
T->hasPointerRepresentation()) {
22159 }
else if (
T->isRealFloatingType()) {
22160 llvm::APFloat F(0.0);
22164 }
else if (
T->isAnyComplexType()) {
22169 }
else if (
T->isFixedPointType()) {
22170 if (!FixedPointExprEvaluator(Info,
Result).Visit(E))
return false;
22171 }
else if (
T->isMemberPointerType()) {
22177 }
else if (
T->isArrayType()) {
22180 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
22184 }
else if (
T->isRecordType()) {
22187 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
22191 }
else if (
T->isVoidType()) {
22192 if (!Info.getLangOpts().CPlusPlus11)
22193 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
22197 }
else if (
T->isAtomicType()) {
22198 QualType Unqual =
T.getAtomicUnqualifiedType();
22202 E, Unqual, ScopeKind::FullExpression, LV);
22210 }
else if (Info.getLangOpts().CPlusPlus11) {
22211 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
22214 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
22225 const Expr *E,
bool AllowNonLiteralTypes) {
22241 if (
T->isArrayType())
22243 else if (
T->isRecordType())
22245 else if (
T->isAtomicType()) {
22246 QualType Unqual =
T.getAtomicUnqualifiedType();
22260 assert(!Info.Ctx.getLangOpts().EnableNewConstInterp);
22274 LV.setFrom(Info.Ctx,
Result);
22281 ConstantExprKind::Normal) &&
22289 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
22291 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
22296 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
22302 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
22308 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
22314 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
22315 if (CE->hasAPValueResult()) {
22316 APValue APV = CE->getAPValueResult();
22318 Result = std::move(APV);
22390 bool InConstantContext) {
22392 "Expression evaluator can't be called on a dependent expression.");
22406 Info.InConstantContext = InConstantContext;
22407 return ::EvaluateAsRValue(E,
Result, Ctx, Info);
22416 bool InConstantContext)
const {
22417 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
22418 return ::doEvaluateAsRValue(
this,
Result, Ctx,
nullptr,
22419 InConstantContext);
22425 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsMandatedConstantRValue");
22426 return ::doEvaluateAsRValue(
this,
Result, Ctx, &SProxy,
22431 bool InConstantContext)
const {
22433 "Expression evaluator can't be called on a dependent expression.");
22434 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
22442 bool InConstantContext)
const {
22444 "Expression evaluator can't be called on a dependent expression.");
22446 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
22448 if (!
getType()->isIntegralOrEnumerationType())
22462 if (!
Result.Val.isInt() ||
22468 EvalInfo Info(Ctx,
nullptr,
Result,
22470 Info.InConstantContext = InConstantContext;
22471 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
22476 bool InConstantContext)
const {
22478 "Expression evaluator can't be called on a dependent expression.");
22479 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
22481 if (!
getType()->isFixedPointType())
22492 if (!
Result.Val.isFixedPoint() ||
22499 EvalInfo Info(Ctx,
nullptr,
Result,
22501 Info.InConstantContext = InConstantContext;
22502 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
22507 bool InConstantContext)
const {
22509 "Expression evaluator can't be called on a dependent expression.");
22511 if (!
getType()->isRealFloatingType())
22514 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
22526 bool InConstantContext)
const {
22528 "Expression evaluator can't be called on a dependent expression.");
22530 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
22540 Info.InConstantContext = InConstantContext;
22544 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
22545 Result.HasSideEffects ||
22548 ConstantExprKind::Normal, CheckedTemps))
22551 LV.moveInto(
Result.Val);
22559 bool IsConstantDestruction) {
22560 EvalInfo Info(Ctx, SProxy, EStatus,
22563 Info.setEvaluatingDecl(
Base, DestroyedValue,
22564 EvalInfo::EvaluatingDeclKind::Dtor);
22565 Info.InConstantContext = IsConstantDestruction;
22574 if (!Info.discardCleanups())
22575 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22584 "Expression evaluator can't be called on a dependent expression.");
22601 EvalInfo Info(Ctx, SProxy,
Result, EM);
22602 Info.InConstantContext =
true;
22606 if (Kind == ConstantExprKind::ClassTemplateArgument)
22622 FullExpressionRAII
Scope(Info);
22627 if (!Info.discardCleanups())
22628 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22630 if (
Result.HasSideEffects ||
22639 if (Kind == ConstantExprKind::ClassTemplateArgument &&
22642 Result.HasSideEffects)) {
22654 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
22655 return ::doEvaluateConstantExpr(
Result, Ctx,
nullptr,
this, Kind);
22662 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsMandatedConstantExpr");
22663 return ::doEvaluateConstantExpr(
Result, Ctx, &SProxy,
this, Kind);
22669 bool IsConstantInitialization) {
22671 "Expression evaluator can't be called on a dependent expression.");
22672 assert(VD &&
"Need a valid VarDecl");
22675 (IsConstantInitialization &&
22690 EvalInfo Info(Ctx, SProxy, EStatus, EvalMode);
22691 Info.setEvaluatingDecl(VD, EStatus.
Val);
22692 Info.InConstantContext = IsConstantInitialization;
22707 FullExpressionRAII
Scope(Info);
22716 Info.performLifetimeExtension();
22718 if (!Info.discardCleanups())
22719 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22722 ConstantExprKind::Normal) &&
22728 bool IsConstantInitialization)
const {
22729 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
22731 llvm::raw_string_ostream OS(Name);
22736 return ::doEvaluateInitializer(Ctx,
nullptr, VD,
this, EStatus,
22737 IsConstantInitialization);
22744 llvm::TimeTraceScope TimeScope(
"EvaluateAsMandatedConstantInitializer", [&] {
22746 llvm::raw_string_ostream OS(Name);
22751 return ::doEvaluateInitializer(Ctx, &SProxy, VD,
this, EStatus,
22756 bool IsConstantDestruction,
22774 EStatus.
Diag = &Notes;
22792 std::move(DestroyedValue)))
22799 VD->
getLocation(), EStatus, IsConstantDestruction) ||
22813 return ::doEvaluateDestruction(
this,
nullptr,
22814 IsConstantDestruction, Notes);
22823 return ::doEvaluateDestruction(
this, &SProxy, IsConstantDestruction, Notes);
22830 "Expression evaluator can't be called on a dependent expression.");
22839 "Expression evaluator can't be called on a dependent expression.");
22841 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
22847 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22848 return EVResult.Val.getInt();
22855 [[maybe_unused]]
bool Result =
22857 assert(
Result &&
"Could not evaluate expression");
22858 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22860 return EVResult.Val.getInt();
22863 EvalInfo Info(Ctx,
nullptr, EVResult,
22865 Info.InConstantContext =
true;
22869 assert(
Result &&
"Could not evaluate expression");
22870 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22872 return EVResult.Val.getInt();
22878 "Expression evaluator can't be called on a dependent expression.");
22880 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
22882 EVResult.Diag =
Diag;
22887 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22888 return EVResult.Val.getInt();
22896 [[maybe_unused]]
bool Result =
22898 assert(
Result &&
"Could not evaluate expression");
22899 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22901 return EVResult.Val.getInt();
22904 EvalInfo Info(Ctx,
nullptr, EVResult,
22906 Info.InConstantContext =
true;
22907 Info.CheckingForUndefinedBehavior =
true;
22911 assert(
Result &&
"Could not evaluate expression");
22912 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22914 return EVResult.Val.getInt();
22919 "Expression evaluator can't be called on a dependent expression.");
22921 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
22935 EvalInfo Info(Ctx,
nullptr, EVResult,
22937 Info.CheckingForUndefinedBehavior =
true;
22942 assert(
Val.isLValue());
22968 IK_ICEIfUnevaluated,
22984static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
23000 EvalInfo Info(Ctx,
nullptr, Status,
23003 Info.InConstantContext =
true;
23012 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
23017#define ABSTRACT_STMT(Node)
23018#define STMT(Node, Base) case Expr::Node##Class:
23019#define EXPR(Node, Base)
23020#include "clang/AST/StmtNodes.inc"
23021 case Expr::PredefinedExprClass:
23022 case Expr::FloatingLiteralClass:
23023 case Expr::ImaginaryLiteralClass:
23024 case Expr::StringLiteralClass:
23025 case Expr::ArraySubscriptExprClass:
23026 case Expr::MatrixSingleSubscriptExprClass:
23027 case Expr::MatrixSubscriptExprClass:
23028 case Expr::ArraySectionExprClass:
23029 case Expr::OMPArrayShapingExprClass:
23030 case Expr::OMPIteratorExprClass:
23031 case Expr::CompoundAssignOperatorClass:
23032 case Expr::CompoundLiteralExprClass:
23033 case Expr::ExtVectorElementExprClass:
23034 case Expr::MatrixElementExprClass:
23035 case Expr::DesignatedInitExprClass:
23036 case Expr::ArrayInitLoopExprClass:
23037 case Expr::ArrayInitIndexExprClass:
23038 case Expr::NoInitExprClass:
23039 case Expr::DesignatedInitUpdateExprClass:
23040 case Expr::ImplicitValueInitExprClass:
23041 case Expr::ParenListExprClass:
23042 case Expr::VAArgExprClass:
23043 case Expr::AddrLabelExprClass:
23044 case Expr::StmtExprClass:
23045 case Expr::CXXMemberCallExprClass:
23046 case Expr::CUDAKernelCallExprClass:
23047 case Expr::CXXAddrspaceCastExprClass:
23048 case Expr::CXXDynamicCastExprClass:
23049 case Expr::CXXTypeidExprClass:
23050 case Expr::CXXUuidofExprClass:
23051 case Expr::MSPropertyRefExprClass:
23052 case Expr::MSPropertySubscriptExprClass:
23053 case Expr::CXXNullPtrLiteralExprClass:
23054 case Expr::UserDefinedLiteralClass:
23055 case Expr::CXXThisExprClass:
23056 case Expr::CXXThrowExprClass:
23057 case Expr::CXXNewExprClass:
23058 case Expr::CXXDeleteExprClass:
23059 case Expr::CXXPseudoDestructorExprClass:
23060 case Expr::UnresolvedLookupExprClass:
23061 case Expr::RecoveryExprClass:
23062 case Expr::DependentScopeDeclRefExprClass:
23063 case Expr::DependentTemplateIdExprClass:
23064 case Expr::CXXConstructExprClass:
23065 case Expr::CXXInheritedCtorInitExprClass:
23066 case Expr::CXXStdInitializerListExprClass:
23067 case Expr::CXXBindTemporaryExprClass:
23068 case Expr::ExprWithCleanupsClass:
23069 case Expr::CXXTemporaryObjectExprClass:
23070 case Expr::CXXUnresolvedConstructExprClass:
23071 case Expr::CXXDependentScopeMemberExprClass:
23072 case Expr::UnresolvedMemberExprClass:
23073 case Expr::ObjCStringLiteralClass:
23074 case Expr::ObjCBoxedExprClass:
23075 case Expr::ObjCArrayLiteralClass:
23076 case Expr::ObjCDictionaryLiteralClass:
23077 case Expr::ObjCEncodeExprClass:
23078 case Expr::ObjCMessageExprClass:
23079 case Expr::ObjCSelectorExprClass:
23080 case Expr::ObjCProtocolExprClass:
23081 case Expr::ObjCIvarRefExprClass:
23082 case Expr::ObjCPropertyRefExprClass:
23083 case Expr::ObjCSubscriptRefExprClass:
23084 case Expr::ObjCIsaExprClass:
23085 case Expr::ObjCAvailabilityCheckExprClass:
23086 case Expr::ShuffleVectorExprClass:
23087 case Expr::ConvertVectorExprClass:
23088 case Expr::BlockExprClass:
23090 case Expr::OpaqueValueExprClass:
23091 case Expr::PackExpansionExprClass:
23092 case Expr::SubstNonTypeTemplateParmPackExprClass:
23093 case Expr::FunctionParmPackExprClass:
23094 case Expr::AsTypeExprClass:
23095 case Expr::ObjCIndirectCopyRestoreExprClass:
23096 case Expr::MaterializeTemporaryExprClass:
23097 case Expr::PseudoObjectExprClass:
23098 case Expr::AtomicExprClass:
23099 case Expr::LambdaExprClass:
23100 case Expr::CXXFoldExprClass:
23101 case Expr::CoawaitExprClass:
23102 case Expr::DependentCoawaitExprClass:
23103 case Expr::CoyieldExprClass:
23104 case Expr::SYCLUniqueStableNameExprClass:
23105 case Expr::CXXParenListInitExprClass:
23106 case Expr::HLSLOutArgExprClass:
23107 case Expr::CXXExpansionSelectExprClass:
23110 case Expr::MemberExprClass: {
23113 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
23116 ME = M->getBase()->IgnoreParenImpCasts();
23118 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
23120 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
23128 case Expr::InitListExprClass: {
23139 case Expr::SizeOfPackExprClass:
23140 case Expr::GNUNullExprClass:
23141 case Expr::SourceLocExprClass:
23142 case Expr::EmbedExprClass:
23143 case Expr::OpenACCAsteriskSizeExprClass:
23146 case Expr::PackIndexingExprClass:
23149 case Expr::SubstNonTypeTemplateParmExprClass:
23153 case Expr::ConstantExprClass:
23156 case Expr::ParenExprClass:
23158 case Expr::GenericSelectionExprClass:
23160 case Expr::IntegerLiteralClass:
23161 case Expr::FixedPointLiteralClass:
23162 case Expr::CharacterLiteralClass:
23163 case Expr::ObjCBoolLiteralExprClass:
23164 case Expr::CXXBoolLiteralExprClass:
23165 case Expr::CXXScalarValueInitExprClass:
23166 case Expr::TypeTraitExprClass:
23167 case Expr::ConceptSpecializationExprClass:
23168 case Expr::RequiresExprClass:
23169 case Expr::ArrayTypeTraitExprClass:
23170 case Expr::ExpressionTraitExprClass:
23171 case Expr::CXXNoexceptExprClass:
23172 case Expr::CXXReflectExprClass:
23174 case Expr::CallExprClass:
23175 case Expr::CXXOperatorCallExprClass: {
23184 case Expr::CXXRewrittenBinaryOperatorClass:
23187 case Expr::DeclRefExprClass: {
23201 const VarDecl *VD = dyn_cast<VarDecl>(D);
23208 case Expr::UnaryOperatorClass: {
23231 llvm_unreachable(
"invalid unary operator class");
23233 case Expr::OffsetOfExprClass: {
23242 case Expr::UnaryExprOrTypeTraitExprClass: {
23244 if ((Exp->
getKind() == UETT_SizeOf) &&
23247 if (Exp->
getKind() == UETT_CountOf) {
23254 if (VAT->getElementType()->isArrayType())
23266 case Expr::BinaryOperatorClass: {
23311 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
23314 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
23315 if (REval.isSigned() && REval.isAllOnes()) {
23317 if (LEval.isMinSignedValue())
23318 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
23326 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
23327 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
23333 return Worst(LHSResult, RHSResult);
23339 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
23349 return Worst(LHSResult, RHSResult);
23352 llvm_unreachable(
"invalid binary operator kind");
23354 case Expr::ImplicitCastExprClass:
23355 case Expr::CStyleCastExprClass:
23356 case Expr::CXXFunctionalCastExprClass:
23357 case Expr::CXXStaticCastExprClass:
23358 case Expr::CXXReinterpretCastExprClass:
23359 case Expr::CXXConstCastExprClass:
23360 case Expr::ObjCBridgedCastExprClass: {
23367 APSInt IgnoredVal(DestWidth, !DestSigned);
23372 if (FL->getValue().convertToInteger(IgnoredVal,
23373 llvm::APFloat::rmTowardZero,
23374 &Ignored) & APFloat::opInvalidOp)
23380 case CK_LValueToRValue:
23381 case CK_AtomicToNonAtomic:
23382 case CK_NonAtomicToAtomic:
23384 case CK_IntegralToBoolean:
23385 case CK_IntegralCast:
23391 case Expr::BinaryConditionalOperatorClass: {
23394 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
23396 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
23397 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
23398 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
23400 return FalseResult;
23402 case Expr::ConditionalOperatorClass: {
23410 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
23413 if (CondResult.Kind == IK_NotICE)
23419 if (TrueResult.Kind == IK_NotICE)
23421 if (FalseResult.Kind == IK_NotICE)
23422 return FalseResult;
23423 if (CondResult.Kind == IK_ICEIfUnevaluated)
23425 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
23431 return FalseResult;
23434 case Expr::CXXDefaultArgExprClass:
23436 case Expr::CXXDefaultInitExprClass:
23438 case Expr::ChooseExprClass: {
23441 case Expr::BuiltinBitCastExprClass: {
23442 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
23448 llvm_unreachable(
"Invalid StmtClass!");
23454 llvm::APSInt *
Value,
23455 bool AllowRelaxedEval =
false) {
23472 "Expression evaluator can't be called on a dependent expression.");
23474 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
23480 if (D.Kind != IK_ICE)
23485std::optional<llvm::APSInt>
23487 bool AllowRelaxedEval)
const {
23490 return std::nullopt;
23498 return std::nullopt;
23502 return std::nullopt;
23516 llvm_unreachable(
"ICE cannot be evaluated!");
23521 EvalInfo Info(Ctx,
nullptr, Status,
23523 Info.InConstantContext =
true;
23526 llvm_unreachable(
"ICE cannot be evaluated!");
23533 "Expression evaluator can't be called on a dependent expression.");
23535 return CheckICE(
this, Ctx).Kind == IK_ICE;
23539 bool AllowRelaxedEval)
const {
23541 "Expression evaluator can't be called on a dependent expression.");
23554 Status.ExtendedDiag = AllowRelaxedEval ? &MSRelaxedDiag :
nullptr;
23563 EvalInfo Info(Ctx,
nullptr, Status,
23569 Info.discardCleanups() && !Status.HasSideEffects;
23571 return IsConstExpr && !Status.DiagEmitted;
23579 "Expression evaluator can't be called on a dependent expression.");
23581 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
23583 llvm::raw_string_ostream OS(Name);
23595 if (std::optional<bool> BoolResult =
23597 Args,
This,
this)) {
23604 EvalInfo Info(Ctx,
nullptr, Status,
23606 Info.InConstantContext =
true;
23609 const LValue *ThisPtr =
nullptr;
23612 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
23613 assert(MD &&
"Don't provide `this` for non-methods.");
23614 assert(MD->isImplicitObjectMemberFunction() &&
23615 "Don't provide `this` for methods without an implicit object.");
23617 if (!
This->isValueDependent() &&
23619 !Info.EvalStatus.HasSideEffects)
23620 ThisPtr = &ThisVal;
23624 Info.EvalStatus.HasSideEffects =
false;
23627 CallRef
Call = Info.CurrentCall->createCall(Callee);
23630 unsigned Idx = I - Args.begin();
23631 if (Idx >= Callee->getNumParams())
23633 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
23634 if ((*I)->isValueDependent() ||
23636 Info.EvalStatus.HasSideEffects) {
23638 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
23644 Info.EvalStatus.HasSideEffects =
false;
23649 Info.discardCleanups();
23650 Info.EvalStatus.HasSideEffects =
false;
23653 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
23656 FullExpressionRAII
Scope(Info);
23658 !Info.EvalStatus.HasSideEffects;
23670 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
23672 llvm::raw_string_ostream OS(Name);
23680 Status.
Diag = &Diags;
23683 if (Ctx.getLangOpts().EnableNewConstInterp) {
23688 Ctx.getInterpContext().isPotentialConstantExpr(Settings, FD);
23689 return Diags.empty();
23692 EvalInfo Info(Ctx,
nullptr, Status,
23694 Info.InConstantContext =
true;
23695 Info.CheckingPotentialConstantExpression =
true;
23705 This.set({&VIE, Info.CurrentCall->Index});
23713 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
23719 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
23723 return Diags.empty();
23731 "Expression evaluator can't be called on a dependent expression.");
23735 Status.
Diag = &Diags;
23743 return Diags.empty();
23746 EvalInfo Info(Ctx,
nullptr, Status,
23748 Info.InConstantContext =
true;
23749 Info.CheckingPotentialConstantExpression =
true;
23753 nullptr, CallRef());
23757 return Diags.empty();
23761 unsigned Type)
const {
23762 if (!
getType()->isPointerType())
23763 return std::nullopt;
23777static std::optional<uint64_t>
23779 std::string *StringResult) {
23781 return std::nullopt;
23786 return std::nullopt;
23789 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
23790 String.getLValueBase().dyn_cast<
const Expr *>())) {
23793 if (
Off >= 0 && (uint64_t)
Off <= (uint64_t)Str.size()) {
23795 if (StringResult) {
23797 Str = Str.substr(
Off, *ZeroIndex);
23798 *StringResult = Str;
23801 return ZeroIndex.
value_or(Str.size());
23808 for (uint64_t Strlen = 0; ; ++Strlen) {
23812 return std::nullopt;
23815 else if (StringResult)
23816 StringResult->push_back(Char.
getInt().getExtValue());
23818 return std::nullopt;
23824 std::string StringResult;
23830 return std::nullopt;
23831 return StringResult;
23836 return StringResult;
23837 return std::nullopt;
23840template <
typename T>
23842 const Expr *SizeExpression,
23843 const Expr *PtrExpression,
23855 Info.InConstantContext =
true;
23858 FullExpressionRAII
Scope(Info);
23863 uint64_t Size = SizeValue.getZExtValue();
23866 if constexpr (std::is_same_v<APValue, T>)
23869 if (Size <
Result.max_size())
23876 for (uint64_t I = 0; I < Size; ++I) {
23882 if constexpr (std::is_same_v<APValue, T>) {
23883 Result.getArrayInitializedElt(I) = std::move(Char);
23887 assert(
C.getBitWidth() <= 8 &&
23888 "string element not representable in char");
23890 Result.push_back(
static_cast<char>(
C.getExtValue()));
23901 const Expr *SizeExpression,
23906 PtrExpression, Ctx, SProxy, Status);
23910 const Expr *SizeExpression,
23915 PtrExpression, Ctx, SProxy, Status);
23931struct IsWithinLifetimeHandler {
23934 using result_type = std::optional<bool>;
23935 std::optional<bool> failed() {
return std::nullopt; }
23936 template <
typename T>
23937 std::optional<bool> found(
T &Subobj,
QualType SubobjType,
23941 template <
typename T>
23942 std::optional<bool> found(
T &Subobj, QualType SubobjType) {
23947std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
23948 const CallExpr *E) {
23949 EvalInfo &Info = IEE.Info;
23954 if (!Info.InConstantContext)
23955 return std::nullopt;
23957 const Expr *Arg = E->
getArg(0);
23959 return std::nullopt;
23962 return std::nullopt;
23964 if (Val.allowConstexprUnknown())
23968 bool CalledFromStd =
false;
23969 const auto *
Callee = Info.CurrentCall->getCallee();
23970 if (Callee &&
Callee->isInStdNamespace()) {
23971 const IdentifierInfo *Identifier =
Callee->getIdentifier();
23972 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
23974 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
23976 diag::err_invalid_is_within_lifetime)
23977 << (CalledFromStd ?
"std::is_within_lifetime"
23978 :
"__builtin_is_within_lifetime")
23980 return std::nullopt;
23990 if (Val.isNullPointer() || Val.getLValueBase().isNull())
23992 QualType
T = Val.getLValueBase().getType();
23994 "Pointers to functions should have been typed as function pointers "
23995 "which would have been rejected earlier");
23998 if (Val.getLValueDesignator().isOnePastTheEnd())
24000 assert(Val.getLValueDesignator().isValidSubobject() &&
24001 "Unchecked case for valid subobject");
24005 CompleteObject CO =
24009 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
24014 IsWithinLifetimeHandler handler{Info};
24015 return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
static bool isUnsigned(SValBuilder &SVB, NonLoc Value)
Defines enum values for all the target-independent builtin functions.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr)
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
bool isTemplateArgument(ConstantExprKind Kind)
bool isOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
bool isForManglingOnly(ConstantExprKind Kind)
Determines whether the given kind of constant expression is only ever used for name mangling.
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
@ PointerToMemberFunction
static bool isRead(AccessKinds AK)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of access valid on an indeterminate object value?
static unsigned elementwiseSize(EvalInfo &Info, QualType BaseTy)
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps, bool IsCompleteClass=true)
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result, llvm::function_ref< APInt(const APSInt &)> PackFn)
static bool EvaluateReflection(const Expr *E, APValue &Result, EvalInfo &Info)
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool hlslElementwiseCastHelper(EvalInfo &Info, const Expr *E, QualType DestTy, SmallVectorImpl< APValue > &SrcVals, SmallVectorImpl< QualType > &SrcTypes)
static bool ShouldPropagateBreakContinue(EvalInfo &Info, const Stmt *LoopOrSwitch, ArrayRef< BlockScopeRAII * > Scopes, EvalStmtResult &ESR)
Helper to implement named break/continue.
static bool doEvaluateAsRValue(const Expr *E, Expr::EvalResult &Result, const ASTContext &Ctx, SemaProxy *SProxy, bool InConstantContext)
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
std::optional< APFloat > EvalScalarMinMaxFp(const APFloat &A, const APFloat &B, std::optional< APSInt > RoundingMode, bool IsMin)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static bool handleScalarCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool flattenAPValue(EvalInfo &Info, const Expr *E, APValue Value, QualType BaseTy, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &Types, unsigned Size)
static bool hlslAggSplatHelper(EvalInfo &Info, const Expr *E, APValue &SrcVal, QualType &SrcTy)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
unsigned ConvertBuiltinIDToX86BuiltinID(const ASTContext &Ctx, unsigned BuiltinOp)
Convert a builtin ID to the canonical x86 builtin ID the constant evaluators dispatch on in their x86...
static bool ConvertDoubleToFloatStrict(EvalInfo &Info, const Expr *E, APFloat OrigVal, APValue &Result)
static ICEDiag Worst(ICEDiag A, ICEDiag B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, unsigned Version, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
static bool checkFloatingPointResultForConstantFolding(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given floating-point evaluation result is allowed for compile-time constant folding duri...
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, ConstantExprKind Kind, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op, APSInt &Result)
Perform the given integer operation, which is known to need at most BitWidth bits,...
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal, bool WantObjectRepresentation=false)
Perform an lvalue-to-rvalue conversion on the given glvalue.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAllocKind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
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 bool doEvaluateDestruction(const VarDecl *VD, SemaProxy *SProxy, bool IsConstantDestruction, SmallVectorImpl< PartialDiagnosticAt > &Notes)
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static bool evalShuffleGeneric(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< std::pair< unsigned, int >(unsigned, unsigned)> GetSourceIndex)
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleLValueDirectVirtualBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
static void expandVector(APValue &Vec, unsigned NumElements)
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
static bool IsOpaqueConstantCall(const LValue &LVal)
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
static std::optional< uint64_t > EvaluateBuiltinStrLen(const Expr *E, EvalInfo &Info, std::string *StringResult=nullptr)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static void TryInstantiateFunctionBeforeCall(const FunctionDecl *FD, EvalInfo &Info, SourceLocation Loc)
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 doEvaluateInitializer(const ASTContext &Ctx, SemaProxy *SProxy, const VarDecl *VD, const Expr *E, Expr::EvalResult &EStatus, bool IsConstantInitialization)
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T, bool IsCompleteClass=true)
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static bool EvaluateComparisonResult(EvalInfo &Info, const Expr *E, ComparisonCategoryResult CCR, APValue &Result)
static bool EvaluateMatrix(const Expr *E, APValue &Result, EvalInfo &Info)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout....
bool isGlobalLValue(const ValueDecl *D, const Expr *E)
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue. In some cases, the in-place evaluati...
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result, bool IsCompleteClass=true)
Perform zero-initialization on an object of non-union class type. C++11 [dcl.init]p5: To zero-initial...
static bool EvaluateDestruction(const ASTContext &Ctx, SemaProxy *SProxy, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value, bool AllowRelaxedEval=false)
Evaluate an expression as a C++11 integral constant expression.
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue. This can be legitimately called on expressions which are not glv...
static bool EvaluateReflectionMetafunctionBuiltin(EvalInfo &Info, const CallExpr *E, unsigned BuiltinOp, APValue &Result)
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result, bool IsCompleteClass=true)
Evaluate a constructor call.
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool doEvaluateConstantExpr(Expr::EvalResult &Result, const ASTContext &Ctx, SemaProxy *SProxy, const Expr *E, ConstantExprKind Kind)
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...
bool FunctionDefinitionCanBeLazilyInstantiated(const FunctionDecl *FD)
Whether we can instantiate FD during constant evaluation.
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 bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, SemaProxy &SProxy, Expr::EvalResult &Status)
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 handleDefaultInitValue(QualType T, APValue &Result, bool IsCompleteClass=true)
Get the value to use for a default-initialized object of type T.
static bool EvaluateStdcLoad8(EvalInfo &Info, const CallExpr *E, bool IsBE, bool IsAligned, APSInt &Result)
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static std::optional< uint64_t > tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, bool IsDynamic=false)
Tries to evaluate the __builtin_object_size for E.
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
uint8_t GFNIMul(uint8_t AByte, uint8_t BByte)
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
uint8_t GFNIMultiplicativeInverse(uint8_t Byte)
uint8_t GFNIAffine(uint8_t XByte, const APInt &AQword, const APSInt &Imm, bool Inverse)
APSInt NormalizeRotateAmount(const APSInt &Value, const APSInt &Amount)
Result
Implement __builtin_bit_cast and related operations.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const Pointer &Ptr, bool InvalidBase)
Does Ptr point to the last object AND to a flexible array member?
static bool isModification(AccessKinds AK)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
static bool hasLayout(const RecordDecl *D)
Whether layout (offset and size) information can be queried for D.
a trap message and trap category.
llvm::APInt getValue() const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
unsigned getMatrixNumColumns() const
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
ReflectionKind getReflectionOperandKind() const
APValue & getStructVirtualBase(unsigned i)
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
unsigned getStructNumBases() const
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getMatrixNumRows() const
unsigned getArraySize() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
APValue & getMatrixElt(unsigned Idx)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const TargetInfo * getAuxTargetInfo() const
interp::Context & getInterpContext() const
Returns the clang bytecode interpreter context.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
const VariableArrayType * getAsVariableArrayType(QualType T) const
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
LabelDecl * getLabel() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
uint64_t getValue() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Attr - This represents one attribute.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isRelationalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
SourceLocation getExprLoc() const
static bool isAdditiveOp(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isEqualityOp(Opcode Opc)
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
const BlockDecl * getBlockDecl() const
bool isAuxBuiltinID(unsigned ID) const
Return true if the builtin ID belongs exclusively to the AuxTarget, and false if it belongs to both p...
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool isAmbiguous(CanQualType BaseType) const
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
Represents a base class of a C++ class.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
const Expr * getSubExpr() const
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
SourceLocation getBeginLoc() const LLVM_READONLY
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()
SourceLocation getBeginLoc() const LLVM_READONLY
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
QualType getFunctionObjectParameterReferenceType() const
Return the type of the object pointed by this.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Expr * getPlacementArg(unsigned I)
unsigned getNumPlacementArgs() const
SourceRange getSourceRange() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_range vbases()
capture_const_range captures() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
ReflectionKind getKind() const
const void * getOpaqueValue() const
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.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
unsigned path_size() const
CastKind getCastKind() const
const FieldDecl * getTargetUnionField() const
const CXXBaseSpecifier *const * path_const_iterator
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operation.
This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
Test whether the quantity is a power of two.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
Test whether the quantity equals zero.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the correct result kind for this category.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
CompoundLiteralExpr - [C99 6.5.2.5].
bool hasStaticStorage() const
APValue & getOrCreateStaticValue(ASTContext &Ctx) const
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
body_iterator body_begin()
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
ConditionalOperator - The ?
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
unsigned getSizeBitWidth() const
Return the bit width of the size type.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
uint64_t getLimitedSize() const
Return the size zero-extended to uint64_t or UINT64_MAX if the value is larger than UINT64_MAX.
bool isZeroSize() const
Return true if the size is zero.
const Expr * getSizeExpr() const
Return a pointer to the size expression.
llvm::APInt getSize() const
Return the constant array size as an APInt.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Represents the current source location and context used to determine the value of the source location...
const Expr * getDefaultExpr() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
bool isAnyOperatorNew() const
A decomposition declaration.
auto flat_bindings() const
InitListExpr * getUpdater() const
Designator - A designator in a C99 designated initializer.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static uintptr_t getMaxIndex()
unsigned getIndex() const
DynAllocKind getAllocKind() const
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.
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 EvaluateAsMandatedConstantInitializer(EvalResult &Result, const ASTContext &Ctx, SemaProxy &SProxy, const VarDecl *VD) const
Evaluate an expression that is required by the language to be a constant expression.
bool isValueDependent() const
Determines whether the value of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool EvaluateAsMandatedConstantExpr(EvalResult &Result, const ASTContext &Ctx, SemaProxy &SProxy, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required by the language to be a constant expression.
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue &Result, bool AllowRelaxedEval=false) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
bool EvaluateAsMandatedConstantRValue(EvalResult &Result, const ASTContext &Ctx, SemaProxy &SProxy) const
Evaluate an expression that is required by the language to be a constant expression,...
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsInitializer(const ASTContext &Ctx, const VarDecl *VD, EvalResult &Result, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, SemaProxy &SProxy, EvalResult &Status) const
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
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
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 isImplicitlyInstantiable() const
Determines whether this function is a function template specialization or a member of a class templat...
FunctionDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
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.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
Expr * getResultExpr()
Return the result expression of this controlling expression.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits() const
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
StrictFlexArraysLevelKind
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompatibleWith(ClangABI Version) const
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExpressibleAsConstantInitializer() const
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
bool isWrapType() const
Returns true if it is a OverflowBehaviorType of Wrap kind.
Represents a struct/union/class.
unsigned getNumFields() const
Returns the number of fields (non-static data members) in this record.
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
bool isSatisfied() const
Whether or not the requires clause is satisfied.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
Classes implementing SemaProxy present a restricted view of the (possibly mutating) actions and queri...
virtual void instantiateFunctionDefinition(SourceLocation PointOfInstantiation, FunctionDecl *Function)=0
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
std::string printToString(const SourceManager &SM) const
CompoundStmt * getSubStmt()
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
UnsignedOrNone findZeroCodeUnit(unsigned StartIndex=0) const
Scan the string literal contents for a code unit with value 0.
unsigned getLength() const
uint32_t getCodeUnit(size_t I) const
Return the code unit at the given position.
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
StringRef getString() const
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Exposes information about the current target.
unsigned getNewAlign() const
Return the largest alignment for which a suitably-sized allocation with 'operator new(size_t)' is gua...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned getLongLongAlign() const
unsigned getLongDoubleAlign() const
unsigned size() const
Retrieve the number of template arguments in this template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
@ Type
The template argument is a type.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
bool isStoredAsComparisonResult() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isCountAttributedType() const
bool isConstantMatrixType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() 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,...
const Type * getArrayElementTypeNoTypeQual() const
If this is an array type, return the element type of the array, potentially with type qualifiers miss...
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
bool isStdByteType() 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 isMetaInfoType() const
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 evaluateConstantDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes, SemaProxy &SProxy) const
Evaluate the destruction of a variable that is required by the language to have constant destruction.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
const APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or nullptr if the value is not yet...
CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const
If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value might be usable in a constant expression, according to the re...
EvaluatedStmt * ensureEvaluatedStmt() const
Convert the initializer for this declaration to the elaborated EvaluatedStmt form,...
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool isCXXForRangeImplicitVar() const
Whether this variable is the implicit '__range' variable in C++ range-based for loops.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Expr * getSizeExpr() const
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
std::optional< uint64_t > tryEvaluateObjectSize(const EvalSettings &Settings, const Expr *E, unsigned Kind, bool IsDynamic)
If.
bool evaluateString(const EvalSettings &Settings, const Expr *E, std::string &Result)
Evaluate.
bool evaluateDestruction(const EvalSettings &Settings, const VarDecl *VD, APValue Value)
Evaluates the destruction of a variable.
std::optional< bool > evaluateWithSubstitution(const EvalSettings &Settings, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This, const Expr *Condition)
bool evaluate(const EvalSettings &Settings, const Expr *E, APValue &Result)
Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion.
bool evaluateAsInitializer(const EvalSettings &Settings, const VarDecl *VD, const Expr *Init, APValue &Result)
Evaluates a toplevel initializer.
bool evaluateAsRValue(const EvalSettings &Settings, const Expr *E, APValue &Result)
Evaluates a toplevel expression as an rvalue.
bool evaluateCharRange(const EvalSettings &Settings, const Expr *SizeExpr, const Expr *PtrExpr, APValue &Result)
std::optional< uint64_t > evaluateStrlen(const EvalSettings &Settings, const Expr *E)
Evalute.
void isPotentialConstantExprUnevaluated(const EvalSettings &Settings, const Expr *E, const FunctionDecl *FD)
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
uint32_t Literal
Literals are represented as positive integers.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
std::optional< llvm::AllocTokenMetadata > getAllocTokenMetadata(QualType T, const ASTContext &Ctx)
Get the information required for construction of an allocation token ID.
QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx, const CastExpr *CastE)
Infer the possible allocated type from an allocation call expression.
bool Sub(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool This(InterpState &S, CodePtr OpPC)
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
void info(bool Verbose, unsigned Level, const char *Fmt, Ts &&...Args)
Prints an indented note to stderr when Verbose is set.
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
DynAllocKind
Kind of source for a dynamic allocation.
const Expr * findStructFieldAccess(const Expr *E, const Expr **OutArrayIndex=nullptr, QualType *OutArrayElementTy=nullptr)
Walk E through parens, implicit casts, unary &/*, array subscripts and comma operators to find the he...
bool hasSpecificAttr(const Container &container)
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
Expr::ConstantExprKind ConstantExprKind
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
CheckSubobjectKind
The order of this enum is important for diagnostics.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
@ Off
Never emit colors regardless of the output stream.
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)
@ 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
CharUnits GetAlignOfDynamicAlloc(const ASTContext &Ctx, QualType AllocType, DynAllocKind AllocKind)
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::dependencies::ModuleID &ID)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 __builtin_riscv_mqwacc_i64 __packed_splat4 uint16_t
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_t
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 __builtin_riscv_mqwacc_i64 uint8_t
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_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.
unsigned HasConstantDestruction
Whether this variable is known to have constant destruction.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool isGlobalLValue() const
Return true if the evaluated lvalue expression is global.
EvalStatus is a struct with detailed info about an evaluation in progress.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
bool HasSideEffects
Whether the evaluated expression has side effects.
unsigned SuppressLambdaBody
Whether to suppress printing the body of a lambda.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
bool CheckingForUndefinedBehavior
bool CheckingPotentialConstantExpression
DenseMapInfo< APValue::LValueBase > Base
static unsigned getHashValue(const ObjectUnderConstruction &Object)
static bool isEqual(const ObjectUnderConstruction &LHS, const ObjectUnderConstruction &RHS)